|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [XEN][RFC PATCH v4 11/16] common/device_tree: Add rwlock for dt_host
Dynamic programming ops will modify the dt_host and there might be other
function which are browsing the dt_host at the same time. To avoid the race
conditions, adding rwlock for browsing the dt_host.
Signed-off-by: Vikram Garhwal <vikram.garhwal@xxxxxxx>
---
xen/common/device_tree.c | 27 +++++++++++++++++++++++++++
xen/include/xen/device_tree.h | 6 ++++++
2 files changed, 33 insertions(+)
diff --git a/xen/common/device_tree.c b/xen/common/device_tree.c
index acf26a411d..51ee2a5edf 100644
--- a/xen/common/device_tree.c
+++ b/xen/common/device_tree.c
@@ -140,6 +140,8 @@ const struct dt_property *dt_find_property(const struct
dt_device_node *np,
if ( !np )
return NULL;
+ read_lock(&dt_host->lock);
+
for ( pp = np->properties; pp; pp = pp->next )
{
if ( dt_prop_cmp(pp->name, name) == 0 )
@@ -150,6 +152,7 @@ const struct dt_property *dt_find_property(const struct
dt_device_node *np,
}
}
+ read_unlock(&dt_host->lock);
return pp;
}
@@ -336,11 +339,14 @@ struct dt_device_node *dt_find_node_by_name(struct
dt_device_node *from,
struct dt_device_node *np;
struct dt_device_node *dt;
+ read_lock(&dt_host->lock);
+
dt = from ? from->allnext : dt_host;
dt_for_each_device_node(dt, np)
if ( np->name && (dt_node_cmp(np->name, name) == 0) )
break;
+ read_unlock(&dt_host->lock);
return np;
}
@@ -350,11 +356,14 @@ struct dt_device_node *dt_find_node_by_type(struct
dt_device_node *from,
struct dt_device_node *np;
struct dt_device_node *dt;
+ read_lock(&dt_host->lock);
+
dt = from ? from->allnext : dt_host;
dt_for_each_device_node(dt, np)
if ( np->type && (dt_node_cmp(np->type, type) == 0) )
break;
+ read_unlock(&dt_host->lock);
return np;
}
@@ -363,10 +372,13 @@ struct dt_device_node
*device_tree_find_node_by_path(struct dt_device_node *dt,
{
struct dt_device_node *np;
+ read_lock(&dt_host->lock);
+
dt_for_each_device_node(dt, np)
if ( np->full_name && (dt_node_cmp(np->full_name, path) == 0) )
break;
+ read_unlock(&dt_host->lock);
return np;
}
@@ -450,6 +462,8 @@ dt_find_compatible_node(struct dt_device_node *from,
struct dt_device_node *np;
struct dt_device_node *dt;
+ read_lock(&dt_host->lock);
+
dt = from ? from->allnext : dt_host;
dt_for_each_device_node(dt, np)
{
@@ -460,6 +474,7 @@ dt_find_compatible_node(struct dt_device_node *from,
break;
}
+ read_unlock(&dt_host->lock);
return np;
}
@@ -470,13 +485,19 @@ dt_find_matching_node(struct dt_device_node *from,
struct dt_device_node *np;
struct dt_device_node *dt;
+ read_lock(&dt_host->lock);
+
dt = from ? from->allnext : dt_host;
dt_for_each_device_node(dt, np)
{
if ( dt_match_node(matches, np) )
+ {
+ read_unlock(&dt_host->lock);
return np;
+ }
}
+ read_unlock(&dt_host->lock);
return NULL;
}
@@ -1052,10 +1073,13 @@ struct dt_device_node
*dt_find_node_by_phandle(dt_phandle handle)
{
struct dt_device_node *np;
+ read_lock(&dt_host->lock);
+
dt_for_each_device_node(dt_host, np)
if ( np->phandle == handle )
break;
+ read_unlock(&dt_host->lock);
return np;
}
@@ -2102,6 +2126,9 @@ int unflatten_device_tree(const void *fdt, struct
dt_device_node **mynodes)
dt_dprintk(" <- unflatten_device_tree()\n");
+ /* Init r/w lock for host device tree. */
+ rwlock_init(&dt_host->lock);
+
return 0;
}
diff --git a/xen/include/xen/device_tree.h b/xen/include/xen/device_tree.h
index 51e251b0b4..bafc898f1c 100644
--- a/xen/include/xen/device_tree.h
+++ b/xen/include/xen/device_tree.h
@@ -18,6 +18,7 @@
#include <xen/string.h>
#include <xen/types.h>
#include <xen/list.h>
+#include <xen/rwlock.h>
#define DEVICE_TREE_MAX_DEPTH 16
@@ -106,6 +107,11 @@ struct dt_device_node {
struct list_head domain_list;
struct device dev;
+
+ /*
+ * Lock that protects r/w updates to unflattened device tree i.e. dt_host.
+ */
+ rwlock_t lock;
};
#define dt_to_dev(dt_node) (&(dt_node)->dev)
--
2.17.1
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |