Delayed processor processing

Hey, so I look at this function in the kernel source . I am trying to understand how Linux handles a situation where a task cannot be scheduled on a local processor.

/**
* queue_delayed_work - queue work on a workqueue after delay
* @wq: workqueue to use
* @dwork: delayable work to queue
* @delay: number of jiffies to wait before queueing
*
* Equivalent to queue_delayed_work_on() but tries to use the local CPU.
*/
static inline bool queue_delayed_work(struct workqueue_struct *wq,
                                      struct delayed_work *dwork,
                                      unsigned long delay)
{
        return queue_delayed_work_on(WORK_CPU_UNBOUND, wq, dwork, delay);
}

And here queue_delayed_work_on:

bool queue_delayed_work_on(int cpu, struct workqueue_struct *wq,
                           struct delayed_work *dwork, unsigned long delay)
{
        struct work_struct *work = &dwork->work;
        bool ret = false;
        unsigned long flags;

        /* read the comment in __queue_work() */
        local_irq_save(flags);

        if (!test_and_set_bit(WORK_STRUCT_PENDING_BIT, work_data_bits(work))) {
                __queue_delayed_work(cpu, wq, dwork, delay);
                ret = true;
        }

        local_irq_restore(flags);
        return ret;
}

Say, if you have 4 processors, and he cannot schedule a task on CPU 1, which one does he choose and where is this processed in the source code? I searched for a while and cannot find it. Even if you don’t understand how this works, I really appreciate the link to where the magic happens.

+4
source share
2 answers

, queue_delayed_work cpu WORK_CPU_UNBOUND. , , . __queue_delayed_work, delay , ( add_timer delayed_work_timer_fn ( ). - __queue_work, WORK_CPU_UNBOUND cpu. , "".

, cpu WORK_CPU_UNBOUND cpu :

if (req_cpu == WORK_CPU_UNBOUND)
    cpu = raw_smp_processor_id()

, , . , IIRC LDD3, , ( CPU , , IRQ ), . , .

, , , - . queue_work, : " CPU, , , ". WORK_CPU_UNBOUND cpu.

, - , IRQ, , . - ​​ , CPU . migrate_timers(), timer_cpu_notify, , , , cpu_notifier.

migrate_timers , cpu CPU_DEAD CPU_DEAD_FROZEN. _cpu_down, :

cpu_notify_nofail(CPU_DEAD | mod, hcpu);

__cpu_die(cpu), , CPU, , , , - . migrate_timers .

, , ? , :

  • cpu_down , , , , .

  • cpu_down CPU, , __cpu_die, .

+1

, Scheduler LWN.

0

Source: https://habr.com/ru/post/1599382/


All Articles