cpuidle: powerpc: cpuidle set polling before enabling irqs
authorNicholas Piggin <npiggin@gmail.com>
Wed, 14 Jun 2017 13:02:39 +0000 (23:02 +1000)
committerMichael Ellerman <mpe@ellerman.id.au>
Wed, 28 Jun 2017 03:08:11 +0000 (13:08 +1000)
local_irq_enable can cause interrupts to be taken which could
take significant amount of processing time. The idle process
should set its polling flag before this, so another process that
wakes it during this time will not have to send an IPI.

Expand the TIF_POLLING_NRFLAG coverage to as large as possible.

Reviewed-by: Gautham R. Shenoy <ego@linux.vnet.ibm.com>
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
drivers/cpuidle/cpuidle-powernv.c
drivers/cpuidle/cpuidle-pseries.c

index 79152676f62b2f6d913b723dfc2eb2fe785b0e4f..50b3c2e0306f9565151f58d26f86c8c115db242d 100644 (file)
@@ -51,9 +51,10 @@ static int snooze_loop(struct cpuidle_device *dev,
 {
        u64 snooze_exit_time;
 
-       local_irq_enable();
        set_thread_flag(TIF_POLLING_NRFLAG);
 
+       local_irq_enable();
+
        snooze_exit_time = get_tb() + snooze_timeout;
        ppc64_runlatch_off();
        HMT_very_low();
@@ -66,6 +67,7 @@ static int snooze_loop(struct cpuidle_device *dev,
        ppc64_runlatch_on();
        clear_thread_flag(TIF_POLLING_NRFLAG);
        smp_mb();
+
        return index;
 }
 
index 166ccd711ec970c365c4743ed0e808a8049f0c63..7b12bb2ea70f563c1e5a6589f21a169357c8dec1 100644 (file)
@@ -62,9 +62,10 @@ static int snooze_loop(struct cpuidle_device *dev,
        unsigned long in_purr;
        u64 snooze_exit_time;
 
+       set_thread_flag(TIF_POLLING_NRFLAG);
+
        idle_loop_prolog(&in_purr);
        local_irq_enable();
-       set_thread_flag(TIF_POLLING_NRFLAG);
        snooze_exit_time = get_tb() + snooze_timeout;
 
        while (!need_resched()) {