Commit 803b0ebae921714d1c36f0996db8125eda5fae53

Authored by Paul E. McKenney
Committed by Paul E. McKenney
1 parent 7a11e2058f

time: RCU permitted to stop idle entry via softirq

The can_stop_idle_tick() function complains if a softirq vector is
raised too late in the idle-entry process, presumably in order to
prevent dangling softirq invocations from being delayed across the
full idle period, which might be indefinitely long -- and if softirq
was asserted any later than the call to this function, such a delay
might well happen.

However, RCU needs to be able to use softirq to stop idle entry in
order to be able to drain RCU callbacks from the current CPU, which in
turn enables faster entry into dyntick-idle mode, which in turn reduces
power consumption.  Because RCU takes this action at a well-defined
point in the idle-entry path, it is safe for RCU to take this approach.

This commit therefore silences the error message that is sometimes
produced when the going-idle CPU suddenly finds that it has an RCU_SOFTIRQ
to process.  The error message will continue to be issued for other
softirq vectors.

Reported-by: Sedat Dilek <sedat.dilek@gmail.com>
Signed-off-by: Paul E. McKenney <paul.mckenney@linaro.org>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
Tested-by: Sedat Dilek <sedat.dilek@gmail.com>
Reviewed-by: Josh Triplett <josh@joshtriplett.org>

Showing 2 changed files with 4 additions and 1 deletions Side-by-side Diff

include/linux/interrupt.h
... ... @@ -430,6 +430,8 @@
430 430 NR_SOFTIRQS
431 431 };
432 432  
  433 +#define SOFTIRQ_STOP_IDLE_MASK (~(1 << RCU_SOFTIRQ))
  434 +
433 435 /* map softirq index to softirq name. update 'softirq_to_name' in
434 436 * kernel/softirq.c when adding a new softirq.
435 437 */
kernel/time/tick-sched.c
... ... @@ -436,7 +436,8 @@
436 436 if (unlikely(local_softirq_pending() && cpu_online(cpu))) {
437 437 static int ratelimit;
438 438  
439   - if (ratelimit < 10) {
  439 + if (ratelimit < 10 &&
  440 + (local_softirq_pending() & SOFTIRQ_STOP_IDLE_MASK)) {
440 441 printk(KERN_ERR "NOHZ: local_softirq_pending %02x\n",
441 442 (unsigned int) local_softirq_pending());
442 443 ratelimit++;