aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/rcutree.c
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2012-10-18 07:55:36 -0400
committerPaul E. McKenney <paulmck@linux.vnet.ibm.com>2012-11-13 17:07:57 -0500
commit878d7439d0f45a95869e417576774673d1fa243f (patch)
treebf16331cb2e31ab00fe69d91755b7ac6ccb6a7d6 /kernel/rcutree.c
parent62da1921292ef789c23a7bf01d671d7572baf377 (diff)
rcu: Fix batch-limit size problem
Commit 29c00b4a1d9e27 (rcu: Add event-tracing for RCU callback invocation) added a regression in rcu_do_batch() Under stress, RCU is supposed to allow to process all items in queue, instead of a batch of 10 items (blimit), but an integer overflow makes the effective limit being 1. So, unless there is frequent idle periods (during which RCU ignores batch limits), RCU can be forced into a state where it cannot keep up with the callback-generation rate, eventually resulting in OOM. This commit therefore converts a few variables in rcu_do_batch() from int to long to fix this problem, along with the module parameters controlling the batch limits. Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Cc: <stable@vger.kernel.org> # 3.2 +
Diffstat (limited to 'kernel/rcutree.c')
-rw-r--r--kernel/rcutree.c15
1 files changed, 8 insertions, 7 deletions
diff --git a/kernel/rcutree.c b/kernel/rcutree.c
index 93d6871bf7f9..e4c2192b47c8 100644
--- a/kernel/rcutree.c
+++ b/kernel/rcutree.c
@@ -212,13 +212,13 @@ DEFINE_PER_CPU(struct rcu_dynticks, rcu_dynticks) = {
212#endif 212#endif
213}; 213};
214 214
215static int blimit = 10; /* Maximum callbacks per rcu_do_batch. */ 215static long blimit = 10; /* Maximum callbacks per rcu_do_batch. */
216static int qhimark = 10000; /* If this many pending, ignore blimit. */ 216static long qhimark = 10000; /* If this many pending, ignore blimit. */
217static int qlowmark = 100; /* Once only this many pending, use blimit. */ 217static long qlowmark = 100; /* Once only this many pending, use blimit. */
218 218
219module_param(blimit, int, 0444); 219module_param(blimit, long, 0444);
220module_param(qhimark, int, 0444); 220module_param(qhimark, long, 0444);
221module_param(qlowmark, int, 0444); 221module_param(qlowmark, long, 0444);
222 222
223int rcu_cpu_stall_suppress __read_mostly; /* 1 = suppress stall warnings. */ 223int rcu_cpu_stall_suppress __read_mostly; /* 1 = suppress stall warnings. */
224int rcu_cpu_stall_timeout __read_mostly = CONFIG_RCU_CPU_STALL_TIMEOUT; 224int rcu_cpu_stall_timeout __read_mostly = CONFIG_RCU_CPU_STALL_TIMEOUT;
@@ -1791,7 +1791,8 @@ static void rcu_do_batch(struct rcu_state *rsp, struct rcu_data *rdp)
1791{ 1791{
1792 unsigned long flags; 1792 unsigned long flags;
1793 struct rcu_head *next, *list, **tail; 1793 struct rcu_head *next, *list, **tail;
1794 int bl, count, count_lazy, i; 1794 long bl, count, count_lazy;
1795 int i;
1795 1796
1796 /* If no callbacks are ready, just return.*/ 1797 /* If no callbacks are ready, just return.*/
1797 if (!cpu_has_callbacks_ready_to_invoke(rdp)) { 1798 if (!cpu_has_callbacks_ready_to_invoke(rdp)) {