linux
linux copied to clipboard
[linux kernel 5.16, HS38x2] uio driver waiting queue can't wakeup by calling function wake_up_interruptible().
Hi expert,
I try to use uio driver to handle memory access and one IRQ signal. I use those functions to reach this goal: open, write, read. After open uo device and before waiting interrupt by read function. I use write function to renew the IRQ. But sometimes I will stuck in read function. Then I use "cat /proc/interrupts" to check interrupt trigger time. That uio has one trigger. And I observe the function uio_event_notify(), it has execute the function wake_up_interruptible(). But the uio_read() still stuck in while loop.
Do you know why or there has more method can debug this issue ??
Thanks, Joshua
Hi @joshualin-petaio,
If I understood you correctly, uio_read runs in a while loope because this check: https://elixir.bootlin.com/linux/latest/source/drivers/uio/uio.c#L591 is false.
Could you please check the contents of idev->event and listener->event_count? Also, please check what is happening here: https://elixir.bootlin.com/linux/latest/source/drivers/uio/uio.c#L433 and here: https://elixir.bootlin.com/linux/latest/source/drivers/uio/uio.c#L489 ? Just wondering if open_uio is correctly setting this value and notify updates the value correctly.
Hi Evgenii,
Long time no see!!! Thanks for your quick reply.
Yes, you fully understand my question.
As your suggestion, I try to print some message when uio waiting IRQ and got IRQ. It seems idev->event had update correctly(log file line 3). But read function can't wakeup and run the while loop when notify function do wake_up_interruptible(). So, I didn't get the event count check message that in read while loop. Does there has other thing need confirm??
I had attach the uio.c and log file as uio_code_and_log_0.zip uio_code_and_log_0.zip . You can check it also.
Thanks, Joshua
Hi Evgenii,
When I stuck in schedule() after execute wake_up_interruptible(). I got following message period.
rcu: INFO: rcu_preempt self-detected stall on CPU rcu: 0-....: (1 GPs behind) idle=2e3/1/0x40000004 softirq=371/372 fqs=955 (t=2100 jiffies g=-11 q=24) Task dump for CPU 0: task:ipcTest state:R running task stack: 0 pid: 70 ppid: 1 flags:0x00000008
Stack Trace: arc_unwind_core+0xe8/0x118 rcu_dump_cpu_stacks+0xc4/0x100 rcu_sched_clock_irq+0x818/0xa90 update_process_times+0x96/0xc0 tick_sched_timer+0x72/0xec __hrtimer_run_queues+0x132/0x1dc hrtimer_interrupt+0xde/0x25c timer_irq_handler+0x28/0x30 __handle_irq_event_percpu+0x4e/0x154 handle_irq_event_percpu+0x14/0x4c handle_percpu_irq+0x46/0x64 generic_handle_domain_irq+0x74/0xb8 arch_do_IRQ+0x3a/0x58 ret_from_exception+0x0/0x8
Thanks, Joshua
Hi Joshua,
Sorry for delayed reply!
Indeed, for some reason wakeup is not working properly. It is hard to tell what might be wrong there, add_wait_queue() and schedule() functions are common and well tested, as well as uio driver. Probably, idev->wait value can be checked in both uio_read() and uio_event_notify() function calls. Also, could you please share .dts you are using if possible?
Thanks, Evgeniy
Hi Evgeniy,
Thanks for your reply. I'll try to observe the idev->wait. And attachment is my .dts.
Thanks, Joshua fpga_hs_idu.txt
Hi Evgenii,
I found some phenomena about this issue. Success case: wakeup thread run on CPU1. Fail case: wakeup thread run on CPU0. <= will reschedule after wakeup directly in schedule().
Do you have any recommend for this phenomena ?
Thanks, Joshua