深入理解linux网络技术内幕读书笔记(九)--中断与网络驱动程序
Table of Contents
接收到帧时通知驱动程序
轮询
例如,内核可以持续读取设备上的一个内存寄存器,或者当一个定时器到期时就回头检查哪个寄存器。
中断
此时,当特定事件发生时,设备驱动程序会代表内核指示设备产生硬件中断。内核将中断其他活动,然后调用一个驱动程序
所注册的处理函数,以满足设备的需要。当事件是接收到一个帧时,处理函数就会把该帧排入队列某处,然后通知内核。
中断处理程序
函数/宏 | 描述 |
---|---|
in_interrupt | 处于软硬件中断中,且抢占功能是关闭的 |
in_softirq | 处于软件中断中 |
in_irq | 处于硬件中断中 |
softirq_pending | 软件中断未决 |
local_softirq_pending | 本地软件中断未决 |
__raise_softirq_irqoff | 设置与输入的软IRQ类型相关联的标识,将该软IRQ标记为未决 |
raise_softirq_irqoff | 先关闭硬件中断,再调用__raise_softirq_irqoff,再恢复其原有状态 |
raise_softirq | |
__local_bh_enable | |
local_bh_enable | |
local_bh_disable | |
local_irq_disable | |
local_irq_enable | |
local_irq_save | |
local_irq_restore | |
spin_lock_bh | |
spin_unlock_bh |
抢占功能
- preempt_disable()
为当前任务关闭抢占功能。可以重复调用,递增一个引用计数器。 - preempt_enable()
- preempt_enable_no_resched()
开启抢占功能。preempt_enable_no_reched()只是递减一个引用计数器,使得其值为0时,可以让抢占再度开启。
下半部函数
内核2.4版本以后的下半部函数: 引入软IRQ
对并发的唯一限制就是何时,在一个CPU上每个软IRQ都只能有一个实例运行。
新式的软IRQ模型只有10种模型(include/linux/interrupt.h):
1: /* PLEASE, avoid to allocate new softirqs, if you need not _really_ high
2: frequency threaded job scheduling. For almost all the purposes
3: tasklets are more than enough. F.e. all serial device BHs et
4: al. should be converted to tasklets, not to softirqs.
5: */
6:
7: enum
8: {
9: HI_SOFTIRQ=,
10: TIMER_SOFTIRQ,
11: NET_TX_SOFTIRQ,
12: NET_RX_SOFTIRQ,
13: BLOCK_SOFTIRQ,
14: BLOCK_IOPOLL_SOFTIRQ,
15: TASKLET_SOFTIRQ,
16: SCHED_SOFTIRQ,
17: HRTIMER_SOFTIRQ,
18: RCU_SOFTIRQ, /* Preferable RCU should always be the last softirq */
19:
20: NR_SOFTIRQS
21: };
网络代码如何使用软IRQ
网络子系统在net/core/dev.c中注册接收发送软中断:
open_softirq(NET_TX_SOFTIRQ, net_tx_action);
open_softirq(NET_RX_SOFTIRQ, net_rx_action);
1: /*
2: * Initialize the DEV module. At boot time this walks the device list and
3: * unhooks any devices that fail to initialise (normally hardware not
4: * present) and leaves us with a valid list of present and active devices.
5: *
6: */
7:
8: /*
9: * This is called single threaded during boot, so no need
10: * to take the rtnl semaphore.
11: */
12: static int __init net_dev_init(void)
13: {
14: int i, rc = -ENOMEM;
15:
16: BUG_ON(!dev_boot_phase);
17:
18: if (dev_proc_init())
19: goto out;
20:
21: if (netdev_kobject_init())
22: goto out;
23:
24: INIT_LIST_HEAD(&ptype_all);
25: for (i = ; i < PTYPE_HASH_SIZE; i++)
26: INIT_LIST_HEAD(&ptype_base[i]);
27:
28: if (register_pernet_subsys(&netdev_net_ops))
29: goto out;
30:
31: /*
32: * Initialise the packet receive queues.
33: */
34:
35: for_each_possible_cpu(i) {
36: struct softnet_data *sd = &per_cpu(softnet_data, i);
37:
38: memset(sd, , sizeof(*sd));
39: skb_queue_head_init(&sd->input_pkt_queue);
40: skb_queue_head_init(&sd->process_queue);
41: sd->completion_queue = NULL;
42: INIT_LIST_HEAD(&sd->poll_list);
43: sd->output_queue = NULL;
44: sd->output_queue_tailp = &sd->output_queue;
45: #ifdef CONFIG_RPS
46: sd->csd.func = rps_trigger_softirq;
47: sd->csd.info = sd;
48: sd->csd.flags = ;
49: sd->cpu = i;
50: #endif
51:
52: sd->backlog.poll = process_backlog;
53: sd->backlog.weight = weight_p;
54: sd->backlog.gro_list = NULL;
55: sd->backlog.gro_count = ;
56: }
57:
58: dev_boot_phase = ;
59:
60: /* The loopback device is special if any other network devices
61: * is present in a network namespace the loopback device must
62: * be present. Since we now dynamically allocate and free the
63: * loopback device ensure this invariant is maintained by
64: * keeping the loopback device as the first device on the
65: * list of network devices. Ensuring the loopback devices
66: * is the first device that appears and the last network device
67: * that disappears.
68: */
69: if (register_pernet_device(&loopback_net_ops))
70: goto out;
71:
72: if (register_pernet_device(&default_device_ops))
73: goto out;
74:
75: open_softirq(NET_TX_SOFTIRQ, net_tx_action);
76: open_softirq(NET_RX_SOFTIRQ, net_rx_action);
77:
78: hotcpu_notifier(dev_cpu_callback, );
79: dst_init();
80: dev_mcast_init();
81: rc = ;
82: out:
83: return rc;
84: }
85:
86: subsys_initcall(net_dev_init);
softnet_data结构
每个CPU都有其队列,用来接收进来的帧。数据结构为:
1: /*
2: * Incoming packets are placed on per-cpu queues
3: */
4: struct softnet_data {
5: struct Qdisc *output_queue;
6: struct Qdisc **output_queue_tailp;
7: struct list_head poll_list;
8: struct sk_buff *completion_queue;
9: struct sk_buff_head process_queue;
10:
11: /* stats */
12: unsigned int processed;
13: unsigned int time_squeeze;
14: unsigned int cpu_collision;
15: unsigned int received_rps;
16:
17: #ifdef CONFIG_RPS
18: struct softnet_data *rps_ipi_list;
19:
20: /* Elements below can be accessed between CPUs for RPS */
21: struct call_single_data csd ____cacheline_aligned_in_smp;
22: struct softnet_data *rps_ipi_next;
23: unsigned int cpu;
24: unsigned int input_queue_head;
25: unsigned int input_queue_tail;
26: #endif
27: unsigned dropped;
28: struct sk_buff_head input_pkt_queue;
29: struct napi_struct backlog;
30: };
深入理解linux网络技术内幕读书笔记(九)--中断与网络驱动程序的更多相关文章
- 深入理解linux网络技术内幕读书笔记(三)--用户空间与内核的接口
Table of Contents 1 概论 1.1 procfs (/proc 文件系统) 1.1.1 编程接口 1.2 sysctl (/proc/sys目录) 1.2.1 编程接口 1.3 sy ...
- 深入理解linux网络技术内幕读书笔记(十)--帧的接收
Table of Contents 1 概述 1.1 帧接收的中断处理 2 设备的开启与关闭 3 队列 4 通知内核帧已接收:NAPI和netif_rx 4.1 NAPI简介 4.1.1 NAPI优点 ...
- 深入理解linux网络技术内幕读书笔记(四)--通知链
Table of Contents 1 概述 2 定义链 3 链注册 4 链上的通知事件 5 网络子系统的通知链 5.1 包裹函数 5.2 范例 6 测试实例 概述 [注意] 通知链只在内核子系统之间 ...
- 深入理解linux网络技术内幕读书笔记(二)--关键数据结构
Table of Contents 1 套接字缓冲区: sk_buff结构 1.1 网络选项及内核结构 1.2 结构说明及操作函数 2 net_device结构 2.1 MTU 2.2 结构说明及操作 ...
- 深入理解linux网络技术内幕读书笔记(八)--设备注册与初始化
Table of Contents 1 设备注册之时 2 设备除名之时 3 分配net_device结构 4 NIC注册和除名架构 4.1 注册 4.2 除名 5 设备初始化 6 设备类型初始化: x ...
- 深入理解linux网络技术内幕读书笔记(七)--组件初始化的内核基础架构
Table of Contents 1 引导期间的内核选项 2 注册关键字 3 模块初始化代码 引导期间的内核选项 linux运行用户把内核配置选项传给引导记录,然后引导记录再把选项传给内核. 在引导 ...
- 深入理解linux网络技术内幕读书笔记(五)--网络设备初始化
Table of Contents 1 简介 2 系统初始化概论 2.1 引导期间选项 2.2 中断和定时器 2.3 初始化函数 3 设备注册和初始化 3.1 硬件初始化 3.2 软件初始化 3.3 ...
- 深入理解linux网络技术内幕读书笔记(六)--PCI层与网络接口卡
Table of Contents 1 本章涉及的数据结构 1.1 pci_device_id结构 1.2 pci_dev结构 1.3 pci_driver结构 2 PCI NIC设备驱动程序的注册 ...
- 深入理解linux网络技术内幕读书笔记(一)--简介
Table of Contents 1 基本术语 1.1 本书常用的缩写 2 引用计数 2.1 引用计数函数 3 垃圾回收 3.1 异步 3.2 同步 4 函数指针 4.1 缺点 5 goto语句 5 ...
随机推荐
- JBoss 系列九十六:JBoss MSC - 简介及一个简单演示样例
什么是 JBoss MSC JBoss MSC 即 JBoss Modular Service Container,是第三代 JBoss 产品 JBoss 7和WildFfly的内核,JBoss MS ...
- Android学习–Android app 语言切换功能
功能: app用户根据自己的语言喜好,设置app语言.语言设置只针对本app,并在下次启动应用时保留前一次启动设置. 更新语言: public static void changeAppLanguag ...
- linux 启动network后报错:device eth0 does not seem to be present, delaying initialization
问题背景: 在vsphere client中部署ovf模板后启动linux 的network后提示:device eth0 does not seem to be present, delaying ...
- 【网络流#6】POJ 3041 Asteroids 二分图最大匹配 - 《挑战程序设计竞赛》例题
学习网络流中ing...作为初学者练习是不可少的~~~构图方法因为书上很详细了,所以就简单说一说 把光束作为图的顶点,小行星当做连接顶点的边,建图,由于 最小顶点覆盖 等于 二分图最大匹配 ,因此求二 ...
- HDU 5144 NPY and shot(三分法)
当时做这道题时一直想退出物理公式来,但是后来推到导数那一部分,由于数学不好,没有推出来那个关于Θ的最值,后来直接暴力了,很明显超时了,忘了三分法的应用,这道题又是典型的三分求最值,是个单峰曲线,下面是 ...
- 读取文件内容返回List<String>类型
文件内容格式: string1 string2 String 3 …… 很简单,两句话 String content = new String(Files.readAllBytes(Paths.get ...
- 简单竖向Tab选项卡
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- 9、第九节课jquery选择器jq2,20151007
1.表单选择器 2.not 里面不能加其他标签 $div p:not(not:disable) 错误的 $div p:not(:disable) 正确的 3.选择设置相应属性的标签项 $(&quo ...
- Js实现简单的联动,无数据库版本
<html> <head> <title></title> <script language="javascript" typ ...
- [linux常用命令]查看当前文件夹或该文件夹下文件(夹)的大小
du -sh *(星号表示当前所有文件夹)可以查看当前目录下各个文件夹的大小,-s表示只显示当前文件夹(不加-s你可以看到所有文件夹下的子文件夹的大小,太多了),-h表示以合适的大小查看.(可以用- ...