From: Niklas Neronin <niklas.neronin@linux.intel.com>
To: mathias.nyman@linux.intel.com
Cc: linux-usb@vger.kernel.org,
Niklas Neronin <niklas.neronin@linux.intel.com>,
Harald Judt <h.judt@gmx.at>,
Lovekesh Solanki <lovekeshsolanki00@gmail.com>
Subject: [PATCH 1/5] usb: xhci: clear stale bandwidth data after hibernation
Date: Tue, 6 Oct 2026 17:24:23 +0200 [thread overview]
Message-ID: <20261006152427.3735383-2-niklas.neronin@linux.intel.com> (raw)
In-Reply-To: <20261006152427.3735383-1-niklas.neronin@linux.intel.com>
Controllers using software managed bandwidth accounting maintain
periodic endpoint bandwidth information in struct 'xhci_interval_bw_table'.
Each root hub port owns a bandwidth table and a list of TT bandwidth
domains, where each TT has its own bandwidth table. Virtual devices
reference the bandwidth table of their current bandwidth domain through
'bw_table' or 'tt_info'.
Historically, resume from S4 re-allocated the entire xHCI driver state,
which implicitly cleared all bandwidth accounting data. After the
hibernation resume path was optimized to preserve parts of the driver
state, virtual devices and TT bandwidth information were freed and
recreated, but the root hub bandwidth tables were left intact.
As a result, stale bandwidth accounting data could remain in the root
hub bandwidth tables across hibernation resume, leading to incorrect
bandwidth calculations after devices were rediscovered.
Fix this by resetting all software bandwidth accounting state in
xhci_rh_bw_cleanup() so that resume starts with a clean bandwidth state.
This includes 'xhci->num_active_eps', which must remain consistent with
the cleared bandwidth tables.
Fixes: <2a70e5dc0301> ("usb: xhci: optimize resuming from S4 (suspend-to-disk)")
Reported-by: Harald Judt <h.judt@gmx.at>
Link: https://bugzilla.kernel.org/show_bug.cgi?id=222071
Suggested-by: Lovekesh Solanki <lovekeshsolanki00@gmail.com>
Tested-by: Harald Judt <h.judt@gmx.at>
Signed-off-by: Niklas Neronin <niklas.neronin@linux.intel.com>
---
drivers/usb/host/xhci-mem.c | 16 +++++++++++++++-
drivers/usb/host/xhci.c | 1 +
2 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index af8d4b74c4ba..75577f441cdd 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -1903,24 +1903,38 @@ EXPORT_SYMBOL_GPL(xhci_remove_secondary_interrupter);
void xhci_rh_bw_cleanup(struct xhci_hcd *xhci)
{
struct xhci_root_port_bw_info *rh_bw;
+ struct xhci_interval_bw_table *bw_table;
+ struct xhci_interval_bw *interval_bw;
struct xhci_tt_bw_info *tt_info, *tt_next;
struct list_head *eps, *ep, *ep_next;
for (int i = 0; i < xhci->max_ports; i++) {
rh_bw = &xhci->rh_bw[i];
+ rh_bw->num_active_tts = 0;
/* Clear and free all TT bandwidth entries */
list_for_each_entry_safe(tt_info, tt_next, &rh_bw->tts, tt_list) {
list_del(&tt_info->tt_list);
kfree(tt_info);
}
+ bw_table = &rh_bw->bw_table;
+ bw_table->interval0_esit_payload = 0;
+ bw_table->bw_used = 0;
+ bw_table->ss_bw_in = 0;
+ bw_table->ss_bw_out = 0;
+
/* Clear per-interval endpoint lists */
for (int j = 0; j < XHCI_MAX_INTERVAL; j++) {
- eps = &rh_bw->bw_table.interval_bw[j].endpoints;
+ interval_bw = &bw_table->interval_bw[j];
+ eps = &interval_bw->endpoints;
+ interval_bw->num_packets = 0;
list_for_each_safe(ep, ep_next, eps)
list_del_init(ep);
+ interval_bw->overhead[LS_OVERHEAD_TYPE] = 0;
+ interval_bw->overhead[FS_OVERHEAD_TYPE] = 0;
+ interval_bw->overhead[HS_OVERHEAD_TYPE] = 0;
}
}
}
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index a9e47e178c28..4708fabba84a 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -1185,6 +1185,7 @@ int xhci_resume(struct xhci_hcd *xhci, bool power_lost, bool is_auto_resume)
for (int i = xhci->max_slots; i > 0; i--)
xhci_free_virt_devices_depth_first(xhci, i);
+ xhci->num_active_eps = 0;
xhci_rh_bw_cleanup(xhci);
xhci->cmd_ring_reserved_trbs = 0;
--
2.50.1
next prev parent reply other threads:[~2026-10-06 15:24 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-06 15:24 [PATCH 0/5] usb: xhci: bandwidth accounting fixes and cleanup Niklas Neronin
2026-10-06 15:24 ` Niklas Neronin [this message]
2026-10-06 16:12 ` [PATCH 1/5] usb: xhci: clear stale bandwidth data after hibernation Michal Pecio
2026-10-06 16:22 ` sashiko-bot
2026-10-06 15:24 ` [PATCH 2/5] usb: xhci: correct num_active_eps accounting on allocation failure Niklas Neronin
2026-10-06 16:29 ` sashiko-bot
2026-10-06 16:33 ` Michal Pecio
2026-10-06 21:02 ` Michal Pecio
2026-10-07 9:28 ` Neronin, Niklas
2026-10-06 15:24 ` [PATCH 3/5] usb: xhci: remove redundant TT active EP update from xhci_free_virt_device() Niklas Neronin
2026-10-06 16:41 ` sashiko-bot
2026-10-06 15:24 ` [PATCH 4/5] usb: xhci: correct variable size conversion Niklas Neronin
2026-10-06 16:46 ` sashiko-bot
2026-10-06 15:24 ` [PATCH 5/5] usb: xhci: remove unused structs Niklas Neronin
2026-10-06 16:47 ` sashiko-bot
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261006152427.3735383-2-niklas.neronin@linux.intel.com \
--to=niklas.neronin@linux.intel.com \
--cc=h.judt@gmx.at \
--cc=linux-usb@vger.kernel.org \
--cc=lovekeshsolanki00@gmail.com \
--cc=mathias.nyman@linux.intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox