• Daniel Lezcano's avatar
    sched: Let the scheduler see CPU idle states · 442bf3aa
    Daniel Lezcano authored
    When the cpu enters idle, it stores the cpuidle state pointer in its
    struct rq instance which in turn could be used to make a better decision
    when balancing tasks.
    
    As soon as the cpu exits its idle state, the struct rq reference is
    cleared.
    
    There are a couple of situations where the idle state pointer could be changed
    while it is being consulted:
    
    1. For x86/acpi with dynamic c-states, when a laptop switches from battery
       to AC that could result on removing the deeper idle state. The acpi driver
       triggers:
    	'acpi_processor_cst_has_changed'
    		'cpuidle_pause_and_lock'
    			'cpuidle_uninstall_idle_handler'
    				'kick_all_cpus_sync'.
    
    All cpus will exit their idle state and the pointed object will be set to
    NULL.
    
    2. The cpuidle driver is unloaded. Logically that could happen but not
    in practice because the drivers are always compiled in and 95% of them are
    not coded to unregister themselves.  In any case, the unloading code must
    call 'cpuidle_unregister_device', that calls 'cpuidle_pause_and_lock'
    leading to 'kick_all_cpus_sync' as mentioned above.
    
    A race can happen if we use the pointer and then one of these two scenarios
    occurs at the same moment.
    
    In order to be safe, the idle state pointer stored in the rq must be
    used inside a rcu_read_lock section where we are protected with the
    'rcu_barrier' in the 'cpuidle_uninstall_idle_handler' function. The
    idle_get_state() and idle_put_state() accessors should be used to that
    effect.
    Signed-off-by: default avatarDaniel Lezcano <daniel.lezcano@linaro.org>
    Signed-off-by: default avatarNicolas Pitre <nico@linaro.org>
    Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
    Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>
    Cc: linux-pm@vger.kernel.org
    Cc: linaro-kernel@lists.linaro.org
    Cc: Daniel Lezcano <daniel.lezcano@linaro.org>
    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    Link: http://lkml.kernel.org/n/tip-@git.kernel.orgSigned-off-by: default avatarIngo Molnar <mingo@kernel.org>
    442bf3aa
cpuidle.c 12.9 KB