Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

driver core: Avoid deferred probe due to fw_devlink_pause/resume()

With the earlier patch in this series, all devices that deferred probe
due to fw_devlink_pause() will have their probes delayed till the
deferred probe thread is kicked off during late_initcall. This will also
affect all their consumers.

This delayed probing in unnecessary. So this patch just keeps track of
the devices that had their probe deferred due to fw_devlink_pause() and
attempts to probe them once during fw_devlink_resume().

Fixes: 716a7a259690 ("driver core: fw_devlink: Add support for batching fwnode parsing")
Signed-off-by: Saravana Kannan <saravanak@google.com>
Tested-by: Geert Uytterhoeven <geert+renesas@glider.be>
Link: https://lore.kernel.org/r/20200701194259.3337652-4-saravanak@google.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Saravana Kannan and committed by
Greg Kroah-Hartman
2451e746 ec7bd784

+23 -1
+21
drivers/base/core.c
··· 50 50 static LIST_HEAD(deferred_sync); 51 51 static unsigned int defer_sync_state_count = 1; 52 52 static unsigned int defer_fw_devlink_count; 53 + static LIST_HEAD(deferred_fw_devlink); 53 54 static DEFINE_MUTEX(defer_fw_devlink_lock); 54 55 static bool fw_devlink_is_permissive(void); 55 56 ··· 1245 1244 fw_ret = -EAGAIN; 1246 1245 } else { 1247 1246 fw_ret = -ENODEV; 1247 + /* 1248 + * defer_hook is not used to add device to deferred_sync list 1249 + * until device is bound. Since deferred fw devlink also blocks 1250 + * probing, same list hook can be used for deferred_fw_devlink. 1251 + */ 1252 + list_add_tail(&dev->links.defer_hook, &deferred_fw_devlink); 1248 1253 } 1249 1254 1250 1255 if (fw_ret == -ENODEV) ··· 1319 1312 */ 1320 1313 void fw_devlink_resume(void) 1321 1314 { 1315 + struct device *dev, *tmp; 1316 + LIST_HEAD(probe_list); 1317 + 1322 1318 mutex_lock(&defer_fw_devlink_lock); 1323 1319 if (!defer_fw_devlink_count) { 1324 1320 WARN(true, "Unmatched fw_devlink pause/resume!"); ··· 1333 1323 goto out; 1334 1324 1335 1325 device_link_add_missing_supplier_links(); 1326 + list_splice_tail_init(&deferred_fw_devlink, &probe_list); 1336 1327 out: 1337 1328 mutex_unlock(&defer_fw_devlink_lock); 1329 + 1330 + /* 1331 + * bus_probe_device() can cause new devices to get added and they'll 1332 + * try to grab defer_fw_devlink_lock. So, this needs to be done outside 1333 + * the defer_fw_devlink_lock. 1334 + */ 1335 + list_for_each_entry_safe(dev, tmp, &probe_list, links.defer_hook) { 1336 + list_del_init(&dev->links.defer_hook); 1337 + bus_probe_device(dev); 1338 + } 1338 1339 } 1339 1340 /* Device links support end. */ 1340 1341
+2 -1
include/linux/device.h
··· 433 433 * @suppliers: List of links to supplier devices. 434 434 * @consumers: List of links to consumer devices. 435 435 * @needs_suppliers: Hook to global list of devices waiting for suppliers. 436 - * @defer_hook: Hook to global list of devices that have deferred sync_state. 436 + * @defer_hook: Hook to global list of devices that have deferred sync_state or 437 + * deferred fw_devlink. 437 438 * @need_for_probe: If needs_suppliers is on a list, this indicates if the 438 439 * suppliers are needed for probe or not. 439 440 * @status: Driver status information.