lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20251021042110.513095-1-jackzxcui1989@163.com>
Date: Tue, 21 Oct 2025 12:21:10 +0800
From: Xin Zhao <jackzxcui1989@....com>
To: gregkh@...uxfoundation.org,
	jirislaby@...nel.org
Cc: linux-kernel@...r.kernel.org,
	linux-serial@...r.kernel.org,
	tj@...nel.org,
	hch@...radead.org,
	Xin Zhao <jackzxcui1989@....com>
Subject: [PATCH] tty: tty_buffer: add interface to queue work on specific wq and cpu

On the embedded platform, certain critical data, such as IMU data, is
transmitted through UART. We have customized our own 8250 driver, but
we still need to reuse the kernel's TTY layer. The tty_flip_buffer_push
interface in the TTY layer uses system_unbound_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, the priority of
the kworker thread itself is not high. Even if the CPU running this work
was idle just a moment ago, it may be preempted by real-time tasks or
other high-priority tasks.
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.
Adding the tty_flip_buffer_push_wq interface would allow our 8250 driver
code to push work to a specified CPU. Since CPU tasks, especially real-time
tasks, often have a certain distribution pattern in the system, we found
that by pushing to a specified CPU with a WQ_HIGHPRI workqueue, we can
stably eliminate the jitter and ensure that the frame processing interval
remains between 10 and 15 ms. Furthermore, if we implement an RT workqueue
based on this, using the tty_flip_buffer_push_wq interface to push to the
RT workqueue(FIFO 1) we can further stabilize the processing interval,
significantly reducing the occurrences of 14-15 ms intervals and increasing
the frequency of 11-12 ms intervals.

Signed-off-by: Xin Zhao <jackzxcui1989@....com>
---
 drivers/tty/tty_buffer.c | 23 +++++++++++++++++++++++
 include/linux/tty_flip.h |  3 +++
 2 files changed, 26 insertions(+)

diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c
index 67271fc0b..112a650e2 100644
--- a/drivers/tty/tty_buffer.c
+++ b/drivers/tty/tty_buffer.c
@@ -534,6 +534,29 @@ void tty_flip_buffer_push(struct tty_port *port)
 }
 EXPORT_SYMBOL(tty_flip_buffer_push);
 
+/**
+ * tty_flip_buffer_push		-	push terminal buffers
+ * @port: tty port to push
+ * @wq: workqueue on which to queue work
+ * @cpu: cpu on which to queue work
+ *
+ * Queue a push of the terminal flip buffers to the line discipline. Can be
+ * called from IRQ/atomic context.
+ *
+ * In the event of the queue being busy for flipping the work will be held off
+ * and retried later.
+ */
+void tty_flip_buffer_push_wq(struct tty_port *port,
+			     struct workqueue_struct *wq,
+			     int cpu)
+{
+	struct tty_bufhead *buf = &port->buf;
+
+	tty_flip_buffer_commit(buf->tail);
+	queue_work_on(cpu, wq, &buf->work);
+}
+EXPORT_SYMBOL(tty_flip_buffer_push_wq);
+
 /**
  * tty_insert_flip_string_and_push_buffer - add characters to the tty buffer and
  *	push
diff --git a/include/linux/tty_flip.h b/include/linux/tty_flip.h
index af4fce98f..0138b6bfb 100644
--- a/include/linux/tty_flip.h
+++ b/include/linux/tty_flip.h
@@ -15,6 +15,9 @@ size_t __tty_insert_flip_string_flags(struct tty_port *port, const u8 *chars,
 				      size_t size);
 size_t tty_prepare_flip_string(struct tty_port *port, u8 **chars, size_t size);
 void tty_flip_buffer_push(struct tty_port *port);
+void tty_flip_buffer_push_wq(struct tty_port *port,
+			     struct workqueue_struct *wq,
+			     int cpu);
 
 /**
  * tty_insert_flip_string_fixed_flag - add characters to the tty buffer
-- 
2.34.1


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