aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter
diff options
context:
space:
mode:
authorSimon Horman <horms@verge.net.au>2009-08-31 08:18:48 -0400
committerPatrick McHardy <kaber@trash.net>2009-08-31 08:18:48 -0400
commit1e66dafc75f40a08b2addb82779987b269b4ca23 (patch)
tree8e8804cb6ffdd05e5ac7758d0559d4698026dd65 /net/netfilter
parent3993832464dd4e14a4c926583a11f0fa92c1f0f0 (diff)
ipvs: Use atomic operations atomicly
A pointed out by Shin Hong, IPVS doesn't always use atomic operations in an atomic manner. While this seems unlikely to be manifest in strange behaviour, it seems appropriate to clean this up. Cc: shin hong <hongshin@gmail.com> Signed-off-by: Simon Horman <horms@verge.net.au> Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'net/netfilter')
-rw-r--r--net/netfilter/ipvs/ip_vs_core.c6
-rw-r--r--net/netfilter/ipvs/ip_vs_wrr.c7
2 files changed, 7 insertions, 6 deletions
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
index b227750af752..a986ee20e128 100644
--- a/net/netfilter/ipvs/ip_vs_core.c
+++ b/net/netfilter/ipvs/ip_vs_core.c
@@ -1259,7 +1259,7 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb,
1259 struct ip_vs_iphdr iph; 1259 struct ip_vs_iphdr iph;
1260 struct ip_vs_protocol *pp; 1260 struct ip_vs_protocol *pp;
1261 struct ip_vs_conn *cp; 1261 struct ip_vs_conn *cp;
1262 int ret, restart, af; 1262 int ret, restart, af, pkts;
1263 1263
1264 af = (skb->protocol == htons(ETH_P_IP)) ? AF_INET : AF_INET6; 1264 af = (skb->protocol == htons(ETH_P_IP)) ? AF_INET : AF_INET6;
1265 1265
@@ -1346,12 +1346,12 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb,
1346 * Sync connection if it is about to close to 1346 * Sync connection if it is about to close to
1347 * encorage the standby servers to update the connections timeout 1347 * encorage the standby servers to update the connections timeout
1348 */ 1348 */
1349 atomic_inc(&cp->in_pkts); 1349 pkts = atomic_add_return(1, &cp->in_pkts);
1350 if (af == AF_INET && 1350 if (af == AF_INET &&
1351 (ip_vs_sync_state & IP_VS_STATE_MASTER) && 1351 (ip_vs_sync_state & IP_VS_STATE_MASTER) &&
1352 (((cp->protocol != IPPROTO_TCP || 1352 (((cp->protocol != IPPROTO_TCP ||
1353 cp->state == IP_VS_TCP_S_ESTABLISHED) && 1353 cp->state == IP_VS_TCP_S_ESTABLISHED) &&
1354 (atomic_read(&cp->in_pkts) % sysctl_ip_vs_sync_threshold[1] 1354 (pkts % sysctl_ip_vs_sync_threshold[1]
1355 == sysctl_ip_vs_sync_threshold[0])) || 1355 == sysctl_ip_vs_sync_threshold[0])) ||
1356 ((cp->protocol == IPPROTO_TCP) && (cp->old_state != cp->state) && 1356 ((cp->protocol == IPPROTO_TCP) && (cp->old_state != cp->state) &&
1357 ((cp->state == IP_VS_TCP_S_FIN_WAIT) || 1357 ((cp->state == IP_VS_TCP_S_FIN_WAIT) ||
diff --git a/net/netfilter/ipvs/ip_vs_wrr.c b/net/netfilter/ipvs/ip_vs_wrr.c
index 70ff82cda57d..6182e8ea0be7 100644
--- a/net/netfilter/ipvs/ip_vs_wrr.c
+++ b/net/netfilter/ipvs/ip_vs_wrr.c
@@ -77,11 +77,12 @@ static int ip_vs_wrr_gcd_weight(struct ip_vs_service *svc)
77static int ip_vs_wrr_max_weight(struct ip_vs_service *svc) 77static int ip_vs_wrr_max_weight(struct ip_vs_service *svc)
78{ 78{
79 struct ip_vs_dest *dest; 79 struct ip_vs_dest *dest;
80 int weight = 0; 80 int new_weight, weight = 0;
81 81
82 list_for_each_entry(dest, &svc->destinations, n_list) { 82 list_for_each_entry(dest, &svc->destinations, n_list) {
83 if (atomic_read(&dest->weight) > weight) 83 new_weight = atomic_read(&dest->weight);
84 weight = atomic_read(&dest->weight); 84 if (new_weight > weight)
85 weight = new_weight;
85 } 86 }
86 87
87 return weight; 88 return weight;