diff options
author | Eric Dumazet <edumazet@google.com> | 2015-02-26 10:20:34 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-02-27 17:55:14 -0500 |
commit | 5beb5c90c1f54d745da040aa05634a5830ba4a4c (patch) | |
tree | 4626f1033a05b15b4cd046d066de1011c7a7f67d /lib | |
parent | 061c1a6e367855a9ed1110ba059bc2e7634fd429 (diff) |
rhashtable: use cond_resched()
If a hash table has 128 slots and 16384 elems, expand to 256 slots
takes more than one second. For larger sets, a soft lockup is detected.
Holding cpu for that long, even in a work queue is a show stopper
for non preemptable kernels.
cond_resched() at strategic points to allow process scheduler
to reschedule us.
Signed-off-by: Eric Dumazet <edumazet@google.com>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/rhashtable.c | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/lib/rhashtable.c b/lib/rhashtable.c index 090641db4c0d..b5344ef4c684 100644 --- a/lib/rhashtable.c +++ b/lib/rhashtable.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
19 | #include <linux/log2.h> | 19 | #include <linux/log2.h> |
20 | #include <linux/sched.h> | ||
20 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
21 | #include <linux/vmalloc.h> | 22 | #include <linux/vmalloc.h> |
22 | #include <linux/mm.h> | 23 | #include <linux/mm.h> |
@@ -412,6 +413,7 @@ int rhashtable_expand(struct rhashtable *ht) | |||
412 | } | 413 | } |
413 | } | 414 | } |
414 | unlock_buckets(new_tbl, old_tbl, new_hash); | 415 | unlock_buckets(new_tbl, old_tbl, new_hash); |
416 | cond_resched(); | ||
415 | } | 417 | } |
416 | 418 | ||
417 | /* Unzip interleaved hash chains */ | 419 | /* Unzip interleaved hash chains */ |
@@ -435,6 +437,7 @@ int rhashtable_expand(struct rhashtable *ht) | |||
435 | complete = false; | 437 | complete = false; |
436 | 438 | ||
437 | unlock_buckets(new_tbl, old_tbl, old_hash); | 439 | unlock_buckets(new_tbl, old_tbl, old_hash); |
440 | cond_resched(); | ||
438 | } | 441 | } |
439 | } | 442 | } |
440 | 443 | ||
@@ -493,6 +496,7 @@ int rhashtable_shrink(struct rhashtable *ht) | |||
493 | tbl->buckets[new_hash + new_tbl->size]); | 496 | tbl->buckets[new_hash + new_tbl->size]); |
494 | 497 | ||
495 | unlock_buckets(new_tbl, tbl, new_hash); | 498 | unlock_buckets(new_tbl, tbl, new_hash); |
499 | cond_resched(); | ||
496 | } | 500 | } |
497 | 501 | ||
498 | /* Publish the new, valid hash table */ | 502 | /* Publish the new, valid hash table */ |