struct net_device_ops 详解

本文详细解析了Linux网络驱动中net_device_ops结构体的各个回调函数,包括ndo_init、ndo_uninit、ndo_open等,涵盖了网络设备的初始化、开启、关闭等关键操作,涉及中断处理、MAC配置、描述符环内存分配、传输队列管理等多个方面。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【ndo_init】

注册网络设备时调用,驱动程序一般不使用,虚拟网络设备可能使用


【ndo_uninit】

网络设备卸载时调用,驱动程序一般使用


【ndo_open】

1、禁止所有中断、关闭载波(netif_carrier_off);

2、分配并初始化传输和接收描述符环内存(使用dma_alloc_coherent分配确保EMAC和CPU都可以访问);

3、分配发送skb处理状态的链表或者数组空间(使用kzalloc),其实也可以用sk_buff_head相关的数据结构和函数;

4、初始化接收描述符环,包括分配struct sk_buff以及数据缓存区(netdev_alloc_skb),并且进行DMA映射(dma_map_single);

5、注册中断相关函数(request_irq);

6、初始化MAC硬件模块(设置MAC相关过滤参数、填写传输和接收描述符初始化地址dma_addr_t、中断设置、聚合功能配置);

7、PHY芯片初始化并启动;

8、使能NAPI模块(napi_enable);

9、调用netif_start_queue或者netif_tx_start_all_queues使能传输队列调度;

10、调用netif_wake_queue或者netif_tx_wake_all_queues开启传输队列的调度(因为此时所有的传输环为空,可以立刻开始传输);

11、使能传输/接收通道,打开中断,开启定时器功能;

 

【ndo_stop】

1、停止上层传输调度;

2、停止NAPI功能;

3、停止MAC接收功能;

4、等待既有的skb数据发出去,释放skb跟踪链表;

5、停止发送功能;

6、禁止中断功能;

7、手动处理已接收到的数据包传递给上层协议;

8、释放接受和发送描述符环内存空间;

9、释放接收缓存数据空间;

10、反注册中断函数;

11、删除NAPI功能(netif_napi_del);

12、停止并删除timer功能、取消并删除delaywork;

13、关闭载波netif_carrier_off;

14、关闭MAC和PHY电源;


【ndo_start_xmit】

1、检查skb_shinfo(skb)->tx_flags标志位,SKBTX_HW_TSTAMP指示硬件向上层软件提供硬件时间戳(调用skb_tstamp_tx  、skb_tx_timestamp),设置过程中置位SKBTX_IN_PROGRESS,表示硬件正在处理上层的时间戳提取要求;

