2017-11-06 18:11:51 +01:00
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tty: Implement lookahead to process XON/XOFF timely
When tty is not read from, XON/XOFF may get stuck into an
intermediate buffer. As those characters are there to do software
flow-control, it is not very useful. In the case where neither end
reads from ttys, the receiving ends might not be able receive the
XOFF characters and just keep sending more data to the opposite
direction. This problem is almost guaranteed to occur with DMA
which sends data in large chunks.
If TTY is slow to process characters, that is, eats less than given
amount in receive_buf, invoke lookahead for the rest of the chars
to process potential XON/XOFF characters.
We need to keep track of how many characters have been processed by the
lookahead to avoid processing the flow control char again on the normal
path. Bookkeeping occurs parallel on two layers (tty_buffer and n_tty)
to avoid passing the lookahead_count through the whole call chain.
When a flow-control char is processed, two things must occur:
a) it must not be treated as normal char
b) if not yet processed, flow-control actions need to be taken
The return value of n_tty_receive_char_flow_ctrl() tells caller a), and
b) is kept internal to n_tty_receive_char_flow_ctrl().
If characters were previous looked ahead, __receive_buf() makes two
calls to the appropriate n_tty_receive_buf_* function. First call is
made with lookahead_done=true for the characters that were subject to
lookahead earlier and then with lookahead=false for the new characters.
Either of the calls might be skipped when it has no characters to
handle.
Reported-by: Gilles Buloz <gilles.buloz@kontron.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Link: https://lore.kernel.org/r/20220606153652.63554-2-ilpo.jarvinen@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-06-06 18:36:51 +03:00
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2024-02-15 13:15:38 +02:00
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-02-12 02:00:43 -05:00
|
|
|
|
2021-04-08 14:51:30 +02:00
|
|
|
|
2013-06-15 09:36:02 -04:00
|
|
|
|
|
|
|
|
|
2022-10-19 13:55:04 +03:00
|
|
|
|
2013-06-15 09:36:02 -04:00
|
|
|
|
2013-06-15 09:36:08 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2019-01-28 19:01:10 +01:00
|
|
|
|
2013-06-15 09:36:08 -04:00
|
|
|
|
2013-06-15 09:36:16 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-05-12 17:26:12 +08:00
|
|
|
|
|
|
|
|
|
2013-06-15 09:36:16 -04:00
|
|
|
|
|
|
|
|
|
2022-10-19 13:55:04 +03:00
|
|
|
|
2013-06-15 09:36:16 -04:00
|
|
|
|
2013-06-15 09:36:15 -04:00
|
|
|
|
2021-11-26 09:16:02 +01:00
|
|
|
|
|
|
|
|
|
2013-06-15 09:36:15 -04:00
|
|
|
|
2021-11-26 09:16:02 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-06-15 09:36:15 -04:00
|
|
|
|
2021-11-26 09:16:02 +01:00
|
|
|
|
2013-06-15 09:36:15 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2014-05-19 01:03:06 +01:00
|
|
|
|
2013-06-15 09:36:15 -04:00
|
|
|
|
tty: tty_port: add workqueue to flip TTY buffer
On the embedded platform, certain critical data, such as IMU data, is
transmitted through UART. The tty_flip_buffer_push() interface in the TTY
layer uses system_dfl_wq to handle the flipping of the TTY buffer.
Although the unbound workqueue can create new threads on demand and wake
up the kworker thread on an idle CPU, it may be preempted by real-time
tasks or other high-prio tasks.
flush_to_ldisc() needs to wake up the relevant data handle thread. When
executing __wake_up_common_lock(), it calls spin_lock_irqsave(), which
does not disable preemption but disables migration in RT-Linux. This
prevents the kworker thread from being migrated to other cores by CPU's
balancing logic, resulting in long delays. The call trace is as follows:
__wake_up_common_lock
__wake_up
ep_poll_callback
__wake_up_common
__wake_up_common_lock
__wake_up
n_tty_receive_buf_common
n_tty_receive_buf2
tty_ldisc_receive_buf
tty_port_default_receive_buf
flush_to_ldisc
In our system, the processing interval for each frame of IMU data
transmitted via UART can experience significant jitter due to this issue.
Instead of the expected 10 to 15 ms frame processing interval, we see
spikes up to 30 to 35 ms. Moreover, in just one or two hours, there can
be 2 to 3 occurrences of such high jitter, which is quite frequent. This
jitter exceeds the software's tolerable limit of 20 ms.
Introduce flip_wq in tty_port which can be set by tty_port_link_wq() or as
default linked to default workqueue allocated when tty_register_driver().
The default workqueue is allocated with flag WQ_SYSFS, so that cpumask and
nice can be set dynamically. The execution timing of tty_port_link_wq() is
not clearly restricted. The newly added function tty_port_link_driver_wq()
checks whether the flip_wq of the tty_port has already been assigned when
linking the default tty_driver's workqueue to the port. After the user has
set a custom workqueue for a certain tty_port using tty_port_link_wq(), the
system will only use this custom workqueue, even if tty_driver does not
have %TTY_DRIVER_NO_WORKQUEUE flag. When tty_port register device, flip_wq
link operation is done by tty_port_link_driver_wq(), but for in-memory
devices the link operation cannot cover all the cases. Although
tty_port_install() is dedicated for in-memory devices lik PTY to link port
allocated on demand, the logic of tty_port_install() is so simple that
people may not call it, vc_cons[0].d->port is one such case. We check the
buf.flip_wq when flip TTY buffer, if buf.flip_wq of TTY port is NULL, use
system_dfl_wq as a backup.
To avoid naming conflict of the default tty_driver's workqueue, using
'"%s-%s", driver->name, driver->driver_name' as the workqueue name. In
cases where driver_name is not specified and therefore is NULL, the
workqueue is not created. Drivers that do not define driver_name are
potentially in-memory devices like vty, which generally do not require
special workqueue settings. Even with the combination of name and
driver_name, the workqueue names can still be duplicated, as many tty
serial drivers use "ttyS" as dev_name and "serial" as driver_name. I
modified the conflicting driver_name of these drivers by appending a
suffix of _xx based on the corresponding .c file. If this modification is
not made, it could not only lead to duplicate workqueue names but also
result in duplicate entries for the /proc/tty/driver/<driver_name> nodes.
Introduce %TTY_DRIVER_NO_WORKQUEUE flag meaning not to create the
default single tty_driver workqueue. Two reasons why need to introduce the
%TTY_DRIVER_NO_WORKQUEUE flag:
1. If the WQ_SYSFS parameter is enabled, workqueue_sysfs_register() will
fail when trying to create a workqueue with the same name. The pty is an
example of this; if both CONFIG_LEGACY_PTYS and CONFIG_UNIX98_PTYS are
enabled, the call to tty_register_driver() in unix98_pty_init() will fail.
2. Different TTY ports may be used for different tasks, which may require
separate core binding control via workqueues. In this case, the workqueue
created by default in the TTY driver is unnecessary. Enabling this flag
prevents the creation of this redundant workqueue.
After applying this patch, we can set the related UART TTY flip buffer
workqueue by sysfs. We set the cpumask to CPU cores associated with the
IMU tasks, and set the nice to -20. Testing has shown significant
improvement in the previously described issue, with almost no stuttering
occurring anymore.
Tested-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Xin Zhao <jackzxcui1989@163.com>
Link: https://patch.msgid.link/20260213085039.3274704-1-jackzxcui1989@163.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-02-13 16:50:39 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-11-26 09:16:02 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-06-15 09:36:15 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-09-19 10:51:52 +02:00
|
|
|
|
2013-06-15 09:36:15 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-09-19 10:51:52 +02:00
|
|
|
|
2013-06-15 09:36:15 -04:00
|
|
|
|
tty: tty_port: add workqueue to flip TTY buffer
On the embedded platform, certain critical data, such as IMU data, is
transmitted through UART. The tty_flip_buffer_push() interface in the TTY
layer uses system_dfl_wq to handle the flipping of the TTY buffer.
Although the unbound workqueue can create new threads on demand and wake
up the kworker thread on an idle CPU, it may be preempted by real-time
tasks or other high-prio tasks.
flush_to_ldisc() needs to wake up the relevant data handle thread. When
executing __wake_up_common_lock(), it calls spin_lock_irqsave(), which
does not disable preemption but disables migration in RT-Linux. This
prevents the kworker thread from being migrated to other cores by CPU's
balancing logic, resulting in long delays. The call trace is as follows:
__wake_up_common_lock
__wake_up
ep_poll_callback
__wake_up_common
__wake_up_common_lock
__wake_up
n_tty_receive_buf_common
n_tty_receive_buf2
tty_ldisc_receive_buf
tty_port_default_receive_buf
flush_to_ldisc
In our system, the processing interval for each frame of IMU data
transmitted via UART can experience significant jitter due to this issue.
Instead of the expected 10 to 15 ms frame processing interval, we see
spikes up to 30 to 35 ms. Moreover, in just one or two hours, there can
be 2 to 3 occurrences of such high jitter, which is quite frequent. This
jitter exceeds the software's tolerable limit of 20 ms.
Introduce flip_wq in tty_port which can be set by tty_port_link_wq() or as
default linked to default workqueue allocated when tty_register_driver().
The default workqueue is allocated with flag WQ_SYSFS, so that cpumask and
nice can be set dynamically. The execution timing of tty_port_link_wq() is
not clearly restricted. The newly added function tty_port_link_driver_wq()
checks whether the flip_wq of the tty_port has already been assigned when
linking the default tty_driver's workqueue to the port. After the user has
set a custom workqueue for a certain tty_port using tty_port_link_wq(), the
system will only use this custom workqueue, even if tty_driver does not
have %TTY_DRIVER_NO_WORKQUEUE flag. When tty_port register device, flip_wq
link operation is done by tty_port_link_driver_wq(), but for in-memory
devices the link operation cannot cover all the cases. Although
tty_port_install() is dedicated for in-memory devices lik PTY to link port
allocated on demand, the logic of tty_port_install() is so simple that
people may not call it, vc_cons[0].d->port is one such case. We check the
buf.flip_wq when flip TTY buffer, if buf.flip_wq of TTY port is NULL, use
system_dfl_wq as a backup.
To avoid naming conflict of the default tty_driver's workqueue, using
'"%s-%s", driver->name, driver->driver_name' as the workqueue name. In
cases where driver_name is not specified and therefore is NULL, the
workqueue is not created. Drivers that do not define driver_name are
potentially in-memory devices like vty, which generally do not require
special workqueue settings. Even with the combination of name and
driver_name, the workqueue names can still be duplicated, as many tty
serial drivers use "ttyS" as dev_name and "serial" as driver_name. I
modified the conflicting driver_name of these drivers by appending a
suffix of _xx based on the corresponding .c file. If this modification is
not made, it could not only lead to duplicate workqueue names but also
result in duplicate entries for the /proc/tty/driver/<driver_name> nodes.
Introduce %TTY_DRIVER_NO_WORKQUEUE flag meaning not to create the
default single tty_driver workqueue. Two reasons why need to introduce the
%TTY_DRIVER_NO_WORKQUEUE flag:
1. If the WQ_SYSFS parameter is enabled, workqueue_sysfs_register() will
fail when trying to create a workqueue with the same name. The pty is an
example of this; if both CONFIG_LEGACY_PTYS and CONFIG_UNIX98_PTYS are
enabled, the call to tty_register_driver() in unix98_pty_init() will fail.
2. Different TTY ports may be used for different tasks, which may require
separate core binding control via workqueues. In this case, the workqueue
created by default in the TTY driver is unnecessary. Enabling this flag
prevents the creation of this redundant workqueue.
After applying this patch, we can set the related UART TTY flip buffer
workqueue by sysfs. We set the cpumask to CPU cores associated with the
IMU tasks, and set the nice to -20. Testing has shown significant
improvement in the previously described issue, with almost no stuttering
occurring anymore.
Tested-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Xin Zhao <jackzxcui1989@163.com>
Link: https://patch.msgid.link/20260213085039.3274704-1-jackzxcui1989@163.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-02-13 16:50:39 +08:00
|
|
|
|
2013-06-15 09:36:15 -04:00
|
|
|
|
2014-05-19 01:03:06 +01:00
|
|
|
|
2013-06-15 09:36:15 -04:00
|
|
|
|
2013-06-15 09:36:08 -04:00
|
|
|
|
2021-11-26 09:16:02 +01:00
|
|
|
|
|
|
|
|
|
2013-06-15 09:36:08 -04:00
|
|
|
|
2021-11-26 09:16:02 +01:00
|
|
|
|
|
|
|
|
|
2013-06-15 09:36:08 -04:00
|
|
|
|
2021-11-26 09:16:02 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-06-15 09:36:08 -04:00
|
|
|
|
2021-05-05 11:19:17 +02:00
|
|
|
|
2013-06-15 09:36:08 -04:00
|
|
|
|
2013-11-22 12:09:56 -05:00
|
|
|
|
2021-05-12 17:26:11 +08:00
|
|
|
|
2013-06-15 09:36:08 -04:00
|
|
|
|
|
|
|
|
|
2013-11-22 13:06:08 -05:00
|
|
|
|
2013-06-15 09:36:08 -04:00
|
|
|
|
2013-06-15 09:36:03 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tty: Implement lookahead to process XON/XOFF timely
When tty is not read from, XON/XOFF may get stuck into an
intermediate buffer. As those characters are there to do software
flow-control, it is not very useful. In the case where neither end
reads from ttys, the receiving ends might not be able receive the
XOFF characters and just keep sending more data to the opposite
direction. This problem is almost guaranteed to occur with DMA
which sends data in large chunks.
If TTY is slow to process characters, that is, eats less than given
amount in receive_buf, invoke lookahead for the rest of the chars
to process potential XON/XOFF characters.
We need to keep track of how many characters have been processed by the
lookahead to avoid processing the flow control char again on the normal
path. Bookkeeping occurs parallel on two layers (tty_buffer and n_tty)
to avoid passing the lookahead_count through the whole call chain.
When a flow-control char is processed, two things must occur:
a) it must not be treated as normal char
b) if not yet processed, flow-control actions need to be taken
The return value of n_tty_receive_char_flow_ctrl() tells caller a), and
b) is kept internal to n_tty_receive_char_flow_ctrl().
If characters were previous looked ahead, __receive_buf() makes two
calls to the appropriate n_tty_receive_buf_* function. First call is
made with lookahead_done=true for the characters that were subject to
lookahead earlier and then with lookahead=false for the new characters.
Either of the calls might be skipped when it has no characters to
handle.
Reported-by: Gilles Buloz <gilles.buloz@kontron.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Link: https://lore.kernel.org/r/20220606153652.63554-2-ilpo.jarvinen@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-06-06 18:36:51 +03:00
|
|
|
|
2013-06-15 09:36:03 -04:00
|
|
|
|
2022-10-19 13:55:03 +03:00
|
|
|
|
2013-06-15 09:36:03 -04:00
|
|
|
|
|
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2021-11-26 09:16:02 +01:00
|
|
|
|
|
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2021-11-26 09:16:02 +01:00
|
|
|
|
|
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2012-10-18 22:26:47 +02:00
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2012-10-18 22:26:47 +02:00
|
|
|
|
2013-06-15 09:36:06 -04:00
|
|
|
|
|
|
|
|
|
2018-09-07 15:19:06 +02:00
|
|
|
|
|
|
|
|
|
2012-10-18 22:26:45 +02:00
|
|
|
|
2013-06-15 09:36:05 -04:00
|
|
|
|
|
|
|
|
|
2018-09-07 15:19:06 +02:00
|
|
|
|
2013-06-15 09:36:07 -04:00
|
|
|
|
|
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2013-06-15 09:36:06 -04:00
|
|
|
|
|
|
|
|
|
2013-06-15 09:36:05 -04:00
|
|
|
|
2013-06-15 09:36:06 -04:00
|
|
|
|
2013-06-15 09:36:07 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-06-15 09:36:08 -04:00
|
|
|
|
2018-09-07 15:19:06 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-11-26 09:16:02 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2021-11-26 09:16:02 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2012-10-18 22:26:47 +02:00
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2013-06-15 09:36:06 -04:00
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
|
|
|
|
|
2013-06-15 09:36:04 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-06-15 09:36:06 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-06-15 09:36:04 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-05-12 17:26:13 +08:00
|
|
|
|
|
|
|
|
|
2013-11-22 12:09:56 -05:00
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
treewide: Replace kmalloc with kmalloc_obj for non-scalar types
This is the result of running the Coccinelle script from
scripts/coccinelle/api/kmalloc_objs.cocci. The script is designed to
avoid scalar types (which need careful case-by-case checking), and
instead replace kmalloc-family calls that allocate struct or union
object instances:
Single allocations: kmalloc(sizeof(TYPE), ...)
are replaced with: kmalloc_obj(TYPE, ...)
Array allocations: kmalloc_array(COUNT, sizeof(TYPE), ...)
are replaced with: kmalloc_objs(TYPE, COUNT, ...)
Flex array allocations: kmalloc(struct_size(PTR, FAM, COUNT), ...)
are replaced with: kmalloc_flex(*PTR, FAM, COUNT, ...)
(where TYPE may also be *VAR)
The resulting allocations no longer return "void *", instead returning
"TYPE *".
Signed-off-by: Kees Cook <kees@kernel.org>
2026-02-20 23:49:23 -08:00
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
|
|
|
|
|
2013-06-15 09:36:03 -04:00
|
|
|
|
2013-06-15 09:36:04 -04:00
|
|
|
|
2013-06-15 09:36:03 -04:00
|
|
|
|
2013-11-22 12:09:56 -05:00
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-11-26 09:16:02 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2021-11-26 09:16:02 +01:00
|
|
|
|
|
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2012-10-18 22:26:47 +02:00
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2012-10-18 22:26:47 +02:00
|
|
|
|
2012-10-18 22:26:45 +02:00
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2013-11-22 12:09:56 -05:00
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2013-06-15 09:36:02 -04:00
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2013-06-15 09:36:07 -04:00
|
|
|
|
2013-06-15 09:36:06 -04:00
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-11-26 09:16:02 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2021-11-26 09:16:02 +01:00
|
|
|
|
|
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2021-11-26 09:16:02 +01:00
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2014-11-05 12:13:09 -05:00
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2012-10-18 22:26:44 +02:00
|
|
|
|
2012-10-18 22:26:47 +02:00
|
|
|
|
2013-06-15 09:36:14 -04:00
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2013-06-15 09:36:15 -04:00
|
|
|
|
2013-06-15 09:36:10 -04:00
|
|
|
|
2013-06-15 09:36:15 -04:00
|
|
|
|
2015-09-17 17:17:09 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-06-15 09:36:14 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tty: Implement lookahead to process XON/XOFF timely
When tty is not read from, XON/XOFF may get stuck into an
intermediate buffer. As those characters are there to do software
flow-control, it is not very useful. In the case where neither end
reads from ttys, the receiving ends might not be able receive the
XOFF characters and just keep sending more data to the opposite
direction. This problem is almost guaranteed to occur with DMA
which sends data in large chunks.
If TTY is slow to process characters, that is, eats less than given
amount in receive_buf, invoke lookahead for the rest of the chars
to process potential XON/XOFF characters.
We need to keep track of how many characters have been processed by the
lookahead to avoid processing the flow control char again on the normal
path. Bookkeeping occurs parallel on two layers (tty_buffer and n_tty)
to avoid passing the lookahead_count through the whole call chain.
When a flow-control char is processed, two things must occur:
a) it must not be treated as normal char
b) if not yet processed, flow-control actions need to be taken
The return value of n_tty_receive_char_flow_ctrl() tells caller a), and
b) is kept internal to n_tty_receive_char_flow_ctrl().
If characters were previous looked ahead, __receive_buf() makes two
calls to the appropriate n_tty_receive_buf_* function. First call is
made with lookahead_done=true for the characters that were subject to
lookahead earlier and then with lookahead=false for the new characters.
Either of the calls might be skipped when it has no characters to
handle.
Reported-by: Gilles Buloz <gilles.buloz@kontron.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Link: https://lore.kernel.org/r/20220606153652.63554-2-ilpo.jarvinen@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-06-06 18:36:51 +03:00
|
|
|
|
2014-11-05 12:13:09 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-06-15 09:36:15 -04:00
|
|
|
|
|
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2021-11-26 09:16:02 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-10-19 13:55:03 +03:00
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2021-11-26 09:16:02 +01:00
|
|
|
|
2013-12-09 09:23:52 -05:00
|
|
|
|
2021-11-26 09:16:02 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2013-12-09 09:23:52 -05:00
|
|
|
|
2022-10-19 13:55:03 +03:00
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2012-10-18 22:26:47 +02:00
|
|
|
|
2023-08-16 12:55:29 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-06-15 09:36:09 -04:00
|
|
|
|
2023-08-16 12:55:30 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
|
|
|
|
|
2013-12-09 09:23:52 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-10-19 13:55:03 +03:00
|
|
|
|
2013-12-09 09:23:52 -05:00
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
|
|
|
|
|
2023-08-16 12:55:25 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2023-08-16 12:55:23 +02:00
|
|
|
|
2023-08-16 12:55:25 +02:00
|
|
|
|
2021-05-12 17:26:11 +08:00
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2023-08-16 12:55:25 +02:00
|
|
|
|
|
|
|
|
|
2013-01-19 18:16:20 +04:00
|
|
|
|
2021-05-12 17:26:11 +08:00
|
|
|
|
2013-06-15 09:36:07 -04:00
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2023-08-16 12:55:23 +02:00
|
|
|
|
2013-06-15 09:36:01 -04:00
|
|
|
|
2023-08-16 12:55:23 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-08-16 12:55:24 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-08-16 12:55:23 +02:00
|
|
|
|
|
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-08-16 12:55:23 +02:00
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2021-05-12 17:26:13 +08:00
|
|
|
|
|
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2023-08-16 12:55:23 +02:00
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
|
|
|
|
|
2023-08-16 12:55:23 +02:00
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
|
|
|
|
|
2021-11-26 09:16:02 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2021-11-26 09:16:02 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2023-08-16 12:55:26 +02:00
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2023-08-16 12:55:26 +02:00
|
|
|
|
2021-05-12 17:26:11 +08:00
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2013-01-19 18:16:20 +04:00
|
|
|
|
2021-05-12 17:26:11 +08:00
|
|
|
|
2013-06-15 09:36:01 -04:00
|
|
|
|
2022-10-19 13:55:03 +03:00
|
|
|
|
2013-12-09 09:23:52 -05:00
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
|
|
|
|
|
2023-08-16 12:55:26 +02:00
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-01-10 20:36:13 -08:00
|
|
|
|
2021-11-26 09:16:02 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-01-10 20:36:13 -08:00
|
|
|
|
2021-11-26 09:16:02 +01:00
|
|
|
|
|
|
|
|
|
2016-01-10 20:36:13 -08:00
|
|
|
|
2021-11-26 09:16:02 +01:00
|
|
|
|
2016-01-10 20:36:13 -08:00
|
|
|
|
2023-08-10 11:14:51 +02:00
|
|
|
|
2023-08-10 11:14:50 +02:00
|
|
|
|
2016-01-10 20:36:13 -08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-08-10 11:14:46 +02:00
|
|
|
|
2016-01-10 20:36:13 -08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
tty: Implement lookahead to process XON/XOFF timely
When tty is not read from, XON/XOFF may get stuck into an
intermediate buffer. As those characters are there to do software
flow-control, it is not very useful. In the case where neither end
reads from ttys, the receiving ends might not be able receive the
XOFF characters and just keep sending more data to the opposite
direction. This problem is almost guaranteed to occur with DMA
which sends data in large chunks.
If TTY is slow to process characters, that is, eats less than given
amount in receive_buf, invoke lookahead for the rest of the chars
to process potential XON/XOFF characters.
We need to keep track of how many characters have been processed by the
lookahead to avoid processing the flow control char again on the normal
path. Bookkeeping occurs parallel on two layers (tty_buffer and n_tty)
to avoid passing the lookahead_count through the whole call chain.
When a flow-control char is processed, two things must occur:
a) it must not be treated as normal char
b) if not yet processed, flow-control actions need to be taken
The return value of n_tty_receive_char_flow_ctrl() tells caller a), and
b) is kept internal to n_tty_receive_char_flow_ctrl().
If characters were previous looked ahead, __receive_buf() makes two
calls to the appropriate n_tty_receive_buf_* function. First call is
made with lookahead_done=true for the characters that were subject to
lookahead earlier and then with lookahead=false for the new characters.
Either of the calls might be skipped when it has no characters to
handle.
Reported-by: Gilles Buloz <gilles.buloz@kontron.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Link: https://lore.kernel.org/r/20220606153652.63554-2-ilpo.jarvinen@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-06-06 18:36:51 +03:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-08-18 13:50:26 +02:00
|
|
|
|
2023-08-10 11:14:50 +02:00
|
|
|
|
2022-08-18 13:50:26 +02:00
|
|
|
|
|
|
|
|
|
2022-10-19 13:55:03 +03:00
|
|
|
|
2022-08-18 13:50:26 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tty: Implement lookahead to process XON/XOFF timely
When tty is not read from, XON/XOFF may get stuck into an
intermediate buffer. As those characters are there to do software
flow-control, it is not very useful. In the case where neither end
reads from ttys, the receiving ends might not be able receive the
XOFF characters and just keep sending more data to the opposite
direction. This problem is almost guaranteed to occur with DMA
which sends data in large chunks.
If TTY is slow to process characters, that is, eats less than given
amount in receive_buf, invoke lookahead for the rest of the chars
to process potential XON/XOFF characters.
We need to keep track of how many characters have been processed by the
lookahead to avoid processing the flow control char again on the normal
path. Bookkeeping occurs parallel on two layers (tty_buffer and n_tty)
to avoid passing the lookahead_count through the whole call chain.
When a flow-control char is processed, two things must occur:
a) it must not be treated as normal char
b) if not yet processed, flow-control actions need to be taken
The return value of n_tty_receive_char_flow_ctrl() tells caller a), and
b) is kept internal to n_tty_receive_char_flow_ctrl().
If characters were previous looked ahead, __receive_buf() makes two
calls to the appropriate n_tty_receive_buf_* function. First call is
made with lookahead_done=true for the characters that were subject to
lookahead earlier and then with lookahead=false for the new characters.
Either of the calls might be skipped when it has no characters to
handle.
Reported-by: Gilles Buloz <gilles.buloz@kontron.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Link: https://lore.kernel.org/r/20220606153652.63554-2-ilpo.jarvinen@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-06-06 18:36:51 +03:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-08-10 11:14:45 +02:00
|
|
|
|
|
|
|
|
|
2013-06-15 09:14:14 -04:00
|
|
|
|
2023-08-10 11:14:43 +02:00
|
|
|
|
|
|
|
|
|
2023-08-10 11:14:45 +02:00
|
|
|
|
2013-12-09 09:23:52 -05:00
|
|
|
|
2022-10-19 13:55:03 +03:00
|
|
|
|
2013-12-09 09:23:52 -05:00
|
|
|
|
2013-06-15 09:14:14 -04:00
|
|
|
|
2018-10-04 11:06:13 -07:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-06-15 09:14:14 -04:00
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
|
|
|
|
|
2021-11-26 09:16:02 +01:00
|
|
|
|
|
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2021-11-26 09:16:02 +01:00
|
|
|
|
|
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2021-11-26 09:16:02 +01:00
|
|
|
|
2013-06-15 09:36:10 -04:00
|
|
|
|
2021-11-26 09:16:02 +01:00
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2012-10-18 22:26:47 +02:00
|
|
|
|
|
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2013-06-15 09:36:15 -04:00
|
|
|
|
2009-10-14 08:59:49 -07:00
|
|
|
|
2013-06-15 09:36:11 -04:00
|
|
|
|
|
|
|
|
|
2014-05-02 10:56:12 -04:00
|
|
|
|
2023-08-10 11:14:45 +02:00
|
|
|
|
2009-10-14 08:59:49 -07:00
|
|
|
|
2013-06-15 09:36:15 -04:00
|
|
|
|
|
|
|
|
|
2013-06-15 09:36:11 -04:00
|
|
|
|
2013-06-15 09:36:10 -04:00
|
|
|
|
2015-07-12 20:50:49 -04:00
|
|
|
|
2014-05-02 10:56:12 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2015-07-12 20:50:49 -04:00
|
|
|
|
2015-09-17 17:17:10 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-06-15 09:36:11 -04:00
|
|
|
|
2016-03-06 13:16:30 -08:00
|
|
|
|
2013-06-15 09:14:14 -04:00
|
|
|
|
2014-05-02 10:56:12 -04:00
|
|
|
|
2013-06-15 09:36:11 -04:00
|
|
|
|
|
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2013-06-15 09:36:11 -04:00
|
|
|
|
tty: Implement lookahead to process XON/XOFF timely
When tty is not read from, XON/XOFF may get stuck into an
intermediate buffer. As those characters are there to do software
flow-control, it is not very useful. In the case where neither end
reads from ttys, the receiving ends might not be able receive the
XOFF characters and just keep sending more data to the opposite
direction. This problem is almost guaranteed to occur with DMA
which sends data in large chunks.
If TTY is slow to process characters, that is, eats less than given
amount in receive_buf, invoke lookahead for the rest of the chars
to process potential XON/XOFF characters.
We need to keep track of how many characters have been processed by the
lookahead to avoid processing the flow control char again on the normal
path. Bookkeeping occurs parallel on two layers (tty_buffer and n_tty)
to avoid passing the lookahead_count through the whole call chain.
When a flow-control char is processed, two things must occur:
a) it must not be treated as normal char
b) if not yet processed, flow-control actions need to be taken
The return value of n_tty_receive_char_flow_ctrl() tells caller a), and
b) is kept internal to n_tty_receive_char_flow_ctrl().
If characters were previous looked ahead, __receive_buf() makes two
calls to the appropriate n_tty_receive_buf_* function. First call is
made with lookahead_done=true for the characters that were subject to
lookahead earlier and then with lookahead=false for the new characters.
Either of the calls might be skipped when it has no characters to
handle.
Reported-by: Gilles Buloz <gilles.buloz@kontron.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Link: https://lore.kernel.org/r/20220606153652.63554-2-ilpo.jarvinen@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2022-06-06 18:36:51 +03:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-06-15 09:36:11 -04:00
|
|
|
|
2021-10-11 22:08:24 +08:00
|
|
|
|
2025-07-14 18:17:15 +02:00
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2009-10-14 08:59:49 -07:00
|
|
|
|
2013-06-15 09:36:15 -04:00
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-07-07 10:25:57 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2021-11-26 09:16:02 +01:00
|
|
|
|
|
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2021-11-26 09:16:02 +01:00
|
|
|
|
|
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2021-11-26 09:16:02 +01:00
|
|
|
|
|
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2013-01-03 15:53:06 +01:00
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2021-11-22 12:16:48 +01:00
|
|
|
|
|
|
|
|
|
2022-07-07 10:25:57 +02:00
|
|
|
|
tty: tty_port: add workqueue to flip TTY buffer
On the embedded platform, certain critical data, such as IMU data, is
transmitted through UART. The tty_flip_buffer_push() interface in the TTY
layer uses system_dfl_wq to handle the flipping of the TTY buffer.
Although the unbound workqueue can create new threads on demand and wake
up the kworker thread on an idle CPU, it may be preempted by real-time
tasks or other high-prio tasks.
flush_to_ldisc() needs to wake up the relevant data handle thread. When
executing __wake_up_common_lock(), it calls spin_lock_irqsave(), which
does not disable preemption but disables migration in RT-Linux. This
prevents the kworker thread from being migrated to other cores by CPU's
balancing logic, resulting in long delays. The call trace is as follows:
__wake_up_common_lock
__wake_up
ep_poll_callback
__wake_up_common
__wake_up_common_lock
__wake_up
n_tty_receive_buf_common
n_tty_receive_buf2
tty_ldisc_receive_buf
tty_port_default_receive_buf
flush_to_ldisc
In our system, the processing interval for each frame of IMU data
transmitted via UART can experience significant jitter due to this issue.
Instead of the expected 10 to 15 ms frame processing interval, we see
spikes up to 30 to 35 ms. Moreover, in just one or two hours, there can
be 2 to 3 occurrences of such high jitter, which is quite frequent. This
jitter exceeds the software's tolerable limit of 20 ms.
Introduce flip_wq in tty_port which can be set by tty_port_link_wq() or as
default linked to default workqueue allocated when tty_register_driver().
The default workqueue is allocated with flag WQ_SYSFS, so that cpumask and
nice can be set dynamically. The execution timing of tty_port_link_wq() is
not clearly restricted. The newly added function tty_port_link_driver_wq()
checks whether the flip_wq of the tty_port has already been assigned when
linking the default tty_driver's workqueue to the port. After the user has
set a custom workqueue for a certain tty_port using tty_port_link_wq(), the
system will only use this custom workqueue, even if tty_driver does not
have %TTY_DRIVER_NO_WORKQUEUE flag. When tty_port register device, flip_wq
link operation is done by tty_port_link_driver_wq(), but for in-memory
devices the link operation cannot cover all the cases. Although
tty_port_install() is dedicated for in-memory devices lik PTY to link port
allocated on demand, the logic of tty_port_install() is so simple that
people may not call it, vc_cons[0].d->port is one such case. We check the
buf.flip_wq when flip TTY buffer, if buf.flip_wq of TTY port is NULL, use
system_dfl_wq as a backup.
To avoid naming conflict of the default tty_driver's workqueue, using
'"%s-%s", driver->name, driver->driver_name' as the workqueue name. In
cases where driver_name is not specified and therefore is NULL, the
workqueue is not created. Drivers that do not define driver_name are
potentially in-memory devices like vty, which generally do not require
special workqueue settings. Even with the combination of name and
driver_name, the workqueue names can still be duplicated, as many tty
serial drivers use "ttyS" as dev_name and "serial" as driver_name. I
modified the conflicting driver_name of these drivers by appending a
suffix of _xx based on the corresponding .c file. If this modification is
not made, it could not only lead to duplicate workqueue names but also
result in duplicate entries for the /proc/tty/driver/<driver_name> nodes.
Introduce %TTY_DRIVER_NO_WORKQUEUE flag meaning not to create the
default single tty_driver workqueue. Two reasons why need to introduce the
%TTY_DRIVER_NO_WORKQUEUE flag:
1. If the WQ_SYSFS parameter is enabled, workqueue_sysfs_register() will
fail when trying to create a workqueue with the same name. The pty is an
example of this; if both CONFIG_LEGACY_PTYS and CONFIG_UNIX98_PTYS are
enabled, the call to tty_register_driver() in unix98_pty_init() will fail.
2. Different TTY ports may be used for different tasks, which may require
separate core binding control via workqueues. In this case, the workqueue
created by default in the TTY driver is unnecessary. Enabling this flag
prevents the creation of this redundant workqueue.
After applying this patch, we can set the related UART TTY flip buffer
workqueue by sysfs. We set the cpumask to CPU cores associated with the
IMU tasks, and set the nice to -20. Testing has shown significant
improvement in the previously described issue, with almost no stuttering
occurring anymore.
Tested-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Xin Zhao <jackzxcui1989@163.com>
Link: https://patch.msgid.link/20260213085039.3274704-1-jackzxcui1989@163.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-02-13 16:50:39 +08:00
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2022-07-07 10:25:58 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-08-10 11:14:50 +02:00
|
|
|
|
2022-07-07 10:25:58 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tty: tty_port: add workqueue to flip TTY buffer
On the embedded platform, certain critical data, such as IMU data, is
transmitted through UART. The tty_flip_buffer_push() interface in the TTY
layer uses system_dfl_wq to handle the flipping of the TTY buffer.
Although the unbound workqueue can create new threads on demand and wake
up the kworker thread on an idle CPU, it may be preempted by real-time
tasks or other high-prio tasks.
flush_to_ldisc() needs to wake up the relevant data handle thread. When
executing __wake_up_common_lock(), it calls spin_lock_irqsave(), which
does not disable preemption but disables migration in RT-Linux. This
prevents the kworker thread from being migrated to other cores by CPU's
balancing logic, resulting in long delays. The call trace is as follows:
__wake_up_common_lock
__wake_up
ep_poll_callback
__wake_up_common
__wake_up_common_lock
__wake_up
n_tty_receive_buf_common
n_tty_receive_buf2
tty_ldisc_receive_buf
tty_port_default_receive_buf
flush_to_ldisc
In our system, the processing interval for each frame of IMU data
transmitted via UART can experience significant jitter due to this issue.
Instead of the expected 10 to 15 ms frame processing interval, we see
spikes up to 30 to 35 ms. Moreover, in just one or two hours, there can
be 2 to 3 occurrences of such high jitter, which is quite frequent. This
jitter exceeds the software's tolerable limit of 20 ms.
Introduce flip_wq in tty_port which can be set by tty_port_link_wq() or as
default linked to default workqueue allocated when tty_register_driver().
The default workqueue is allocated with flag WQ_SYSFS, so that cpumask and
nice can be set dynamically. The execution timing of tty_port_link_wq() is
not clearly restricted. The newly added function tty_port_link_driver_wq()
checks whether the flip_wq of the tty_port has already been assigned when
linking the default tty_driver's workqueue to the port. After the user has
set a custom workqueue for a certain tty_port using tty_port_link_wq(), the
system will only use this custom workqueue, even if tty_driver does not
have %TTY_DRIVER_NO_WORKQUEUE flag. When tty_port register device, flip_wq
link operation is done by tty_port_link_driver_wq(), but for in-memory
devices the link operation cannot cover all the cases. Although
tty_port_install() is dedicated for in-memory devices lik PTY to link port
allocated on demand, the logic of tty_port_install() is so simple that
people may not call it, vc_cons[0].d->port is one such case. We check the
buf.flip_wq when flip TTY buffer, if buf.flip_wq of TTY port is NULL, use
system_dfl_wq as a backup.
To avoid naming conflict of the default tty_driver's workqueue, using
'"%s-%s", driver->name, driver->driver_name' as the workqueue name. In
cases where driver_name is not specified and therefore is NULL, the
workqueue is not created. Drivers that do not define driver_name are
potentially in-memory devices like vty, which generally do not require
special workqueue settings. Even with the combination of name and
driver_name, the workqueue names can still be duplicated, as many tty
serial drivers use "ttyS" as dev_name and "serial" as driver_name. I
modified the conflicting driver_name of these drivers by appending a
suffix of _xx based on the corresponding .c file. If this modification is
not made, it could not only lead to duplicate workqueue names but also
result in duplicate entries for the /proc/tty/driver/<driver_name> nodes.
Introduce %TTY_DRIVER_NO_WORKQUEUE flag meaning not to create the
default single tty_driver workqueue. Two reasons why need to introduce the
%TTY_DRIVER_NO_WORKQUEUE flag:
1. If the WQ_SYSFS parameter is enabled, workqueue_sysfs_register() will
fail when trying to create a workqueue with the same name. The pty is an
example of this; if both CONFIG_LEGACY_PTYS and CONFIG_UNIX98_PTYS are
enabled, the call to tty_register_driver() in unix98_pty_init() will fail.
2. Different TTY ports may be used for different tasks, which may require
separate core binding control via workqueues. In this case, the workqueue
created by default in the TTY driver is unnecessary. Enabling this flag
prevents the creation of this redundant workqueue.
After applying this patch, we can set the related UART TTY flip buffer
workqueue by sysfs. We set the cpumask to CPU cores associated with the
IMU tasks, and set the nice to -20. Testing has shown significant
improvement in the previously described issue, with almost no stuttering
occurring anymore.
Tested-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Xin Zhao <jackzxcui1989@163.com>
Link: https://patch.msgid.link/20260213085039.3274704-1-jackzxcui1989@163.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-02-13 16:50:39 +08:00
|
|
|
|
2022-07-07 10:25:58 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2021-11-26 09:16:02 +01:00
|
|
|
|
|
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2021-11-26 09:16:02 +01:00
|
|
|
|
|
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2012-10-18 22:26:47 +02:00
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2012-10-18 22:26:47 +02:00
|
|
|
|
2012-10-18 22:26:45 +02:00
|
|
|
|
2013-06-15 09:36:15 -04:00
|
|
|
|
2013-06-15 09:36:07 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-06-15 09:36:06 -04:00
|
|
|
|
2013-11-22 12:09:56 -05:00
|
|
|
|
2013-06-15 09:36:15 -04:00
|
|
|
|
2012-10-18 22:26:45 +02:00
|
|
|
|
2013-11-22 12:09:55 -05:00
|
|
|
|
2008-10-13 10:36:58 +01:00
|
|
|
|
2013-11-22 12:09:55 -05:00
|
|
|
|
|
|
|
|
|
2021-11-26 09:16:02 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-11-22 12:09:55 -05:00
|
|
|
|
2021-11-26 09:16:02 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-11-22 12:09:55 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2015-01-17 15:42:05 -05:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2015-10-17 16:36:23 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tty: tty_port: add workqueue to flip TTY buffer
On the embedded platform, certain critical data, such as IMU data, is
transmitted through UART. The tty_flip_buffer_push() interface in the TTY
layer uses system_dfl_wq to handle the flipping of the TTY buffer.
Although the unbound workqueue can create new threads on demand and wake
up the kworker thread on an idle CPU, it may be preempted by real-time
tasks or other high-prio tasks.
flush_to_ldisc() needs to wake up the relevant data handle thread. When
executing __wake_up_common_lock(), it calls spin_lock_irqsave(), which
does not disable preemption but disables migration in RT-Linux. This
prevents the kworker thread from being migrated to other cores by CPU's
balancing logic, resulting in long delays. The call trace is as follows:
__wake_up_common_lock
__wake_up
ep_poll_callback
__wake_up_common
__wake_up_common_lock
__wake_up
n_tty_receive_buf_common
n_tty_receive_buf2
tty_ldisc_receive_buf
tty_port_default_receive_buf
flush_to_ldisc
In our system, the processing interval for each frame of IMU data
transmitted via UART can experience significant jitter due to this issue.
Instead of the expected 10 to 15 ms frame processing interval, we see
spikes up to 30 to 35 ms. Moreover, in just one or two hours, there can
be 2 to 3 occurrences of such high jitter, which is quite frequent. This
jitter exceeds the software's tolerable limit of 20 ms.
Introduce flip_wq in tty_port which can be set by tty_port_link_wq() or as
default linked to default workqueue allocated when tty_register_driver().
The default workqueue is allocated with flag WQ_SYSFS, so that cpumask and
nice can be set dynamically. The execution timing of tty_port_link_wq() is
not clearly restricted. The newly added function tty_port_link_driver_wq()
checks whether the flip_wq of the tty_port has already been assigned when
linking the default tty_driver's workqueue to the port. After the user has
set a custom workqueue for a certain tty_port using tty_port_link_wq(), the
system will only use this custom workqueue, even if tty_driver does not
have %TTY_DRIVER_NO_WORKQUEUE flag. When tty_port register device, flip_wq
link operation is done by tty_port_link_driver_wq(), but for in-memory
devices the link operation cannot cover all the cases. Although
tty_port_install() is dedicated for in-memory devices lik PTY to link port
allocated on demand, the logic of tty_port_install() is so simple that
people may not call it, vc_cons[0].d->port is one such case. We check the
buf.flip_wq when flip TTY buffer, if buf.flip_wq of TTY port is NULL, use
system_dfl_wq as a backup.
To avoid naming conflict of the default tty_driver's workqueue, using
'"%s-%s", driver->name, driver->driver_name' as the workqueue name. In
cases where driver_name is not specified and therefore is NULL, the
workqueue is not created. Drivers that do not define driver_name are
potentially in-memory devices like vty, which generally do not require
special workqueue settings. Even with the combination of name and
driver_name, the workqueue names can still be duplicated, as many tty
serial drivers use "ttyS" as dev_name and "serial" as driver_name. I
modified the conflicting driver_name of these drivers by appending a
suffix of _xx based on the corresponding .c file. If this modification is
not made, it could not only lead to duplicate workqueue names but also
result in duplicate entries for the /proc/tty/driver/<driver_name> nodes.
Introduce %TTY_DRIVER_NO_WORKQUEUE flag meaning not to create the
default single tty_driver workqueue. Two reasons why need to introduce the
%TTY_DRIVER_NO_WORKQUEUE flag:
1. If the WQ_SYSFS parameter is enabled, workqueue_sysfs_register() will
fail when trying to create a workqueue with the same name. The pty is an
example of this; if both CONFIG_LEGACY_PTYS and CONFIG_UNIX98_PTYS are
enabled, the call to tty_register_driver() in unix98_pty_init() will fail.
2. Different TTY ports may be used for different tasks, which may require
separate core binding control via workqueues. In this case, the workqueue
created by default in the TTY driver is unnecessary. Enabling this flag
prevents the creation of this redundant workqueue.
After applying this patch, we can set the related UART TTY flip buffer
workqueue by sysfs. We set the cpumask to CPU cores associated with the
IMU tasks, and set the nice to -20. Testing has shown significant
improvement in the previously described issue, with almost no stuttering
occurring anymore.
Tested-by: Tommaso Merciai <tommaso.merciai.xr@bp.renesas.com>
Tested-by: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Xin Zhao <jackzxcui1989@163.com>
Link: https://patch.msgid.link/20260213085039.3274704-1-jackzxcui1989@163.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
2026-02-13 16:50:39 +08:00
|
|
|
|
2015-10-17 16:36:23 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2016-03-06 13:16:30 -08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|