BUG: failure at drivers/pci/msi.c:376/free_msi_irqs()!

文章目录

  • [1. pci显示模块卸载](#1. pci显示模块卸载)
  • [2. free_irq未被调用导致xxfb_pci_unregister报错](#2. free_irq未被调用导致xxfb_pci_unregister报错)
  • [3. free_irq第二个参数与request_irq最后一个参数不一致导致报错](#3. free_irq第二个参数与request_irq最后一个参数不一致导致报错)

1. pci显示模块卸载

为方便调试显示驱动将pci模块xxfb编译为内核模块,卸载命令如下:

c 复制代码
echo 0 > /sys/class/vtconsole/vtcon1/bind
systemctl stop lightdm
rmmod xxfb

2. free_irq未被调用导致xxfb_pci_unregister报错

pci_disable_msi调free_msi_irqs报错:

c 复制代码
BUG: failure at drivers/pci/msi.c:376/free_msi_irqs()!
0Kernel panic - not syncing: BUG!
CPU: 0 PID: 3136 Comm: rmmod Not tainted 5.10.0-00811-g123456789012-dirty #134
Hardware name: WIAT WIAT Platform Software, BIOS xxxx-200000 May 24 2020
6Trace:
[<ffffffff80918bb0>] walk_stackframe+0x0/0x100
[<ffffffff81b011d8>] dump_stack+0xd0/0x110
[<ffffffff81af85c8>] panic+0x1a0/0x4e0
[<ffffffff811b6df0>] free_msi_irqs+0xe0/0x270
[<ffffffff811b78d0>] pci_disable_msi+0x190/0x1f0
[<fffff0000021a3b4>] cleanup+0xf4/0x170 [ichfb]
[<fffff0000021a458>] xxfb_pci_unregister+0x28/0x60 [ichfb]
[<ffffffff8119c544>] pci_device_remove+0x54/0x130
[<ffffffff814a347c>] __device_release_driver+0x23c/0x3a0
[<ffffffff814a5028>] driver_detach+0x158/0x210
[<ffffffff814a267c>] bus_remove_driver+0x8c/0x150
[<ffffffff814a5a28>] driver_unregister+0x48/0xa0
[<ffffffff8119be34>] pci_unregister_driver+0x34/0x110
[<fffff0000022b330>] xxfb_exit+0x20/0x38 [ichfb]
[<ffffffff80a335fc>] sys_delete_module+0x1cc/0x370
[<ffffffff80912014>] entSys+0xf4/0x110
[<ffffffff80c08084>] sys_close+0x24/0x70
2SMP: stopping secondary CPUs
0---[ end Kernel panic - not syncing: BUG! ]---

看下free_msi_irqs:

c 复制代码
static void free_msi_irqs(struct pci_dev *dev)
{
        struct list_head *msi_list = dev_to_msi_list(&dev->dev);
        struct msi_desc *entry, *tmp;
        struct attribute **msi_attrs;
        struct device_attribute *dev_attr;
        int i, count = 0;

        for_each_pci_msi_entry(entry, dev)
                if (entry->irq)
                        for (i = 0; i < entry->nvec_used; i++)
                                BUG_ON(irq_has_action(entry->irq + i));//报错地方

        pci_msi_teardown_msi_irqs(dev);
        ...

报错处BUG_ON逻辑为真的函数:irq_has_action(entry->irq + i))

c 复制代码
static inline int irq_desc_has_action(struct irq_desc *desc)
{
        return desc->action != NULL;
} 

也即desc->action未释放。查看代码,DC DMA申请了未释放,xxfbhw_dma_init中调用了

c 复制代码
err = request_irq(xx_par->irq_dma, xxfbhw_dma_irq_handler, IRQF_SHARED, "DMA_TRANSFER_IRQ", xx_par);

xxfbhw_dma_exit未调用free_irq进行irq_dma释放。DMA是非共享中断,因此在xxfbhw_dma_exit中添加free_irq

c 复制代码
xxfbhw_dma_exit
{
	...
	free_irq(xx_par->irq_dma, 0); //to add
}

3. free_irq第二个参数与request_irq最后一个参数不一致导致报错

c 复制代码
const void *free_irq(unsigned int irq, void *dev_id) //dev_id
----------------------------------------------------
static inline int __must_check
request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char *name, void *dev) //dev

xxfbhw_dma_exit中添加free_irq(xx_par->irq_dma, 0)后依然报错:Trying to free already-free IRQ XX

c 复制代码
4------------[ cut here ]------------
4WARNING: CPU: 1 PID: 733 at kernel/irq/manage.c:1751 free_irq+0x32c/0x630
Trying to free already-free IRQ 58
Modules linked in:c xxfb(-)c ngbec sch_fq_codelc efivarfsc ipv6c
CPU: 0 PID: 3136 Comm: rmmod Not tainted 5.10.0-00811-g123456789012-dirty #134
Hardware name: WIAT WIAT Platform Software, BIOS xxxx-200000 May 24 2020
6Trace:
[<ffffffff80918bb0>] walk_stackframe+0x0/0x100
[<ffffffff81b011d8>] dump_stack+0xd0/0x110
[<ffffffff80959a5c>] __warn+0x13c/0x1f0
[<ffffffff809e8478>] free_irq+0x328/0x630
[<ffffffff809e8478>] free_irq+0x328/0x630
[<ffffffff81af89d4>] warn_slowpath_fmt+0xcc/0x100
[<ffffffff809e8478>] free_irq+0x328/0x630
[<ffffffff809e8478>] free_irq+0x328/0x630
[<ffffffff81003b4c>] debugfs_rename+0x3bc/0x3c0
[<ffffffff80c42cc4>] mntput_no_expire+0x184/0x3f0
[<fffff00000229014>] xxfbhw_dma_exit+0x94/0xf0 [xxfb]
[<fffff0000021a420>] cleanup+0x160/0x170 [xxfb]
[<fffff0000021a458>] xxfb_pci_unregister+0x28/0x60 [xxfb]
[<ffffffff8119c544>] pci_device_remove+0x54/0x130
[<ffffffff814a347c>] __device_release_driver+0x23c/0x3a0
[<ffffffff814a5028>] driver_detach+0x158/0x210
[<ffffffff814a267c>] bus_remove_driver+0x8c/0x150
[<ffffffff814a5a28>] driver_unregister+0x48/0xa0
[<ffffffff8119be34>] pci_unregister_driver+0x34/0x110
[<fffff0000022b350>] xxfb_exit+0x20/0x38 [xxfb]

free_irq 第二个参数要与request_irq最后一个参数一致,修改为free_irq(xx_par->irq_dma, xx_par)后正常。

相关推荐
C++ 老炮儿的技术栈16 小时前
在C++ 程序中调用被 C编译器编译后的函数,为什么要加 extern “C”声明?
c语言·c++·windows·git·vscode·visual studio
chinesegf17 小时前
ubuntu中虚拟环境的简单创建和管理
linux·运维·ubuntu
java_logo17 小时前
2025 年 11 月最新 Docker 镜像源加速列表与使用指南
linux·运维·docker·容器·运维开发·kylin
一碗面42118 小时前
Linux下的网络模型
linux·网络模型
CQ_YM18 小时前
ARM--SDK、led、beep与链接脚本
c语言·arm开发·嵌入式硬件·嵌入式
HIT_Weston19 小时前
103、【Ubuntu】【Hugo】搭建私人博客:搜索功能(四)
linux·运维·ubuntu
旖旎夜光19 小时前
Linux(11)(中)
linux·网络
txinyu的博客19 小时前
前置声明与 extern
linux·c++
cat2bug20 小时前
介绍一下如何在Cat2Bug-Platform中通过OpenAI来创建测试用例
功能测试·测试工具·ai·测试用例·bug·openai
傻乐u兔20 小时前
C语音初阶————调试实用技巧2
c语言·开发语言