<
<think>好的,我现在需要详细分析用户的问题。用户之前询问了关于`domain_flush_np_cache`函数的代码,现在又转向了`struct protection_domain`的结构,特别是其中的`struct iommu_domain`成员。用户希望了解这个结构体的各个成员以及`iommu_domain`的详细信息。 首先,我需要回忆`protection_domain`在AMD IOMMU驱动中的角色。通常,保护域用于管理设备的DMA访问,确保设备只能访问被分配的内存区域。`struct protection_domain`可能包含与IOMMU配置相关的信息,如页表、设备列表、锁机制等。 接下来,用户特别提到了`struct iommu_domain`,需要详细说明。根据Linux内核的IOMMU框架,`iommu_domain`是一个通用结构,代表一个IOMMU域,不同厂商(如Intel和AMD)会有自己的具体实现,比如这里的`protection_domain`。 我需要确认`iommu_domain`的成员和功能。通常,`iommu_domain`包含类型、操作函数指针、页表相关信息等。可能包括回调函数,如map、unmap、attach等,用于与IOMMU核心交互。 然后,回到`protection_domain`结构体,每个成员的作用需要逐一解释。例如,`list`和`dev_list`用于链表管理,`lock`和`api_lock`用于同步,`pt_root`指向页表根,`mode`表示分页模式等。需要确保解释准确,尤其是和AMD IOMMU具体实现相关的部分,如`glx`和`gcr3_tbl`可能与虚拟化相关。 用户可能想知道这些结构体如何协同工作,以及它们在IOMMU中的作用。需要将技术术语转化为易懂的语言,避免过于晦涩。同时,注意用户可能对内核同步机制(如自旋锁和互斥锁)不太熟悉,需要简要说明它们的用途。 在组织回答时,应该先介绍整个`protection_domain`结构体,再分点详细说明每个成员,特别是`iommu_domain`。然后单独详细解释`iommu_domain`的结构和功能,强调其通用性和具体实现的差异。 需要确保回答结构清晰,使用列表和表格来增强可读性,同时符合用户之前要求的格式。最后,总结结构体之间的关系和应用场景,帮助用户理解整体架构。</think>### `struct protection_domain` 结构解析 `struct protection_domain` 是 AMD IOMMU 驱动中用于描述 **内存保护域**(Memory Protection Domain)的核心数据结构。每个保护域代表一组设备共享的地址转换规则和内存访问权限。以下是其成员的详细说明: --- #### **1. 核心成员说明** | 成员名称 | 类型 | 作用描述 | |--------------------|-----------------------|--------------------------------------------------------------------------| | `list` | `struct list_head` | 用于将域链接到全局保护域链表中(如系统所有域的列表)。 | | `dev_list` | `struct list_head` | 记录属于该域的所有设备的链表头(设备通过 `struct device` 关联)。 | | `domain` | `struct iommu_domain` | **通用 IOMMU 域结构**,提供与 Linux 内核 IOMMU 框架交互的接口(见下文详细展开)。 | | `lock` | `spinlock_t` | **自旋锁**,保护域内页表操作(如修改页表、刷新 TLB)的并发访问。 | | `api_lock` | `struct mutex` | **互斥锁**,保护用户态 API 路径(如 `iommu_map`/`iommu_unmap`)的页表操作。 | | `id` | `u16` | 域的唯一标识符,写入设备表(Device Table)以关联设备与域。 | | `mode` | `int` | 分页模式级别(0-6),表示页表的层级(如 4 级页表对应 `mode=4`)。 | | `pt_root` | `u64*` | **页表根指针**,指向该域的页表根目录(物理地址)。 | | `glx` | `int` | Guest CR3 表的层级数(用于虚拟化场景)。 | | `gcr3_tbl` | `u64*` | **Guest CR3 表指针**,用于虚拟机监控程序(如嵌套分页)。 | | `flags` | `unsigned long` | 标志位,标识域的类型(如是否为直通域、是否启用虚拟化功能等)。 | | `dev_cnt` | `unsigned` | 绑定到该域的设备数量。 | | `dev_iommu` | `unsigned[MAX_IOMMUS]`| 记录每个 IOMMU 硬件单元上该域的引用计数(用于多 IOMMU 系统)。 | --- ### **2. `struct iommu_domain` 详解** `struct iommu_domain` 是 Linux 内核 IOMMU 框架定义的 **通用域描述符**,用于抽象不同厂商(如 Intel、AMD)的 IOMMU 实现。其核心字段如下: #### **2.1 结构定义(简化版)** ```c struct iommu_domain { enum iommu_domain_type type; // 域类型(如 DMA 域、直通域) const struct iommu_ops *ops; // 操作函数集(厂商实现) unsigned long pgsize_bitmap; // 支持的页大小位图(如 4K、2M、1G) struct iommu_domain_geometry geometry; // 地址空间几何信息(起始/结束地址) void *iova_cookie; // 私有数据(如 IOMMU DMA 映射器句柄) // ... 其他内核内部字段(如设备链表、TLB 刷新状态等) }; ``` #### **2.2 关键成员说明** | 成员名称 | 作用 | |--------------------|----------------------------------------------------------------------------------------| | `type` | 定义域的类型:<br>- `IOMMU_DOMAIN_DMA`:标准 DMA 映射域(使用 IOMMU 页表)<br>- `IOMMU_DOMAIN_IDENTITY`:直通模式(物理地址直接映射)<br>- `IOMMU_DOMAIN_UNMANAGED`:非托管域(用户手动管理页表) | | `ops` | **函数指针表**,指向厂商实现的 IOMMU 操作函数(如 `map`、`unmap`、`attach_dev` 等)。<br>示例:<br>- `map()`:将虚拟地址映射到物理地址<br>- `unmap()`:取消映射<br>- `flush_iotlb_all()`:刷新整个 TLB | | `pgsize_bitmap` | 表示该域支持的页大小(如 `4K | 2M | 1G`),用于优化映射粒度。 | | `geometry` | 定义域的地址空间范围(如限制设备可访问的 DMA 地址范围)。 | | `iova_cookie` | 厂商私有数据指针,通常用于关联 DMA 映射器(如管理 IOVA 分配器)。 | --- ### **3. `protection_domain` 与 `iommu_domain` 的关系** - **继承与扩展**: `struct protection_domain` **内嵌**了 `struct iommu_domain`,表明它是 AMD 对通用 IOMMU 域的具体实现。通过 `iommu_domain` 的 `ops` 字段,AMD 驱动注册了自定义的映射、刷新等函数。 - **分工协作**: - **通用逻辑**:由内核 IOMMU 框架通过 `iommu_domain` 统一处理(如设备绑定、地址分配)。 - **硬件相关操作**:由 `protection_domain` 的私有字段(如 `pt_root`、`gcr3_tbl`)和 `ops` 中的 AMD 实现函数完成。 --- ### **4. 典型应用场景** 1. **设备绑定** 当设备通过 `iommu_attach_device()` 绑定到域时,内核会调用 `protection_domain` 的 `ops->attach_dev()` 函数,将设备添加到 `dev_list` 并更新设备表。 2. **地址映射** 用户调用 `iommu_map()` 时,最终通过 `ops->map()` 操作 AMD 页表(修改 `pt_root` 指向的页表结构)。 3. **TLB 刷新** 映射更新后,调用 `ops->flush_iotlb()` 触发 `domain_flush_pages()`,利用 `pt_root` 和 `lock` 完成缓存刷新。 --- ### **附:AMD IOMMU 页表模式示例** - **Mode=0**:禁用分页(直通模式) - **Mode=4**:4 级页表(支持 48 位地址) - **Mode=5**:5 级页表(支持 57 位地址) - **Mode=6**:6 级页表(保留)
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值