文章目录
- [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)后正常。