From: Eric Dumazet <eric.dumazet@gmail.com>
To: Bhaskar Dutta <bhaskie@gmail.com>
Cc: Stephen Hemminger <shemminger@vyatta.com>,
Ben Hutchings <bhutchings@solarflare.com>,
netdev@vger.kernel.org, David Miller <davem@davemloft.net>
Subject: Re: TCP-MD5 checksum failure on x86_64 SMP
Date: Fri, 07 May 2010 10:00:22 +0200 [thread overview]
Message-ID: <1273219222.2261.11.camel@edumazet-laptop> (raw)
In-Reply-To: <1273210774.2222.45.camel@edumazet-laptop>
Le vendredi 07 mai 2010 à 07:39 +0200, Eric Dumazet a écrit :
> Le jeudi 06 mai 2010 à 17:25 +0530, Bhaskar Dutta a écrit :
> > On Thu, May 6, 2010 at 12:23 AM, Eric Dumazet <eric.dumazet@gmail.com> wrote:
>
> > > I am not familiar with this code, but I suspect same per_cpu data can be
> > > used at both time by a sender (process context) and by a receiver
> > > (softirq context).
> > >
> > > To trigger this, you need at least two active md5 sockets.
> > >
> > > tcp_get_md5sig_pool() should probably disable bh to make sure current
> > > cpu wont be preempted by softirq processing
> > >
> > >
> > > Something like :
> > >
> > > diff --git a/include/net/tcp.h b/include/net/tcp.h
> > > index fb5c66b..e232123 100644
> > > --- a/include/net/tcp.h
> > > +++ b/include/net/tcp.h
> > > @@ -1221,12 +1221,15 @@ struct tcp_md5sig_pool *tcp_get_md5sig_pool(void)
> > > struct tcp_md5sig_pool *ret = __tcp_get_md5sig_pool(cpu);
> > > if (!ret)
> > > put_cpu();
> > > + else
> > > + local_bh_disable();
> > > return ret;
> > > }
> > >
> > > static inline void tcp_put_md5sig_pool(void)
> > > {
> > > __tcp_put_md5sig_pool();
> > > + local_bh_enable();
> > > put_cpu();
> > > }
> > >
> > >
> > >
> >
> > I put in the above change and ran some load tests with around 50
> > active TCP connections doing MD5.
> > I could see only 1 bad packet in 30 min (earlier the problem used to
> > occur instantaneously and repeatedly).
> >
>
>
> > I think there is another possibility of being preempted when calling
> > tcp_alloc_md5sig_pool()
> > this function releases the spinlock when calling __tcp_alloc_md5sig_pool().
> >
> > I will run some more tests after changing the tcp_alloc_md5sig_pool
> > and see if the problem is completely resolved.
Here is my official patch submission, could you please test it ?
Thanks
[PATCH] tcp: fix MD5 (RFC2385) support
TCP MD5 support uses percpu data for temporary storage. It currently
disables preemption so that same storage cannot be reclaimed by another
thread on same cpu.
We also have to make sure a softirq handler wont try to use also same
context. Various bug reports demonstrated corruptions.
Fix is to disable preemption and BH.
Reported-by: Bhaskar Dutta <bhaskie@gmail.com>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
include/net/tcp.h | 21 +++------------------
net/ipv4/tcp.c | 34 ++++++++++++++++++++++++----------
2 files changed, 27 insertions(+), 28 deletions(-)
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 75be5a2..aa04b9a 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -1197,30 +1197,15 @@ extern int tcp_v4_md5_do_del(struct sock *sk,
extern struct tcp_md5sig_pool * __percpu *tcp_alloc_md5sig_pool(struct sock *);
extern void tcp_free_md5sig_pool(void);
-extern struct tcp_md5sig_pool *__tcp_get_md5sig_pool(int cpu);
-extern void __tcp_put_md5sig_pool(void);
+extern struct tcp_md5sig_pool *tcp_get_md5sig_pool(void);
+extern void tcp_put_md5sig_pool(void);
+
extern int tcp_md5_hash_header(struct tcp_md5sig_pool *, struct tcphdr *);
extern int tcp_md5_hash_skb_data(struct tcp_md5sig_pool *, struct sk_buff *,
unsigned header_len);
extern int tcp_md5_hash_key(struct tcp_md5sig_pool *hp,
struct tcp_md5sig_key *key);
-static inline
-struct tcp_md5sig_pool *tcp_get_md5sig_pool(void)
-{
- int cpu = get_cpu();
- struct tcp_md5sig_pool *ret = __tcp_get_md5sig_pool(cpu);
- if (!ret)
- put_cpu();
- return ret;
-}
-
-static inline void tcp_put_md5sig_pool(void)
-{
- __tcp_put_md5sig_pool();
- put_cpu();
-}
-
/* write queue abstraction */
static inline void tcp_write_queue_purge(struct sock *sk)
{
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 0f8caf6..296150b 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -2839,7 +2839,6 @@ static void __tcp_free_md5sig_pool(struct tcp_md5sig_pool * __percpu *pool)
if (p->md5_desc.tfm)
crypto_free_hash(p->md5_desc.tfm);
kfree(p);
- p = NULL;
}
}
free_percpu(pool);
@@ -2937,25 +2936,40 @@ retry:
EXPORT_SYMBOL(tcp_alloc_md5sig_pool);
-struct tcp_md5sig_pool *__tcp_get_md5sig_pool(int cpu)
+
+/**
+ * tcp_get_md5sig_pool - get md5sig_pool for this user
+ *
+ * We use percpu structure, so if we succeed, we exit with preemption
+ * and BH disabled, to make sure another thread or softirq handling
+ * wont try to get same context.
+ */
+struct tcp_md5sig_pool *tcp_get_md5sig_pool(void)
{
struct tcp_md5sig_pool * __percpu *p;
- spin_lock_bh(&tcp_md5sig_pool_lock);
+
+ local_bh_disable();
+
+ spin_lock(&tcp_md5sig_pool_lock);
p = tcp_md5sig_pool;
if (p)
tcp_md5sig_users++;
- spin_unlock_bh(&tcp_md5sig_pool_lock);
- return (p ? *per_cpu_ptr(p, cpu) : NULL);
-}
+ spin_unlock(&tcp_md5sig_pool_lock);
+
+ if (p)
+ return *per_cpu_ptr(p, smp_processor_id());
-EXPORT_SYMBOL(__tcp_get_md5sig_pool);
+ local_bh_enable();
+ return NULL;
+}
+EXPORT_SYMBOL(tcp_get_md5sig_pool);
-void __tcp_put_md5sig_pool(void)
+void tcp_put_md5sig_pool(void)
{
+ local_bh_enable();
tcp_free_md5sig_pool();
}
-
-EXPORT_SYMBOL(__tcp_put_md5sig_pool);
+EXPORT_SYMBOL(tcp_put_md5sig_pool);
int tcp_md5_hash_header(struct tcp_md5sig_pool *hp,
struct tcphdr *th)
next prev parent reply other threads:[~2010-05-07 8:00 UTC|newest]
Thread overview: 48+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <i2h571fb4001005031027y4a58c4dtfd28ddcdc08d8401@mail.gmail.com>
2010-05-04 3:30 ` TCP-MD5 checksum failure on x86_64 SMP Bhaskar Dutta
2010-05-04 11:32 ` Ben Hutchings
2010-05-04 14:28 ` Bhaskar Dutta
2010-05-04 16:12 ` Stephen Hemminger
2010-05-04 17:08 ` Bhaskar Dutta
2010-05-04 17:13 ` Stephen Hemminger
2010-05-05 18:03 ` Bhaskar Dutta
2010-05-05 18:53 ` Eric Dumazet
2010-05-06 11:55 ` Bhaskar Dutta
2010-05-06 12:06 ` Eric Dumazet
2010-05-07 5:04 ` David Miller
2010-05-07 5:32 ` Eric Dumazet
2010-05-07 17:14 ` Stephen Hemminger
2010-05-07 17:21 ` Eric Dumazet
2010-05-07 17:36 ` Stephen Hemminger
2010-05-07 21:40 ` Eric Dumazet
2010-05-10 14:55 ` Bijay Singh
2010-05-10 15:18 ` Eric Dumazet
2010-05-10 17:27 ` Bijay Singh
2010-05-11 4:08 ` Bijay Singh
2010-05-11 6:27 ` Eric Dumazet
2010-05-11 8:23 ` Bijay Singh
2010-05-11 20:50 ` Eric Dumazet
2010-05-12 3:20 ` Eric Dumazet
2010-05-12 22:22 ` Stephen Hemminger
2010-05-12 22:24 ` David Miller
2010-05-16 19:53 ` Eric Dumazet
2010-05-16 20:48 ` Eric Dumazet
2010-05-17 3:49 ` Bijay Singh
2010-05-17 5:03 ` Eric Dumazet
2010-05-17 17:22 ` Stephen Hemminger
2010-05-17 20:42 ` Stephen Hemminger
2010-05-17 21:04 ` [PATCH] tcp: tcp_synack_options() fix Eric Dumazet
2010-05-18 5:35 ` David Miller
2010-05-16 7:30 ` TCP-MD5 checksum failure on x86_64 SMP David Miller
2010-05-07 8:46 ` Lars Eggert
2010-05-07 8:55 ` Eric Dumazet
2010-05-07 9:12 ` David Miller
2010-05-07 5:39 ` Eric Dumazet
2010-05-07 8:00 ` Eric Dumazet [this message]
2010-05-07 8:59 ` Bhaskar Dutta
2010-05-07 9:37 ` Eric Dumazet
2010-05-07 10:50 ` Bhaskar Dutta
2010-05-07 15:18 ` Eric Dumazet
2010-05-07 15:44 ` Eric Dumazet
2010-05-07 21:18 ` Eric Dumazet
2010-05-16 7:37 ` David Miller
2010-05-16 7:35 ` 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=1273219222.2261.11.camel@edumazet-laptop \
--to=eric.dumazet@gmail.com \
--cc=bhaskie@gmail.com \
--cc=bhutchings@solarflare.com \
--cc=davem@davemloft.net \
--cc=netdev@vger.kernel.org \
--cc=shemminger@vyatta.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