当前位置: 首页 > news >正文

内核协议栈源码阅读(一) ---驱动与内核交互

文章目录

    • 一、硬中断
      • 1.1 `e100_intr`
      • 1.2 `__netif_rx_schedule`
      • 1.3 补充:
    • 二、软中断
      • 2.1 net_rx_action
      • 2.2 e100_poll
      • 2.3 补充
    • 三、非 NAPI 的软中断处理
      • 3.1 netif_rx
      • 3.2 backlog_dev->poll
      • 3.3 补充
    • 四、总结

以 e100_intr 为例:

一、硬中断

1.1 e100_intr

网卡触发中断,os 进入中断处理程序 e100_intr,该函数通过 request_irq 注册到中断处理系统中。

static irqreturn_t e100_intr(int irq, void *dev_id)
{struct net_device *netdev = dev_id;struct nic *nic = netdev_priv(netdev);u8 stat_ack = readb(&nic->csr->scb.stat_ack);DPRINTK(INTR, DEBUG, "stat_ack = 0x%02X\n", stat_ack);if(stat_ack == stat_ack_not_ours ||	/* Not our interrupt */stat_ack == stat_ack_not_present)	/* Hardware is ejected */return IRQ_NONE;/* Ack interrupt(s) */writeb(stat_ack, &nic->csr->scb.stat_ack);/* We hit Receive No Resource (RNR); restart RU after cleaning */if(stat_ack & stat_ack_rnr)nic->ru_running = RU_SUSPENDED;if(likely(netif_rx_schedule_prep(netdev))) {e100_disable_irq(nic);__netif_rx_schedule(netdev);}return IRQ_HANDLED;
}
  • 首先对硬中断进行检查,即是否由网络设备激活等
  • netif_rx_schedule_prep 设置网卡 state 的 RX_SCHED 标志。如果设置成功,则 e100_disable_irq(dev) 关闭网络设备的硬中断 (即当前设备再收到包也不会触发中断信号,区别于关闭 cpu 的中断响应。关闭后会在驱动的 poll 函数中重新打开,表示驱动完整的收完一轮包),防止网卡触发大量硬中断。如果 RX_SCHED 已经设置过了,则直接返回,因为设备已经加入 poll_list 且触发过软中断了),然后 __netif_rx_schedule 触发软中断。

1.2 __netif_rx_schedule

__netif_rx_schedule

void __netif_rx_schedule(struct net_device *dev)
{unsigned long flags;local_irq_save(flags); // 保存并关闭 cpu 中断响应dev_hold(dev);list_add_tail(&dev->poll_list, &__get_cpu_var(softnet_data).poll_list);if (dev->quota < 0)dev->quota += dev->weight;elsedev->quota = dev->weight;__raise_softirq_irqoff(NET_RX_SOFTIRQ);local_irq_restore(flags);
}
EXPORT_SYMBOL(__netif_rx_schedule);
  • 保存当前 cpu 的中断响应状态并关闭 cpu 的中断响应(有可能在中断处理中递归被中断,所以这里不能简单的关闭中断或者开启中断,而是保存状态并关闭:local_irq_save(flags)
  • 将 dev 插入到当前 cpu 的 softnet_data 的 poll_list 等待软中断处理(list_add_tail(&dev->poll_list, &__get_cpu_var(softnet_data).poll_list);
    • 这里 softnet_data 是 cpu 级别的数据结构,用来记录有哪些网卡设备将中断捅给了当前 cpu,或者当前 cpu 有哪些包需要发给哪些网卡
  • dev->quota 赋值,即分配 napi 可收取的包数
  • 发起软中断(__raise_softirq_irqoff(NET_RX_SOFTIRQ)
  • 恢复 cpu 中断响应状态(local_irq_restore(flags);
    content_copy

1.3 补充:

local_irq_save(flags) 函数实现:

// 保存 cpu 中断响应标志的函数,保存的同时会关闭 cpu 的中断响应
#define local_irq_save(flags) \do { raw_local_irq_save(flags); trace_hardirqs_off(); } while (0)// include/asm-x86_64/irqflags.h
#define raw_local_irq_save(flags) \do { (flags) = __raw_local_irq_save(); } while (0)static inline unsigned long __raw_local_irq_save(void)
{unsigned long flags = __raw_local_save_flags();raw_local_irq_disable()
http://www.lryc.cn/news/596422.html

相关文章:

  • Spring AI Alibaba + JManus:从架构原理到生产落地的全栈实践——一篇面向 Java 架构师的 20 分钟深度阅读
  • 打造智能化应用新思路:扣子Coze工作流详解与最佳实践
  • MCU中的总线桥是什么?
  • js的基本内容:引用、变量、打印、交互、定时器、demo操作
  • 聚簇索引的优势
  • LeetCode|Day22|231. 2 的幂|Python刷题笔记
  • windows下nvm的安装及使用
  • 融云“通信+AI”解决方案三大场景实例
  • 使用mybatis实现模糊查询和精准查询切换的功能
  • GraphRAG的部署和生成检索过程体验
  • 小白成长之路-部署Zabbix7
  • 使用react编写一个简单的井字棋游戏
  • 17.VRRP技术
  • 接口自动化测试种涉及到接口依赖怎么办?
  • 微调大语言模型(LLM)有多难?
  • Google Gemini 体验
  • 深入解析Hadoop中的推测执行:原理、算法与策略
  • kafka查看消息的具体内容 kafka-dump-log.sh
  • SDC命令详解:使用set_min_library命令进行约束
  • Unity笔记——事件中心
  • HTB赛季8靶场 - Mirage
  • 风险识别清单:构建动态化的风险管理体系
  • Java函数式编程深度解析:从基础到高阶应用
  • 技能系统详解(4)——运动表现
  • 哔哩哔哩视觉算法面试30问全景精解
  • 钢铁逆行者:Deepoc具身智能如何重塑消防机器人的“火场直觉”
  • 【中文翻译】SmolVLA:面向低成本高效机器人的视觉-语言-动作模型
  • Vue 3 响应式系统中的 effectScope、watchEffect、effect 和 watch 详解
  • 如何将iPad中的视频传输到电脑(6种简单方法)
  • 单片机学习笔记.单总线one-wire协议(这里以普中开发板DS18B20为例)