[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20150721183453.GL11985@breakpoint.cc>
Date: Tue, 21 Jul 2015 20:34:53 +0200
From: Florian Westphal <fw@...len.de>
To: Frank Schreuder <fschreuder@...nsip.nl>
Cc: Florian Westphal <fw@...len.de>,
Nikolay Aleksandrov <nikolay@...ulusnetworks.com>,
Johan Schuijt <johan@...nsip.nl>,
Eric Dumazet <eric.dumazet@...il.com>,
"nikolay@...hat.com" <nikolay@...hat.com>,
"davem@...emloft.net" <davem@...emloft.net>,
"chutzpah@...too.org" <chutzpah@...too.org>,
Robin Geuze <robing@...nsip.nl>,
netdev <netdev@...r.kernel.org>
Subject: Re: reproducable panic eviction work queue
Frank Schreuder <fschreuder@...nsip.nl> wrote:
[ inet frag evictor crash ]
We believe we found the bug. This patch should fix it.
We cannot share list for buckets and evictor, the flag member is
subject to race conditions so flags & INET_FRAG_EVICTED test is not
reliable.
It would be great if you could confirm that this fixes the problem
for you, we'll then make formal patch submission.
Please apply this on kernel without previous test patches, wheter you
use affected -stable or net-next kernel shouldn't matter since those are
similar enough.
Many thanks!
diff --git a/include/net/inet_frag.h b/include/net/inet_frag.h
--- a/include/net/inet_frag.h
+++ b/include/net/inet_frag.h
@@ -45,6 +45,7 @@ enum {
* @flags: fragment queue flags
* @max_size: maximum received fragment size
* @net: namespace that this frag belongs to
+ * @list_evictor: list of queues to forcefully evict (e.g. due to low memory)
*/
struct inet_frag_queue {
spinlock_t lock;
@@ -59,6 +60,7 @@ struct inet_frag_queue {
__u8 flags;
u16 max_size;
struct netns_frags *net;
+ struct hlist_node list_evictor;
};
#define INETFRAGS_HASHSZ 1024
diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c
index 5e346a0..1722348 100644
--- a/net/ipv4/inet_fragment.c
+++ b/net/ipv4/inet_fragment.c
@@ -151,14 +151,13 @@ evict_again:
}
fq->flags |= INET_FRAG_EVICTED;
- hlist_del(&fq->list);
- hlist_add_head(&fq->list, &expired);
+ hlist_add_head(&fq->list_evictor, &expired);
++evicted;
}
spin_unlock(&hb->chain_lock);
- hlist_for_each_entry_safe(fq, n, &expired, list)
+ hlist_for_each_entry_safe(fq, n, &expired, list_evictor)
f->frag_expire((unsigned long) fq);
return evicted;
@@ -284,8 +283,7 @@ static inline void fq_unlink(struct inet_frag_queue *fq, struct inet_frags *f)
struct inet_frag_bucket *hb;
hb = get_frag_bucket_locked(fq, f);
- if (!(fq->flags & INET_FRAG_EVICTED))
- hlist_del(&fq->list);
+ hlist_del(&fq->list);
spin_unlock(&hb->chain_lock);
}
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists