When SYNC_STATE_ONLY support was added in commit 05ef983e0d65 ("driver core: Add device link support for SYNC_STATE_ONLY flag"), device_link_add() incorrectly skipped adding the new SYNC_STATE_ONLY device link to the supplier's and consumer's "device link" list. So the "device link" is lost forever from driver core if the caller didn't keep track of it (typically isn't expected to). If the same SYNC_STATE_ONLY device link is created again using device_link_add(), instead of returning the pointer to the previously created device link, a new device link is created and returned. This can cause memory leaks in conjunction with fw_devlinks. Cc: stable@xxxxxxxxxxxxxxx Fixes: 05ef983e0d65 ("driver core: Add device link support for SYNC_STATE_ONLY flag") Signed-off-by: Saravana Kannan <saravanak@xxxxxxxxxx> --- drivers/base/core.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/base/core.c b/drivers/base/core.c index 84c569726d75..d36e9289b2df 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -436,12 +436,16 @@ struct device_link *device_link_add(struct device *consumer, flags & DL_FLAG_PM_RUNTIME) pm_runtime_resume(supplier); + list_add_tail_rcu(&link->s_node, &supplier->links.consumers); + list_add_tail_rcu(&link->c_node, &consumer->links.suppliers); + if (flags & DL_FLAG_SYNC_STATE_ONLY) { dev_dbg(consumer, "Linked as a sync state only consumer to %s\n", dev_name(supplier)); goto out; } + reorder: /* * Move the consumer and all of the devices depending on it to the end @@ -452,12 +456,9 @@ struct device_link *device_link_add(struct device *consumer, */ device_reorder_to_tail(consumer, NULL); - list_add_tail_rcu(&link->s_node, &supplier->links.consumers); - list_add_tail_rcu(&link->c_node, &consumer->links.suppliers); - dev_dbg(consumer, "Linked as a consumer to %s\n", dev_name(supplier)); - out: +out: device_pm_unlock(); device_links_write_unlock(); -- 2.26.2.761.g0e0b3e54be-goog