]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
of: overlay: update phandle cache on overlay apply and remove
authorFrank Rowand <frank.rowand@sony.com>
Thu, 12 Jul 2018 21:00:07 +0000 (14:00 -0700)
committerRob Herring <robh@kernel.org>
Mon, 16 Jul 2018 14:41:32 +0000 (08:41 -0600)
A comment in the review of the patch adding the phandle cache said that
the cache would have to be updated when modules are applied and removed.
This patch implements the cache updates.

Fixes: 0b3ce78e90fc ("of: cache phandle nodes to reduce cost of of_find_node_by_phandle()")
Reported-by: Alan Tull <atull@kernel.org>
Suggested-by: Alan Tull <atull@kernel.org>
Signed-off-by: Frank Rowand <frank.rowand@sony.com>
Signed-off-by: Rob Herring <robh@kernel.org>
drivers/of/base.c
drivers/of/of_private.h
drivers/of/overlay.c

index 848f549164cd0434ae8a28210d47b9ade2b42de3..466e3c8582f0fd62628b90872b2046971e064776 100644 (file)
@@ -102,7 +102,7 @@ static u32 phandle_cache_mask;
  *   - the phandle lookup overhead reduction provided by the cache
  *     will likely be less
  */
-static void of_populate_phandle_cache(void)
+void of_populate_phandle_cache(void)
 {
        unsigned long flags;
        u32 cache_entries;
@@ -134,8 +134,7 @@ static void of_populate_phandle_cache(void)
        raw_spin_unlock_irqrestore(&devtree_lock, flags);
 }
 
-#ifndef CONFIG_MODULES
-static int __init of_free_phandle_cache(void)
+int of_free_phandle_cache(void)
 {
        unsigned long flags;
 
@@ -148,6 +147,7 @@ static int __init of_free_phandle_cache(void)
 
        return 0;
 }
+#if !defined(CONFIG_MODULES)
 late_initcall_sync(of_free_phandle_cache);
 #endif
 
index 891d780c076a12d14dde8d50b87d940e9c83707e..216175d11d3dc2ca3fdfaa429306ecf50218a01a 100644 (file)
@@ -79,6 +79,8 @@ int of_resolve_phandles(struct device_node *tree);
 #if defined(CONFIG_OF_OVERLAY)
 void of_overlay_mutex_lock(void);
 void of_overlay_mutex_unlock(void);
+int of_free_phandle_cache(void);
+void of_populate_phandle_cache(void);
 #else
 static inline void of_overlay_mutex_lock(void) {};
 static inline void of_overlay_mutex_unlock(void) {};
index 7baa53e5b1d74d469959341945e3bc239cf7d5c7..eda57ef12fd057b3d92c750dec983703e85f38e3 100644 (file)
@@ -804,6 +804,8 @@ static int of_overlay_apply(const void *fdt, struct device_node *tree,
                goto err_free_overlay_changeset;
        }
 
+       of_populate_phandle_cache();
+
        ret = __of_changeset_apply_notify(&ovcs->cset);
        if (ret)
                pr_err("overlay changeset entry notify error %d\n", ret);
@@ -1046,8 +1048,17 @@ int of_overlay_remove(int *ovcs_id)
 
        list_del(&ovcs->ovcs_list);
 
+       /*
+        * Disable phandle cache.  Avoids race condition that would arise
+        * from removing cache entry when the associated node is deleted.
+        */
+       of_free_phandle_cache();
+
        ret_apply = 0;
        ret = __of_changeset_revert_entries(&ovcs->cset, &ret_apply);
+
+       of_populate_phandle_cache();
+
        if (ret) {
                if (ret_apply)
                        devicetree_state_flags |= DTSF_REVERT_FAIL;