aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSaravana Kannan <saravanak@google.com>2019-07-31 18:17:15 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-08-01 10:04:13 -0400
commit134b23eec9e3a3c795a6ceb0efe2fa63e87983b2 (patch)
treeb6e05eec658629729fcb33cbae0f0e84a426ac2d
parent5302dd7dd0b6d04c63cdce51d1e9fda9ef0be886 (diff)
driver core: Add edit_links() callback for drivers
The driver core/bus adding supplier-consumer dependencies by default enables functional dependencies to be tracked correctly even when the consumer devices haven't had their drivers registered or loaded (if they are modules). However, when the bus incorrectly adds dependencies that it shouldn't have added, the devices might never probe. For example, if device-C is a consumer of device-S and they have phandles to each other in DT, the following could happen: 1. Device-S get added first. 2. The bus add_links() callback will (incorrectly) try to link it as a consumer of device-C. 3. Since device-C isn't present, device-S will be put in "waiting-for-supplier" list. 4. Device-C gets added next. 5. All devices in "waiting-for-supplier" list are retried for linking. 6. Device-S gets linked as consumer to Device-C. 7. The bus add_links() callback will (correctly) try to link it as a consumer of device-S. 8. This isn't allowed because it would create a cyclic device links. Neither devices will get probed since the supplier is marked as dependent on the consumer. And the consumer will never probe because the consumer can't get resources from the supplier. Without this patch, things stay in this broken state. However, with this patch, the execution will continue like this: 9. Device-C's driver is loaded. 10. Device-C's driver removes Device-S as a consumer of Device-C. 11. Device-C's driver adds Device-C as a consumer of Device-S. 12. Device-S probes. 14. Device-C probes. kbuild test robot reported missing documentation for device.has_edit_links Reported-by: kbuild test robot <lkp@intel.com> Signed-off-by: Saravana Kannan <saravanak@google.com> Link: https://lore.kernel.org/r/20190731221721.187713-3-saravanak@google.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/base/core.c24
-rw-r--r--drivers/base/dd.c29
-rw-r--r--include/linux/device.h20
3 files changed, 71 insertions, 2 deletions
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 18e04ca1de13..feec8dee1e91 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -440,6 +440,19 @@ static void device_link_wait_for_supplier(struct device *consumer)
440} 440}
441 441
442/** 442/**
443 * device_link_remove_from_wfs - Unmark device as waiting for supplier
444 * @consumer: Consumer device
445 *
446 * Unmark the consumer device as waiting for suppliers to become available.
447 */
448void device_link_remove_from_wfs(struct device *consumer)
449{
450 mutex_lock(&wfs_lock);
451 list_del_init(&consumer->links.needs_suppliers);
452 mutex_unlock(&wfs_lock);
453}
454
455/**
443 * device_link_check_waiting_consumers - Try to unmark waiting consumers 456 * device_link_check_waiting_consumers - Try to unmark waiting consumers
444 * 457 *
445 * Loops through all consumers waiting on suppliers and tries to add all their 458 * Loops through all consumers waiting on suppliers and tries to add all their
@@ -456,12 +469,19 @@ static void device_link_wait_for_supplier(struct device *consumer)
456static void device_link_check_waiting_consumers(void) 469static void device_link_check_waiting_consumers(void)
457{ 470{
458 struct device *dev, *tmp; 471 struct device *dev, *tmp;
472 int ret;
459 473
460 mutex_lock(&wfs_lock); 474 mutex_lock(&wfs_lock);
461 list_for_each_entry_safe(dev, tmp, &wait_for_suppliers, 475 list_for_each_entry_safe(dev, tmp, &wait_for_suppliers,
462 links.needs_suppliers) 476 links.needs_suppliers) {
463 if (!dev->bus->add_links(dev)) 477 ret = 0;
478 if (dev->has_edit_links)
479 ret = driver_edit_links(dev);
480 else if (dev->bus->add_links)
481 ret = dev->bus->add_links(dev);
482 if (!ret)
464 list_del_init(&dev->links.needs_suppliers); 483 list_del_init(&dev->links.needs_suppliers);
484 }
465 mutex_unlock(&wfs_lock); 485 mutex_unlock(&wfs_lock);
466} 486}
467 487
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 994a90747420..5e7041ede0d7 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -698,6 +698,12 @@ int driver_probe_device(struct device_driver *drv, struct device *dev)
698 pr_debug("bus: '%s': %s: matched device %s with driver %s\n", 698 pr_debug("bus: '%s': %s: matched device %s with driver %s\n",
699 drv->bus->name, __func__, dev_name(dev), drv->name); 699 drv->bus->name, __func__, dev_name(dev), drv->name);
700 700
701 if (drv->edit_links) {
702 if (drv->edit_links(dev))
703 dev->has_edit_links = true;
704 else
705 device_link_remove_from_wfs(dev);
706 }
701 pm_runtime_get_suppliers(dev); 707 pm_runtime_get_suppliers(dev);
702 if (dev->parent) 708 if (dev->parent)
703 pm_runtime_get_sync(dev->parent); 709 pm_runtime_get_sync(dev->parent);
@@ -786,6 +792,29 @@ struct device_attach_data {
786 bool have_async; 792 bool have_async;
787}; 793};
788 794
795static int __driver_edit_links(struct device_driver *drv, void *data)
796{
797 struct device *dev = data;
798
799 if (!drv->edit_links)
800 return 0;
801
802 if (driver_match_device(drv, dev) <= 0)
803 return 0;
804
805 return drv->edit_links(dev);
806}
807
808int driver_edit_links(struct device *dev)
809{
810 int ret;
811
812 device_lock(dev);
813 ret = bus_for_each_drv(dev->bus, NULL, dev, __driver_edit_links);
814 device_unlock(dev);
815 return ret;
816}
817
789static int __device_attach_driver(struct device_driver *drv, void *_data) 818static int __device_attach_driver(struct device_driver *drv, void *_data)
790{ 819{
791 struct device_attach_data *data = _data; 820 struct device_attach_data *data = _data;
diff --git a/include/linux/device.h b/include/linux/device.h
index 1e05911325f0..d3991810f39d 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -349,6 +349,20 @@ enum probe_type {
349 * @probe_type: Type of the probe (synchronous or asynchronous) to use. 349 * @probe_type: Type of the probe (synchronous or asynchronous) to use.
350 * @of_match_table: The open firmware table. 350 * @of_match_table: The open firmware table.
351 * @acpi_match_table: The ACPI match table. 351 * @acpi_match_table: The ACPI match table.
352 * @edit_links: Called to allow a matched driver to edit the device links the
353 * bus might have added incorrectly. This will be useful to handle
354 * cases where the bus incorrectly adds functional dependencies
355 * that aren't true or tries to create cyclic dependencies. But
356 * doesn't correctly handle functional dependencies that are
357 * missed by the bus as the supplier's sync_state might get to
358 * execute before the driver for a missing consumer is loaded and
359 * gets to edit the device links for the consumer.
360 *
361 * This function might be called multiple times after a new device
362 * is added. The function is expected to create all the device
363 * links for the new device and return 0 if it was completed
364 * successfully or return an error if it needs to be reattempted
365 * in the future.
352 * @probe: Called to query the existence of a specific device, 366 * @probe: Called to query the existence of a specific device,
353 * whether this driver can work with it, and bind the driver 367 * whether this driver can work with it, and bind the driver
354 * to a specific device. 368 * to a specific device.
@@ -388,6 +402,7 @@ struct device_driver {
388 const struct of_device_id *of_match_table; 402 const struct of_device_id *of_match_table;
389 const struct acpi_device_id *acpi_match_table; 403 const struct acpi_device_id *acpi_match_table;
390 404
405 int (*edit_links)(struct device *dev);
391 int (*probe) (struct device *dev); 406 int (*probe) (struct device *dev);
392 int (*remove) (struct device *dev); 407 int (*remove) (struct device *dev);
393 void (*shutdown) (struct device *dev); 408 void (*shutdown) (struct device *dev);
@@ -1220,6 +1235,8 @@ struct dev_links_info {
1220 * @offline: Set after successful invocation of bus type's .offline(). 1235 * @offline: Set after successful invocation of bus type's .offline().
1221 * @of_node_reused: Set if the device-tree node is shared with an ancestor 1236 * @of_node_reused: Set if the device-tree node is shared with an ancestor
1222 * device. 1237 * device.
1238 * @has_edit_links: This device has a driver than is capable of
1239 * editing the device links created by driver core.
1223 * @dma_coherent: this particular device is dma coherent, even if the 1240 * @dma_coherent: this particular device is dma coherent, even if the
1224 * architecture supports non-coherent devices. 1241 * architecture supports non-coherent devices.
1225 * 1242 *
@@ -1313,6 +1330,7 @@ struct device {
1313 bool offline_disabled:1; 1330 bool offline_disabled:1;
1314 bool offline:1; 1331 bool offline:1;
1315 bool of_node_reused:1; 1332 bool of_node_reused:1;
1333 bool has_edit_links:1;
1316#if defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE) || \ 1334#if defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_DEVICE) || \
1317 defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU) || \ 1335 defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU) || \
1318 defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU_ALL) 1336 defined(CONFIG_ARCH_HAS_SYNC_DMA_FOR_CPU_ALL)
@@ -1564,6 +1582,7 @@ extern int __must_check device_attach(struct device *dev);
1564extern int __must_check driver_attach(struct device_driver *drv); 1582extern int __must_check driver_attach(struct device_driver *drv);
1565extern void device_initial_probe(struct device *dev); 1583extern void device_initial_probe(struct device *dev);
1566extern int __must_check device_reprobe(struct device *dev); 1584extern int __must_check device_reprobe(struct device *dev);
1585extern int driver_edit_links(struct device *dev);
1567 1586
1568extern bool device_is_bound(struct device *dev); 1587extern bool device_is_bound(struct device *dev);
1569 1588
@@ -1654,6 +1673,7 @@ struct device_link *device_link_add(struct device *consumer,
1654 struct device *supplier, u32 flags); 1673 struct device *supplier, u32 flags);
1655void device_link_del(struct device_link *link); 1674void device_link_del(struct device_link *link);
1656void device_link_remove(void *consumer, struct device *supplier); 1675void device_link_remove(void *consumer, struct device *supplier);
1676void device_link_remove_from_wfs(struct device *consumer);
1657 1677
1658#ifndef dev_fmt 1678#ifndef dev_fmt
1659#define dev_fmt(fmt) fmt 1679#define dev_fmt(fmt) fmt