Re: nonrt behavior with GPIO interrupts

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello Austin-

On Mon, Feb 05, 2018 at 04:24:57PM -0800, Austin Schuh wrote:
> We are seeing nonrt behavior with GPIO interrupts using the sysfs
> interface.  We setup the pin by setting the ".../edge" file to
> "rising", and then use epoll to wait for a priority event on the
> ".../value" file.

What does "nonrt" behavior look like to you?

Unfortunately, the kernels poll()/select()/epoll() code is completely
dependent on the workqueue infrastructure, which isn't designed with RT
in mind.  (See the documentation in include/linux/swait.h to understand
why that's the case).  This is Problem 1.

> From turning on the IRQ trace events, the workqueue trace events, and
> the scheduler trace events, it looks like the sysfs event goes through
> a workqueue, which is SCHED_OTHER.

Thanks for sharing the trace, next time if you could please not wrap the
trace, that'd be most helpful.

Unwrapped, with my annotations below:

>           <idle>-0     [000] d..h2..  9739.478875: irq_handler_entry: irq=103 name=48057000.gpio
>           <idle>-0     [000] d..h2..  9739.478877: irq_handler_exit: irq=103 ret=handled
>           <idle>-0     [000] d..h3..  9739.478879: sched_waking: comm=irq/103-4805700 pid=105 prio=26 target_cpu=000
>           <idle>-0     [000] dn.h4..  9739.478884: sched_wakeup: comm=irq/103-4805700 pid=105 prio=26 target_cpu=000
>           <idle>-0     [000] d...3..  9739.478892: sched_switch: prev_comm=swapper/0 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=irq/103-4805700 next_pid=105 next_prio=26
>  irq/103-4805700-105   [000] d...211  9739.478904: irq_handler_entry: irq=135 name=gpiolib
>  irq/103-4805700-105   [000] d...211  9739.478906: irq_handler_exit: irq=135 ret=handled
>  irq/103-4805700-105   [000] d...311  9739.478909: sched_waking: comm=irq/135-gpiolib pid=3380 prio=26 target_cpu=001
>  irq/103-4805700-105   [000] d...411  9739.478914: sched_wakeup: comm=irq/135-gpiolib pid=3380 prio=26 target_cpu=001
>           <idle>-0     [001] d...3..  9739.478919: sched_switch: prev_comm=swapper/1 prev_pid=0 prev_prio=120 prev_state=R ==> next_comm=irq/135-gpiolib next_pid=3380 next_prio=26

You haven't mentioned which GPIO driver you are working with, but I
don't think it matters.  Here the irq subsystem is jumping through two
threads, presumably because your controller implements an irq_chip, so
there is some chained handling handling going on.

Problem 2 is that there is no PI chain between the consuming thread(s)
(gps_main in your case) and the servicing irqthread(s).  Static
prioritization of irqthreads is the current guidance, which is a useful
enough proxy for most simple RT applications.

>  irq/135-gpiolib-3380  [001] ....115  9739.478928: workqueue_queue_work: work struct=c0a6c944 function=kernfs_notify_workfn workqueue=ef0c1300 req_cpu=2 cpu=1
>  irq/135-gpiolib-3380  [001] ....115  9739.478930: workqueue_activate_work: work struct c0a6c944

Problem 3 is that workqueues similarly don't participate in PI.  There
is currently no clean way to prioritize work items, as they run from a
set of mostly arbitrary worker threads.

>  irq/135-gpiolib-3380  [001] d...315  9739.478932: sched_waking: comm=kworker/1:1 pid=3168 prio=120 target_cpu=001
>  irq/103-4805700-105   [000] d...3..  9739.478934: sched_switch: prev_comm=irq/103-4805700 prev_pid=105 prev_prio=26 prev_state=S ==> next_comm=swapper/0 next_pid=0 next_prio=120
>  irq/135-gpiolib-3380  [001] d...415  9739.478937: sched_wakeup: comm=kworker/1:1 pid=3168 prio=120 target_cpu=001
>  irq/135-gpiolib-3380  [001] d...3..  9739.478951: sched_switch: prev_comm=irq/135-gpiolib prev_pid=3380 prev_prio=26 prev_state=S ==> next_comm=kworker/1:1 next_pid=3168 next_prio=120
>      kworker/1:1-3168  [001] ....1..  9739.478957: workqueue_execute_start: work struct c0a6c944: function kernfs_notify_workfn
>      kworker/1:1-3168  [001] d...213  9739.478962: sched_waking: comm=gps_main pid=3374 prio=26 target_cpu=001
>      kworker/1:1-3168  [001] dn..313  9739.478967: sched_wakeup: comm=gps_main pid=3374 prio=26 target_cpu=001
>      kworker/1:1-3168  [001] dn..313  9739.478970: sched_stat_runtime: comm=kworker/1:1 pid=3168 runtime=17731 [ns] vruntime=138492205643 [ns]
>
>      kworker/1:1-3168  [001] d...313  9739.478974: sched_switch: prev_comm=kworker/1:1 prev_pid=3168 prev_prio=120 prev_state=R+ ==> next_comm=gps_main next_pid=3374 next_prio=26
>         gps_main-3374  [001] d...411  9739.478983: sched_pi_setprio: comm=kworker/1:1 pid=3168 oldprio=120 newprio=26
>         gps_main-3374  [001] d...311  9739.478994: sched_switch: prev_comm=gps_main prev_pid=3374 prev_prio=26 prev_state=D ==> next_comm=kworker/1:1 next_pid=3168 next_prio=26

And... a lock bounce, the waitqueue lock, probably.  Good times.  See my
above comments about waitqueues, this is an additional manifestation of
Problem 1.

>      kworker/1:1-3168  [001] d...313  9739.479000: sched_waking: comm=gps_main pid=3374 prio=26 target_cpu=001
>      kworker/1:1-3168  [001] d...413  9739.479003: sched_wakeup: comm=gps_main pid=3374 prio=26 target_cpu=001
>      kworker/1:1-3168  [001] d...313  9739.479006: sched_pi_setprio: comm=kworker/1:1 pid=3168 oldprio=26 newprio=120
>      kworker/1:1-3168  [001] d...313  9739.479010: sched_stat_runtime: comm=kworker/1:1 pid=3168 runtime=1952 [ns] vruntime=138492207595 [ns]
>      kworker/1:1-3168  [001] dn..313  9739.479015: sched_stat_runtime: comm=kworker/1:1 pid=3168 runtime=4555 [ns] vruntime=138492212150 [ns]
>      kworker/1:1-3168  [001] d...313  9739.479018: sched_switch: prev_comm=kworker/1:1 prev_pid=3168 prev_prio=120 prev_state=R+ ==> next_comm=gps_main next_pid=3374 next_prio=26
>         gps_main-3374  [001] ....1..  9739.479032: sys_epoll_wait -> 0x1
>         gps_main-3374  [001] ....1..  9739.479033: sys_exit: NR 252 = 1

> For our use case, we were able to switch to the PPS driver, but I
> thought it worthwhile to raise this in case anyone else runs across
> it.  Is this a known issue?

For folks who've had there hands in RT for awhile, they are known
issues.  They are lesser known issues to new users, however.

Fixing these problems is a long and complicated road, requiring either
constructing a new abstraction (see swait for example), or augmenting
existing abstractions to make them RT friendly.

   Julia
--
To unsubscribe from this list: send the line "unsubscribe linux-rt-users" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [RT Stable]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]

  Powered by Linux