前言
这篇博客的内容不是很多,主要是介绍几种一般性信息,适用于前面所讲涉及中断事件和帧的处理
统计数据
有关帧接收的统计数据保存在各个CPU数组netdev_rx_stat
中,其元素为netif_rx_stats
类型(参见include/linux/netdevice.h
)
struct netif_rx_stats netdev_rx_stat(NR_CPUS);
struct netif_rx_stats
{
unsigned total;
unsigned dropped;
unsigned time_squeeze;
unsigned throttled;
unsigned fastroute_hit;
unsigned fastroute_success;
unsigned fastroute_defer;
unsigned fastroute_deferred_out;
unsigned fastroute_latency_reduction;
unsigned cpu_clollision;
}__cacheline_aligned
netif_rx_stats
的元素有
-
total
- 已处理的入口帧总数,包括任何可能被丢弃的。此值会在
netif_rx_receive_skb
中更新,也就说,当驱动程序不使用NAPI时(netif_rx接口),同一个帧被计算两次(错误)。
- 已处理的入口帧总数,包括任何可能被丢弃的。此值会在
-
dropped
- 因为接收时CPU处于窒息状态而被丢弃的帧的数目
-
time_squeeze
- 当帧依然在CPU入口队列中,因此没有变成CPU的贪婪者时,
net_rx_action
返回的次数。
- 当帧依然在CPU入口队列中,因此没有变成CPU的贪婪者时,
-
throttled
- CPU进入窒息状态的次数,此值由
netif_rx
递增
- CPU进入窒息状态的次数,此值由
-
fastroute_hit
-
fastroute_success
-
fastroute_defer
-
fastroute_letency_reduction
-
fastroute_deferred_out
- 由Fastroute功能所用的一些字段。
-
cpu_collision
- CPU无法获得设备驱动程序锁(明确的讲就是
dev->xmit_lock
)的次数,因为该锁已被另一个CPU取走。这个计数器会在qdisc_restart
中更新,而qdisc_restart
只处理帧传输,而无接收。cpu_collision
是此结构中唯一与传输有关的统计数据。
- CPU无法获得设备驱动程序锁(明确的讲就是
前述有些计数器目前都由netif_rx
(由非NAPI驱动程序所用)更新,这表示使用NAPI驱动程序时,其值是不正确的。
netdev_rx_stat
向量的内容可通过/proc
接口查看。
其他统计数据则由驱动程序、较高层协议以及流量控制队列控制保存在私有数据结构中。这些值有些可以通过用户空间程序读取,如ifconfig、tc、ip或netstat
,其他则可通过/proc
输出。
通过/proc和sysfs文件系统调整
下表列出了所有在/proc/sys/net/core
中的文件,都定义在/net/core/sysctl_net_core.c
,你可以找出文件与内核变量之间的关联性。
文件名 | 内核变量 | 默认值 |
---|---|---|
netdev_max_backlog |
netdev_max_backlog |
300 |
mod_cong |
mod_cong |
290 |
lo_cong |
lo_cong |
100 |
no_cong |
no_cong |
20 |
no_cong_thresh |
no_cong_thresh |
10 |
dev_weight |
weight_p |
64 |
需要强调的是,NAPI驱动程序不需要上表中的任何字段。NAPI驱动程序应该以驱动程序的局部变量值设置net_device->weight
,而不使用weight_p
。但是,如果NAPI驱动程序想用weight_p
,也可以使用,特别是它们通常都使用相同的默认值64。从内核2.6.12版本起,net_device
的weight
子段值可以在运行期间以sysfs
通过各个设备文件/sys/class/net/device_name/weight
进行调整。Weight文件是在net/core/net-sysfs.c
中创建的。
netdev_rx_stats
结构所收集的统计数据可通过文件/proc/net/softnet_stat
读取(其输出是十六进制格式)。
本部分涉及的函数和变量
下表介绍或涉及的主要函数、变量以及数据结构。(与中断事件及帧处理相关的函数、变量以及数据结构)
名称 | 描述 |
---|---|
函数 | |
netif_rx |
把输入帧排入CPU队列 |
netif_rx_schedule |
调度NET_RX_SOFTIRQ 软件中断以准备执行 |
__netif_rx_schedule |
功能同上 |
netif_rx_complete |
当net_device->poll 虚拟函数清除队列时就会调用此函数 |
netif_start_queue |
开启设备的传输 |
netif_stop_queue |
关闭设备的传输 |
netif_queue_stopped |
检查设备是否已开启传输功能 |
netif_schedule |
netif_schedule 用于调度设备以准备传输。 |
netif_wake_queue |
开启设备传输功能,并且设备调度以准备传输 |
qdisc_run |
从设备出口队列中退出帧,将其压入设备驱动程序以进行传输。 |
process_backlog |
非NAPI设备驱动程序所用poll 虚拟函数 |
netif_receive_skb |
处理输入帧传给较高层协议处理函数 |
dev_queue_xmit |
帧传输的主要函数 |
dev_kfree_skb |
释放sk_buff 结构 |
dev_kfree_skb_irq |
被net_tx_softirq 函数调用 |
dev_kfreee_skb_any |
同上 |
do_IRQ |
启用相关联的处理函数以负责硬件中断通知信息 |
open_softirq |
为软件中断注册以及调度。 |
raise_softirq |
下半部函数 |
raise_softirq_irqoff |
同上 |
do_softirq |
启用相关联的处理函数以负责未决的软件中断。 |
invoke_softirq |
用于处理未决状态的中断事件 |
net_rx_action |
NET_RX_SOFTIRQ 的处理函数 |
net_tx_action |
NET_TX_SOFTIRQ 的处理函数 |
tasklet_init |
初始化tasklet_struct 结构 |
tasklet_action |
TASKLET_SOFTIRQ 软件中断的处理函数 |
tasklet_hi_action |
HI_SOFTIRQ 软件中断的处理函数 |
tasklet_enable |
分别是开启和关闭微任务。 |
tasklet_hi_enable |
|
tasklet_disable |
|
tasklet_disable_nosync |
|
tasklet_schedule |
为微任务调度以准备执行 |
tasklet_hi_schedule |
|
变量 | |
mod_cong |
输入队列的拥塞等级(由非NAPI设备所用) |
lo_cong |
softnet_data 字段 |
no_cong |
|
no_cong_thresh |
|
netdev_max_backlog |
CPU输入队里的最大尺寸 |
数据结构 | |
softnet_data |
那两个NET_XXX_SOFTIRQ 软件中断会为每个CPU都使用这么一个结构 |
tasklet_struct |
代表一个微任务。 |
本部分涉及的文件和目录
xxx
关键词代表一种体系结构。有些体系结构不需要特殊的特细结构专用文件,因为一个通用文件有时也可以由好几种体系结构使用。