簡體   English   中英

內核功能在中斷時失敗,但在ioctl時失敗

[英]Kernel Function Failing on interrupt but not on ioctl

我正在編寫一個通過i2c接口的內核驅動程序,並在多個位置讀取了總線接口芯片。 有些是通過ioctl在用戶空間中完成的,而有些則是在中斷時發生的。 從ioctl進行的讀取工作正常,但從中斷進行的讀取會導致核心轉儲(請參見下文)。

以下是相關的代碼部分:

static struct i2c_client *pcf8575_client; //global i2c client handle

static void
pcf8575_init_client(struct i2c_client *client) {
   .
   .
   .
    pcf8575_client = client;
   .
   . 
   .
}

static int
pcf8575_ioctl(struct inode *inode,struct file *file,unsigned int request,unsigned long argument)
{
  .
  .
  .
  pcf8575_read_char(pcf8575_client, &key); //works fine here, gets back appropriate value
  .
  .
  .
}

static irqreturn_t i2c_keys_isr (int irq, void *data)
{
   int result;
   static char last_key, key;
   static struct i2c_client *pcf8575_client;
   pcf8575_client = (struct i2c_client*) data;
   .
   .
   .
   result = pcf8575_read_char (pcf8575_client, &key); //this is where it fails from the   irq routine
}

//Here is the functions definition
static inline int
pcf8575_read(struct i2c_client *client, u8 reg, u8 *value) {
    s32 data;

    data = i2c_smbus_read_byte_data(client, reg); //fails on this call only when called from the interrupt

    if (data < 0)
    return -EIO;

    *value = data;

    return 0;
}

我們已經驗證了pcf8575_client是有效的非null指針,我們能夠打印出指針的值,並驗證它與中斷例程中指針所指向的結構中的全局值以及取消引用單個值的匹配。

這是我們收到的核心轉儲:

