ILD

Preemption Disabling
作者:Yuan Jianpeng 邮箱:yuanjp89@163.com
发布时间:2023-4-26 站点:Inside Linux Development

内核有些地方会单独使用禁止抢占,那哪些情况下会单独禁止抢占,而不使用spin lock呢?


最常用的场景就是per-processor data,每cpu变量。因为其它cpu不会访问这个cpu的数据,那么只要禁止抢占,

就可以保证只有当前task访问每cpu数据,否则task A的关键区可能被task B的关键区抢占,如:

task A manipulates per-procesor variable foo, which is not protected by a lock task A is preempted task B is scheduled task B manipulates variable foo task B completes task A is rescheduled task A continues manipulating variable foo


task a只要禁止抢占就可以了:

preempt_disable();
/* preemption is disabled ... */
preempt_enable();


还有一个重要的应用场景,就是获取当前cpu id接口:__smp_processor_id()

必须禁止抢占,防止当前task迁移到其它cpu运行。导致cpu id失效。为此内核提供了get_cpu()和put_cpu()接口:

#define get_cpu()               ({ preempt_disable(); __smp_processor_id(); })

#define put_cpu()               preempt_enable()


例子:netif_rx_internal(),将skb交给本地的backlog queue

                ret = enqueue_to_backlog(skb, get_cpu(), &qtail);

                put_cpu();



参考

http://books.gigatux.nl/mirror/kerneldevelopment/0672327201/ch09lev1sec9.html


Copyright © linuxdev.cc 2017-2024. Some Rights Reserved.