Skip to content

Commit 23f0dac

Browse files
committed
Merge tag 'driver-core-5.7-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core
Pull driver core fixes from Greg KH: "So, turns out the kobject fix didn't quite work, so here are four patches that in the end, result in just two driver core fixes for reported issues that no one has had problems with. The kobject patch that was originally in here has now been reverted, as Guenter reported boot problems with it on some of his systems" * tag 'driver-core-5.7-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core: Revert "kobject: Make sure the parent does not get released before its children" kobject: Make sure the parent does not get released before its children driver core: Fix handling of SYNC_STATE_ONLY + STATELESS device links driver core: Fix SYNC_STATE_ONLY device link implementation
2 parents 0e36fd4 + e6764aa commit 23f0dac

File tree

1 file changed

+37
-18
lines changed

1 file changed

+37
-18
lines changed

drivers/base/core.c

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,7 @@ struct device_link *device_link_add(struct device *consumer,
365365
link->flags |= DL_FLAG_STATELESS;
366366
goto reorder;
367367
} else {
368+
link->flags |= DL_FLAG_STATELESS;
368369
goto out;
369370
}
370371
}
@@ -433,12 +434,16 @@ struct device_link *device_link_add(struct device *consumer,
433434
flags & DL_FLAG_PM_RUNTIME)
434435
pm_runtime_resume(supplier);
435436

437+
list_add_tail_rcu(&link->s_node, &supplier->links.consumers);
438+
list_add_tail_rcu(&link->c_node, &consumer->links.suppliers);
439+
436440
if (flags & DL_FLAG_SYNC_STATE_ONLY) {
437441
dev_dbg(consumer,
438442
"Linked as a sync state only consumer to %s\n",
439443
dev_name(supplier));
440444
goto out;
441445
}
446+
442447
reorder:
443448
/*
444449
* Move the consumer and all of the devices depending on it to the end
@@ -449,12 +454,9 @@ struct device_link *device_link_add(struct device *consumer,
449454
*/
450455
device_reorder_to_tail(consumer, NULL);
451456

452-
list_add_tail_rcu(&link->s_node, &supplier->links.consumers);
453-
list_add_tail_rcu(&link->c_node, &consumer->links.suppliers);
454-
455457
dev_dbg(consumer, "Linked as a consumer to %s\n", dev_name(supplier));
456458

457-
out:
459+
out:
458460
device_pm_unlock();
459461
device_links_write_unlock();
460462

@@ -829,6 +831,13 @@ static void __device_links_supplier_defer_sync(struct device *sup)
829831
list_add_tail(&sup->links.defer_sync, &deferred_sync);
830832
}
831833

834+
static void device_link_drop_managed(struct device_link *link)
835+
{
836+
link->flags &= ~DL_FLAG_MANAGED;
837+
WRITE_ONCE(link->status, DL_STATE_NONE);
838+
kref_put(&link->kref, __device_link_del);
839+
}
840+
832841
/**
833842
* device_links_driver_bound - Update device links after probing its driver.
834843
* @dev: Device to update the links for.
@@ -842,7 +851,7 @@ static void __device_links_supplier_defer_sync(struct device *sup)
842851
*/
843852
void device_links_driver_bound(struct device *dev)
844853
{
845-
struct device_link *link;
854+
struct device_link *link, *ln;
846855
LIST_HEAD(sync_list);
847856

848857
/*
@@ -882,18 +891,35 @@ void device_links_driver_bound(struct device *dev)
882891
else
883892
__device_links_queue_sync_state(dev, &sync_list);
884893

885-
list_for_each_entry(link, &dev->links.suppliers, c_node) {
894+
list_for_each_entry_safe(link, ln, &dev->links.suppliers, c_node) {
895+
struct device *supplier;
896+
886897
if (!(link->flags & DL_FLAG_MANAGED))
887898
continue;
888899

889-
WARN_ON(link->status != DL_STATE_CONSUMER_PROBE);
890-
WRITE_ONCE(link->status, DL_STATE_ACTIVE);
900+
supplier = link->supplier;
901+
if (link->flags & DL_FLAG_SYNC_STATE_ONLY) {
902+
/*
903+
* When DL_FLAG_SYNC_STATE_ONLY is set, it means no
904+
* other DL_MANAGED_LINK_FLAGS have been set. So, it's
905+
* save to drop the managed link completely.
906+
*/
907+
device_link_drop_managed(link);
908+
} else {
909+
WARN_ON(link->status != DL_STATE_CONSUMER_PROBE);
910+
WRITE_ONCE(link->status, DL_STATE_ACTIVE);
911+
}
891912

913+
/*
914+
* This needs to be done even for the deleted
915+
* DL_FLAG_SYNC_STATE_ONLY device link in case it was the last
916+
* device link that was preventing the supplier from getting a
917+
* sync_state() call.
918+
*/
892919
if (defer_sync_state_count)
893-
__device_links_supplier_defer_sync(link->supplier);
920+
__device_links_supplier_defer_sync(supplier);
894921
else
895-
__device_links_queue_sync_state(link->supplier,
896-
&sync_list);
922+
__device_links_queue_sync_state(supplier, &sync_list);
897923
}
898924

899925
dev->links.status = DL_DEV_DRIVER_BOUND;
@@ -903,13 +929,6 @@ void device_links_driver_bound(struct device *dev)
903929
device_links_flush_sync_list(&sync_list, dev);
904930
}
905931

906-
static void device_link_drop_managed(struct device_link *link)
907-
{
908-
link->flags &= ~DL_FLAG_MANAGED;
909-
WRITE_ONCE(link->status, DL_STATE_NONE);
910-
kref_put(&link->kref, __device_link_del);
911-
}
912-
913932
/**
914933
* __device_links_no_driver - Update links of a device without a driver.
915934
* @dev: Device without a drvier.

0 commit comments

Comments
 (0)