Skip to content

fix(monitorusb): replace hwinfo --usb with sysfs reading to eliminate ioctl audio stutter (PMS 381051) - #969

Closed
GongHeng2017 wants to merge 1 commit into
linuxdeepin:develop/eaglefrom
GongHeng2017:agent/agent/35bd8efe17a9
Closed

GongHeng2017 wants to merge 1 commit into
linuxdeepin:develop/eaglefrom
GongHeng2017:agent/agent/35bd8efe17a9

Conversation

@GongHeng2017

@GongHeng2017 GongHeng2017 commented Nov 10, 2026 •

Copy link
Copy Markdown
Contributor

问题描述 (PMS 381051)

在受影响的 xHCI 控制器上,USB 设备热插拔时会导致约 970ms 的音频卡顿。

根因分析

MonitorUsb::monitor() 在检测到 USB add/remove 事件时,同步执行 hwinfo --usb。hwinfo 会打开所有 /dev/bus/usb/*/* 设备节点并发送 ioctl(USBDEVFS_CONTROL) 控制传输来读取设备描述符。这些控制传输在受影响的 xHCI 控制器上会阻塞音频等时传输 (isochronous URB) 约 970ms,超过 PulseAudio 约 93ms 的缓冲区,导致可听见的音频卡顿。

修复方案(方案 3)

用直接读取 /sys/bus/usb/devices/ 下的 sysfs 属性文件替代 hwinfo --usb 外部进程。sysfs 文件读取不涉及任何 USB I/O,从根本上消除了控制传输干扰。

修改内容

文件: deepin-devicemanager-server/deepin-deviceinfo/src/hotplug/monitorusb.cpp

  1. 新增 getUsbInfoFromSysfs() 静态函数,遍历 /sys/bus/usb/devices/ 下的设备条目,读取 sysfs 属性(idVendor、idProduct、manufacturer、product、serial、bDeviceClass、bInterfaceClass 等),生成与 hwinfo --usb 输出格式兼容的字符串。

  2. 新增 usbHardwareClass() 辅助函数,根据 bDeviceClass (0x09=hub) 和 HID 接口的 bInterfaceSubClass/bInterfaceProtocol 推导 hwinfo 风格的 "Hardware Class"(hub/keyboard/mouse/usb)。

  3. 新增 readSysfsAttr() 辅助函数,安全读取 sysfs 属性文件。

  4. 在 monitor() 中将 QProcess::execute("hwinfo", {"--usb"}) 替换为 getUsbInfoFromSysfs() 调用。

兼容性保证

生成的字符串格式完全兼容现有消费者:

  • EnableUtils::disableOutDevice(): 需要 "Vendor"(含0x)、"Device"(含0x)、"SysFS Device Link"/"SysFS ID" 用于哈希唯一标识;"Hardware Class" != "hub" 且存在 "SysFS BusID" 用于过滤
  • WakeupUtils::updateWakeupDeviceInfo(): 需要 "Hardware Class" == "keyboard"/"mouse"、"SysFS ID" 用于 wakeup 路径

所有设备块均超过 10 行(满足 LEAST_NUM=10 要求)。

影响范围

  • 仅修改 monitorusb.cpp 一个文件
  • 不改变任何对外接口
  • 不影响 detectthread.cpp 中的 hwinfo --usb --keyboard --mouse 调用(属设计缺陷,不在本次修复范围)
  • 不影响 mainjob.cpp 中的 sqlCopytoKernel 调用(仅在启动和唤醒时执行,非热插拔路径)

Summary by Sourcery

Eliminate USB hotplug audio stutter by switching device information collection from hwinfo to non-I/O sysfs reads.

Bug Fixes:

  • Replace hotplug-time hwinfo USB probing with sysfs-based enumeration to prevent USB control transfers from stalling audio playback.

Enhancements:

  • Preserve downstream USB device, HID, hub, and network adapter metadata consumers by generating compatible device information from sysfs.

… ioctl audio stutter

Root cause (PMS 381051): On USB hot-plug events, MonitorUsb::monitor()
spawned "hwinfo --usb" which opens every /dev/bus/usb/*/* node and issues
ioctl(USBDEVFS_CONTROL) control transfers to read device descriptors.  On
affected xHCI controllers these control transfers stall isochronous audio
URBs for ~970 ms, exceeding the ~93 ms PulseAudio buffer and causing
audible playback stuttering.

Fix: Replace the external hwinfo process with direct reads of
/sys/bus/usb/devices/ attribute files (idVendor, idProduct, bDeviceClass,
bInterfaceClass, etc.).  Sysfs reads perform no USB I/O whatsoever,
eliminating the control-transfer interference while producing a string in
the same key:value format that EnableUtils::disableOutDevice() and
WakeupUtils::updateWakeupDeviceInfo() already parse.

The new getUsbInfoFromSysfs() function:
- Enumerates device entries (skipping interfaces) under
  /sys/bus/usb/devices/
- Reads standard sysfs USB attributes (idVendor, idProduct, manufacturer,
  product, serial, bcdDevice, bDeviceClass/SubClass/Protocol, busnum,
  devnum, speed)
- Derives hwinfo-compatible "Hardware Class" from bDeviceClass (hub) and
  HID interface class/subclass/protocol (keyboard/mouse)
- Constructs SysFS Device Link and SysFS ID paths from canonical paths
- Detects USB network adapters for Permanent HW Address / Device File
- Builds Module Alias from device attributes
- Emits >10 lines per device block (required by getMapInfo LEAST_NUM=10)
@deepin-ci-robot

Copy link
Copy Markdown

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@deepin-ci-robot

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: GongHeng2017

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@sourcery-ai

sourcery-ai Bot commented Nov 10, 2026

Copy link
Copy Markdown

Reviewer's Guide

Implementation

Replace the hotplug-time hwinfo process with sysfs enumeration, including its helpers and required includes, to avoid USB control transfers while preserving the information consumed downstream.

  • deepin-devicemanager-server/deepin-deviceinfo/src/hotplug/monitorusb.cpp L12-181, L250-255 (+2 small edits)

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@GongHeng2017

Copy link
Copy Markdown
Contributor Author

关闭此 PR:前次修复过于保守(仅修改 monitorusb.cpp 一处 sysfs 替换),未覆盖卡顿核心原因。按负责人纠偏(corr-01a1c449-2)提供的已验证补丁,改由新 PR #971(含 detectthread/monitorusb/threadpool/deviceinfomanager/threadpooltask/mainjob 全链路修改)与 deepin-music 配套 PR #866 共同替代。

Bug: https://pms.uniontech.com/bug-view-381051.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants