[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20251022144707.160181-1-jackzxcui1989@163.com>
Date: Wed, 22 Oct 2025 22:47:07 +0800
From: Xin Zhao <jackzxcui1989@....com>
To: gregkh@...uxfoundation.org
Cc: hch@...radead.org,
jackzxcui1989@....com,
jirislaby@...nel.org,
linux-kernel@...r.kernel.org,
linux-serial@...r.kernel.org,
tj@...nel.org
Subject: Re: [PATCH v1 2/2] serial: 8250_dma: add parameter to queue work on specific cpu
On Tue, 21 Oct 2025 18:26:53 +0200 Greg KH <gregkh@...uxfoundation.org> wrote:
> I do not know, but it was not threaded :(
>
> Try sending it to yourself and see if the delay maybe caused a problem?
> there should not be an issue sending just 3 messages at once.
Now that I think about it, both patches are small and address the same issue, so I
will combine them into a single patch for the next submission.
> 6.1 is very old, please try the latest 6.17.y release, or 6.18-rc1.
> Lots and lots of RT stuff has been fixed since 6.1.
>
> I'm saying that the RT selection should cause you not to have those
> larger variants in delays. Try a newer kernel and see.
I have now clarified, as you mentioned, why there is no issue in the standard kernel
but there is a problem in RT-Linux. In the dma_rx_complete function in 8250_dma.c,
locking is done using uart_port_lock_irqsave and uart_port_unlock_irqrestore, where
uart_port_lock_irqsave calls the spin_lock_irqsave API. In the standard kernel,
spin_lock_irqsave disables both preemption and hardware interrupts, while in RT-Linux,
spin_lock_irqsave does not disable preemption and does not disable hardware interrupts.
This leads to a situation where, after acquiring the spin_lock_irqsave lock, if a
real-time task preempts the current task, the spinlock holding period will lead to
migrate_disable, so if other CPUs back to idle, they cannot pull the preempted kworker
task. The work task can only continue execution after the real-time task releases the
CPU, resulting in high latency. This issue cannot be resolved in any version of the
kernel because the implementation of spin_lock_irqsave in RT-Linux is still defined
as spin_lock in higher version kernels, which means it does not disable preemption or
hardware interrupts. Similarly, in higher version kernels, spin_lock still calls
migrate_disable. Therefore, this issue cannot be resolved by simply using a higher
version of the kernel.
> This should come from a hardware definition somewhere in your DT, not as
> a user-selectable option. And again, why not just tie it to the cpu
> where the irq came from automatically?
I don't think binding the work task to the CPU that handles the interrupt is feasible,
because, in practice, this hardware interrupt is evenly distributed across all cores
in our system. Moreover, from the ftrace data we captured, the IRQ handler thread that
wakes up the kworker threads in RT-Linux is also distributed across various CPUs by
default.
Considering the current situation is still limited to the RT-Linux scenario, if
possible, I will add the logic to create this workqueue only when CONFIG_PREEMPT_RT
is enabled in the next patch. By setting WQ_SYS, it will allow user space to dynamically
modify it. Additionally, in tty_flip_buffer_push, I will check if a private workqueue
has been created; if so, I will use the private workqueue to queue the work task.
If modified this way, there will be no changes for the standard kernel. For the RT-Linux
system, if user space does not dynamically modify the workqueue's CPU affinity and
priority, the effect will be the same as if this patch were not applied. What do you think
about this approach?
--
Xin Zhao
Powered by blists - more mailing lists