内核有些地方会单独使用禁止抢占,那哪些情况下会单独禁止抢占,而不使用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