[ovs-dev] [PATCH 05/12] datapath: Add usage of __rcu annotation.

Jesse Gross jesse at nicira.com
Sun Dec 12 20:53:00 UTC 2010


Sparse can warn about incorrect usage of RCU via direct access to
points when used in conjuction with __rcu and CONFIG_SPARSE_RCU.
This adds the necessary annotations.

Signed-off-by: Jesse Gross <jesse at nicira.com>
---
 datapath/datapath.c    |    2 +-
 datapath/datapath.h    |    6 +++---
 datapath/flow.h        |    2 +-
 datapath/table.c       |   10 +++++-----
 datapath/table.h       |    2 +-
 datapath/tunnel.c      |    3 +--
 datapath/tunnel.h      |    4 ++--
 datapath/vport-patch.c |    7 ++-----
 8 files changed, 16 insertions(+), 20 deletions(-)

diff --git a/datapath/datapath.c b/datapath/datapath.c
index 3ec13a7..ef645f1 100644
--- a/datapath/datapath.c
+++ b/datapath/datapath.c
@@ -67,7 +67,7 @@ EXPORT_SYMBOL(dp_ioctl_hook);
  * It is safe to access the datapath and vport structures with just
  * dp_mutex.
  */
-static struct datapath *dps[ODP_MAX];
+static struct datapath __rcu *dps[ODP_MAX];
 static DEFINE_MUTEX(dp_mutex);
 
 static int new_vport(struct datapath *, struct odp_port *, int port_no);
