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)后正常。

相关推荐
Polevne几秒前
C# GRPC 一元与双向流
linux·算法·c#
拂拉氏3 分钟前
【知识讲解】 Linux程序替换相关接口讲解
linux·程序替换
星源~21 分钟前
zephyr-Linux环境下搭建步骤
linux·mcu·嵌入式开发·zephyr
Huangjin007_23 分钟前
【Linux 系统篇(二十)】进程(八):进程创建、进程退出
linux·运维·服务器
吴声子夜歌35 分钟前
Shell编程——开发规范
linux·运维·shell
个 人 练 习 生35 分钟前
数据结构:排序算法详解
c语言·数据结构·经验分享·学习·算法·排序算法
Shadow(⊙o⊙)38 分钟前
epoll三大接口到内核+正确认识应用层与内核的联系(6000字)
linux·服务器·网络
皓月盈江38 分钟前
Linux系统使用VSCode搭建GO开发环境
linux·vscode·ubuntu·golang·debian
老当益壮梁奶奶39 分钟前
51单片机中断系统详解
c语言·单片机·嵌入式硬件·学习·51单片机
CHHH_HHH1 小时前
【Linux系统篇】进程间通信揭秘:从管道到共享内存
linux·服务器·c语言·开发语言·后端·ubuntu