pci_assign_unassigned_bus_resources地址从新分配代码分析

1. 功能定义

该函数属于 Linux 内核 PCI 子系统,核心功能是为 PCI 总线及其下级设备动态分配未分配的硬件资源(I/O 端口、内存地址、IRQ 等)。
应用场景:系统启动时或热插拔设备后,统一协调 PCI 总线资源。


2. 代码逻辑分解

步骤 1:同步控制
down_read(&pci_bus_sem); 
//...
up_read(&pci_bus_sem);
  • 目的:通过读写信号量 pci_bus_sem 保护 PCI 总线遍历操作的原子性
  • 必要性:防止在遍历总线时发生设备热插拔或配置修改
步骤 2:遍历桥接设备
for_each_pci_bridge(dev, bus)
    if (pci_has_subordinate(dev))
        __pci_bus_size_bridges(dev->subordinate, &add_list);
  • 宏展开
    • for_each_pci_bridge(dev, bus) 展开为遍历 bus 下所有类型为 PCI 桥的设备
    • pci_has_subordinate(dev) 检查桥设备是否有下级总线(即 dev->subordinate 是否非空)
  • 关键操作
    • __pci_bus_size_bridges() 递归计算下级总线所需资源,并将需要额外资源的设备加入 add_list
步骤 3:资源分配
__pci_bus_assign_resources(bus, &add_list, NULL);
  • 内部行为
    1. 遍历 add_list 中的设备
    2. 调用 pci_setup_bridge() 配置桥设备的窗口寄存器
    3. 通过 pci_assign_resource() 为设备分配实际资源
步骤 4:完整性校验
BUG_ON(!list_empty(&add_list));
  • 设计意图:断言 add_list 必须为空,若不为空则触发内核崩溃
  • 隐含逻辑:所有资源请求必须在此函数内处理完毕,否则存在逻辑漏洞

3. 关键数据结构

结构体作用
struct pci_bus描述 PCI 总线的拓扑结构,包含设备列表、资源树等信息
struct pci_dev描述 PCI 设备,包含厂商 ID、配置空间指针、资源需求等
struct list_head内核链表实现,add_list 用于临时存储需要扩展资源的设备

4. 调用链示例

pci_assign_unassigned_bus_resources()
   ├─ __pci_bus_size_bridges()   -- 资源需求计算
   │    ├─ pbus_size_io()        -- 计算 I/O 空间需求
   │    ├─ pbus_size_mem()       -- 计算内存空间需求
   │    └─ pci_bridge_check_ranges() -- 检查桥接器资源限制
   └─ __pci_bus_assign_resources()   -- 实际资源分配
        ├─ pci_assign_resource()     -- 内核资源分配器接口
        └─ pci_setup_bridge()        -- 配置桥接器的窗口寄存器

5. 典型问题场景

  • 资源冲突:当多个设备请求相同资源范围时,可能触发 BUG_ON 或资源分配失败
  • 调试方法
    # 查看 PCI 资源分配日志
    dmesg | grep -i "pci_resource"
    
    # 检查具体设备资源分配情况
    lspci -vvv -s 00:1f.2
    

6. 代码设计亮点

  • 递归处理:通过桥接设备的下级总线递归调用,支持多层 PCI 拓扑
  • 动态链表:使用 add_list 动态记录资源需求,避免静态数组限制
  • 原子性保障:读写信号量确保资源计算与分配的原子性

该函数体现了 Linux 内核按需动态分配的设计哲学,与早期 BIOS 静态分配方案相比,显著提高了 PCI 设备兼容性和资源利用率。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值