diff --git a/datapath/datapath.h b/datapath/datapath.h
index 66ade3e..e4c6534 100644
--- a/datapath/datapath.h
+++ b/datapath/datapath.h
@@ -66,7 +66,7 @@ struct dp_stats_percpu {
  * @queues: %DP_N_QUEUES sets of queued packets for userspace to handle.
  * @waitqueue: Waitqueue, for waiting for new packets in @queues.
  * @n_flows: Number of flows currently in flow table.
- * @table: Current flow table (RCU protected).
+ * @table: Current flow table.
  * @n_ports: Number of ports currently in @ports.
  * @ports: Map from port number to &struct vport.  %ODPP_LOCAL port
  * always exists, other ports may be %NULL.
@@ -88,11 +88,11 @@ struct datapath {
 	wait_queue_head_t waitqueue;
 
 	/* Flow table. */
-	struct tbl *table;
+	struct tbl __rcu *table;
 
 	/* Switch ports. */
 	unsigned int n_ports;
-	struct vport *ports[DP_MAX_PORTS];
+	struct vport __rcu *ports[DP_MAX_PORTS];
 	struct list_head port_list;
 
 	/* Stats. */
diff --git a/datapath/flow.h b/datapath/flow.h
index d58196e..4b462e5 100644
--- a/datapath/flow.h
+++ b/datapath/flow.h
@@ -33,7 +33,7 @@ struct sw_flow {
 	struct tbl_node tbl_node;
 
 	struct odp_flow_key key;
-	struct sw_flow_actions *sf_acts;
+	struct sw_flow_actions __rcu *sf_acts;
 
 	atomic_t refcnt;
 	bool dead;
diff --git a/datapath/table.c b/datapath/table.c
index c6614e1..2806308 100644
--- a/datapath/table.c
+++ b/datapath/table.c
@@ -161,7 +161,7 @@ void tbl_deferred_destroy(struct tbl *table, void (*destructor)(struct tbl_node
 	call_rcu(&table->rcu, destroy_table_rcu);
 }
 
-static struct tbl_bucket **find_bucket(struct tbl *table, u32 hash)
+static struct tbl_bucket __rcu **find_bucket(struct tbl *table, u32 hash)
 {
 	unsigned int l1 = (hash & (table->n_buckets - 1)) >> TBL_L1_SHIFT;
 	unsigned int l2 = hash & ((1 << TBL_L2_BITS) - 1);
@@ -197,7 +197,7 @@ static int search_bucket(const struct tbl_bucket *bucket, void *target, u32 hash
 struct tbl_node *tbl_lookup(struct tbl *table, void *target, u32 hash,
 			    int (*cmp)(const struct tbl_node *, void *))
 {
-	struct tbl_bucket **bucketp = find_bucket(table, hash);
+	struct tbl_bucket __rcu **bucketp = find_bucket(table, hash);
 	struct tbl_bucket *bucket = rcu_dereference(*bucketp);
 	int index;
 
@@ -230,7 +230,7 @@ int tbl_foreach(struct tbl *table,
 {
 	unsigned int i, j, k;
 	for (i = 0; i < table->n_buckets >> TBL_L1_BITS; i++) {
-		struct tbl_bucket **l2 = table->buckets[i];
+		struct tbl_bucket __rcu **l2 = table->buckets[i];
 		for (j = 0; j < TBL_L1_SIZE; j++) {
 			struct tbl_bucket *bucket = rcu_dereference(l2[j]);
 			if (!bucket)
@@ -318,7 +318,7 @@ static void free_bucket_rcu(struct rcu_head *rcu)
  */
 int tbl_insert(struct tbl *table, struct tbl_node *target, u32 hash)
 {
-	struct tbl_bucket **oldp = find_bucket(table, hash);
+	struct tbl_bucket __rcu **oldp = find_bucket(table, hash);
 	struct tbl_bucket *old = rcu_dereference(*oldp);
 	unsigned int n = old ? old->n_objs : 0;
 	struct tbl_bucket *new = bucket_alloc(n + 1);
@@ -356,7 +356,7 @@ int tbl_insert(struct tbl *table, struct tbl_node *target, u32 hash)
  */
 int tbl_remove(struct tbl *table, struct tbl_node *target)
 {
-	struct tbl_bucket **oldp = find_bucket(table, target->hash);
+	struct tbl_bucket __rcu **oldp = find_bucket(table, target->hash);
 	struct tbl_bucket *old = rcu_dereference(*oldp);
 	unsigned int n = old->n_objs;
 	struct tbl_bucket *new;
diff --git a/datapath/table.h b/datapath/table.h
index dac5747..609d9b1 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 ***buckets;
+	struct tbl_bucket ** __rcu *buckets;
 	unsigned int count;
 	void (*obj_destructor)(struct tbl_node *);
 };
diff --git a/datapath/tunnel.c b/datapath/tunnel.c
index 3534909..23a036f 100644
--- a/datapath/tunnel.c
+++ b/datapath/tunnel.c
@@ -68,8 +68,7 @@
 
 #define CACHE_DATA_ALIGN 16
 
-/* Protected by RCU. */
-static struct tbl *port_table __read_mostly;
+static struct tbl __rcu *port_table __read_mostly;
 
 static void cache_cleaner(struct work_struct *work);
 static DECLARE_DELAYED_WORK(cache_cleaner_wq, cache_cleaner);
diff --git a/datapath/tunnel.h b/datapath/tunnel.h
index 5615f6a..aa859f6 100644
--- a/datapath/tunnel.h
+++ b/datapath/tunnel.h
@@ -161,7 +161,7 @@ struct tnl_vport {
 	char name[IFNAMSIZ];
 	const struct tnl_ops *tnl_ops;
 
-	struct tnl_mutable_config *mutable;	/* Protected by RCU. */
+	struct tnl_mutable_config __rcu *mutable;
 
 	/*
 	 * ID of last fragment sent (for tunnel protocols with direct support
@@ -171,7 +171,7 @@ struct tnl_vport {
 	atomic_t frag_id;
 
 	spinlock_t cache_lock;
-	struct tnl_cache *cache;		/* Protected by RCU/cache_lock. */
+	struct tnl_cache __rcu *cache;		/* Protected by RCU/cache_lock. */
 
 #ifdef NEED_CACHE_TIMEOUT
 	/*
diff --git a/datapath/vport-patch.c b/datapath/vport-patch.c
index d27509a..8bb204b 100644
--- a/datapath/vport-patch.c
+++ b/datapath/vport-patch.c
@@ -30,11 +30,8 @@ struct patch_vport {
 	char peer_name[IFNAMSIZ];
 	struct hlist_node hash_node;
 
-	/* Protected by RCU. */
-	struct vport *peer;
-
-	/* Protected by RCU. */
-	struct device_config *devconf;
+	struct vport __rcu *peer;
+	struct device_config __rcu *devconf;
 };
 
 /* Protected by RTNL lock. */
-- 
1.7.1





More information about the dev mailing list