Thread (27 messages) 27 messages, 3 authors, 1d ago
WARM1d

[PATCH net-next 15/17] net: dsa: mv88e6xxx: cancel PTP polling work on .shutdown

From: Luke Howard <hidden>
Date: 2026-07-03 07:47:52
Also in: lkml
Subsystem: marvell 88e6xxx ethernet switch fabric driver, networking drivers, networking [dsa], the rest · Maintainers: Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Vladimir Oltean, Linus Torvalds

DSA core's dsa_switch_shutdown() only closes CPU port conduits and
unlinks DSA uppers; it does not invoke ds->ops->teardown(). On
.shutdown (reboot), the chip's mv88e6xxx_teardown() therefore never
runs, and the PTP overflow / TAI event delayed works are not
cancelled. They continue to fire as the conduit netdev is torn down
by its own driver, racing the teardown and crashing in the RMU
request path when conduit->dev_addr is released.

Factor the work cancellation out of mv88e6xxx_ptp_free() into a new
mv88e6xxx_ptp_shutdown() helper that leaves the PTP clock registered,
and call it from mv88e6xxx_shutdown_common() before
dsa_switch_shutdown(). mv88e6xxx_ptp_free() now calls the helper
itself, so the regular .remove path is unchanged.

Signed-off-by: Luke Howard <redacted>
---
 drivers/net/dsa/mv88e6xxx/chip.c |  6 ++++++
 drivers/net/dsa/mv88e6xxx/ptp.c  | 14 ++++++++++++--
 drivers/net/dsa/mv88e6xxx/ptp.h  |  5 +++++
 3 files changed, 23 insertions(+), 2 deletions(-)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 531a59093ef97..3d92c59de7b5f 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -7543,6 +7543,12 @@ static void mv88e6xxx_shutdown(struct mdio_device *mdiodev)
 	if (!ds)
 		return;
 
+	/* DSA core does not call ->teardown on .shutdown, so stop PTP
+	 * polling here before the conduit goes away. Otherwise the work
+	 * can race teardown and dereference a stale conduit->dev_addr.
+	 */
+	mv88e6xxx_ptp_shutdown(ds->priv);
+
 	dsa_switch_shutdown(ds);
 
 	dev_set_drvdata(&mdiodev->dev, NULL);
diff --git a/drivers/net/dsa/mv88e6xxx/ptp.c b/drivers/net/dsa/mv88e6xxx/ptp.c
index f7603573d3a98..f6ce3232d10ff 100644
--- a/drivers/net/dsa/mv88e6xxx/ptp.c
+++ b/drivers/net/dsa/mv88e6xxx/ptp.c
@@ -551,14 +551,24 @@ int mv88e6xxx_ptp_setup(struct mv88e6xxx_chip *chip)
 	return 0;
 }
 
-/* This must never be called holding the register lock */
-void mv88e6xxx_ptp_free(struct mv88e6xxx_chip *chip)
+/* Cancel any pending PTP polling work. Safe to call from .shutdown
+ * paths where the PTP clock itself stays registered.
+ * This must never be called holding the register lock.
+ */
+void mv88e6xxx_ptp_shutdown(struct mv88e6xxx_chip *chip)
 {
 	if (chip->ptp_clock) {
 		cancel_delayed_work_sync(&chip->overflow_work);
 		if (chip->info->ops->ptp_ops->event_work)
 			cancel_delayed_work_sync(&chip->tai_event_work);
+	}
+}
 
+/* This must never be called holding the register lock */
+void mv88e6xxx_ptp_free(struct mv88e6xxx_chip *chip)
+{
+	if (chip->ptp_clock) {
+		mv88e6xxx_ptp_shutdown(chip);
 		ptp_clock_unregister(chip->ptp_clock);
 		chip->ptp_clock = NULL;
 	}
diff --git a/drivers/net/dsa/mv88e6xxx/ptp.h b/drivers/net/dsa/mv88e6xxx/ptp.h
index 95bdddb0bf39f..90031b05d2514 100644
--- a/drivers/net/dsa/mv88e6xxx/ptp.h
+++ b/drivers/net/dsa/mv88e6xxx/ptp.h
@@ -68,6 +68,7 @@
 
 int mv88e6xxx_ptp_setup(struct mv88e6xxx_chip *chip);
 void mv88e6xxx_ptp_free(struct mv88e6xxx_chip *chip);
+void mv88e6xxx_ptp_shutdown(struct mv88e6xxx_chip *chip);
 
 #define ptp_to_chip(ptp) container_of(ptp, struct mv88e6xxx_chip,	\
 				      ptp_clock_info)
@@ -87,6 +88,10 @@ static inline void mv88e6xxx_ptp_free(struct mv88e6xxx_chip *chip)
 {
 }
 
+static inline void mv88e6xxx_ptp_shutdown(struct mv88e6xxx_chip *chip)
+{
+}
+
 static const struct mv88e6xxx_ptp_ops mv88e6165_ptp_ops = {};
 static const struct mv88e6xxx_ptp_ops mv88e6352_ptp_ops = {};
 static const struct mv88e6xxx_ptp_ops mv88e6390_ptp_ops = {};
-- 
2.43.0
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help