linux内核的延时函数,linux-kernel – 延迟工作的CPU处理

嘿所以我在

kernel source code中看这个函数.我试图弄清楚Linux如何处理无法在本地CPU上安排任务的情况./**

* 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);

}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;

}

假如你有4个CPU并且它无法在CPU 1上安排任务,选择哪一个以及源代码在哪里处理?我一直在找一段时间而找不到它.即使你不理解它是如何工作的,我也非常感谢魔法发生的链接.

最佳答案 如您所见,queue_delayed_work将cpu参数设置为WORK_CPU_UNBOUND.该值定义为大于内核支持的实际CPU数.该值传递给__queue_delayed_work,如果延迟非零,则使用定时器(使用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()

因此,工作将在处理之前设置的定时器中断的处理器上执行.现在我没有研究定时器代码,而是从LDD3书中研究IIRC,定时器中断将由他们注册的CPU处理(除非此时CPU将被禁用,当然,在这种情况下,定时器IRQ将被移动到其他CPU),但那本书已经老了一些,这可能不再是真的了.

内核代码中还有另一个提示应该证明我写的内容 – 请参阅queue_work函数的注释:“我们将工作排队到提交它的CPU,但如果CPU死了,它可以由另一个CPU处理”.此函数还使用WORK_CPU_UNBOUND作为cpu参数.

计时器迁移细节

如前所述,如果某个处理器出现故障,它将无法再处理IRQ,因此无法处理已注册的定时器.因此,当CPU脱机时,内核会将所有挂起的计时器迁移到其他CPU.此任务由migrate_timers()函数完成,该函数由timer_cpu_notify运行,而timer_cpu_notify又是一个注册为cpu_notifier的回调.

当cpu状态更改为CPU_DEAD或CPU_DEAD_FROZEN时,将运行migrate_timers.通过调用以下方法在_cpu_down函数内设置此状态:cpu_notify_nofail(CPU_DEAD | mod, hcpu);

它在__cpu_die(cpu)之后调用,它确保我们禁用的CPU不再工作,因此我们可以确保此代码在其他CPU上运行. migrate_timers会将所有计时器重新分配给正在运行的CPU.

那么决定哪个CPU应该接管定时器的决定在哪里?可以说它是由调度程序完成的:

>如果在与要禁用的CPU不同的CPU上调用cpu_down,则这将是将要接管的CPU.

>如果在要禁用的CPU上调用cpu_down,它将在__cpu_die中自行调度,然后其他代码将在其他CPU上重新调度.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值