• Marcelo Tosatti's avatar
    tick/nohz: Kick only _queued_ task whose tick dependency is updated · a1dfb631
    Marcelo Tosatti authored
    When the tick dependency of a task is updated, we want it to aknowledge
    the new state and restart the tick if needed. If the task is not
    running, we don't need to kick it because it will observe the new
    dependency upon scheduling in. But if the task is running, we may need
    to send an IPI to it so that it gets notified.
    
    Unfortunately we don't have the means to check if a task is running
    in a race free way. Checking p->on_cpu in a synchronized way against
    p->tick_dep_mask would imply adding a full barrier between
    prepare_task_switch() and tick_nohz_task_switch(), which we want to
    avoid in this fast-path.
    
    Therefore we blindly fire an IPI to the task's CPU.
    
    Meanwhile we can check if the task is queued on the CPU rq because
    p->on_rq is always set to TASK_ON_RQ_QUEUED _before_ schedule() and its
    full barrier that precedes tick_nohz_task_switch(). And if the task is
    queued on a nohz_full CPU, it also has fair chances to be running as the
    isolation constraints prescribe running single tasks on full dynticks
    CPUs.
    
    So use this as a trick to check if we can spare an IPI toward a
    non-running task.
    
    NOTE: For the ordering to be correct, it is assumed that we never
    deactivate a task while it is running, the only exception being the task
    deactivating itself while scheduling out.
    Suggested-by: default avatarPeter Zijlstra <peterz@infradead.org>
    Signed-off-by: default avatarMarcelo Tosatti <mtosatti@redhat.com>
    Signed-off-by: default avatarFrederic Weisbecker <frederic@kernel.org>
    Signed-off-by: default avatarIngo Molnar <mingo@kernel.org>
    Acked-by: default avatarPeter Zijlstra <peterz@infradead.org>
    Link: https://lore.kernel.org/r/20210512232924.150322-9-frederic@kernel.org
    a1dfb631
sched.h 60 KB