diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2009-06-16 06:12:03 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-06-17 07:31:25 -0400 |
commit | c564039fd83ea16a86a96d52632794b24849e507 (patch) | |
tree | 42c9f525d08ea2e7d36c0231cc628587a175a39b /net | |
parent | 1d4ac5d5ef9dd965ae211ebe8acbf83dc4d9571b (diff) |
net: sk_wmem_alloc has initial value of one, not zero
commit 2b85a34e911bf483c27cfdd124aeb1605145dc80
(net: No more expensive sock_hold()/sock_put() on each tx)
changed initial sk_wmem_alloc value.
Some protocols check sk_wmem_alloc value to determine if a timer
must delay socket deallocation. We must take care of the sk_wmem_alloc
value being one instead of zero when no write allocations are pending.
Reported by Ingo Molnar, and full diagnostic from David Miller.
This patch introduces three helpers to get read/write allocations
and a followup patch will use these helpers to report correct
write allocations to user.
Reported-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/appletalk/ddp.c | 6 | ||||
-rw-r--r-- | net/ax25/af_ax25.c | 3 | ||||
-rw-r--r-- | net/econet/af_econet.c | 6 | ||||
-rw-r--r-- | net/netrom/af_netrom.c | 3 | ||||
-rw-r--r-- | net/rose/af_rose.c | 3 | ||||
-rw-r--r-- | net/x25/af_x25.c | 3 |
6 files changed, 8 insertions, 16 deletions
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c index b603cbacdc58..f7a53b219ef0 100644 --- a/net/appletalk/ddp.c +++ b/net/appletalk/ddp.c | |||
@@ -162,8 +162,7 @@ static void atalk_destroy_timer(unsigned long data) | |||
162 | { | 162 | { |
163 | struct sock *sk = (struct sock *)data; | 163 | struct sock *sk = (struct sock *)data; |
164 | 164 | ||
165 | if (atomic_read(&sk->sk_wmem_alloc) || | 165 | if (sk_has_allocations(sk)) { |
166 | atomic_read(&sk->sk_rmem_alloc)) { | ||
167 | sk->sk_timer.expires = jiffies + SOCK_DESTROY_TIME; | 166 | sk->sk_timer.expires = jiffies + SOCK_DESTROY_TIME; |
168 | add_timer(&sk->sk_timer); | 167 | add_timer(&sk->sk_timer); |
169 | } else | 168 | } else |
@@ -175,8 +174,7 @@ static inline void atalk_destroy_socket(struct sock *sk) | |||
175 | atalk_remove_socket(sk); | 174 | atalk_remove_socket(sk); |
176 | skb_queue_purge(&sk->sk_receive_queue); | 175 | skb_queue_purge(&sk->sk_receive_queue); |
177 | 176 | ||
178 | if (atomic_read(&sk->sk_wmem_alloc) || | 177 | if (sk_has_allocations(sk)) { |
179 | atomic_read(&sk->sk_rmem_alloc)) { | ||
180 | setup_timer(&sk->sk_timer, atalk_destroy_timer, | 178 | setup_timer(&sk->sk_timer, atalk_destroy_timer, |
181 | (unsigned long)sk); | 179 | (unsigned long)sk); |
182 | sk->sk_timer.expires = jiffies + SOCK_DESTROY_TIME; | 180 | sk->sk_timer.expires = jiffies + SOCK_DESTROY_TIME; |
diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index fd9d06f291dc..61b35b955490 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c | |||
@@ -330,8 +330,7 @@ void ax25_destroy_socket(ax25_cb *ax25) | |||
330 | } | 330 | } |
331 | 331 | ||
332 | if (ax25->sk != NULL) { | 332 | if (ax25->sk != NULL) { |
333 | if (atomic_read(&ax25->sk->sk_wmem_alloc) || | 333 | if (sk_has_allocations(ax25->sk)) { |
334 | atomic_read(&ax25->sk->sk_rmem_alloc)) { | ||
335 | /* Defer: outstanding buffers */ | 334 | /* Defer: outstanding buffers */ |
336 | setup_timer(&ax25->dtimer, ax25_destroy_timer, | 335 | setup_timer(&ax25->dtimer, ax25_destroy_timer, |
337 | (unsigned long)ax25); | 336 | (unsigned long)ax25); |
diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c index 8121bf0029e3..2e1f836d4240 100644 --- a/net/econet/af_econet.c +++ b/net/econet/af_econet.c | |||
@@ -540,8 +540,7 @@ static void econet_destroy_timer(unsigned long data) | |||
540 | { | 540 | { |
541 | struct sock *sk=(struct sock *)data; | 541 | struct sock *sk=(struct sock *)data; |
542 | 542 | ||
543 | if (!atomic_read(&sk->sk_wmem_alloc) && | 543 | if (!sk_has_allocations(sk)) { |
544 | !atomic_read(&sk->sk_rmem_alloc)) { | ||
545 | sk_free(sk); | 544 | sk_free(sk); |
546 | return; | 545 | return; |
547 | } | 546 | } |
@@ -579,8 +578,7 @@ static int econet_release(struct socket *sock) | |||
579 | 578 | ||
580 | skb_queue_purge(&sk->sk_receive_queue); | 579 | skb_queue_purge(&sk->sk_receive_queue); |
581 | 580 | ||
582 | if (atomic_read(&sk->sk_rmem_alloc) || | 581 | if (sk_has_allocations(sk)) { |
583 | atomic_read(&sk->sk_wmem_alloc)) { | ||
584 | sk->sk_timer.data = (unsigned long)sk; | 582 | sk->sk_timer.data = (unsigned long)sk; |
585 | sk->sk_timer.expires = jiffies + HZ; | 583 | sk->sk_timer.expires = jiffies + HZ; |
586 | sk->sk_timer.function = econet_destroy_timer; | 584 | sk->sk_timer.function = econet_destroy_timer; |
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c index 3be0e016ab7d..cd911904cbe1 100644 --- a/net/netrom/af_netrom.c +++ b/net/netrom/af_netrom.c | |||
@@ -286,8 +286,7 @@ void nr_destroy_socket(struct sock *sk) | |||
286 | kfree_skb(skb); | 286 | kfree_skb(skb); |
287 | } | 287 | } |
288 | 288 | ||
289 | if (atomic_read(&sk->sk_wmem_alloc) || | 289 | if (sk_has_allocations(sk)) { |
290 | atomic_read(&sk->sk_rmem_alloc)) { | ||
291 | /* Defer: outstanding buffers */ | 290 | /* Defer: outstanding buffers */ |
292 | sk->sk_timer.function = nr_destroy_timer; | 291 | sk->sk_timer.function = nr_destroy_timer; |
293 | sk->sk_timer.expires = jiffies + 2 * HZ; | 292 | sk->sk_timer.expires = jiffies + 2 * HZ; |
diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c index 877a7f65f707..4dd9a7d18945 100644 --- a/net/rose/af_rose.c +++ b/net/rose/af_rose.c | |||
@@ -356,8 +356,7 @@ void rose_destroy_socket(struct sock *sk) | |||
356 | kfree_skb(skb); | 356 | kfree_skb(skb); |
357 | } | 357 | } |
358 | 358 | ||
359 | if (atomic_read(&sk->sk_wmem_alloc) || | 359 | if (sk_has_allocations(sk)) { |
360 | atomic_read(&sk->sk_rmem_alloc)) { | ||
361 | /* Defer: outstanding buffers */ | 360 | /* Defer: outstanding buffers */ |
362 | setup_timer(&sk->sk_timer, rose_destroy_timer, | 361 | setup_timer(&sk->sk_timer, rose_destroy_timer, |
363 | (unsigned long)sk); | 362 | (unsigned long)sk); |
diff --git a/net/x25/af_x25.c b/net/x25/af_x25.c index c51f3095739c..8cd2390b0d45 100644 --- a/net/x25/af_x25.c +++ b/net/x25/af_x25.c | |||
@@ -372,8 +372,7 @@ static void __x25_destroy_socket(struct sock *sk) | |||
372 | kfree_skb(skb); | 372 | kfree_skb(skb); |
373 | } | 373 | } |
374 | 374 | ||
375 | if (atomic_read(&sk->sk_wmem_alloc) || | 375 | if (sk_has_allocations(sk)) { |
376 | atomic_read(&sk->sk_rmem_alloc)) { | ||
377 | /* Defer: outstanding buffers */ | 376 | /* Defer: outstanding buffers */ |
378 | sk->sk_timer.expires = jiffies + 10 * HZ; | 377 | sk->sk_timer.expires = jiffies + 10 * HZ; |
379 | sk->sk_timer.function = x25_destroy_timer; | 378 | sk->sk_timer.function = x25_destroy_timer; |