BUG: scheduling while atomic: swapper/0/0x00010000
Modules linked in: i2c_keys<7>s3c2410-i2c s3c2410-i2c: READ: Send Stop
Unable to handle kernel NULL pointer dereference at virtual address 00000000
pgd = c0004000
[00000000] *pgd=00000000
Internal error: Oops: 0 [#1]
Modules linked in: i2c_keys i2cts(P) gpio
CPU: 0    Tainted: P            (2.6.28.10 #143)
PC is at 0x0
LR is at activate_task+0x48/0x60
pc : [<00000000>]    lr : [<c0080560>]    psr: 40000093
sp : c0347b80  ip : c0347b98  fp : c0347b94
r10: 00000000  r9 : 00000003  r8 : c035e7b8
r7 : 00000000  r6 : 20000093  r5 : c0364f60  r4 : c0348fe4
r3 : c0299098  r2 : 00000001  r1 : c0348fe4  r0 : c0364f60
Flags: nZcv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment kernel
Control: c000717f  Table: 3fbb0000  DAC: 00000017
Process swapper (pid: 0, stack limit = 0xc0346260)
Stack: (0xc0347b80 to 0xc0348000)
7b80: c0348fe4 c035e7ac c0347bb4 c0347b98 c00819e4 c0080528 c0347e24 c035e7ac 
7ba0: 00000000 00000001 c0347bc4 c0347bb8 c0081a5c c0081994 c0347bd8 c0347bc8 
7bc0: c00994fc c0081a58 c0347e24 c0347c04 c0347bdc c0080a74 c00994f8 60000093 
7be0: c035e7b8 00000000 0000002b 00000009 00000000 c0346000 c0347c1c c0347c08 
7c00: c0080ae4 c0080a4c 00000000 00000091 c0347c40 c0347c20 c020fde4 c0080ac8 
7c20: cfaaffc0 00000000 00000000 0000002b 00000009 c0347c60 c0347c44 c00a888c 
7c40: c020fc70 c03518e0 0000002b cfaaffc0 c037832c c0347c80 c0347c64 c00a9d40 
7c60: c00a8858 0000002b c0347f4c 08000000 c0347d70 c0347c98 c0347c84 c0072064 
7c80: c00a9c40 ffffffff f4000000 c0347d58 c0347c9c c0072a44 c0072010 c034f50c 
7ca0: 80000013 c034f4cc c034f4cc c0375864 00000000 c037586d c0347d70 00000009 
7cc0: 00000000 c0346000 c0347d58 c0347cb8 c0347ce4 c0085b48 c0086158 60000013 
7ce0: ffffffff c034f52c c034f52c c0347d7c c0347cdc 00000004 80000013 c0086158 
7d00: 60000013 ffffffff c034e430 c0347d28 c0347d1c c007d440 00000003 60000013 
7d20: c0347d58 c0347d30 c0085b48 c009ce50 bf00b420 c0350dd4 c0347d7c 000003e8 
7d40: c0364f60 00000000 c0346000 c0347d68 c0347d5c c02962fc c0085eb4 c0347d9c 
7d60: c0347d7c c00a43e0 c02962f4 c030252e bf00b42c c0347d7c 00000000 c0085e00 
7d80: c0347db0 c0347f4c c0348fe4 c034913c c0347db0 c0347da0 c0082e7c c00a43a4 
7da0: ffff4a0b c0347ddc c0347db4 c0296740 c0082e58 ffff4a0b c0347de0 c0350238 
7dc0: 000003e8 c0346000 c0347e30 c0347e24 c0347e14 c0347de0 c0296ba0 c0296704 
7de0: c0376678 c0376678 ffff4a0b c008ecd4 c0348fe4 c0375e20 000003e8 c035e7b8 
7e00: 00000000 00000000 c0347e60 c0347e18 c020fb7c c0296b18 00000001 c0347eac 
7e20: c035e7f4 00000000 c0348fe4 c00994e8 c035e7b8 c035e7b8 00000052 c02fbb1d 
7e40: 00000002 c035e7f4 c0347eb8 c035e834 00000001 c0347ea8 c0347e64 c020c290 
7e60: c020fa20 00000052 00000021 00000002 c02fbb1d c035e8c0 00000001 c0347eac 
7e80: c035e7f4 00000021 c0347eda 00000002 30020fdc 41129200 30020f40 c0347ed4 
7ea0: c0347eac c020d018 c020c198 00010021 c0290002 c0347eda cfba5e00 00000000 
7ec0: 00000000 00000010 c0347ef0 c0347ed8 bf00a2b4 c020cfd0 ffff7f10 cfbbe300 
7ee0: 00000000 c0347f10 c0347ef4 c00a888c bf00a25c c035128c 00000010 cfbbe300 
7f00: c037832c c0347f30 c0347f14 c00a9d40 c00a8858 00000010 00000000 00000001 
7f20: c03644e8 c0347f48 c0347f34 c0072064 c00a9c40 ffffffff f4000000 c0347fa0 
7f40: c0347f4c c0072a44 c0072010 f4100000 00000032 f4100000 60000013 c00738f8 
7f60: c0346000 c00738f8 c03644e8 30020fdc 41129200 30020f40 c0347fa0 c0347fa4 
7f80: c0347f94 c0073f08 c0073998 60000013 ffffffff c0347fc0 c0347fa4 c0073f08 
7fa0: c0073908 c03786d8 c0364088 c0022f00 c0349c34 c0347fd0 c0347fc4 c0295258 
7fc0: c0073ed8 c0347ff4 c0347fd4 c000896c c0295214 c0008458 c0022f00 c0007175 
7fe0: c036454c c0023304 00000000 c0347ff8 30008034 c0008704 00000000 00000000 
Backtrace: 
[<c0080518>] (activate_task+0x0/0x60) from [<c00819e4>] (try_to_wake_up+0x60/0xc4)
 r5:c035e7ac r4:c0348fe4
[<c0081984>] (try_to_wake_up+0x0/0xc4) from [<c0081a5c>] (default_wake_function+0x14/0x18)
 r7:00000001 r6:00000000 r5:c035e7ac r4:c0347e24
[<c0081a48>] (default_wake_function+0x0/0x18) from [<c00994fc>] (autoremove_wake_function+0x14/0x3c)
[<c00994e8>] (autoremove_wake_function+0x0/0x3c) from [<c0080a74>] (__wake_up_common+0x38/0x7c)
 r4:c0347e24
[<c0080a3c>] (__wake_up_common+0x0/0x7c) from [<c0080ae4>] (__wake_up+0x2c/0x44)
[<c0080ab8>] (__wake_up+0x0/0x44) from [<c020fde4>] (s3c24xx_i2c_irq+0x184/0x5c4)
 r4:00000091
[<c020fc60>] (s3c24xx_i2c_irq+0x0/0x5c4) from [<c00a888c>] (handle_IRQ_event+0x44/0x80)
 r8:00000009 r7:0000002b r6:00000000 r5:00000000 r4:cfaaffc0
[<c00a8848>] (handle_IRQ_event+0x0/0x80) from [<c00a9d40>] (handle_edge_irq+0x110/0x14c)
 r7:c037832c r6:cfaaffc0 r5:0000002b r4:c03518e0
[<c00a9c30>] (handle_edge_irq+0x0/0x14c) from [<c0072064>] (__exception_text_start+0x64/0x84)
 r7:c0347d70 r6:08000000 r5:c0347f4c r4:0000002b
[<c0072000>] (__exception_text_start+0x0/0x84) from [<c0072a44>] (__irq_svc+0x24/0xa0)
Exception stack(0xc0347c9c to 0xc0347ce4)
7c80:                                                                c034f50c 
7ca0: 80000013 c034f4cc c034f4cc c0375864 00000000 c037586d c0347d70 00000009 
7cc0: 00000000 c0346000 c0347d58 c0347cb8 c0347ce4 c0085b48 c0086158 60000013 
7ce0: ffffffff                                                                
 r5:f4000000 r4:ffffffff
[<c0085ea4>] (vprintk+0x0/0x2fc) from [<c02962fc>] (printk+0x1c/0x24)
[<c02962e0>] (printk+0x0/0x24) from [<c00a43e0>] (print_modules+0x4c/0x9c)
 r3:00000000 r2:c0347d7c r1:bf00b42c r0:c030252e
[<c00a4394>] (print_modules+0x0/0x9c) from [<c0082e7c>] (__schedule_bug+0x34/0x5c)
 r6:c034913c r5:c0348fe4 r4:c0347f4c
[<c0082e48>] (__schedule_bug+0x0/0x5c) from [<c0296740>] (schedule+0x4c/0x2b8)
 r4:ffff4a0b
[<c02966f4>] (schedule+0x0/0x2b8) from [<c0296ba0>] (schedule_timeout+0x98/0xc4)
[<c0296b08>] (schedule_timeout+0x0/0xc4) from [<c020fb7c>] (s3c24xx_i2c_xfer+0x16c/0x250)
 r7:00000000 r6:00000000 r5:c035e7b8 r4:000003e8
[<c020fa10>] (s3c24xx_i2c_xfer+0x0/0x250) from [<c020c290>] (i2c_transfer+0x108/0x168)
[<c020c188>] (i2c_transfer+0x0/0x168) from [<c020d018>] (i2c_master_recv+0x58/0x80)
[<c020cfc0>] (i2c_master_recv+0x0/0x80) from [<bf00a2b4>] (i2c_keys_isr+0x68/0x1b4 [i2c_keys])
 r7:00000010 r6:00000000 r5:00000000 r4:cfba5e00
[<bf00a24c>] (i2c_keys_isr+0x0/0x1b4 [i2c_keys]) from [<c00a888c>] (handle_IRQ_event+0x44/0x80)
 r5:00000000 r4:cfbbe300
[<c00a8848>] (handle_IRQ_event+0x0/0x80) from [<c00a9d40>] (handle_edge_irq+0x110/0x14c)
 r7:c037832c r6:cfbbe300 r5:00000010 r4:c035128c
[<c00a9c30>] (handle_edge_irq+0x0/0x14c) from [<c0072064>] (__exception_text_start+0x64/0x84)
 r7:c03644e8 r6:00000001 r5:00000000 r4:00000010
[<c0072000>] (__exception_text_start+0x0/0x84) from [<c0072a44>] (__irq_svc+0x24/0xa0)
Exception stack(0xc0347f4c to 0xc0347f94)
7f40:                            f4100000 00000032 f4100000 60000013 c00738f8 
7f60: c0346000 c00738f8 c03644e8 30020fdc 41129200 30020f40 c0347fa0 c0347fa4 
7f80: c0347f94 c0073f08 c0073998 60000013 ffffffff                            
 r5:f4000000 r4:ffffffff
[<c00738f8>] (default_idle+0x0/0xb0) from [<c0073f08>] (cpu_idle+0x40/0x5c)
[<c0073ec8>] (cpu_idle+0x0/0x5c) from [<c0295258>] (rest_init+0x54/0x68)
 r7:c0349c34 r6:c0022f00 r5:c0364088 r4:c03786d8
[<c0295204>] (rest_init+0x0/0x68) from [<c000896c>] (start_kernel+0x278/0x2e0)
[<c00086f4>] (start_kernel+0x0/0x2e0) from [<30008034>] (0x30008034)
 r6:c0023304 r5:c036454c r4:c0007175
Code: bad PC value.
Kernel panic - not syncing: Fatal exception in interrupt

這是您的問題: i2c_smbus_read_byte_data()調用i2c_smbus_xfer() ,后者調用i2c_lock_adapter() ,后者調用rt_mutex_lock()

rt_mutex_lock()可以休眠。 可以休眠的功能只能從流程上下文中調用。

因此,從中斷處理程序中調用i2c_smbus_read_byte_data()是非法的。

如果您在中斷處理程序或Tasklet中或持有自旋鎖,則必須不要休眠(或調用可能休眠的函數),否則可能使系統死鎖。 這就是“ BUG:原子時調度”消息試圖告訴您的。

如果需要使用該功能,則需要重新組織代碼,以便可以從流程上下文中調用它。 您可能會考慮讓中斷處理程序喚醒任務或將work_struct提交給工作隊列,然后進行必要的工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM