深入理解Linux网络技术内幕——设备的注册与初始化(二)
设备注册于设备除名
切割操作:netdev_run_todo
Netlink信号量的保护。这也是为什么register_netdev执行时需要请求锁,并且在返回时要释放锁的原因。一旦register_netdevice完成了它自己的工作,它会通过net_set_todo将net_device结构体添加到net_todo_list中。net_todo_list包含一系列有注册(或除名)操作需要被完成的设备列表。这份列表有register_netdev在释放锁时间接予以处理。
void rtnl_unlock(void)
{
/* This fellow will unlock it for us. */
netdev_run_todo();
}
EXPORT_SYMBOL(rtnl_unlock);
设备注册状态通知
//格式:
#define NETDEV_UP 0x0001 /* For now you can't veto a device up/down */
#define NETDEV_DOWN 0x0002
...... //含义:
NETDEV_UP //该报告表明设备被启用,由dev_open产生报告
NETDEV_DOWN //设备已关闭,由dev_close生成报告
NETDEV_REBOOT //因硬件设备,设备已重启
NETDEV_CHANGE //设备的状态或者配置发生改变
NETDEV_REGISTER //设备已经注册
NETDEV_UNREGISTER //设备已经除名
NETDEV_CHANGEMTU //
NETDE //
NETDEV_PRE_UP //
NETDEV_PRE_TYPE_CHANGE //
NETDEV_POST_TYPE_CHANGE //
NETDEV_POST_INIT //
NETDEV_UNREGISTER_FINAL //
NETDEV_RELEASE //
NETDEV_NOTIFY_PEERS //
NETDEV_JOIN //
NETDEV_CHANGEUPPER
V_CHANGEADDR //设备硬件地址(或关联的广播地址)发生改变
NETDEV_GOING_DOWN //
NETDEV_CHANGENAME //设备名称发生改变
NETDEV_FEAT_CHANGE //
NETDEV_BONDING_FAILOVER
//
NETDEV_RESEND_IGMP //
设备注册:
int register_netdev(struct net_device *dev)
{
int err; rtnl_lock();
err = register_netdevice(dev);
rtnl_unlock();
return err;
}
- 初始化net_device的部分字段
- 如果内核支持Divert功能,则用alloc_divert_blk分配该功能所需的数据空间块,并连接至dev->divert
- 如果设备驱动已经对dev->init进行初始化,则执行此函数。
- 由dev_new_index分配给设备一个识别码。
- 把net_device插入到全局表dev_base,以及两张哈希表dev_name_head,dev_index_head。
- 检查功能标识是否有无效的组合。
- 设置dev->state中的__LINK_STATE_PRESENT标识,使得设备能为内核所用。
- 用dev_init_scheduler初始化设备队列规则,以便流量控制用于实现Qos。
- 通过netdev_chain通知表链通知所有对本设备注册感兴趣的子系统。
设备除名:
- 用dev_close关闭设备
- 释放所有分配的资源(IRQ、I/O端口...)
- 从全局表dev_base和两张哈希表中删除设备
- 当该设备的所有引用都释放后,释放net_device结构的空间、该驱动程序的私有数据结构、以及相链接的内存区域块。
- 删除添加到/proc 和/sys的所有文件
dev->stop //用以关闭设备,通常包括关闭netif_stop_queue出口,释放硬件资源等
dev->uninit //主要负责引用计数,少用到
dev->destructor //少数虚拟设备使用,通常初始化为: free_netdev 或其包裹函数
- 如果设备没关闭,使用dev_close关闭
- 从全局表dev_base和两张哈希表中删除设备
- 所有与该设备关联的队列规则实例,由dev_shutdown销毁
- 发送NETDEV_UNREGISTER消息到netdev_chain通知链。
- 除名消息也必须通知用户空间。
- 任何链接至net_device的数据块被释放
- register_netdevice中dev_init的所有操作都要有dev_uninit复原。
引用计数
网络设备的启用和关闭
//net/core/dev.c
int dev_open(struct net_device *dev)
static int __dev_open(struct net_device *dev)
- 如果 dev->open初始化了,就调用dev->open。
- 设置dev_state中的__LINK_STATE_START标识,以表明设备开启或在运行中
- 设置dev_flags中的IFF_UP,标识设备为开启。
- 调用dev_activate初始化流量控制所需使用到的出口队列规则,然后启用看门狗定时器。
- 向netdev_chain发送NETDEV_UP通知
- 向netdev_chain发送 NETDEV_GOING_DOWN通知
- 调用dev_deactivat关闭队列规则
- 清除dev->state的_ _LINK_STATE_START标志,以表明设备禁用了
- 如果正在执行读取入口队列数据包的轮询操作,则等待该操作完成。因为dev->state关系,入口队列不会再有入队操作,所以读取当前已经在队列中的即可
- 如果dev->stop有定义,执行它。
- 清除dev->flags的IFF_UP操作。
- 向netdev_chain发送NEtdEV_DOWN通知。
更新队列规则状态:
从用户空间配置设备相关信息
- ipconfig和mii-tool 来自net-tool套件
- ethtool 来自ethtool套件
- ip link:来自IP ROUTER2 套件
深入理解Linux网络技术内幕——设备的注册与初始化(二)的更多相关文章
- 深入理解linux网络技术内幕读书笔记(五)--网络设备初始化
Table of Contents 1 简介 2 系统初始化概论 2.1 引导期间选项 2.2 中断和定时器 2.3 初始化函数 3 设备注册和初始化 3.1 硬件初始化 3.2 软件初始化 3.3 ...
- 深入理解linux网络技术内幕读书笔记(七)--组件初始化的内核基础架构
Table of Contents 1 引导期间的内核选项 2 注册关键字 3 模块初始化代码 引导期间的内核选项 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网络技术内幕——网络设备初始化
概述 内核的初始化过程过程中,与网络相关的工作如下所示: 内核引导时执行start_kernel,start_kernel结束之前会调用rest_init,rest_init初始化内核线 ...
- 深入理解linux网络技术内幕读书笔记(八)--设备注册与初始化
Table of Contents 1 设备注册之时 2 设备除名之时 3 分配net_device结构 4 NIC注册和除名架构 4.1 注册 4.2 除名 5 设备初始化 6 设备类型初始化: x ...
- 深入理解Linux网络技术内幕——PCI层和网络接口卡
概述 内核的PCI子系统(即PCI层)提供了不同设备一些通用的功能,以便简化各种设备驱动程序. PCI层重要结构体如下: pci_device_id 设备标识,根据PCI标志定 ...
- 《深入理解Linux网络技术内幕》阅读笔记 --- 路由基本概念
一.路由的基本概念 1.一条路由就是一组参数,这些参数存储了往一个给定目的地转发流量所需的信息,而一条路由所需的最少的参数集合为:(1)目的网络,(2)出口设备,(3)下一跳网关 2.路由中的相关术语 ...
- 深入理解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 接收到帧时通知驱动程序 1.1 轮询 1.2 中断 2 中断处理程序 3 抢占功能 4 下半部函数 4.1 内核2.4版本以后的下半部函数: 引入软IRQ 5 ...
随机推荐
- [BZOJ1122][POI2008]账本BBB 单调队列+后缀和
Description 一个长度为n的记账单,+表示存¥1,-表示取¥1.现在发现记账单有问题.一开始本来已经存了¥p,并且知道最后账户上还有¥q.你要把记账单修改正确,使得 1:账户永远不会出现负数 ...
- spring boot 多数据源分布式事务处理
有参考文章 ,但是自己没有测试.
- Ubuntu 14.04 删除软件附加依赖
参考:FlowVisor的学习笔记 eg.mininet $ sudo apt-get remove mininet $ sudo apt-get remove --auto-remove minin ...
- js循环遍历弹框,先弹出第一个之后逐步弹出第二个。。
var data = [{ "login_advertTitle": "即使生活琐碎,也要活得优雅", "login_advertCont" ...
- Python实现自平衡二叉树AVL
# -*- coding: utf-8 -*- from enum import Enum #参考http://blog.csdn.net/niteip/article/details/1184069 ...
- SPOJ - HIGH Highways(矩阵树定理)
https://vjudge.net/problem/SPOJ-HIGH 题意: 给n个点m条边,求生成树个数. 思路: 矩阵树裸题. 具体的话可以看一下周冬的论文<生成树的计数及其应用> ...
- ThreadPool开启多线程时支持最大连接200个(默认为2个),不加则会超时
//ThreadPool System.Net.ServicePointManager.DefaultConnectionLimit = 200;
- ubuntu16.04上安装Java
1.下载jdk8 登录网址:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 选择 ...
- 简单介绍tomcat中maxThreads,acceptCount,connectionTimeout
<?xml version='1.0' encoding='utf-8'?> <Server port="8005" shutdown="SHUTDOW ...
- MongoDB(课时8 模运算)
3.4.2.3 求模 模运算使用“$mod”来完成,语法: {$mod : [除数,余数]} 范例:求模 db.students.find({"age" : {"$mod ...