It seems for the sake of saving stack memory of couple of pointers,
the locking in release_nodes() callers becomes interesting.

Replace this logic with a straight forward locking and unlocking scheme.

Signed-off-by: Andy Shevchenko <andriy.shevche...@linux.intel.com>
---
v3: new patch
 drivers/base/devres.c | 30 +++++++++++++++---------------
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/drivers/base/devres.c b/drivers/base/devres.c
index 8746f2212781..7970217191e0 100644
--- a/drivers/base/devres.c
+++ b/drivers/base/devres.c
@@ -503,28 +503,18 @@ static int remove_nodes(struct device *dev,
        return cnt;
 }
 
-static int release_nodes(struct device *dev, struct list_head *first,
-                        struct list_head *end, unsigned long flags)
-       __releases(&dev->devres_lock)
+static void release_nodes(struct device *dev, struct list_head *todo)
 {
-       LIST_HEAD(todo);
-       int cnt;
        struct devres *dr, *tmp;
 
-       cnt = remove_nodes(dev, first, end, &todo);
-
-       spin_unlock_irqrestore(&dev->devres_lock, flags);
-
        /* Release.  Note that both devres and devres_group are
         * handled as devres in the following loop.  This is safe.
         */
-       list_for_each_entry_safe_reverse(dr, tmp, &todo, node.entry) {
+       list_for_each_entry_safe_reverse(dr, tmp, todo, node.entry) {
                devres_log(dev, &dr->node, "REL");
                dr->node.release(dev, dr->data);
                kfree(dr);
        }
-
-       return cnt;
 }
 
 /**
@@ -537,13 +527,19 @@ static int release_nodes(struct device *dev, struct 
list_head *first,
 int devres_release_all(struct device *dev)
 {
        unsigned long flags;
+       LIST_HEAD(todo);
+       int cnt;
 
        /* Looks like an uninitialized device structure */
        if (WARN_ON(dev->devres_head.next == NULL))
                return -ENODEV;
+
        spin_lock_irqsave(&dev->devres_lock, flags);
-       return release_nodes(dev, dev->devres_head.next, &dev->devres_head,
-                            flags);
+       cnt = remove_nodes(dev, dev->devres_head.next, &dev->devres_head, 
&todo);
+       spin_unlock_irqrestore(&dev->devres_lock, flags);
+
+       release_nodes(dev, &todo);
+       return cnt;
 }
 
 /**
@@ -679,6 +675,7 @@ int devres_release_group(struct device *dev, void *id)
 {
        struct devres_group *grp;
        unsigned long flags;
+       LIST_HEAD(todo);
        int cnt = 0;
 
        spin_lock_irqsave(&dev->devres_lock, flags);
@@ -691,7 +688,10 @@ int devres_release_group(struct device *dev, void *id)
                if (!list_empty(&grp->node[1].entry))
                        end = grp->node[1].entry.next;
 
-               cnt = release_nodes(dev, first, end, flags);
+               cnt = remove_nodes(dev, first, end, &todo);
+               spin_unlock_irqrestore(&dev->devres_lock, flags);
+
+               release_nodes(dev, &todo);
        } else {
                WARN_ON(1);
                spin_unlock_irqrestore(&dev->devres_lock, flags);
-- 
2.30.2

Reply via email to