From: Eric Dumazet <eric.dumazet@gmail.com>
To: Jarek Poplawski <jarkao2@gmail.com>
Cc: David Miller <davem@davemloft.net>,
albcamus@gmail.com, parag.lkml@gmail.com,
linux-kernel@vger.kernel.org, netdev@vger.kernel.org
Subject: Re: [PATCH] net: Fix sock_wfree() race
Date: Thu, 24 Sep 2009 22:49:24 +0200 [thread overview]
Message-ID: <4ABBDB54.4000609@gmail.com> (raw)
In-Reply-To: <4ABBD18A.70208@gmail.com>
Jarek Poplawski a écrit :
> Eric Dumazet wrote, On 09/23/2009 03:44 PM:
>
> ...
>> Here is the patch for reference :
>>
>> [PATCH] net: Fix sock_wfree() race
>>
>> Commit 2b85a34e911bf483c27cfdd124aeb1605145dc80
>> (net: No more expensive sock_hold()/sock_put() on each tx)
>> opens a window in sock_wfree() where another cpu
>> might free the socket we are working on.
>>
>> A fix is to call sk->sk_write_space(sk) while still
>> holding a reference on sk.
>>
>>
>> Reported-by: Jike Song <albcamus@gmail.com>
>> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
>> ---
>> net/core/sock.c | 19 ++++++++++++-------
>> 1 files changed, 12 insertions(+), 7 deletions(-)
>>
>> diff --git a/net/core/sock.c b/net/core/sock.c
>> index 30d5446..e1f034e 100644
>> --- a/net/core/sock.c
>> +++ b/net/core/sock.c
>> @@ -1228,17 +1228,22 @@ void __init sk_init(void)
>> void sock_wfree(struct sk_buff *skb)
>> {
>> struct sock *sk = skb->sk;
>> - int res;
>> + unsigned int len = skb->truesize;
>>
>> - /* In case it might be waiting for more memory. */
>> - res = atomic_sub_return(skb->truesize, &sk->sk_wmem_alloc);
>> - if (!sock_flag(sk, SOCK_USE_WRITE_QUEUE))
>> + if (!sock_flag(sk, SOCK_USE_WRITE_QUEUE)) {
>> + /*
>> + * Keep a reference on sk_wmem_alloc, this will be released
>> + * after sk_write_space() call
>> + */
>> + atomic_sub(len - 1, &sk->sk_wmem_alloc);
>> sk->sk_write_space(sk);
>> + len = 1;
>> + }
>> /*
>> - * if sk_wmem_alloc reached 0, we are last user and should
>> - * free this sock, as sk_free() call could not do it.
>> + * if sk_wmem_alloc reaches 0, we must finish what sk_free()
>> + * could not do because of in-flight packets
>> */
>> - if (res == 0)
>> + if (atomic_sub_return(len, &sk->sk_wmem_alloc) == 0)
>> __sk_free(sk);
>
>
> Probably atomic_sub_and_test() is more popular for this.
Indeed, as x86 can generate faster code (no need of xadd instruction)
Thanks Jarek
[PATCH] net: Fix sock_wfree() race
Commit 2b85a34e911bf483c27cfdd124aeb1605145dc80
(net: No more expensive sock_hold()/sock_put() on each tx)
opens a window in sock_wfree() where another cpu
might free the socket we are working on.
A fix is to call sk->sk_write_space(sk) while still
holding a reference on sk.
Reported-by: Jike Song <albcamus@gmail.com>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
net/core/sock.c | 19 ++++++++++++-------
1 files changed, 12 insertions(+), 7 deletions(-)
diff --git a/net/core/sock.c b/net/core/sock.c
index 30d5446..e1f034e 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1228,17 +1228,22 @@ void __init sk_init(void)
void sock_wfree(struct sk_buff *skb)
{
struct sock *sk = skb->sk;
- int res;
+ unsigned int len = skb->truesize;
- /* In case it might be waiting for more memory. */
- res = atomic_sub_return(skb->truesize, &sk->sk_wmem_alloc);
- if (!sock_flag(sk, SOCK_USE_WRITE_QUEUE))
+ if (!sock_flag(sk, SOCK_USE_WRITE_QUEUE)) {
+ /*
+ * Keep a reference on sk_wmem_alloc, this will be released
+ * after sk_write_space() call
+ */
+ atomic_sub(len - 1, &sk->sk_wmem_alloc);
sk->sk_write_space(sk);
+ len = 1;
+ }
/*
- * if sk_wmem_alloc reached 0, we are last user and should
- * free this sock, as sk_free() call could not do it.
+ * if sk_wmem_alloc reaches 0, we must finish what sk_free()
+ * could not do because of in-flight packets
*/
- if (res == 0)
+ if (atomic_sub_and_test(len, &sk->sk_wmem_alloc))
__sk_free(sk);
}
EXPORT_SYMBOL(sock_wfree);
next prev parent reply other threads:[~2009-09-24 20:49 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <alpine.DEB.2.00.0909072323350.3940@parag-desktop>
2009-09-08 4:51 ` BUG UNIX: Poison overwritten with 2.6.31-rc6-00223-g6c30c53 Jike Song
2009-09-08 7:38 ` Eric Dumazet
2009-09-08 8:09 ` Jike Song
2009-09-08 12:12 ` Eric Dumazet
2009-09-08 22:49 ` [PATCH] net: Fix sock_wfree() race Eric Dumazet
2009-09-09 7:14 ` Jike Song
2009-09-09 9:18 ` Eric Dumazet
2009-09-11 18:43 ` David Miller
2009-09-11 19:52 ` David Miller
2009-09-23 13:44 ` Eric Dumazet
2009-09-24 20:07 ` Jarek Poplawski
2009-09-24 20:49 ` Eric Dumazet [this message]
2009-09-30 23:23 ` David Miller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4ABBDB54.4000609@gmail.com \
--to=eric.dumazet@gmail.com \
--cc=albcamus@gmail.com \
--cc=davem@davemloft.net \
--cc=jarkao2@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=parag.lkml@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).