On Thu, 2015-12-03 at 20:51 +0800, Herbert Xu wrote: > On Mon, Nov 30, 2015 at 06:18:59PM +0800, Herbert Xu wrote: > > > > OK that's better. I think I see the problem. The test in > > rhashtable_insert_rehash is racy and if two threads both try > > to grow the table one of them may be tricked into doing a rehash > > instead. > > > > I'm working on a fix. > > While the EBUSY errors are gone for me, I can still see plenty > of ENOMEM errors. In fact it turns out that the reason is quite > understandable. When you pound the rhashtable hard so that it > doesn't actually get a chance to grow the table in process context, > then the table will only grow with GFP_ATOMIC allocations. > > For me this starts failing regularly at around 2^19 entries, which > requires about 1024 contiguous pages if I'm not mistaken.
Well, it will fail before this point if memory is fragmented. Anyway, __vmalloc() can be used with GFP_ATOMIC, have you tried this ? diff --git a/lib/rhashtable.c b/lib/rhashtable.c index a54ff8949f91..9ef5d74963b2 100644 --- a/lib/rhashtable.c +++ b/lib/rhashtable.c @@ -120,8 +120,9 @@ static struct bucket_table *bucket_table_alloc(struct rhashtable *ht, if (size <= (PAGE_SIZE << PAGE_ALLOC_COSTLY_ORDER) || gfp != GFP_KERNEL) tbl = kzalloc(size, gfp | __GFP_NOWARN | __GFP_NORETRY); - if (tbl == NULL && gfp == GFP_KERNEL) - tbl = vzalloc(size); + if (tbl == NULL) + tbl = __vmalloc(size, gfp | __GFP_HIGHMEM | __GFP_ZERO, + PAGE_KERNEL); if (tbl == NULL) return NULL; -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html