当前位置: 首页 > 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.xdnf.cn/news/1167157.html

相关文章:

  • 进程优先级切换调度-进程概念(6)
  • Taro 网络 API 详解与实用案例
  • SecretFlow (3) --- 添加合作方并创建项目
  • JavaScript,发生异常,try...catch...finally处理,继续向上层调用者传递异常信息
  • RabbitMQ03——面试题
  • uniapp各大平台导航组件
  • 在 Ubuntu 22.04 上安装并优化 Nginx nginx入门操作 稍难,需要有一定理论 多理解 多实践
  • 《Uniapp-Vue 3-TS 实战开发》自定义时间选择
  • Kafka基础理论速通
  • IDEA全局Maven配置
  • 比特币技术简史 第六章:网络协议 - P2P网络、节点类型与消息传播
  • 未来趋势:LeafletJS 与 Web3/AI 的融合
  • Visual Studio Code 远端云服务器开发使用指南
  • (3)重定向 | 时间相关指令 | 文件查找 | 打包与压缩
  • FastDFS 6.11.0 单机环境搭建与测试(附 Nginx 集成)+ docker构建+k8s启动文件
  • Linux异常与信号处理
  • 浙江大学PTA程序设计C语言基础编程练习题1-5
  • 【论文阅读 | TIV 2024 | CDC-YOLOFusion:利用跨尺度动态卷积融合实现可见光-红外目标检测】
  • 边缘计算网关赋能智慧农业:物联网边缘计算的创新应用与实践
  • 【每日算法】专题九_链表
  • python-FTP爆破脚本(phpstudy)-一点bug记录
  • C++性能优化擂台技术文章大纲
  • Unity笔记——事件中心
  • Web3介绍(Web 3.0)(一种基于区块链技术的去中心化互联网范式,旨在通过技术手段实现用户对数据的自主权、隐私保护和价值共享)
  • 算法第26天|贪心算法:用最少数量的箭引爆气球、无重叠区间、划分字母区间
  • solidity从入门到精通 第二章:Solidity初相见
  • AI 音频产品开发模板及流程(二)
  • 数据结构 堆(2)---堆的实现
  • Markdown 转 PDF API 数据接口
  • Android ViewModel 深度解析:原理、使用与最佳实践