All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] RFC: move global bus add lock to per-controller lock
@ 2021-05-14 18:17 Ben Dooks
  0 siblings, 0 replies; only message in thread
From: Ben Dooks @ 2021-05-14 18:17 UTC (permalink / raw)
  To: linux-spi; +Cc: Ben Dooks

When trying to use the spi-mux code the system deadlocked with the
spi_add_lock being held by a parent of the new devices being created
by the spi-mux. This ended up with a hung task and no devices being
added.

To try and stop this, I think it is possible (but not certain) to
put a lock per-controller to stop new additions when devices are
being added to that controller. The lock will also be held when
the controller is being removed.

Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
---
 drivers/spi/spi.c       | 14 ++++----------
 include/linux/spi/spi.h |  2 ++
 2 files changed, 6 insertions(+), 10 deletions(-)

diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index ba425b9c7700..a111868df24b 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -484,12 +484,6 @@ static LIST_HEAD(spi_controller_list);
  */
 static DEFINE_MUTEX(board_lock);
 
-/*
- * Prevents addition of devices with same chip select and
- * addition of devices below an unregistering controller.
- */
-static DEFINE_MUTEX(spi_add_lock);
-
 /**
  * spi_alloc_device - Allocate a new SPI device
  * @ctlr: Controller to which device is connected
@@ -587,7 +581,7 @@ int spi_add_device(struct spi_device *spi)
 	 * chipselect **BEFORE** we call setup(), else we'll trash
 	 * its configuration.  Lock against concurrent add() calls.
 	 */
-	mutex_lock(&spi_add_lock);
+	mutex_lock(&ctlr->bus_add_mutex);
 
 	status = bus_for_each_dev(&spi_bus_type, NULL, spi, spi_dev_check);
 	if (status) {
@@ -629,7 +623,7 @@ int spi_add_device(struct spi_device *spi)
 		dev_dbg(dev, "registered child %s\n", dev_name(&spi->dev));
 
 done:
-	mutex_unlock(&spi_add_lock);
+	mutex_unlock(&ctlr->bus_add_mutex);
 	return status;
 }
 EXPORT_SYMBOL_GPL(spi_add_device);
@@ -2850,7 +2844,7 @@ void spi_unregister_controller(struct spi_controller *ctlr)
 
 	/* Prevent addition of new devices, unregister existing ones */
 	if (IS_ENABLED(CONFIG_SPI_DYNAMIC))
-		mutex_lock(&spi_add_lock);
+		mutex_lock(&ctlr->bus_add_mutex);
 
 	device_for_each_child(&ctlr->dev, NULL, __unregister);
 
@@ -2881,7 +2875,7 @@ void spi_unregister_controller(struct spi_controller *ctlr)
 	mutex_unlock(&board_lock);
 
 	if (IS_ENABLED(CONFIG_SPI_DYNAMIC))
-		mutex_unlock(&spi_add_lock);
+		mutex_unlock(&ctlr->bus_add_mutex);
 }
 EXPORT_SYMBOL_GPL(spi_unregister_controller);
 
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index 360a3bc767ca..8b6940d77c99 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -345,6 +345,7 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
  * @bus_lock_spinlock: spinlock for SPI bus locking
  * @bus_lock_mutex: mutex for exclusion of multiple callers
  * @bus_lock_flag: indicates that the SPI bus is locked for exclusive use
+ * @bus_add_mutex: lock to stop mulitple devices being added
  * @setup: updates the device mode and clocking records used by a
  *	device's SPI controller; protocol code may call this.  This
  *	must fail if an unrecognized or unsupported mode is requested.
@@ -528,6 +529,7 @@ struct spi_controller {
 	/* lock and mutex for SPI bus locking */
 	spinlock_t		bus_lock_spinlock;
 	struct mutex		bus_lock_mutex;
+	struct mutex		bus_add_mutex;
 
 	/* flag indicating that the SPI bus is locked for exclusive use */
 	bool			bus_lock_flag;
-- 
2.30.2


^ permalink raw reply related	[flat|nested] only message in thread

only message in thread, other threads:[~2021-05-14 18:41 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-05-14 18:17 [PATCH] RFC: move global bus add lock to per-controller lock Ben Dooks

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.