foss-for-synopsys-dwc-arc-processors/linux

[linux kernel 5.16, HS38x2] uio driver waiting queue can't wakeup by calling function wake_up_interruptible().

joshualin-petaio opened this issue · 6 comments

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