Skip to content

fix(hid): widen the Bolt per-slot probe budget for high-latency USB paths - #562

Open
tagawa0525 wants to merge 3 commits into
AprilNEA:masterfrom
tagawa0525:fix/bolt-slot-probe-budget
Open

fix(hid): widen the Bolt per-slot probe budget for high-latency USB paths#562
tagawa0525 wants to merge 3 commits into
AprilNEA:masterfrom
tagawa0525:fix/bolt-slot-probe-budget

Conversation

@tagawa0525

Copy link
Copy Markdown
Contributor

Summary

The per-slot Bolt probe cap (3 s) is sized for direct-radio latency. Behind a KVM's USB emulation a healthy HID++ 2.0 feature walk takes several seconds, so every slot hit the cap on every watcher tick and a newly paired device never acquired model info — it stayed permanently identity-only. This raises BOLT_SLOT_PROBE to 10 s. The cap is a ceiling, not a wait: healthy nodes still settle in a couple of seconds, and the concurrent slot walk plus the 25 s PROBE_BUDGET already cover the rest.

Changes

  • hid: raise BOLT_SLOT_PROBE from 3 s to 10 s and reword the budget rustdoc to match the current concurrent-walk structure.

Testing

  • cargo fmt --all -- --check / cargo clippy --workspace --all-targets -- -D warnings / cargo test --workspace — green on this branch.
  • The failure mode was reproduced on real hardware: a KVM-routed Bolt receiver where the 3 s cap reproducibly starved both slots every tick. The widened cap has not yet been runtime-verified on that same path — to test, pair a device through a KVM-routed receiver and confirm model info and capabilities appear within a few ticks.

…aths

Upstream now walks Bolt slots concurrently behind a sequential register
pass (the structure this commit originally introduced), and has since
raised PROBE_BUDGET to 25 s for the Bluetooth-direct feature walk — wide
enough to cover the arrival drain, the register pass and one full slot
budget, so only the per-slot cap is left to fix here. That cap is still
sized for direct-radio latency: behind a KVM's USB emulation a healthy
feature walk takes several seconds, so every slot kept hitting the 3 s cap
on every tick and a newly paired device never acquired model info. Raise
BOLT_SLOT_PROBE to 10 s; healthy nodes still settle in a couple of seconds
— this is a ceiling, not a wait.

Verified against a KVM-routed receiver where the shorter cap reproducibly
starved both slots.
Copilot AI lite review requested due to automatic review settings August 11, 2026 07:06
@greptile-apps

greptile-apps Bot commented Aug 11, 2026

Copy link
Copy Markdown

Greptile Summary

The PR increases the Bolt per-slot HID++ feature-walk timeout from 3 seconds to 10 seconds to accommodate high-latency USB paths.

  • Updates the timeout documentation to describe the sequential pairing-register pass and concurrent slot probing.
  • Leaves the overall 25-second receiver probe budget unchanged.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

Important Files Changed

Filename Overview
crates/openlogi-hid/src/inventory.rs Widens the Bolt slot probe ceiling and updates its timing rationale; no eligible follow-up defect was established.

Reviews (4): Last reviewed commit: "docs(hid): attribute the KVM slot starva..." | Re-trigger Greptile

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adjusts Bolt receiver probing behavior in openlogi-hid to better tolerate high-latency USB paths (e.g., KVM USB emulation) so paired devices can complete HID++ 2.0 feature discovery and surface full model/capability info.

Changes:

  • Increased the Bolt per-slot HID++ 2.0 feature-walk timeout (BOLT_SLOT_PROBE) from 3s to 10s.
  • Updated the probe budget rustdoc to reflect the current probing structure (including the sequential Bolt register phase + concurrent per-slot walks).
Suppressed comments (2)

crates/openlogi-hid/src/inventory.rs:74

  • This rustdoc says the per-slot cap prevents “pinning its slot future forever”, but the outer node probe is already bounded by PROBE_BUDGET (so it’s not truly forever). Consider rewording to reflect that the cap prevents a single hung slot from stalling the receiver probe until the outer budget elapses.
/// Bounds a single device that stops answering its feature-walk reads (seen on
/// a recent macOS IOHID stack with a new MX Master 4) so it falls back to its
/// cached / identity-only data instead of pinning its slot future forever
/// (#218). Slots walk *concurrently* (mirroring the Unifying path), so this

crates/openlogi-hid/src/inventory.rs:81

  • The comment references an “earlier 1 s cap”, but in this PR the cap is being changed from 3 s → 10 s. To keep the historical note consistent with the actual prior value (and the PR summary), this should likely refer to the earlier 3 s cap.
/// high-latency USB paths (a Bolt receiver behind a KVM's USB emulation) it
/// takes several seconds — the earlier 1 s cap starved every slot there, so a
/// newly paired device could never acquire model info at all. 10 s is generous

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread crates/openlogi-hid/src/inventory.rs Outdated
Comment on lines +46 to +49
/// Slots are probed concurrently on both receiver paths, so a receiver's worst
/// case is the 1.5 s arrival drain plus the sequential register pass plus a
/// single slot's [`BOLT_SLOT_PROBE`] / [`UNIFYING_SLOT_PROBE`] — not their sum
/// — which this stays comfortably above, so awake devices never trip it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in e765148 — the PROBE_BUDGET rustdoc now scopes the sequential pairing-register pass to the Bolt path explicitly (Unifying's pairing-info registers use a different sub-register base and are not polled), and the BOLT_SLOT_PROBE doc names it as Bolt's.

The probe-budget rustdoc described the pairing-register pass as part of
every receiver's worst case, but only the Bolt path performs it —
Unifying's pairing-info registers use a different sub-register base and
are not polled.

Refs: AprilNEA#562 (comment)
@tagawa0525

Copy link
Copy Markdown
Contributor Author

@greptileai review

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.

Suppressed comments (1)

crates/openlogi-hid/src/inventory.rs:82

  • The updated BOLT_SLOT_PROBE rustdoc explains the KVM/high-latency failure mode but attributes it to an “earlier 1 s cap”. In this PR the cap being widened is 3 s → 10 s (per PR description and prior code), so the doc should refer to the previous 3 s cap to avoid confusing readers about what change fixed the issue.
/// (the MX Master 4's 45 features take ~1–1.6 s over Bolt even awake), and on
/// high-latency USB paths (a Bolt receiver behind a KVM's USB emulation) it
/// takes several seconds — the earlier 1 s cap starved every slot there, so a
/// newly paired device could never acquire model info at all. 10 s is generous

The high-latency repro ran against the 3 s cap this PR widens; the 1 s
cap is older history (AprilNEA#218) unrelated to the KVM path.
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