diff options
| -rw-r--r-- | include/net/ip_vs.h | 34 | ||||
| -rw-r--r-- | net/ipv4/ipvs/Makefile | 2 | ||||
| -rw-r--r-- | net/ipv4/ipvs/ip_vs_conn.c | 9 | ||||
| -rw-r--r-- | net/ipv4/ipvs/ip_vs_core.c | 3 | ||||
| -rw-r--r-- | net/ipv4/ipvs/ip_vs_timer.c | 264 |
5 files changed, 6 insertions, 306 deletions
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index 772d67c971f5..92336b4d945c 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h @@ -408,17 +408,6 @@ union ip_vs_tphdr { /* - * Slow timer for IPVS connections - */ -struct sltimer_list { - struct list_head list; - unsigned long expires; - unsigned long data; - void (*function)(unsigned long); -}; - - -/* * Delta sequence info structure * Each ip_vs_conn has 2 (output AND input seq. changes). * Only used in the VS/NAT. @@ -535,7 +524,7 @@ struct ip_vs_conn { /* counter and timer */ atomic_t refcnt; /* reference count */ - struct sltimer_list timer; /* Expiration timer */ + struct timer_list timer; /* Expiration timer */ volatile unsigned long timeout; /* timeout */ /* Flags and state transition */ @@ -939,27 +928,6 @@ extern int ip_vs_new_estimator(struct ip_vs_stats *stats); extern void ip_vs_kill_estimator(struct ip_vs_stats *stats); extern void ip_vs_zero_estimator(struct ip_vs_stats *stats); - -/* - * Slow timer functions for IPVS - * (from ip_vs_timer.c) - */ -extern void add_sltimer(struct sltimer_list *timer); -extern int del_sltimer(struct sltimer_list *timer); -extern void mod_sltimer(struct sltimer_list *timer, unsigned long expires); -extern void ip_vs_sltimer_init(void); -extern void ip_vs_sltimer_cleanup(void); -static inline void init_sltimer(struct sltimer_list *timer) -{ - timer->list.next = timer->list.prev = NULL; -} - -static inline int sltimer_pending(const struct sltimer_list *timer) -{ - return timer->list.next != NULL; -} - - /* * Various IPVS packet transmitters (from ip_vs_xmit.c) */ diff --git a/net/ipv4/ipvs/Makefile b/net/ipv4/ipvs/Makefile index a0079d237d82..15fcc9e41ef1 100644 --- a/net/ipv4/ipvs/Makefile +++ b/net/ipv4/ipvs/Makefile @@ -16,7 +16,7 @@ ip_vs_proto-objs-$(CONFIG_IP_VS_PROTO_ESP) += ip_vs_proto_esp.o ip_vs_proto-objs-$(CONFIG_IP_VS_PROTO_AH) += ip_vs_proto_ah.o ip_vs-objs := ip_vs_conn.o ip_vs_core.o ip_vs_ctl.o ip_vs_sched.o \ - ip_vs_xmit.o ip_vs_timer.o ip_vs_app.o ip_vs_sync.o \ + ip_vs_xmit.o ip_vs_app.o ip_vs_sync.o \ ip_vs_est.o ip_vs_proto.o ip_vs_proto_icmp.o \ $(ip_vs_proto-objs-y) diff --git a/net/ipv4/ipvs/ip_vs_conn.c b/net/ipv4/ipvs/ip_vs_conn.c index 6b8806205f5e..73de3e8e8779 100644 --- a/net/ipv4/ipvs/ip_vs_conn.c +++ b/net/ipv4/ipvs/ip_vs_conn.c @@ -282,7 +282,7 @@ struct ip_vs_conn *ip_vs_conn_out_get void ip_vs_conn_put(struct ip_vs_conn *cp) { /* reset it expire in its timeout */ - mod_sltimer(&cp->timer, jiffies+cp->timeout); + mod_timer(&cp->timer, jiffies+cp->timeout); __ip_vs_conn_put(cp); } @@ -508,8 +508,7 @@ static void ip_vs_conn_expire(unsigned long data) */ if (likely(atomic_read(&cp->refcnt) == 1)) { /* make sure that there is no timer on it now */ - if (sltimer_pending(&cp->timer)) - del_sltimer(&cp->timer); + del_timer_sync(&cp->timer); /* does anybody control me? */ if (cp->control) @@ -542,7 +541,7 @@ static void ip_vs_conn_expire(unsigned long data) void ip_vs_conn_expire_now(struct ip_vs_conn *cp) { cp->timeout = 0; - mod_sltimer(&cp->timer, jiffies); + mod_timer(&cp->timer, jiffies); __ip_vs_conn_put(cp); } @@ -566,7 +565,7 @@ ip_vs_conn_new(int proto, __u32 caddr, __u16 cport, __u32 vaddr, __u16 vport, memset(cp, 0, sizeof(*cp)); INIT_LIST_HEAD(&cp->c_list); - init_sltimer(&cp->timer); + init_timer(&cp->timer); cp->timer.data = (unsigned long)cp; cp->timer.function = ip_vs_conn_expire; cp->protocol = proto; diff --git a/net/ipv4/ipvs/ip_vs_core.c b/net/ipv4/ipvs/ip_vs_core.c index 6440fde1c8aa..5695301dc253 100644 --- a/net/ipv4/ipvs/ip_vs_core.c +++ b/net/ipv4/ipvs/ip_vs_core.c @@ -1092,7 +1092,6 @@ static int __init ip_vs_init(void) goto cleanup_nothing; } - ip_vs_sltimer_init(); ip_vs_protocol_init(); ret = ip_vs_app_init(); @@ -1144,7 +1143,6 @@ static int __init ip_vs_init(void) ip_vs_app_cleanup(); cleanup_protocol: ip_vs_protocol_cleanup(); - ip_vs_sltimer_cleanup(); ip_vs_control_cleanup(); cleanup_nothing: return ret; @@ -1159,7 +1157,6 @@ static void __exit ip_vs_cleanup(void) ip_vs_conn_cleanup(); ip_vs_app_cleanup(); ip_vs_protocol_cleanup(); - ip_vs_sltimer_cleanup(); ip_vs_control_cleanup(); IP_VS_INFO("ipvs unloaded.\n"); } diff --git a/net/ipv4/ipvs/ip_vs_timer.c b/net/ipv4/ipvs/ip_vs_timer.c deleted file mode 100644 index 03efb49fce0f..000000000000 --- a/net/ipv4/ipvs/ip_vs_timer.c +++ /dev/null @@ -1,264 +0,0 @@ -/* - * IPVS An implementation of the IP virtual server support for the - * LINUX operating system. IPVS is now implemented as a module - * over the Netfilter framework. IPVS can be used to build a - * high-performance and highly available server based on a - * cluster of servers. - * - * Version: $Id: ip_vs_timer.c,v 1.11 2003/06/08 09:31:19 wensong Exp $ - * - * Authors: Wensong Zhang <wensong@linuxvirtualserver.org> - * Julian Anastasov <ja@ssi.bg> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - * - * Changes: - * - */ -#include <linux/kernel.h> -#include <linux/types.h> -#include <linux/timer.h> - -#include <net/ip_vs.h> - -/* - * The following block implements slow timers for IPVS, most code is stolen - * from linux/kernel/timer.c. - * Slow timer is used to avoid the overhead of cascading timers, when lots - * of connection entries (>50,000) are cluttered in the system. - */ -#define SHIFT_BITS 6 -#define TVN_BITS 8 -#define TVR_BITS 10 -#define TVN_SIZE (1 << TVN_BITS) -#define TVR_SIZE (1 << TVR_BITS) -#define TVN_MASK (TVN_SIZE - 1) -#define TVR_MASK (TVR_SIZE - 1) - -struct sltimer_vec { - int index; - struct list_head vec[TVN_SIZE]; -}; - -struct sltimer_vec_root { - int index; - struct list_head vec[TVR_SIZE]; -}; - -static struct sltimer_vec sltv3 = { 0 }; -static struct sltimer_vec sltv2 = { 0 }; -static struct sltimer_vec_root sltv1 = { 0 }; - -static struct sltimer_vec * const sltvecs[] = { - (struct sltimer_vec *)&sltv1, &sltv2, &sltv3 -}; - -#define NOOF_SLTVECS (sizeof(sltvecs) / sizeof(sltvecs[0])) - -static void init_sltimervecs(void) -{ - int i; - - for (i = 0; i < TVN_SIZE; i++) { - INIT_LIST_HEAD(sltv3.vec + i); - INIT_LIST_HEAD(sltv2.vec + i); - } - for (i = 0; i < TVR_SIZE; i++) - INIT_LIST_HEAD(sltv1.vec + i); -} - -static unsigned long sltimer_jiffies = 0; - -static inline void internal_add_sltimer(struct sltimer_list *timer) -{ - /* - * must hold the sltimer lock when calling this - */ - unsigned long expires = timer->expires; - unsigned long idx = expires - sltimer_jiffies; - struct list_head * vec; - - if (idx < 1 << (SHIFT_BITS + TVR_BITS)) { - int i = (expires >> SHIFT_BITS) & TVR_MASK; - vec = sltv1.vec + i; - } else if (idx < 1 << (SHIFT_BITS + TVR_BITS + TVN_BITS)) { - int i = (expires >> (SHIFT_BITS+TVR_BITS)) & TVN_MASK; - vec = sltv2.vec + i; - } else if ((signed long) idx < 0) { - /* - * can happen if you add a timer with expires == jiffies, - * or you set a timer to go off in the past - */ - vec = sltv1.vec + sltv1.index; - } else if (idx <= 0xffffffffUL) { - int i = (expires >> (SHIFT_BITS+TVR_BITS+TVN_BITS)) & TVN_MASK; - vec = sltv3.vec + i; - } else { - /* Can only get here on architectures with 64-bit jiffies */ - INIT_LIST_HEAD(&timer->list); - } - /* - * Timers are FIFO! - */ - list_add(&timer->list, vec->prev); -} - - -static spinlock_t __ip_vs_sltimerlist_lock = SPIN_LOCK_UNLOCKED; - -void add_sltimer(struct sltimer_list *timer) -{ - spin_lock(&__ip_vs_sltimerlist_lock); - if (timer->list.next) - goto bug; - internal_add_sltimer(timer); - out: - spin_unlock(&__ip_vs_sltimerlist_lock); - return; - - bug: - printk("bug: kernel sltimer added twice at %p.\n", - __builtin_return_address(0)); - goto out; -} - -static inline int detach_sltimer(struct sltimer_list *timer) -{ - if (!sltimer_pending(timer)) - return 0; - list_del(&timer->list); - return 1; -} - -void mod_sltimer(struct sltimer_list *timer, unsigned long expires) -{ - int ret; - - spin_lock(&__ip_vs_sltimerlist_lock); - timer->expires = expires; - ret = detach_sltimer(timer); - internal_add_sltimer(timer); - spin_unlock(&__ip_vs_sltimerlist_lock); -} - -int del_sltimer(struct sltimer_list * timer) -{ - int ret; - - spin_lock(&__ip_vs_sltimerlist_lock); - ret = detach_sltimer(timer); - timer->list.next = timer->list.prev = 0; - spin_unlock(&__ip_vs_sltimerlist_lock); - return ret; -} - - -static inline void cascade_sltimers(struct sltimer_vec *tv) -{ - /* - * cascade all the timers from tv up one level - */ - struct list_head *head, *curr, *next; - - head = tv->vec + tv->index; - curr = head->next; - - /* - * We are removing _all_ timers from the list, so we don't have to - * detach them individually, just clear the list afterwards. - */ - while (curr != head) { - struct sltimer_list *tmp; - - tmp = list_entry(curr, struct sltimer_list, list); - next = curr->next; - list_del(curr); // not needed - internal_add_sltimer(tmp); - curr = next; - } - INIT_LIST_HEAD(head); - tv->index = (tv->index + 1) & TVN_MASK; -} - -static inline void run_sltimer_list(void) -{ - spin_lock(&__ip_vs_sltimerlist_lock); - while ((long)(jiffies - sltimer_jiffies) >= 0) { - struct list_head *head, *curr; - if (!sltv1.index) { - int n = 1; - do { - cascade_sltimers(sltvecs[n]); - } while (sltvecs[n]->index == 1 && ++n < NOOF_SLTVECS); - } - repeat: - head = sltv1.vec + sltv1.index; - curr = head->next; - if (curr != head) { - struct sltimer_list *timer; - void (*fn)(unsigned long); - unsigned long data; - - timer = list_entry(curr, struct sltimer_list, list); - fn = timer->function; - data= timer->data; - - detach_sltimer(timer); - timer->list.next = timer->list.prev = NULL; - spin_unlock(&__ip_vs_sltimerlist_lock); - fn(data); - spin_lock(&__ip_vs_sltimerlist_lock); - goto repeat; - } - sltimer_jiffies += 1<<SHIFT_BITS; - sltv1.index = (sltv1.index + 1) & TVR_MASK; - } - spin_unlock(&__ip_vs_sltimerlist_lock); -} - -static struct timer_list slow_timer; - -/* - * Slow timer handler is activated every second - */ -#define SLTIMER_PERIOD 1*HZ - -static void sltimer_handler(unsigned long data) -{ - run_sltimer_list(); - - update_defense_level(); - if (atomic_read(&ip_vs_dropentry)) - ip_vs_random_dropentry(); - - mod_timer(&slow_timer, (jiffies + SLTIMER_PERIOD)); -} - - -void ip_vs_sltimer_init(void) -{ - /* initialize the slow timer vectors */ - init_sltimervecs(); - - /* initialize the slow timer jiffies and the vector indexes */ - sltimer_jiffies = jiffies; - sltv1.index = (sltimer_jiffies >> SHIFT_BITS) & TVR_MASK; - sltv2.index = (sltimer_jiffies >> (SHIFT_BITS + TVR_BITS)) & TVN_MASK; - sltv3.index = (sltimer_jiffies >> (SHIFT_BITS + TVR_BITS + TVN_BITS)) - & TVN_MASK; - - /* Hook the slow_timer handler in the system timer */ - init_timer(&slow_timer); - slow_timer.function = sltimer_handler; - slow_timer.expires = jiffies+SLTIMER_PERIOD; - add_timer(&slow_timer); -} - - -void ip_vs_sltimer_cleanup(void) -{ - del_timer_sync(&slow_timer); -} |
