aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/ipvs
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/ipvs')
-rw-r--r--net/ipv4/ipvs/ip_vs_app.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_conn.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_ctl.c27
-rw-r--r--net/ipv4/ipvs/ip_vs_dh.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_est.c116
-rw-r--r--net/ipv4/ipvs/ip_vs_lblc.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_lblcr.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_lc.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_nq.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_proto.c4
-rw-r--r--net/ipv4/ipvs/ip_vs_rr.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_sched.c4
-rw-r--r--net/ipv4/ipvs/ip_vs_sed.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_sh.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_sync.c4
-rw-r--r--net/ipv4/ipvs/ip_vs_wlc.c2
-rw-r--r--net/ipv4/ipvs/ip_vs_wrr.c2
17 files changed, 77 insertions, 102 deletions
diff --git a/net/ipv4/ipvs/ip_vs_app.c b/net/ipv4/ipvs/ip_vs_app.c
index 1f1897a1a702..201b8ea3020d 100644
--- a/net/ipv4/ipvs/ip_vs_app.c
+++ b/net/ipv4/ipvs/ip_vs_app.c
@@ -608,7 +608,7 @@ int ip_vs_skb_replace(struct sk_buff *skb, gfp_t pri,
608} 608}
609 609
610 610
611int ip_vs_app_init(void) 611int __init ip_vs_app_init(void)
612{ 612{
613 /* we will replace it with proc_net_ipvs_create() soon */ 613 /* we will replace it with proc_net_ipvs_create() soon */
614 proc_net_fops_create(&init_net, "ip_vs_app", 0, &ip_vs_app_fops); 614 proc_net_fops_create(&init_net, "ip_vs_app", 0, &ip_vs_app_fops);
diff --git a/net/ipv4/ipvs/ip_vs_conn.c b/net/ipv4/ipvs/ip_vs_conn.c
index f8bdae47a77f..44a6872dc245 100644
--- a/net/ipv4/ipvs/ip_vs_conn.c
+++ b/net/ipv4/ipvs/ip_vs_conn.c
@@ -965,7 +965,7 @@ static void ip_vs_conn_flush(void)
965} 965}
966 966
967 967
968int ip_vs_conn_init(void) 968int __init ip_vs_conn_init(void)
969{ 969{
970 int idx; 970 int idx;
971 971
diff --git a/net/ipv4/ipvs/ip_vs_ctl.c b/net/ipv4/ipvs/ip_vs_ctl.c
index 9a5ace0b4dd6..6379705a8dcb 100644
--- a/net/ipv4/ipvs/ip_vs_ctl.c
+++ b/net/ipv4/ipvs/ip_vs_ctl.c
@@ -683,9 +683,22 @@ static void
683ip_vs_zero_stats(struct ip_vs_stats *stats) 683ip_vs_zero_stats(struct ip_vs_stats *stats)
684{ 684{
685 spin_lock_bh(&stats->lock); 685 spin_lock_bh(&stats->lock);
686 memset(stats, 0, (char *)&stats->lock - (char *)stats); 686
687 spin_unlock_bh(&stats->lock); 687 stats->conns = 0;
688 stats->inpkts = 0;
689 stats->outpkts = 0;
690 stats->inbytes = 0;
691 stats->outbytes = 0;
692
693 stats->cps = 0;
694 stats->inpps = 0;
695 stats->outpps = 0;
696 stats->inbps = 0;
697 stats->outbps = 0;
698
688 ip_vs_zero_estimator(stats); 699 ip_vs_zero_estimator(stats);
700
701 spin_unlock_bh(&stats->lock);
689} 702}
690 703
691/* 704/*
@@ -1589,7 +1602,7 @@ static struct ctl_table vs_vars[] = {
1589 { .ctl_name = 0 } 1602 { .ctl_name = 0 }
1590}; 1603};
1591 1604
1592struct ctl_path net_vs_ctl_path[] = { 1605const struct ctl_path net_vs_ctl_path[] = {
1593 { .procname = "net", .ctl_name = CTL_NET, }, 1606 { .procname = "net", .ctl_name = CTL_NET, },
1594 { .procname = "ipv4", .ctl_name = NET_IPV4, }, 1607 { .procname = "ipv4", .ctl_name = NET_IPV4, },
1595 { .procname = "vs", }, 1608 { .procname = "vs", },
@@ -1784,7 +1797,9 @@ static const struct file_operations ip_vs_info_fops = {
1784 1797
1785#endif 1798#endif
1786 1799
1787struct ip_vs_stats ip_vs_stats; 1800struct ip_vs_stats ip_vs_stats = {
1801 .lock = __SPIN_LOCK_UNLOCKED(ip_vs_stats.lock),
1802};
1788 1803
1789#ifdef CONFIG_PROC_FS 1804#ifdef CONFIG_PROC_FS
1790static int ip_vs_stats_show(struct seq_file *seq, void *v) 1805static int ip_vs_stats_show(struct seq_file *seq, void *v)
@@ -2306,7 +2321,7 @@ static struct nf_sockopt_ops ip_vs_sockopts = {
2306}; 2321};
2307 2322
2308 2323
2309int ip_vs_control_init(void) 2324int __init ip_vs_control_init(void)
2310{ 2325{
2311 int ret; 2326 int ret;
2312 int idx; 2327 int idx;
@@ -2333,8 +2348,6 @@ int ip_vs_control_init(void)
2333 INIT_LIST_HEAD(&ip_vs_rtable[idx]); 2348 INIT_LIST_HEAD(&ip_vs_rtable[idx]);
2334 } 2349 }
2335 2350
2336 memset(&ip_vs_stats, 0, sizeof(ip_vs_stats));
2337 spin_lock_init(&ip_vs_stats.lock);
2338 ip_vs_new_estimator(&ip_vs_stats); 2351 ip_vs_new_estimator(&ip_vs_stats);
2339 2352
2340 /* Hook the defense timer */ 2353 /* Hook the defense timer */
diff --git a/net/ipv4/ipvs/ip_vs_dh.c b/net/ipv4/ipvs/ip_vs_dh.c
index 8afc1503ed20..fa66824d264f 100644
--- a/net/ipv4/ipvs/ip_vs_dh.c
+++ b/net/ipv4/ipvs/ip_vs_dh.c
@@ -233,6 +233,7 @@ static struct ip_vs_scheduler ip_vs_dh_scheduler =
233 .name = "dh", 233 .name = "dh",
234 .refcnt = ATOMIC_INIT(0), 234 .refcnt = ATOMIC_INIT(0),
235 .module = THIS_MODULE, 235 .module = THIS_MODULE,
236 .n_list = LIST_HEAD_INIT(ip_vs_dh_scheduler.n_list),
236 .init_service = ip_vs_dh_init_svc, 237 .init_service = ip_vs_dh_init_svc,
237 .done_service = ip_vs_dh_done_svc, 238 .done_service = ip_vs_dh_done_svc,
238 .update_service = ip_vs_dh_update_svc, 239 .update_service = ip_vs_dh_update_svc,
@@ -242,7 +243,6 @@ static struct ip_vs_scheduler ip_vs_dh_scheduler =
242 243
243static int __init ip_vs_dh_init(void) 244static int __init ip_vs_dh_init(void)
244{ 245{
245 INIT_LIST_HEAD(&ip_vs_dh_scheduler.n_list);
246 return register_ip_vs_scheduler(&ip_vs_dh_scheduler); 246 return register_ip_vs_scheduler(&ip_vs_dh_scheduler);
247} 247}
248 248
diff --git a/net/ipv4/ipvs/ip_vs_est.c b/net/ipv4/ipvs/ip_vs_est.c
index bc04eedd6dbb..5a20f93bd7f9 100644
--- a/net/ipv4/ipvs/ip_vs_est.c
+++ b/net/ipv4/ipvs/ip_vs_est.c
@@ -17,6 +17,7 @@
17#include <linux/types.h> 17#include <linux/types.h>
18#include <linux/interrupt.h> 18#include <linux/interrupt.h>
19#include <linux/sysctl.h> 19#include <linux/sysctl.h>
20#include <linux/list.h>
20 21
21#include <net/ip_vs.h> 22#include <net/ip_vs.h>
22 23
@@ -44,28 +45,11 @@
44 */ 45 */
45 46
46 47
47struct ip_vs_estimator 48static void estimation_timer(unsigned long arg);
48{
49 struct ip_vs_estimator *next;
50 struct ip_vs_stats *stats;
51
52 u32 last_conns;
53 u32 last_inpkts;
54 u32 last_outpkts;
55 u64 last_inbytes;
56 u64 last_outbytes;
57
58 u32 cps;
59 u32 inpps;
60 u32 outpps;
61 u32 inbps;
62 u32 outbps;
63};
64
65 49
66static struct ip_vs_estimator *est_list = NULL; 50static LIST_HEAD(est_list);
67static DEFINE_RWLOCK(est_lock); 51static DEFINE_SPINLOCK(est_lock);
68static struct timer_list est_timer; 52static DEFINE_TIMER(est_timer, estimation_timer, 0, 0);
69 53
70static void estimation_timer(unsigned long arg) 54static void estimation_timer(unsigned long arg)
71{ 55{
@@ -76,9 +60,9 @@ static void estimation_timer(unsigned long arg)
76 u64 n_inbytes, n_outbytes; 60 u64 n_inbytes, n_outbytes;
77 u32 rate; 61 u32 rate;
78 62
79 read_lock(&est_lock); 63 spin_lock(&est_lock);
80 for (e = est_list; e; e = e->next) { 64 list_for_each_entry(e, &est_list, list) {
81 s = e->stats; 65 s = container_of(e, struct ip_vs_stats, est);
82 66
83 spin_lock(&s->lock); 67 spin_lock(&s->lock);
84 n_conns = s->conns; 68 n_conns = s->conns;
@@ -114,19 +98,16 @@ static void estimation_timer(unsigned long arg)
114 s->outbps = (e->outbps+0xF)>>5; 98 s->outbps = (e->outbps+0xF)>>5;
115 spin_unlock(&s->lock); 99 spin_unlock(&s->lock);
116 } 100 }
117 read_unlock(&est_lock); 101 spin_unlock(&est_lock);
118 mod_timer(&est_timer, jiffies + 2*HZ); 102 mod_timer(&est_timer, jiffies + 2*HZ);
119} 103}
120 104
121int ip_vs_new_estimator(struct ip_vs_stats *stats) 105void ip_vs_new_estimator(struct ip_vs_stats *stats)
122{ 106{
123 struct ip_vs_estimator *est; 107 struct ip_vs_estimator *est = &stats->est;
124 108
125 est = kzalloc(sizeof(*est), GFP_KERNEL); 109 INIT_LIST_HEAD(&est->list);
126 if (est == NULL)
127 return -ENOMEM;
128 110
129 est->stats = stats;
130 est->last_conns = stats->conns; 111 est->last_conns = stats->conns;
131 est->cps = stats->cps<<10; 112 est->cps = stats->cps<<10;
132 113
@@ -142,59 +123,40 @@ int ip_vs_new_estimator(struct ip_vs_stats *stats)
142 est->last_outbytes = stats->outbytes; 123 est->last_outbytes = stats->outbytes;
143 est->outbps = stats->outbps<<5; 124 est->outbps = stats->outbps<<5;
144 125
145 write_lock_bh(&est_lock); 126 spin_lock_bh(&est_lock);
146 est->next = est_list; 127 if (list_empty(&est_list))
147 if (est->next == NULL) { 128 mod_timer(&est_timer, jiffies + 2 * HZ);
148 setup_timer(&est_timer, estimation_timer, 0); 129 list_add(&est->list, &est_list);
149 est_timer.expires = jiffies + 2*HZ; 130 spin_unlock_bh(&est_lock);
150 add_timer(&est_timer);
151 }
152 est_list = est;
153 write_unlock_bh(&est_lock);
154 return 0;
155} 131}
156 132
157void ip_vs_kill_estimator(struct ip_vs_stats *stats) 133void ip_vs_kill_estimator(struct ip_vs_stats *stats)
158{ 134{
159 struct ip_vs_estimator *est, **pest; 135 struct ip_vs_estimator *est = &stats->est;
160 int killed = 0; 136
161 137 spin_lock_bh(&est_lock);
162 write_lock_bh(&est_lock); 138 list_del(&est->list);
163 pest = &est_list; 139 while (list_empty(&est_list) && try_to_del_timer_sync(&est_timer) < 0) {
164 while ((est=*pest) != NULL) { 140 spin_unlock_bh(&est_lock);
165 if (est->stats != stats) { 141 cpu_relax();
166 pest = &est->next; 142 spin_lock_bh(&est_lock);
167 continue;
168 }
169 *pest = est->next;
170 kfree(est);
171 killed++;
172 } 143 }
173 if (killed && est_list == NULL) 144 spin_unlock_bh(&est_lock);
174 del_timer_sync(&est_timer);
175 write_unlock_bh(&est_lock);
176} 145}
177 146
178void ip_vs_zero_estimator(struct ip_vs_stats *stats) 147void ip_vs_zero_estimator(struct ip_vs_stats *stats)
179{ 148{
180 struct ip_vs_estimator *e; 149 struct ip_vs_estimator *est = &stats->est;
181 150
182 write_lock_bh(&est_lock); 151 /* set counters zero, caller must hold the stats->lock lock */
183 for (e = est_list; e; e = e->next) { 152 est->last_inbytes = 0;
184 if (e->stats != stats) 153 est->last_outbytes = 0;
185 continue; 154 est->last_conns = 0;
186 155 est->last_inpkts = 0;
187 /* set counters zero */ 156 est->last_outpkts = 0;
188 e->last_conns = 0; 157 est->cps = 0;
189 e->last_inpkts = 0; 158 est->inpps = 0;
190 e->last_outpkts = 0; 159 est->outpps = 0;
191 e->last_inbytes = 0; 160 est->inbps = 0;
192 e->last_outbytes = 0; 161 est->outbps = 0;
193 e->cps = 0;
194 e->inpps = 0;
195 e->outpps = 0;
196 e->inbps = 0;
197 e->outbps = 0;
198 }
199 write_unlock_bh(&est_lock);
200} 162}
diff --git a/net/ipv4/ipvs/ip_vs_lblc.c b/net/ipv4/ipvs/ip_vs_lblc.c
index 0efa3db4b180..7a6a319f544a 100644
--- a/net/ipv4/ipvs/ip_vs_lblc.c
+++ b/net/ipv4/ipvs/ip_vs_lblc.c
@@ -539,6 +539,7 @@ static struct ip_vs_scheduler ip_vs_lblc_scheduler =
539 .name = "lblc", 539 .name = "lblc",
540 .refcnt = ATOMIC_INIT(0), 540 .refcnt = ATOMIC_INIT(0),
541 .module = THIS_MODULE, 541 .module = THIS_MODULE,
542 .n_list = LIST_HEAD_INIT(ip_vs_lblc_scheduler.n_list),
542 .init_service = ip_vs_lblc_init_svc, 543 .init_service = ip_vs_lblc_init_svc,
543 .done_service = ip_vs_lblc_done_svc, 544 .done_service = ip_vs_lblc_done_svc,
544 .update_service = ip_vs_lblc_update_svc, 545 .update_service = ip_vs_lblc_update_svc,
@@ -550,7 +551,6 @@ static int __init ip_vs_lblc_init(void)
550{ 551{
551 int ret; 552 int ret;
552 553
553 INIT_LIST_HEAD(&ip_vs_lblc_scheduler.n_list);
554 sysctl_header = register_sysctl_paths(net_vs_ctl_path, vs_vars_table); 554 sysctl_header = register_sysctl_paths(net_vs_ctl_path, vs_vars_table);
555 ret = register_ip_vs_scheduler(&ip_vs_lblc_scheduler); 555 ret = register_ip_vs_scheduler(&ip_vs_lblc_scheduler);
556 if (ret) 556 if (ret)
diff --git a/net/ipv4/ipvs/ip_vs_lblcr.c b/net/ipv4/ipvs/ip_vs_lblcr.c
index 8e3bbeb45138..c234e73968a6 100644
--- a/net/ipv4/ipvs/ip_vs_lblcr.c
+++ b/net/ipv4/ipvs/ip_vs_lblcr.c
@@ -728,6 +728,7 @@ static struct ip_vs_scheduler ip_vs_lblcr_scheduler =
728 .name = "lblcr", 728 .name = "lblcr",
729 .refcnt = ATOMIC_INIT(0), 729 .refcnt = ATOMIC_INIT(0),
730 .module = THIS_MODULE, 730 .module = THIS_MODULE,
731 .n_list = LIST_HEAD_INIT(ip_vs_lblcr_scheduler.n_list),
731 .init_service = ip_vs_lblcr_init_svc, 732 .init_service = ip_vs_lblcr_init_svc,
732 .done_service = ip_vs_lblcr_done_svc, 733 .done_service = ip_vs_lblcr_done_svc,
733 .update_service = ip_vs_lblcr_update_svc, 734 .update_service = ip_vs_lblcr_update_svc,
@@ -739,7 +740,6 @@ static int __init ip_vs_lblcr_init(void)
739{ 740{
740 int ret; 741 int ret;
741 742
742 INIT_LIST_HEAD(&ip_vs_lblcr_scheduler.n_list);
743 sysctl_header = register_sysctl_paths(net_vs_ctl_path, vs_vars_table); 743 sysctl_header = register_sysctl_paths(net_vs_ctl_path, vs_vars_table);
744 ret = register_ip_vs_scheduler(&ip_vs_lblcr_scheduler); 744 ret = register_ip_vs_scheduler(&ip_vs_lblcr_scheduler);
745 if (ret) 745 if (ret)
diff --git a/net/ipv4/ipvs/ip_vs_lc.c b/net/ipv4/ipvs/ip_vs_lc.c
index ac9f08e065d5..ebcdbf75ac65 100644
--- a/net/ipv4/ipvs/ip_vs_lc.c
+++ b/net/ipv4/ipvs/ip_vs_lc.c
@@ -98,6 +98,7 @@ static struct ip_vs_scheduler ip_vs_lc_scheduler = {
98 .name = "lc", 98 .name = "lc",
99 .refcnt = ATOMIC_INIT(0), 99 .refcnt = ATOMIC_INIT(0),
100 .module = THIS_MODULE, 100 .module = THIS_MODULE,
101 .n_list = LIST_HEAD_INIT(ip_vs_lc_scheduler.n_list),
101 .init_service = ip_vs_lc_init_svc, 102 .init_service = ip_vs_lc_init_svc,
102 .done_service = ip_vs_lc_done_svc, 103 .done_service = ip_vs_lc_done_svc,
103 .update_service = ip_vs_lc_update_svc, 104 .update_service = ip_vs_lc_update_svc,
@@ -107,7 +108,6 @@ static struct ip_vs_scheduler ip_vs_lc_scheduler = {
107 108
108static int __init ip_vs_lc_init(void) 109static int __init ip_vs_lc_init(void)
109{ 110{
110 INIT_LIST_HEAD(&ip_vs_lc_scheduler.n_list);
111 return register_ip_vs_scheduler(&ip_vs_lc_scheduler) ; 111 return register_ip_vs_scheduler(&ip_vs_lc_scheduler) ;
112} 112}
113 113
diff --git a/net/ipv4/ipvs/ip_vs_nq.c b/net/ipv4/ipvs/ip_vs_nq.c
index a46bf258d420..92f3a6770031 100644
--- a/net/ipv4/ipvs/ip_vs_nq.c
+++ b/net/ipv4/ipvs/ip_vs_nq.c
@@ -136,6 +136,7 @@ static struct ip_vs_scheduler ip_vs_nq_scheduler =
136 .name = "nq", 136 .name = "nq",
137 .refcnt = ATOMIC_INIT(0), 137 .refcnt = ATOMIC_INIT(0),
138 .module = THIS_MODULE, 138 .module = THIS_MODULE,
139 .n_list = LIST_HEAD_INIT(ip_vs_nq_scheduler.n_list),
139 .init_service = ip_vs_nq_init_svc, 140 .init_service = ip_vs_nq_init_svc,
140 .done_service = ip_vs_nq_done_svc, 141 .done_service = ip_vs_nq_done_svc,
141 .update_service = ip_vs_nq_update_svc, 142 .update_service = ip_vs_nq_update_svc,
@@ -145,7 +146,6 @@ static struct ip_vs_scheduler ip_vs_nq_scheduler =
145 146
146static int __init ip_vs_nq_init(void) 147static int __init ip_vs_nq_init(void)
147{ 148{
148 INIT_LIST_HEAD(&ip_vs_nq_scheduler.n_list);
149 return register_ip_vs_scheduler(&ip_vs_nq_scheduler); 149 return register_ip_vs_scheduler(&ip_vs_nq_scheduler);
150} 150}
151 151
diff --git a/net/ipv4/ipvs/ip_vs_proto.c b/net/ipv4/ipvs/ip_vs_proto.c
index 876714f23d65..6099a88fc200 100644
--- a/net/ipv4/ipvs/ip_vs_proto.c
+++ b/net/ipv4/ipvs/ip_vs_proto.c
@@ -43,7 +43,7 @@ static struct ip_vs_protocol *ip_vs_proto_table[IP_VS_PROTO_TAB_SIZE];
43/* 43/*
44 * register an ipvs protocol 44 * register an ipvs protocol
45 */ 45 */
46static int __used register_ip_vs_protocol(struct ip_vs_protocol *pp) 46static int __used __init register_ip_vs_protocol(struct ip_vs_protocol *pp)
47{ 47{
48 unsigned hash = IP_VS_PROTO_HASH(pp->protocol); 48 unsigned hash = IP_VS_PROTO_HASH(pp->protocol);
49 49
@@ -190,7 +190,7 @@ ip_vs_tcpudp_debug_packet(struct ip_vs_protocol *pp,
190} 190}
191 191
192 192
193int ip_vs_protocol_init(void) 193int __init ip_vs_protocol_init(void)
194{ 194{
195 char protocols[64]; 195 char protocols[64];
196#define REGISTER_PROTOCOL(p) \ 196#define REGISTER_PROTOCOL(p) \
diff --git a/net/ipv4/ipvs/ip_vs_rr.c b/net/ipv4/ipvs/ip_vs_rr.c
index c8db12d39e61..358110d17e59 100644
--- a/net/ipv4/ipvs/ip_vs_rr.c
+++ b/net/ipv4/ipvs/ip_vs_rr.c
@@ -94,6 +94,7 @@ static struct ip_vs_scheduler ip_vs_rr_scheduler = {
94 .name = "rr", /* name */ 94 .name = "rr", /* name */
95 .refcnt = ATOMIC_INIT(0), 95 .refcnt = ATOMIC_INIT(0),
96 .module = THIS_MODULE, 96 .module = THIS_MODULE,
97 .n_list = LIST_HEAD_INIT(ip_vs_rr_scheduler.n_list),
97 .init_service = ip_vs_rr_init_svc, 98 .init_service = ip_vs_rr_init_svc,
98 .done_service = ip_vs_rr_done_svc, 99 .done_service = ip_vs_rr_done_svc,
99 .update_service = ip_vs_rr_update_svc, 100 .update_service = ip_vs_rr_update_svc,
@@ -102,7 +103,6 @@ static struct ip_vs_scheduler ip_vs_rr_scheduler = {
102 103
103static int __init ip_vs_rr_init(void) 104static int __init ip_vs_rr_init(void)
104{ 105{
105 INIT_LIST_HEAD(&ip_vs_rr_scheduler.n_list);
106 return register_ip_vs_scheduler(&ip_vs_rr_scheduler); 106 return register_ip_vs_scheduler(&ip_vs_rr_scheduler);
107} 107}
108 108
diff --git a/net/ipv4/ipvs/ip_vs_sched.c b/net/ipv4/ipvs/ip_vs_sched.c
index b64767309855..a46ad9e35016 100644
--- a/net/ipv4/ipvs/ip_vs_sched.c
+++ b/net/ipv4/ipvs/ip_vs_sched.c
@@ -184,7 +184,7 @@ int register_ip_vs_scheduler(struct ip_vs_scheduler *scheduler)
184 184
185 write_lock_bh(&__ip_vs_sched_lock); 185 write_lock_bh(&__ip_vs_sched_lock);
186 186
187 if (scheduler->n_list.next != &scheduler->n_list) { 187 if (!list_empty(&scheduler->n_list)) {
188 write_unlock_bh(&__ip_vs_sched_lock); 188 write_unlock_bh(&__ip_vs_sched_lock);
189 ip_vs_use_count_dec(); 189 ip_vs_use_count_dec();
190 IP_VS_ERR("register_ip_vs_scheduler(): [%s] scheduler " 190 IP_VS_ERR("register_ip_vs_scheduler(): [%s] scheduler "
@@ -229,7 +229,7 @@ int unregister_ip_vs_scheduler(struct ip_vs_scheduler *scheduler)
229 } 229 }
230 230
231 write_lock_bh(&__ip_vs_sched_lock); 231 write_lock_bh(&__ip_vs_sched_lock);
232 if (scheduler->n_list.next == &scheduler->n_list) { 232 if (list_empty(&scheduler->n_list)) {
233 write_unlock_bh(&__ip_vs_sched_lock); 233 write_unlock_bh(&__ip_vs_sched_lock);
234 IP_VS_ERR("unregister_ip_vs_scheduler(): [%s] scheduler " 234 IP_VS_ERR("unregister_ip_vs_scheduler(): [%s] scheduler "
235 "is not in the list. failed\n", scheduler->name); 235 "is not in the list. failed\n", scheduler->name);
diff --git a/net/ipv4/ipvs/ip_vs_sed.c b/net/ipv4/ipvs/ip_vs_sed.c
index 2a7d31358181..77663d84cbd1 100644
--- a/net/ipv4/ipvs/ip_vs_sed.c
+++ b/net/ipv4/ipvs/ip_vs_sed.c
@@ -138,6 +138,7 @@ static struct ip_vs_scheduler ip_vs_sed_scheduler =
138 .name = "sed", 138 .name = "sed",
139 .refcnt = ATOMIC_INIT(0), 139 .refcnt = ATOMIC_INIT(0),
140 .module = THIS_MODULE, 140 .module = THIS_MODULE,
141 .n_list = LIST_HEAD_INIT(ip_vs_sed_scheduler.n_list),
141 .init_service = ip_vs_sed_init_svc, 142 .init_service = ip_vs_sed_init_svc,
142 .done_service = ip_vs_sed_done_svc, 143 .done_service = ip_vs_sed_done_svc,
143 .update_service = ip_vs_sed_update_svc, 144 .update_service = ip_vs_sed_update_svc,
@@ -147,7 +148,6 @@ static struct ip_vs_scheduler ip_vs_sed_scheduler =
147 148
148static int __init ip_vs_sed_init(void) 149static int __init ip_vs_sed_init(void)
149{ 150{
150 INIT_LIST_HEAD(&ip_vs_sed_scheduler.n_list);
151 return register_ip_vs_scheduler(&ip_vs_sed_scheduler); 151 return register_ip_vs_scheduler(&ip_vs_sed_scheduler);
152} 152}
153 153
diff --git a/net/ipv4/ipvs/ip_vs_sh.c b/net/ipv4/ipvs/ip_vs_sh.c
index b8fdfac65001..7b979e228056 100644
--- a/net/ipv4/ipvs/ip_vs_sh.c
+++ b/net/ipv4/ipvs/ip_vs_sh.c
@@ -230,6 +230,7 @@ static struct ip_vs_scheduler ip_vs_sh_scheduler =
230 .name = "sh", 230 .name = "sh",
231 .refcnt = ATOMIC_INIT(0), 231 .refcnt = ATOMIC_INIT(0),
232 .module = THIS_MODULE, 232 .module = THIS_MODULE,
233 .n_list = LIST_HEAD_INIT(ip_vs_sh_scheduler.n_list),
233 .init_service = ip_vs_sh_init_svc, 234 .init_service = ip_vs_sh_init_svc,
234 .done_service = ip_vs_sh_done_svc, 235 .done_service = ip_vs_sh_done_svc,
235 .update_service = ip_vs_sh_update_svc, 236 .update_service = ip_vs_sh_update_svc,
@@ -239,7 +240,6 @@ static struct ip_vs_scheduler ip_vs_sh_scheduler =
239 240
240static int __init ip_vs_sh_init(void) 241static int __init ip_vs_sh_init(void)
241{ 242{
242 INIT_LIST_HEAD(&ip_vs_sh_scheduler.n_list);
243 return register_ip_vs_scheduler(&ip_vs_sh_scheduler); 243 return register_ip_vs_scheduler(&ip_vs_sh_scheduler);
244} 244}
245 245
diff --git a/net/ipv4/ipvs/ip_vs_sync.c b/net/ipv4/ipvs/ip_vs_sync.c
index 45e9bd96c286..a652da2c3200 100644
--- a/net/ipv4/ipvs/ip_vs_sync.c
+++ b/net/ipv4/ipvs/ip_vs_sync.c
@@ -904,9 +904,9 @@ int stop_sync_thread(int state)
904 * progress of stopping the master sync daemon. 904 * progress of stopping the master sync daemon.
905 */ 905 */
906 906
907 spin_lock(&ip_vs_sync_lock); 907 spin_lock_bh(&ip_vs_sync_lock);
908 ip_vs_sync_state &= ~IP_VS_STATE_MASTER; 908 ip_vs_sync_state &= ~IP_VS_STATE_MASTER;
909 spin_unlock(&ip_vs_sync_lock); 909 spin_unlock_bh(&ip_vs_sync_lock);
910 kthread_stop(sync_master_thread); 910 kthread_stop(sync_master_thread);
911 sync_master_thread = NULL; 911 sync_master_thread = NULL;
912 } else if (state == IP_VS_STATE_BACKUP) { 912 } else if (state == IP_VS_STATE_BACKUP) {
diff --git a/net/ipv4/ipvs/ip_vs_wlc.c b/net/ipv4/ipvs/ip_vs_wlc.c
index 772c3cb4eca1..9b0ef86bb1f7 100644
--- a/net/ipv4/ipvs/ip_vs_wlc.c
+++ b/net/ipv4/ipvs/ip_vs_wlc.c
@@ -126,6 +126,7 @@ static struct ip_vs_scheduler ip_vs_wlc_scheduler =
126 .name = "wlc", 126 .name = "wlc",
127 .refcnt = ATOMIC_INIT(0), 127 .refcnt = ATOMIC_INIT(0),
128 .module = THIS_MODULE, 128 .module = THIS_MODULE,
129 .n_list = LIST_HEAD_INIT(ip_vs_wlc_scheduler.n_list),
129 .init_service = ip_vs_wlc_init_svc, 130 .init_service = ip_vs_wlc_init_svc,
130 .done_service = ip_vs_wlc_done_svc, 131 .done_service = ip_vs_wlc_done_svc,
131 .update_service = ip_vs_wlc_update_svc, 132 .update_service = ip_vs_wlc_update_svc,
@@ -135,7 +136,6 @@ static struct ip_vs_scheduler ip_vs_wlc_scheduler =
135 136
136static int __init ip_vs_wlc_init(void) 137static int __init ip_vs_wlc_init(void)
137{ 138{
138 INIT_LIST_HEAD(&ip_vs_wlc_scheduler.n_list);
139 return register_ip_vs_scheduler(&ip_vs_wlc_scheduler); 139 return register_ip_vs_scheduler(&ip_vs_wlc_scheduler);
140} 140}
141 141
diff --git a/net/ipv4/ipvs/ip_vs_wrr.c b/net/ipv4/ipvs/ip_vs_wrr.c
index 1d6932d7dc97..0d86a79b87b5 100644
--- a/net/ipv4/ipvs/ip_vs_wrr.c
+++ b/net/ipv4/ipvs/ip_vs_wrr.c
@@ -212,6 +212,7 @@ static struct ip_vs_scheduler ip_vs_wrr_scheduler = {
212 .name = "wrr", 212 .name = "wrr",
213 .refcnt = ATOMIC_INIT(0), 213 .refcnt = ATOMIC_INIT(0),
214 .module = THIS_MODULE, 214 .module = THIS_MODULE,
215 .n_list = LIST_HEAD_INIT(ip_vs_wrr_scheduler.n_list),
215 .init_service = ip_vs_wrr_init_svc, 216 .init_service = ip_vs_wrr_init_svc,
216 .done_service = ip_vs_wrr_done_svc, 217 .done_service = ip_vs_wrr_done_svc,
217 .update_service = ip_vs_wrr_update_svc, 218 .update_service = ip_vs_wrr_update_svc,
@@ -220,7 +221,6 @@ static struct ip_vs_scheduler ip_vs_wrr_scheduler = {
220 221
221static int __init ip_vs_wrr_init(void) 222static int __init ip_vs_wrr_init(void)
222{ 223{
223 INIT_LIST_HEAD(&ip_vs_wrr_scheduler.n_list);
224 return register_ip_vs_scheduler(&ip_vs_wrr_scheduler) ; 224 return register_ip_vs_scheduler(&ip_vs_wrr_scheduler) ;
225} 225}
226 226