Kernel 我们可以从工作队列调用enable_irq()吗?

Kernel 我们可以从工作队列调用enable_irq()吗?,kernel,driver,linux-device-driver,Kernel,Driver,Linux Device Driver,从工作队列调用enable_irq()是否有任何副作用?我看到通过workqueue执行此操作时报告的异常 static void mmxx\u irq\u worker(结构工作\u结构*工作) { 结构mmxx_数据*mma=容器(工作、结构mmxx_数据、加速工作); 如果(不太可能(读取和报告绝对值(mmxx)!=0)) dev_err(&mmxx_i2c_client->dev,“读取和报告失败\n”); 启用irq(mmxx->irq); } [2029.755981]异常堆栈(0

从工作队列调用
enable_irq()
是否有任何副作用?我看到通过workqueue执行此操作时报告的异常

static void mmxx\u irq\u worker(结构工作\u结构*工作)
{
结构mmxx_数据*mma=容器(工作、结构mmxx_数据、加速工作);
如果(不太可能(读取和报告绝对值(mmxx)!=0))
dev_err(&mmxx_i2c_client->dev,“读取和报告失败\n”);
启用irq(mmxx->irq);
}
[2029.755981]异常堆栈(0xd51fbe70到0xd51fbeb8)
[2029.761718]be60:c09cee10 600b0113 00000001 00000000
[2029.771057]be80:C09CEDC00000001 000002bf D508BB4C000002D6 c09b3ac0 FFFFFFF E d51fbec4
[2029.780426]bea0:d51fbec8 d51fbeb8 c00b6458 c06e5b28 400b0113 FFFFFF
[2029.787841]r6:ffffffff r5:400b0113 r4:c06e5b28 r3:c00b6458
[2029.795379][](原始旋转解锁irqrestore+0x0/0x50)来自[](原始旋转解锁+0x1c/0x40)
[2029.807189][](启用irq+0x54/0x7c)中的[](输入描述解锁+0x0/0x40)
[2029.817352]r5:00000 1E5 r4:c09cedc0
[2029.821990][](从[](mmxx\u irq\u worker+0x1b8/0x238)启用\u irq+0x0/0x7c)
[2029.832061]r5:c0a1d8b4 r4:c0abb340
[2029.836700][](mmxx irq工人+0x0/0x238)来自[](一个工作流程+0x134/0x4ac)
[2029.847442][](进程单线程+0x0/0x4ac)来自[](工作线程+0x18c/0x3d8)
[2029.857757][](辅助线程+0x0/0x3d8)来自[](kthread+0x90/0x9c)
[2029.866790][](kthread+0x0/0x9c)来自[](do_exit+0x0/0x81c)
[2029.875366]r6:c004c9f4 r5:c0068d68 r4:D69944

工作队列正在启用IRQ的流程上下文中运行。因此,除非您先前禁用了此irq,否则您应该在工作队列处理程序中执行
启用\u irq()

但你也不应该犯这样的错误。可能
mmxx->irq
编号错误或未请求。请注意回溯中的这一行:

(__irq_put_desc_unlock) from (enable_irq)
它发生在函数中:

void启用\u irq(无符号整数irq)
{
无符号长旗;
结构irq_desc*desc=irq_get_desc_buslock(irq和标志),
IRQ(获取描述检查全局);
如果(!desc)
返回;
如果(警告(!desc->irq_data.chip),
KERN\u ERR“在设置/请求之前启用\u irq\u irq:irq%u\n”,irq))
出去;
__启用irq(描述、irq);
输出:
irq_put_desc_BUSIUNLOCK(描述、标志);
}
其中,
irq\u put\u desc\u bussunlock()
基本上是
\uu irq\u put\u desc\u unlock()
。 现在您可以看到,执行此链的唯一方式是当
desc->irq\u data.chip
NULL
时。此外,您还应该在回溯中观察如下输出:

“在设置/请求之前启用\u irq\u irq:irq%u\n”
从这里我想说,您传递给
enable\u irq()
mmxx->irq
号码是错误的(
0
?),或者此irq不是先前请求的。尝试检查您在
mmxx->irq
中的确切值,并确保在首次调用您的工作队列处理程序之前已请求该值


无论如何,从代码中删除
enable\u irq()
行应该可以解决问题(因为您可能实际上不需要这样做)。

显示您的工作队列处理程序的代码。@SamProtsenko:code updated,thanks@SamProtsenko,记住它们是用于html、css和javascript的。您应该删除它们在任何其他帖子上的使用。@gunr2171:谢谢,我不确定是否必须删除它。您提供的回溯上面有任何警告或值得注意的输出吗?可能类似于
enable\u irq before setup/request\u irq:irq…
?在调用request\u irq()之前是否可以从工作线程调用enable\u irq(),或者我们应该首先从request\u irq分配irq资源,然后调用enable\u irq()?我认为最好的方法是在模块初始化函数中调用
request\u irq()
,然后才开始工作(可能也在module init函数或其他地方,但必须确保在
请求\u irq
之后开始工作)。这样你就可以消除你的问题。另外,我认为您根本不需要调用
enable\u irq()
:在工作线程中启用AFAIR中断。无论如何,如果你想这样做——如果你在为你的irq号码调用
enable\u irq()
之前调用
request\u irq()
,应该是无害的。
(__irq_put_desc_unlock) from (enable_irq)