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: [email protected]
Fixes: 05ef983e0d65 ("driver core: Add device link support for SYNC_STATE_ONLY 
flag")
Signed-off-by: Saravana Kannan <[email protected]>
---
 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

Reply via email to