diff options
author | Hans Schillstrom <hans.schillstrom@ericsson.com> | 2011-01-03 08:44:54 -0500 |
---|---|---|
committer | Simon Horman <horms@verge.net.au> | 2011-01-12 20:30:28 -0500 |
commit | 29c2026fd4980c144d9c746dc1565060f08e5796 (patch) | |
tree | 37373a66fac997e01c83e774c21e00dca713598a | |
parent | ab8a5e8408c3df2d654611bffc3aaf04f418b266 (diff) |
IPVS: netns awareness to ip_vs_est
All variables moved to struct ipvs,
most external changes fixed (i.e. init_net removed)
*v3
timer per ns instead of a common timer in estimator.
Signed-off-by: Hans Schillstrom <hans.schillstrom@ericsson.com>
Acked-by: Julian Anastasov <ja@ssi.bg>
Signed-off-by: Simon Horman <horms@verge.net.au>
-rw-r--r-- | include/net/ip_vs.h | 4 | ||||
-rw-r--r-- | include/net/netns/ip_vs.h | 4 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_ctl.c | 20 | ||||
-rw-r--r-- | net/netfilter/ipvs/ip_vs_est.c | 86 |
4 files changed, 64 insertions, 50 deletions
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index 0cdd8ce454c2..c08927bb1728 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h | |||
@@ -1004,8 +1004,8 @@ extern void ip_vs_sync_cleanup(void); | |||
1004 | */ | 1004 | */ |
1005 | extern int ip_vs_estimator_init(void); | 1005 | extern int ip_vs_estimator_init(void); |
1006 | extern void ip_vs_estimator_cleanup(void); | 1006 | extern void ip_vs_estimator_cleanup(void); |
1007 | extern void ip_vs_new_estimator(struct ip_vs_stats *stats); | 1007 | extern void ip_vs_new_estimator(struct net *net, struct ip_vs_stats *stats); |
1008 | extern void ip_vs_kill_estimator(struct ip_vs_stats *stats); | 1008 | extern void ip_vs_kill_estimator(struct net *net, struct ip_vs_stats *stats); |
1009 | extern void ip_vs_zero_estimator(struct ip_vs_stats *stats); | 1009 | extern void ip_vs_zero_estimator(struct ip_vs_stats *stats); |
1010 | 1010 | ||
1011 | /* | 1011 | /* |
diff --git a/include/net/netns/ip_vs.h b/include/net/netns/ip_vs.h index 03f7fe1bede6..db0240198339 100644 --- a/include/net/netns/ip_vs.h +++ b/include/net/netns/ip_vs.h | |||
@@ -70,6 +70,10 @@ struct netns_ipvs { | |||
70 | int sysctl_lblcr_expiration; | 70 | int sysctl_lblcr_expiration; |
71 | struct ctl_table_header *lblcr_ctl_header; | 71 | struct ctl_table_header *lblcr_ctl_header; |
72 | struct ctl_table *lblcr_ctl_table; | 72 | struct ctl_table *lblcr_ctl_table; |
73 | /* ip_vs_est */ | ||
74 | struct list_head est_list; /* estimator list */ | ||
75 | spinlock_t est_lock; | ||
76 | struct timer_list est_timer; /* Estimation timer */ | ||
73 | }; | 77 | }; |
74 | 78 | ||
75 | #endif /* IP_VS_H_ */ | 79 | #endif /* IP_VS_H_ */ |
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index 88474f1e828a..c89beb8eafbb 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c | |||
@@ -816,7 +816,7 @@ __ip_vs_update_dest(struct ip_vs_service *svc, struct ip_vs_dest *dest, | |||
816 | spin_unlock(&dest->dst_lock); | 816 | spin_unlock(&dest->dst_lock); |
817 | 817 | ||
818 | if (add) | 818 | if (add) |
819 | ip_vs_new_estimator(&dest->stats); | 819 | ip_vs_new_estimator(svc->net, &dest->stats); |
820 | 820 | ||
821 | write_lock_bh(&__ip_vs_svc_lock); | 821 | write_lock_bh(&__ip_vs_svc_lock); |
822 | 822 | ||
@@ -1009,9 +1009,9 @@ ip_vs_edit_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest) | |||
1009 | /* | 1009 | /* |
1010 | * Delete a destination (must be already unlinked from the service) | 1010 | * Delete a destination (must be already unlinked from the service) |
1011 | */ | 1011 | */ |
1012 | static void __ip_vs_del_dest(struct ip_vs_dest *dest) | 1012 | static void __ip_vs_del_dest(struct net *net, struct ip_vs_dest *dest) |
1013 | { | 1013 | { |
1014 | ip_vs_kill_estimator(&dest->stats); | 1014 | ip_vs_kill_estimator(net, &dest->stats); |
1015 | 1015 | ||
1016 | /* | 1016 | /* |
1017 | * Remove it from the d-linked list with the real services. | 1017 | * Remove it from the d-linked list with the real services. |
@@ -1080,6 +1080,7 @@ static int | |||
1080 | ip_vs_del_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest) | 1080 | ip_vs_del_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest) |
1081 | { | 1081 | { |
1082 | struct ip_vs_dest *dest; | 1082 | struct ip_vs_dest *dest; |
1083 | struct net *net = svc->net; | ||
1083 | __be16 dport = udest->port; | 1084 | __be16 dport = udest->port; |
1084 | 1085 | ||
1085 | EnterFunction(2); | 1086 | EnterFunction(2); |
@@ -1108,7 +1109,7 @@ ip_vs_del_dest(struct ip_vs_service *svc, struct ip_vs_dest_user_kern *udest) | |||
1108 | /* | 1109 | /* |
1109 | * Delete the destination | 1110 | * Delete the destination |
1110 | */ | 1111 | */ |
1111 | __ip_vs_del_dest(dest); | 1112 | __ip_vs_del_dest(net, dest); |
1112 | 1113 | ||
1113 | LeaveFunction(2); | 1114 | LeaveFunction(2); |
1114 | 1115 | ||
@@ -1197,7 +1198,7 @@ ip_vs_add_service(struct net *net, struct ip_vs_service_user_kern *u, | |||
1197 | else if (svc->port == 0) | 1198 | else if (svc->port == 0) |
1198 | atomic_inc(&ip_vs_nullsvc_counter); | 1199 | atomic_inc(&ip_vs_nullsvc_counter); |
1199 | 1200 | ||
1200 | ip_vs_new_estimator(&svc->stats); | 1201 | ip_vs_new_estimator(net, &svc->stats); |
1201 | 1202 | ||
1202 | /* Count only IPv4 services for old get/setsockopt interface */ | 1203 | /* Count only IPv4 services for old get/setsockopt interface */ |
1203 | if (svc->af == AF_INET) | 1204 | if (svc->af == AF_INET) |
@@ -1345,7 +1346,7 @@ static void __ip_vs_del_service(struct ip_vs_service *svc) | |||
1345 | if (svc->af == AF_INET) | 1346 | if (svc->af == AF_INET) |
1346 | ip_vs_num_services--; | 1347 | ip_vs_num_services--; |
1347 | 1348 | ||
1348 | ip_vs_kill_estimator(&svc->stats); | 1349 | ip_vs_kill_estimator(svc->net, &svc->stats); |
1349 | 1350 | ||
1350 | /* Unbind scheduler */ | 1351 | /* Unbind scheduler */ |
1351 | old_sched = svc->scheduler; | 1352 | old_sched = svc->scheduler; |
@@ -1368,7 +1369,7 @@ static void __ip_vs_del_service(struct ip_vs_service *svc) | |||
1368 | */ | 1369 | */ |
1369 | list_for_each_entry_safe(dest, nxt, &svc->destinations, n_list) { | 1370 | list_for_each_entry_safe(dest, nxt, &svc->destinations, n_list) { |
1370 | __ip_vs_unlink_dest(svc, dest, 0); | 1371 | __ip_vs_unlink_dest(svc, dest, 0); |
1371 | __ip_vs_del_dest(dest); | 1372 | __ip_vs_del_dest(svc->net, dest); |
1372 | } | 1373 | } |
1373 | 1374 | ||
1374 | /* | 1375 | /* |
@@ -3460,7 +3461,7 @@ int __net_init __ip_vs_control_init(struct net *net) | |||
3460 | vs_vars); | 3461 | vs_vars); |
3461 | if (sysctl_header == NULL) | 3462 | if (sysctl_header == NULL) |
3462 | goto err_reg; | 3463 | goto err_reg; |
3463 | ip_vs_new_estimator(&ip_vs_stats); | 3464 | ip_vs_new_estimator(net, &ip_vs_stats); |
3464 | return 0; | 3465 | return 0; |
3465 | 3466 | ||
3466 | err_reg: | 3467 | err_reg: |
@@ -3472,7 +3473,7 @@ static void __net_exit __ip_vs_control_cleanup(struct net *net) | |||
3472 | if (!net_eq(net, &init_net)) /* netns not enabled yet */ | 3473 | if (!net_eq(net, &init_net)) /* netns not enabled yet */ |
3473 | return; | 3474 | return; |
3474 | 3475 | ||
3475 | ip_vs_kill_estimator(&ip_vs_stats); | 3476 | ip_vs_kill_estimator(net, &ip_vs_stats); |
3476 | unregister_net_sysctl_table(sysctl_header); | 3477 | unregister_net_sysctl_table(sysctl_header); |
3477 | proc_net_remove(net, "ip_vs_stats"); | 3478 | proc_net_remove(net, "ip_vs_stats"); |
3478 | proc_net_remove(net, "ip_vs"); | 3479 | proc_net_remove(net, "ip_vs"); |
@@ -3536,7 +3537,6 @@ void ip_vs_control_cleanup(void) | |||
3536 | ip_vs_trash_cleanup(); | 3537 | ip_vs_trash_cleanup(); |
3537 | cancel_delayed_work_sync(&defense_work); | 3538 | cancel_delayed_work_sync(&defense_work); |
3538 | cancel_work_sync(&defense_work.work); | 3539 | cancel_work_sync(&defense_work.work); |
3539 | ip_vs_kill_estimator(&ip_vs_stats); | ||
3540 | unregister_pernet_subsys(&ipvs_control_ops); | 3540 | unregister_pernet_subsys(&ipvs_control_ops); |
3541 | ip_vs_genl_unregister(); | 3541 | ip_vs_genl_unregister(); |
3542 | nf_unregister_sockopt(&ip_vs_sockopts); | 3542 | nf_unregister_sockopt(&ip_vs_sockopts); |
diff --git a/net/netfilter/ipvs/ip_vs_est.c b/net/netfilter/ipvs/ip_vs_est.c index 7417a0c1408b..07d839bef537 100644 --- a/net/netfilter/ipvs/ip_vs_est.c +++ b/net/netfilter/ipvs/ip_vs_est.c | |||
@@ -8,8 +8,12 @@ | |||
8 | * as published by the Free Software Foundation; either version | 8 | * as published by the Free Software Foundation; either version |
9 | * 2 of the License, or (at your option) any later version. | 9 | * 2 of the License, or (at your option) any later version. |
10 | * | 10 | * |
11 | * Changes: | 11 | * Changes: Hans Schillstrom <hans.schillstrom@ericsson.com> |
12 | * | 12 | * Network name space (netns) aware. |
13 | * Global data moved to netns i.e struct netns_ipvs | ||
14 | * Affected data: est_list and est_lock. | ||
15 | * estimation_timer() runs with timer per netns. | ||
16 | * get_stats()) do the per cpu summing. | ||
13 | */ | 17 | */ |
14 | 18 | ||
15 | #define KMSG_COMPONENT "IPVS" | 19 | #define KMSG_COMPONENT "IPVS" |
@@ -48,12 +52,6 @@ | |||
48 | */ | 52 | */ |
49 | 53 | ||
50 | 54 | ||
51 | static void estimation_timer(unsigned long arg); | ||
52 | |||
53 | static LIST_HEAD(est_list); | ||
54 | static DEFINE_SPINLOCK(est_lock); | ||
55 | static DEFINE_TIMER(est_timer, estimation_timer, 0, 0); | ||
56 | |||
57 | static void estimation_timer(unsigned long arg) | 55 | static void estimation_timer(unsigned long arg) |
58 | { | 56 | { |
59 | struct ip_vs_estimator *e; | 57 | struct ip_vs_estimator *e; |
@@ -62,9 +60,12 @@ static void estimation_timer(unsigned long arg) | |||
62 | u32 n_inpkts, n_outpkts; | 60 | u32 n_inpkts, n_outpkts; |
63 | u64 n_inbytes, n_outbytes; | 61 | u64 n_inbytes, n_outbytes; |
64 | u32 rate; | 62 | u32 rate; |
63 | struct net *net = (struct net *)arg; | ||
64 | struct netns_ipvs *ipvs; | ||
65 | 65 | ||
66 | spin_lock(&est_lock); | 66 | ipvs = net_ipvs(net); |
67 | list_for_each_entry(e, &est_list, list) { | 67 | spin_lock(&ipvs->est_lock); |
68 | list_for_each_entry(e, &ipvs->est_list, list) { | ||
68 | s = container_of(e, struct ip_vs_stats, est); | 69 | s = container_of(e, struct ip_vs_stats, est); |
69 | 70 | ||
70 | spin_lock(&s->lock); | 71 | spin_lock(&s->lock); |
@@ -75,38 +76,39 @@ static void estimation_timer(unsigned long arg) | |||
75 | n_outbytes = s->ustats.outbytes; | 76 | n_outbytes = s->ustats.outbytes; |
76 | 77 | ||
77 | /* scaled by 2^10, but divided 2 seconds */ | 78 | /* scaled by 2^10, but divided 2 seconds */ |
78 | rate = (n_conns - e->last_conns)<<9; | 79 | rate = (n_conns - e->last_conns) << 9; |
79 | e->last_conns = n_conns; | 80 | e->last_conns = n_conns; |
80 | e->cps += ((long)rate - (long)e->cps)>>2; | 81 | e->cps += ((long)rate - (long)e->cps) >> 2; |
81 | s->ustats.cps = (e->cps+0x1FF)>>10; | 82 | s->ustats.cps = (e->cps + 0x1FF) >> 10; |
82 | 83 | ||
83 | rate = (n_inpkts - e->last_inpkts)<<9; | 84 | rate = (n_inpkts - e->last_inpkts) << 9; |
84 | e->last_inpkts = n_inpkts; | 85 | e->last_inpkts = n_inpkts; |
85 | e->inpps += ((long)rate - (long)e->inpps)>>2; | 86 | e->inpps += ((long)rate - (long)e->inpps) >> 2; |
86 | s->ustats.inpps = (e->inpps+0x1FF)>>10; | 87 | s->ustats.inpps = (e->inpps + 0x1FF) >> 10; |
87 | 88 | ||
88 | rate = (n_outpkts - e->last_outpkts)<<9; | 89 | rate = (n_outpkts - e->last_outpkts) << 9; |
89 | e->last_outpkts = n_outpkts; | 90 | e->last_outpkts = n_outpkts; |
90 | e->outpps += ((long)rate - (long)e->outpps)>>2; | 91 | e->outpps += ((long)rate - (long)e->outpps) >> 2; |
91 | s->ustats.outpps = (e->outpps+0x1FF)>>10; | 92 | s->ustats.outpps = (e->outpps + 0x1FF) >> 10; |
92 | 93 | ||
93 | rate = (n_inbytes - e->last_inbytes)<<4; | 94 | rate = (n_inbytes - e->last_inbytes) << 4; |
94 | e->last_inbytes = n_inbytes; | 95 | e->last_inbytes = n_inbytes; |
95 | e->inbps += ((long)rate - (long)e->inbps)>>2; | 96 | e->inbps += ((long)rate - (long)e->inbps) >> 2; |
96 | s->ustats.inbps = (e->inbps+0xF)>>5; | 97 | s->ustats.inbps = (e->inbps + 0xF) >> 5; |
97 | 98 | ||
98 | rate = (n_outbytes - e->last_outbytes)<<4; | 99 | rate = (n_outbytes - e->last_outbytes) << 4; |
99 | e->last_outbytes = n_outbytes; | 100 | e->last_outbytes = n_outbytes; |
100 | e->outbps += ((long)rate - (long)e->outbps)>>2; | 101 | e->outbps += ((long)rate - (long)e->outbps) >> 2; |
101 | s->ustats.outbps = (e->outbps+0xF)>>5; | 102 | s->ustats.outbps = (e->outbps + 0xF) >> 5; |
102 | spin_unlock(&s->lock); | 103 | spin_unlock(&s->lock); |
103 | } | 104 | } |
104 | spin_unlock(&est_lock); | 105 | spin_unlock(&ipvs->est_lock); |
105 | mod_timer(&est_timer, jiffies + 2*HZ); | 106 | mod_timer(&ipvs->est_timer, jiffies + 2*HZ); |
106 | } | 107 | } |
107 | 108 | ||
108 | void ip_vs_new_estimator(struct ip_vs_stats *stats) | 109 | void ip_vs_new_estimator(struct net *net, struct ip_vs_stats *stats) |
109 | { | 110 | { |
111 | struct netns_ipvs *ipvs = net_ipvs(net); | ||
110 | struct ip_vs_estimator *est = &stats->est; | 112 | struct ip_vs_estimator *est = &stats->est; |
111 | 113 | ||
112 | INIT_LIST_HEAD(&est->list); | 114 | INIT_LIST_HEAD(&est->list); |
@@ -126,18 +128,19 @@ void ip_vs_new_estimator(struct ip_vs_stats *stats) | |||
126 | est->last_outbytes = stats->ustats.outbytes; | 128 | est->last_outbytes = stats->ustats.outbytes; |
127 | est->outbps = stats->ustats.outbps<<5; | 129 | est->outbps = stats->ustats.outbps<<5; |
128 | 130 | ||
129 | spin_lock_bh(&est_lock); | 131 | spin_lock_bh(&ipvs->est_lock); |
130 | list_add(&est->list, &est_list); | 132 | list_add(&est->list, &ipvs->est_list); |
131 | spin_unlock_bh(&est_lock); | 133 | spin_unlock_bh(&ipvs->est_lock); |
132 | } | 134 | } |
133 | 135 | ||
134 | void ip_vs_kill_estimator(struct ip_vs_stats *stats) | 136 | void ip_vs_kill_estimator(struct net *net, struct ip_vs_stats *stats) |
135 | { | 137 | { |
138 | struct netns_ipvs *ipvs = net_ipvs(net); | ||
136 | struct ip_vs_estimator *est = &stats->est; | 139 | struct ip_vs_estimator *est = &stats->est; |
137 | 140 | ||
138 | spin_lock_bh(&est_lock); | 141 | spin_lock_bh(&ipvs->est_lock); |
139 | list_del(&est->list); | 142 | list_del(&est->list); |
140 | spin_unlock_bh(&est_lock); | 143 | spin_unlock_bh(&ipvs->est_lock); |
141 | } | 144 | } |
142 | 145 | ||
143 | void ip_vs_zero_estimator(struct ip_vs_stats *stats) | 146 | void ip_vs_zero_estimator(struct ip_vs_stats *stats) |
@@ -159,14 +162,25 @@ void ip_vs_zero_estimator(struct ip_vs_stats *stats) | |||
159 | 162 | ||
160 | static int __net_init __ip_vs_estimator_init(struct net *net) | 163 | static int __net_init __ip_vs_estimator_init(struct net *net) |
161 | { | 164 | { |
165 | struct netns_ipvs *ipvs = net_ipvs(net); | ||
166 | |||
162 | if (!net_eq(net, &init_net)) /* netns not enabled yet */ | 167 | if (!net_eq(net, &init_net)) /* netns not enabled yet */ |
163 | return -EPERM; | 168 | return -EPERM; |
164 | 169 | ||
170 | INIT_LIST_HEAD(&ipvs->est_list); | ||
171 | spin_lock_init(&ipvs->est_lock); | ||
172 | setup_timer(&ipvs->est_timer, estimation_timer, (unsigned long)net); | ||
173 | mod_timer(&ipvs->est_timer, jiffies + 2 * HZ); | ||
165 | return 0; | 174 | return 0; |
166 | } | 175 | } |
167 | 176 | ||
177 | static void __net_exit __ip_vs_estimator_exit(struct net *net) | ||
178 | { | ||
179 | del_timer_sync(&net_ipvs(net)->est_timer); | ||
180 | } | ||
168 | static struct pernet_operations ip_vs_app_ops = { | 181 | static struct pernet_operations ip_vs_app_ops = { |
169 | .init = __ip_vs_estimator_init, | 182 | .init = __ip_vs_estimator_init, |
183 | .exit = __ip_vs_estimator_exit, | ||
170 | }; | 184 | }; |
171 | 185 | ||
172 | int __init ip_vs_estimator_init(void) | 186 | int __init ip_vs_estimator_init(void) |
@@ -174,14 +188,10 @@ int __init ip_vs_estimator_init(void) | |||
174 | int rv; | 188 | int rv; |
175 | 189 | ||
176 | rv = register_pernet_subsys(&ip_vs_app_ops); | 190 | rv = register_pernet_subsys(&ip_vs_app_ops); |
177 | if (rv < 0) | ||
178 | return rv; | ||
179 | mod_timer(&est_timer, jiffies + 2 * HZ); | ||
180 | return rv; | 191 | return rv; |
181 | } | 192 | } |
182 | 193 | ||
183 | void ip_vs_estimator_cleanup(void) | 194 | void ip_vs_estimator_cleanup(void) |
184 | { | 195 | { |
185 | del_timer_sync(&est_timer); | ||
186 | unregister_pernet_subsys(&ip_vs_app_ops); | 196 | unregister_pernet_subsys(&ip_vs_app_ops); |
187 | } | 197 | } |