)]}'
{
  "commit": "d000422a46aad32217cf1be747eb61d641baae2f",
  "tree": "a62110539ef62284a9f5987d801c90a7fb433776",
  "parents": [
    "3f0716c604e81d8440b16d0d8f5420c4a6f3c17a"
  ],
  "author": {
    "name": "Xin Zhao",
    "email": "jackzxcui1989@163.com",
    "time": "Tue Dec 23 11:48:36 2025 +0800"
  },
  "committer": {
    "name": "Greg Kroah-Hartman",
    "email": "gregkh@linuxfoundation.org",
    "time": "Fri Jan 23 17:25:11 2026 +0100"
  },
  "message": "tty: tty_port: add workqueue to flip TTY buffer\n\nOn the embedded platform, certain critical data, such as IMU data, is\ntransmitted through UART. The tty_flip_buffer_push() interface in the TTY\nlayer uses system_dfl_wq to handle the flipping of the TTY buffer.\nAlthough the unbound workqueue can create new threads on demand and wake\nup the kworker thread on an idle CPU, it may be preempted by real-time\ntasks or other high-prio tasks.\n\nflush_to_ldisc() needs to wake up the relevant data handle thread. When\nexecuting __wake_up_common_lock(), it calls spin_lock_irqsave(), which\ndoes not disable preemption but disables migration in RT-Linux. This\nprevents the kworker thread from being migrated to other cores by CPU\u0027s\nbalancing logic, resulting in long delays. The call trace is as follows:\n    __wake_up_common_lock\n    __wake_up\n    ep_poll_callback\n    __wake_up_common\n    __wake_up_common_lock\n    __wake_up\n    n_tty_receive_buf_common\n    n_tty_receive_buf2\n    tty_ldisc_receive_buf\n    tty_port_default_receive_buf\n    flush_to_ldisc\n\nIn our system, the processing interval for each frame of IMU data\ntransmitted via UART can experience significant jitter due to this issue.\nInstead of the expected 10 to 15 ms frame processing interval, we see\nspikes up to 30 to 35 ms. Moreover, in just one or two hours, there can\nbe 2 to 3 occurrences of such high jitter, which is quite frequent. This\njitter exceeds the software\u0027s tolerable limit of 20 ms.\n\nIntroduce flip_wq in tty_port which can be set by tty_port_link_wq() or as\ndefault linked to default workqueue allocated when tty_register_driver().\nThe default workqueue is allocated with flag WQ_SYSFS, so that cpumask and\nnice can be set dynamically. The execution timing of tty_port_link_wq() is\nnot clearly restricted. The newly added function tty_port_link_driver_wq()\nchecks whether the flip_wq of the tty_port has already been assigned when\nlinking the default tty_driver\u0027s workqueue to the port. After the user has\nset a custom workqueue for a certain tty_port using tty_port_link_wq(), the\nsystem will only use this custom workqueue, even if tty_driver does not\nhave %TTY_DRIVER_CUSTOM_WORKQUEUE flag.\n\nIntroduce %TTY_DRIVER_CUSTOM_WORKQUEUE flag meaning not to create the\ndefault single tty_driver workqueue. Two reasons why need to introduce the\n%TTY_DRIVER_CUSTOM_WORKQUEUE flag:\n1. If the WQ_SYSFS parameter is enabled, workqueue_sysfs_register() will\nfail when trying to create a workqueue with the same name. The pty is an\nexample of this; if both CONFIG_LEGACY_PTYS and CONFIG_UNIX98_PTYS are\nenabled, the call to tty_register_driver() in unix98_pty_init() will fail.\n2. Different tty ports may be used for different tasks, which may require\nseparate core binding control via workqueues. In this case, the workqueue\ncreated by default in the tty driver is unnecessary. Enabling this flag\nprevents the creation of this redundant workqueue.\n\nAfter applying this patch, we can set the related UART TTY flip buffer\nworkqueue by sysfs. We set the cpumask to CPU cores associated with the\nIMU tasks, and set the nice to -20. Testing has shown significant\nimprovement in the previously described issue, with almost no stuttering\noccurring anymore.\n\nSigned-off-by: Xin Zhao \u003cjackzxcui1989@163.com\u003e\nReviewed-by: Jiri Slaby \u003cjirislaby@kernel.org\u003e\nLink: https://patch.msgid.link/20251223034836.2625547-1-jackzxcui1989@163.com\nSigned-off-by: Greg Kroah-Hartman \u003cgregkh@linuxfoundation.org\u003e\n",
  "tree_diff": [
    {
      "type": "modify",
      "old_id": "6120d827a797747233859ec740e89a6b8634930b",
      "old_mode": 33188,
      "old_path": "drivers/tty/pty.c",
      "new_id": "1f17575f8fe0c53de88791de6fb8aacec0ed6ef9",
      "new_mode": 33188,
      "new_path": "drivers/tty/pty.c"
    },
    {
      "type": "modify",
      "old_id": "1a5673acd9b107d55623defcfc1dadb853781274",
      "old_mode": 33188,
      "old_path": "drivers/tty/tty_buffer.c",
      "new_id": "86e1e7178e9001dda2f94be7c83d164d291aa1a6",
      "new_mode": 33188,
      "new_path": "drivers/tty/tty_buffer.c"
    },
    {
      "type": "modify",
      "old_id": "e2d92cf70eb78ec6b2b93b55192e46781160c9dc",
      "old_mode": 33188,
      "old_path": "drivers/tty/tty_io.c",
      "new_id": "d64fb08baa179cfd63bd10ba6e624f2f5d41d43f",
      "new_mode": 33188,
      "new_path": "drivers/tty/tty_io.c"
    },
    {
      "type": "modify",
      "old_id": "fe67c5cb0a3f0c36c0581b44ea21ba858e8a2c4d",
      "old_mode": 33188,
      "old_path": "drivers/tty/tty_port.c",
      "new_id": "611f878149f8a0eb052e7c8814d4044287aab0de",
      "new_mode": 33188,
      "new_path": "drivers/tty/tty_port.c"
    },
    {
      "type": "modify",
      "old_id": "31125e3be3c55e4e65dd62d91fd13e96a91e6c27",
      "old_mode": 33188,
      "old_path": "include/linux/tty_buffer.h",
      "new_id": "48adcb0e8ff390c8b8f20292c05ca8262d87b95c",
      "new_mode": 33188,
      "new_path": "include/linux/tty_buffer.h"
    },
    {
      "type": "modify",
      "old_id": "188ee9b768eb6d928c3c5ae2fd1811755c529e62",
      "old_mode": 33188,
      "old_path": "include/linux/tty_driver.h",
      "new_id": "9c65854f7d94e729e1d95f99ba75c5c1cf2ccd66",
      "new_mode": 33188,
      "new_path": "include/linux/tty_driver.h"
    },
    {
      "type": "modify",
      "old_id": "660c254f1efe5f61f41244f2bb8cfa6bec5f4849",
      "old_mode": 33188,
      "old_path": "include/linux/tty_port.h",
      "new_id": "c1b87f3c56034a5ec801eede1660a7998757b486",
      "new_mode": 33188,
      "new_path": "include/linux/tty_port.h"
    }
  ]
}
