From 6e12581989fa49122850d5969d76d5c42b3ed978 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= Date: Sat, 1 Aug 2026 02:35:12 +0200 Subject: [PATCH] Fix rare deadlock on early xenbus device hotplug See patch description for details. --- ...-otherend_id-only-after-it-has-been-.patch | 46 +++++++++++++++++++ ...ore-information-when-device-state-go.patch | 33 +++++++++++++ kernel.spec.in | 2 + 3 files changed, 81 insertions(+) create mode 100644 0001-xen-xenbus-check-otherend_id-only-after-it-has-been-.patch create mode 100644 0001-xen-xenbus-log-more-information-when-device-state-go.patch diff --git a/0001-xen-xenbus-check-otherend_id-only-after-it-has-been-.patch b/0001-xen-xenbus-check-otherend_id-only-after-it-has-been-.patch new file mode 100644 index 00000000..7d176ab3 --- /dev/null +++ b/0001-xen-xenbus-check-otherend_id-only-after-it-has-been-.patch @@ -0,0 +1,46 @@ +From 00fcc430d3b5e9d1e4b4da3e8eccb4fe0eac7876 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= + +Date: Sat, 1 Aug 2026 01:19:18 +0200 +Subject: [PATCH] xen/xenbus: check otherend_id only after it has been + initialized +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When device just got initialized (for example on module load), the +otherend_id field is initialized only after +xenbus_read_otherend_details() gets called. If xenstore watch triggers +xenbus_dev_changed() before that, it might consider still zeroed +otherend_id field (not matching actual xenstore content) as a sign of +device state reset. It can happen because xenstore watch are handled in +another thread (xenwatch), which can run in parallel to the initial +device probe running at module load. In that case, it would call +device_unregister(), which would deadlock against device probe from +module init. + +Fix this by considering dev->otherend_id change only after dev->otherend +is set (which happen after otherend_id is initialized). + +Signed-off-by: Marek Marczykowski-Górecki +--- + drivers/xen/xenbus/xenbus_probe.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c +index a259c8f0fff4..b42d8d2e5a33 100644 +--- a/drivers/xen/xenbus/xenbus_probe.c ++++ b/drivers/xen/xenbus/xenbus_probe.c +@@ -680,7 +680,8 @@ void xenbus_dev_changed(const char *node, struct xen_bus_type *bus) + dev->otherend_id); + + if (state == XenbusStateInitialising && +- (state != dev->state || backend != dev->otherend_id)) { ++ (state != dev->state || ++ (dev->otherend && backend != dev->otherend_id))) { + /* + * State has been reset, assume the old one vanished + * and new one needs to be probed. +-- +2.54.0 + diff --git a/0001-xen-xenbus-log-more-information-when-device-state-go.patch b/0001-xen-xenbus-log-more-information-when-device-state-go.patch new file mode 100644 index 00000000..de1a8ba8 --- /dev/null +++ b/0001-xen-xenbus-log-more-information-when-device-state-go.patch @@ -0,0 +1,33 @@ +From 2ee49295c56339e22ffdd7547a86a0c707cbcf23 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marek=20Marczykowski-G=C3=B3recki?= + +Date: Thu, 30 Jul 2026 16:11:49 +0200 +Subject: [PATCH] xen/xenbus: log more information when device state got reset +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Ease diagnosing what actually changed. + +Signed-off-by: Marek Marczykowski-Górecki +--- + drivers/xen/xenbus/xenbus_probe.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/xen/xenbus/xenbus_probe.c b/drivers/xen/xenbus/xenbus_probe.c +index eb260eceb4d2..a259c8f0fff4 100644 +--- a/drivers/xen/xenbus/xenbus_probe.c ++++ b/drivers/xen/xenbus/xenbus_probe.c +@@ -686,7 +686,8 @@ void xenbus_dev_changed(const char *node, struct xen_bus_type *bus) + * and new one needs to be probed. + */ + dev_warn(&dev->dev, +- "state reset occurred, reconnecting\n"); ++ "state reset occurred (xenstore state %u, local state %u, xenstore backend %u, local backend %u), reconnecting\n", ++ state, dev->state, backend, dev->otherend_id); + dev->vanished = true; + } + if (dev->vanished) { +-- +2.54.0 + diff --git a/kernel.spec.in b/kernel.spec.in index 64c67937..9ab1ccad 100644 --- a/kernel.spec.in +++ b/kernel.spec.in @@ -144,6 +144,8 @@ Patch27: 0001-amdgpu-timeout.patch Patch30: 0004-pvops-respect-removable-xenstore-flag-for-block-devi.patch Patch31: 0001-PCI-add-a-reset-quirk-for-Intel-I219LM-ethernet-adap.patch Patch34: 0001-rust-fixup.patch +Patch35: 0001-xen-xenbus-log-more-information-when-device-state-go.patch +Patch36: 0001-xen-xenbus-check-otherend_id-only-after-it-has-been-.patch # S0ix support: Patch61: xen-events-Add-wakeup-support-to-xen-pirq.patch