• Paul E. McKenney's avatar
    sched/core: Add function to sample state of locked-down task · 2beaf328
    Paul E. McKenney authored
    A running task's state can be sampled in a consistent manner (for example,
    for diagnostic purposes) simply by invoking smp_call_function_single()
    on its CPU, which may be obtained using task_cpu(), then having the
    IPI handler verify that the desired task is in fact still running.
    However, if the task is not running, this sampling can in theory be done
    immediately and directly.  In practice, the task might start running at
    any time, including during the sampling period.  Gaining a consistent
    sample of a not-running task therefore requires that something be done
    to lock down the target task's state.
    
    This commit therefore adds a try_invoke_on_locked_down_task() function
    that invokes a specified function if the specified task can be locked
    down, returning true if successful and if the specified function returns
    true.  Otherwise this function simply returns false.  Given that the
    function passed to try_invoke_on_nonrunning_task() might be invoked with
    a runqueue lock held, that function had better be quite lightweight.
    
    The function is passed the target task's task_struct pointer and the
    argument passed to try_invoke_on_locked_down_task(), allowing easy access
    to task state and to a location for further variables to be passed in
    and out.
    
    Note that the specified function will be called even if the specified
    task is currently running.  The function can use ->on_rq and task_curr()
    to quickly and easily determine the task's state, and can return false
    if this state is not to the function's liking.  The caller of the
    try_invoke_on_locked_down_task() would then see the false return value,
    and could take appropriate action, for example, trying again later or
    sending an IPI if matters are more urgent.
    
    It is expected that use cases such as the RCU CPU stall warning code will
    simply return false if the task is currently running.  However, there are
    use cases involving nohz_full CPUs where the specified function might
    instead fall back to an alternative sampling scheme that relies on heavier
    synchronization (such as memory barriers) in the target task.
    
    Cc: Ingo Molnar <mingo@redhat.com>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Juri Lelli <juri.lelli@redhat.com>
    Cc: Vincent Guittot <vincent.guittot@linaro.org>
    Cc: Dietmar Eggemann <dietmar.eggemann@arm.com>
    Cc: Ben Segall <bsegall@google.com>
    Cc: Mel Gorman <mgorman@suse.de>
    [ paulmck: Apply feedback from Peter Zijlstra and Steven Rostedt. ]
    [ paulmck: Invoke if running to handle feedback from Mathieu Desnoyers. ]
    Reviewed-by: default avatarSteven Rostedt (VMware) <rostedt@goodmis.org>
    Reviewed-by: default avatarJoel Fernandes (Google) <joel@joelfernandes.org>
    Signed-off-by: default avatarPaul E. McKenney <paulmck@kernel.org>
    2beaf328
core.c 200 KB