[ovs-dev] [PATCH 05/10] datapath: Fix table sparse annotations.

Jesse Gross jesse at nicira.com
Wed Dec 29 04:50:43 UTC 2010


Several of the pointers in table.c were missing the correct
__rcu annotation and the pointer type in the actual declaration
of struct tbl was incorrect, so this fixes that.  It also adds
usage of rcu_dereference() to access an RCU protected pointer,
which is not strictly correct since an update side lock should
be held.  However, since the table is used in different pieces
of code and therefore different locks are used it is difficult
to know which lock to check without threading the information
though, which is ugly.  Since other places in table.c have this
same problem and this code should go away in the future it is
left as is.

Found with sparse.

Signed-off-by: Jesse Gross <jesse at nicira.com>
---
 datapath/table.c |   13 +++++++------
 datapath/table.h |    2 +-
 2 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/datapath/table.c b/datapath/table.c
index d2432e8..5c1b82a 100644
--- a/datapath/table.c
+++ b/datapath/table.c
@@ -40,17 +40,18 @@ static struct tbl_bucket *bucket_alloc(int n_objs)
 	return kmalloc(bucket_size(n_objs), GFP_KERNEL);
 }
 
-static void free_buckets(struct tbl_bucket ***l1, unsigned int n_buckets,
+static void free_buckets(struct tbl_bucket __rcu ***l1,
+			 unsigned int n_buckets,
 			 void (*free_obj)(struct tbl_node *))
 {
 	unsigned int i;
 
 	for (i = 0; i < n_buckets >> TBL_L1_SHIFT; i++) {
-		struct tbl_bucket **l2 = l1[i];
+		struct tbl_bucket __rcu **l2 = l1[i];
 		unsigned int j;
 
 		for (j = 0; j < TBL_L2_SIZE; j++) {
-			struct tbl_bucket *bucket = l2[j];
+			struct tbl_bucket *bucket = rcu_dereference(l2[j]);
 			if (!bucket)
 				continue;
 
@@ -66,9 +67,9 @@ static void free_buckets(struct tbl_bucket ***l1, unsigned int n_buckets,
 	kfree(l1);
 }
 
-static struct tbl_bucket ***alloc_buckets(unsigned int n_buckets)
+static struct tbl_bucket __rcu ***alloc_buckets(unsigned int n_buckets)
 {
-	struct tbl_bucket ***l1;
+	struct tbl_bucket __rcu ***l1;
 	unsigned int i;
 
 	l1 = kmalloc((n_buckets >> TBL_L1_SHIFT) * sizeof(struct tbl_bucket **),
@@ -76,7 +77,7 @@ static struct tbl_bucket ***alloc_buckets(unsigned int n_buckets)
 	if (!l1)
 		return NULL;
 	for (i = 0; i < n_buckets >> TBL_L1_SHIFT; i++) {
-		l1[i] = (struct tbl_bucket **)get_zeroed_page(GFP_KERNEL);
+		l1[i] = (struct tbl_bucket __rcu **)get_zeroed_page(GFP_KERNEL);
 		if (!l1[i]) {
 			free_buckets(l1, i << TBL_L1_SHIFT, NULL);
 			return NULL;
diff --git a/datapath/table.h b/datapath/table.h
index 2fd569b..f186600 100644
--- a/datapath/table.h
+++ b/datapath/table.h
@@ -34,7 +34,7 @@ struct tbl_node {
 struct tbl {
 	struct rcu_head rcu;
 	unsigned int n_buckets;
-	struct tbl_bucket ** __rcu *buckets;
+	struct tbl_bucket __rcu ***buckets;
 	unsigned int count;
 	void (*obj_destructor)(struct tbl_node *);
 };
-- 
1.7.1





More information about the dev mailing list