From: Niklas Neronin <niklas.neronin@linux.intel.com>
To: mathias.nyman@linux.intel.com
Cc: linux-usb@vger.kernel.org, michal.pecio@gmail.com,
regressions@leemhuis.info,
Niklas Neronin <niklas.neronin@linux.intel.com>,
Harald Judt <h.judt@gmx.at>,
Lovekesh Solanki <lovekeshsolanki00@gmail.com>
Subject: [PATCH v2 1/2] usb: xhci: clear stale bandwidth data after hibernation
Date: Mon, 2 Nov 2026 14:42:27 +0100 [thread overview]
Message-ID: <20261102134228.584032-2-niklas.neronin@linux.intel.com> (raw)
In-Reply-To: <20261102134228.584032-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 reinitialized 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 bandwidth accounting data in xhci_rh_bw_cleanup()
so that resume starts with a clean bandwidth state, and resetting the total
active endpoints count.
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>
---
v2:
* Fix commit message format
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 30ac1bc4559b..0361dfaecdd7 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-11-02 13:42 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-02 13:42 [PATCH v2 0/2] usb: xhci: bandwidth and endpoints accounting fixes Niklas Neronin
2026-11-02 13:42 ` Niklas Neronin [this message]
2026-11-02 13:47 ` [PATCH v2 1/2] usb: xhci: clear stale bandwidth data after hibernation sashiko-bot
2026-11-02 13:42 ` [PATCH v2 2/2] usb: xhci: fix 'num_active_eps' accounting on allocation failure Niklas Neronin
2026-11-02 13:49 ` 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=20261102134228.584032-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 \
--cc=michal.pecio@gmail.com \
--cc=regressions@leemhuis.info \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.