Repository navigation
test(libSceUsbd): race the cancel on an interrupt endpoint the host can read - #12448
Conversation
…an read The device test raced sceUsbdCancelTransfer on the first interrupt IN endpoint of the device. On Windows the first one can belong to a mouse or keyboard collection, which the system opens exclusively, so libusb's HID backend cannot read it and the submission failed, reported as a failed cancel race. The test now tries each interrupt IN endpoint, requires a refusal to be the host's I/O error with nothing in flight, and races on the first one the host accepts, with a buffer sized from that endpoint.
MarcZX10
left a comment
There was a problem hiding this comment.
I reviewed exact head 692cc3e025 and syntax-compiled GuestUsbd.cpp with GCC 12/C++20 (-fsyntax-only): it passes. The endpoint buffer now uses the decoded payload size and high-bandwidth multiplier, and the candidate loop verifies refused submits are not left in flight before racing cancellation on an accepted endpoint. The author reports repeatable red/green runs on the affected Logitech receiver and two controls. I cannot reproduce the device-specific Windows behavior without those USB devices; hosted convention/eligibility/intake checks were queued at my last refresh. I found no concrete defect in the changed test.
MarcZX10
left a comment
There was a problem hiding this comment.
Approved at exact head 692cc3e025. I reviewed the endpoint scan and cancellation flow and syntax-compiled the exact GuestUsbd.cpp test with GCC 12/C++20. Refused submissions are required to return the reported host I/O error and leave no transfer in flight; the accepted endpoint is canceled and its callback awaited before the buffer is reused, after which the existing 300-round race runs on that endpoint. The PR reports repeated device runs on the affected Logitech receiver and two controls; I could not reproduce the USB/HID behavior without those devices. Hosted Windows, conventions, eligibility, intake, and labels now pass.
|
Some comparisons could not be completed because a pull request conflicts with the base branch. Review these shared files manually before concluding that there is no overlap.
|
|
Checked the endpoint scan (refused submits must return 0x80240001 and leave nothing in flight, cancel on the first accepted endpoint, then the 300-round race), the buffer sizing from |
What
On
main, the libSceUsbd device test (guest_usbd_tests device) fails withthe cancel race failedon a Logitech LIGHTSPEED receiver (046D:C54D), in 10 runs out of 10. The cancel is not what fails. The race's firstsceUsbdSubmitTransferreturns0x80240001, and the test reports every failed submission as a failed race.0x81, on interface 0, a mouse.ReadFileis refused, and it returnsLIBUSB_ERROR_IO. WithLIBUSB_DEBUG=4the log shows[hid_open] could not open HID device in R/W mode (keyboard or mouse?) - trying without, then[hid_submit_bulk_transfer] matched endpoint 81 with interface 0andHID transfer failed: [5] Access is denied.1462:7D75and31E3:1402pass because their first interrupt IN endpoint is on a vendor-defined collection.The library answers correctly: the refused submission returns the host's I/O error and leaves nothing in flight. So the test changes, and
Export.cppdoes not:0x80240001, and the transfer must not be left in flight (sceUsbdCancelTransferreturns0x80240005).0x80240005, and the callback must report the transfer completed or cancelled. The 300-round race then runs on that endpoint, unchanged.wMaxPacketSize, with the high-bandwidth multiplier. It was a 64-byte array, while the requested length was the rawwMaxPacketSize, which can be larger for a high-speed endpoint.A debt entry records the Windows limit a title would meet: a transfer on a mouse or keyboard collection fails with
0x80240001. What the console answers for a keyboard or mouse its own kernel drives is unknown.There is no deterministic regression test. The refusal comes from the host's HID stack, and the no-device path cannot produce it; it needs a device whose first interrupt IN endpoint is a mouse or keyboard collection, such as this receiver.
Tested
Locally: Windows 11 Pro 10.0.26200, WinLibs GCC 15.2.0 r7 (x86_64-ucrt-posix-seh), Release,
BUILD_TESTING=ON, onmainf3eb573e6f. The device runs below were local only; Linux ran only on GitHub's runners.guest_usbd_tests devicewithAPS5_USBD_DEVICEset to each device attached to this machine, withmain's test and with this branch's:main046D:C54DLogitech LIGHTSPEED receiverUSB Receiverthe cancel race failed0x82, after0x81was refused1462:7D75MSI Mystic Light controllerMYSTIC LIGHT0x8131E3:1402Wooting 80HEWooting 80HE0x81guest_usbd(no device): passes 10 runs out of 10 (ctest --repeat until-fail:10).public_headersandpublic_headers_compile_*: 65/65 pass.main04fefebe90and a fork-only Linux workflow commit: Windows through this repository'sbuild.yml(full), 2837 of 2837 tests pass (run); Linux, Ubuntu 24.04 with lavapipe, 2721 tests and no failure (run). Those runners have no USB device, so only the no-deviceguest_usbdcase ran there, and it passed on both.python tools/check_conventions.py --base origin/mainwith this title and body: all checks pass.python tools/pr_overlap.py --branch test/usbd-cancel-race-readable-endpoint: no conflicting lines.git merge-treeof this branch and feat(libSceUsbd): handle events with FreeBSD libusb's event lock and handler thread #9339's head6c208252d7is clean. fix(libSceUsbd): retain devices during active USB operations #9803 already conflicts withmainin the same three files, so it could not be compared.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed under Silent stubs in their library's technical debt file.mdfiles or images added to the repository (attach them to this PR)