You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Realtek r8169驱动无抢占保护场景下内核临界代码及中断抢占规则问询

内核抢占与临界区相关问题解答

什么是内核驱动中的临界代码

临界代码指的是访问共享资源的代码段,执行过程中如果被其他同样访问该共享资源的上下文打断,会出现竞态、数据不一致、内存损坏甚至系统崩溃。只有当代码段存在并发访问共享资源的风险时,才需要做加锁、关抢占之类的保护,并非所有内核代码都需要额外的抢占保护。

中断上下文的抢占规则

  • 普通中断上半部处理函数执行时,内核默认关闭了本地CPU的中断,同时默认禁止抢占,不需要驱动手动调用preempt_disable。
  • NAPI的poll函数运行在NET_RX_SOFTIRQ软中断上下文,软中断执行期间内核默认也是禁止抢占的,同样不需要驱动手动关抢占。
  • 只有允许抢占的上下文(比如常规进程上下文)访问共享资源时,才需要根据场景手动做抢占保护。

结合r8169驱动代码的说明

你贴出的两段代码都不需要额外关抢占,原因如下:

  • 第一段分配DMA页的代码,使用GFP_KERNEL标记分配内存,该标记允许分配过程睡眠,说明这段代码运行在进程上下文(一般是网卡初始化、接口启动的流程中)。这段代码操作的是网卡设备私有的接收缓冲区资源,只要资源本身已经通过网卡对应的锁(如RX队列锁)保护,就不需要额外关抢占。
    struct page *data;
    
    data = alloc_pages_node(node, GFP_KERNEL, get_order(R8169_RX_BUF_SIZE));
    if (!data)
        return NULL;
    
    mapping = dma_map_page(d, data, 0, R8169_RX_BUF_SIZE, DMA_FROM_DEVICE);
    ...
    
  • 第二段DMA同步的代码运行在NAPI poll的软中断上下文,该上下文本身默认禁止抢占。而且NAPI实例调度时已经和CPU做了绑定,同一个网卡的RX队列同一时间只会在一个CPU上处理,不存在多个上下文并发访问当前DMA缓冲区的问题,自然不需要额外保护。
    dma_sync_single_for_cpu(d, addr, pkt_size, DMA_FROM_DEVICE);
    
    ....
    dma_sync_single_for_device(d, addr, pkt_size, DMA_FROM_DEVICE);
    
  • 你提到代码中没有出现get_cpu、信号量等调用,是因为NAPI框架本身已经保证了同一个RX队列的poll操作是串行执行的,没有并发竞态,不需要驱动额外做保护。

内核通用抢占规则总结

  • 进程上下文:默认允许抢占,访问共享资源时根据场景选择自旋锁(持有期间自动关抢占)、互斥锁、手动关抢占等保护手段。
  • 软中断/tasklet上下文:默认禁止抢占,同一类软中断可以在多个CPU上同时运行,跨CPU共享的资源仍需要加自旋锁保护。
  • 中断上半部上下文:默认关闭本地中断+禁止抢占,跨CPU共享的资源需要加自旋锁保护。

内容的提问来源于stack exchange,提问作者user786

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 09:57:03