【问题标题】:Unable to free the keyboard irq line: Device or resource busy无法释放键盘 irq 线路:设备或资源忙
【发布时间】:2019-05-27 07:52:59
【问题描述】:

我正在编写一个示例 request_irq 代码

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/delay.h>

MODULE_LICENSE("GPL");
int irq = 1;
int dev = 0xaa;

static irqreturn_t keyboard_handler(int irq, void *dev)
{
    static int counter = 0;
    pr_info("Keyboard Counter:%d\n", counter++);
    return IRQ_NONE;
}

static int test_interrupt_init(void)
{
    pr_info("%s: In init\n", __func__);
    return request_irq(irq, keyboard_handler, IRQF_SHARED,
            "my_keyboard_handler", &dev);
}

static void test_interrupt_exit(void)
{
    pr_info("%s: In exit\n", __func__);
    synchronize_irq(irq);
    free_irq(irq, &dev);
}

module_init(test_interrupt_init);
module_exit(test_interrupt_exit);

删除此模块时,我收到错误消息:

rmmod: ERROR: ../libkmod/libkmod-module.c:769 kmod_module_remove_module() could not remove 'interrupt': Device or resource busy
rmmod: ERROR: could not remove module interrupt: Device or resource busy

为什么会出现这个错误,因为我使用的是 IRQF_SHARED 并在 request_irq 和 free_irq 中传递了 dev 参数

更新:从 dmesg,我在 rmmod 上看不到任何 printk 添加 dmesg 日志:

[ 4007.223281] Keyboard Counter:884
[ 4007.560846] Keyboard Counter:885
[ 4007.670339] Keyboard Counter:886
[ 4008.240139] Keyboard Counter:887
[ 4008.275412] Keyboard Counter:888
[ 4008.359338] Keyboard Counter:889
[ 4008.425101] Keyboard Counter:890
[ 4008.433026] Keyboard Counter:891
[ 4008.501763] Keyboard Counter:892
[ 4008.579201] Keyboard Counter:893
[ 4008.653335] Keyboard Counter:894
[ 4008.682862] Keyboard Counter:895
[ 4008.733950] Keyboard Counter:896

$ cat /proc/interrupts 
           CPU0       CPU1       CPU2       CPU3       
  0:          1          0          0          0   IO-APIC   2-edge      timer
  1:        449          0          0        707   IO-APIC   1-edge      i8042, my_keyboard_handler
  6:          0          0          2          0   IO-APIC   6-edge      floppy
  7:          0          0          0          0   IO-APIC   7-edge      parport0
  8:          0          1          0          0   IO-APIC   8-edge      rtc0
  9:          0          0          0          0   IO-APIC   9-fasteoi   acpi

【问题讨论】:

  • cat /proc/modulesinterrupt 的评价是什么?它应该处于Live 状态。你能告诉我们dmesg日志吗?
  • 添加了 dmesg 日志和 cat /proc/interrupts 输出
  • 这个interrupt 模块是否被任何其他模块引用?这可能是设备或资源繁忙的原因。同时您可以通过rmmod -f 删除它,清除dmesg 并再次运行。
  • rmmod -f 也会出现同样的错误
  • 键盘很可能已被控制台认领或 X 未共享。您需要成为第一个或禁用这些。

标签: c linux-kernel linux-device-driver interrupt-handling


【解决方案1】:

试试这个:

static int irq = 1, dev = 0xaa;

您需要授予变量irq 的权限,然后调用module_param(),如下所示

module_param(irq, int, S_IRUGO);

示例代码

MODULE_LICENSE("GPL");
static int irq = 1,  dev = 0xaa, counter = 0;
module_param(irq, int, S_IRUGO); /* give the permission to user space variable */

static irqreturn_t keyboard_handler(int irq, void *dev)
{
        pr_info("Keyboard Counter:%d\n", counter++);
        return IRQ_NONE;
}
/* registering irq */
static int test_interrupt_init(void)
{
        pr_info("%s: In init\n", __func__);
        if(request_irq(irq, keyboard_handler, IRQF_SHARED,"my_keyboard_handler", &dev)) {
                return -1;
        }
        else
        {
                pr_info("success \n");
                return 0;
        }
}

static void test_interrupt_exit(void)
{
        pr_info("%s: In exit\n", __func__);
        synchronize_irq(irq); /* synchronize interrupt */
        free_irq(irq, &dev);
}

module_init(test_interrupt_init);
module_exit(test_interrupt_exit);

【讨论】:

  • 是的,它在我的系统上运行。能说说你的系统内核配置吗?
  • Linux ubuntu 4.20.0-rc6+ #1 SMP Fri Dec 28 00:44:41 PST 2018 x86_64 x86_64 x86_64 GNU/Linux
  • 我复制了你的代码,但仍然是同样的问题:设备或资源繁忙
  • 与 OP 的帖子相同的评论。
猜你喜欢
  • 2017-04-18
  • 1970-01-01
  • 2017-09-02
  • 2012-01-28
  • 1970-01-01
  • 2017-08-30
  • 2023-02-10
  • 2016-08-29
  • 2015-09-24
相关资源
最近更新 更多