datapath: Add usage of __rcu annotation.
authorJesse Gross <jesse@nicira.com>
Sat, 4 Dec 2010 19:50:53 +0000 (11:50 -0800)
committerJesse Gross <jesse@nicira.com>
Mon, 13 Dec 2010 21:40:13 +0000 (13:40 -0800)
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@nicira.com>
Acked-by: Ben Pfaff <blp@nicira.com>
datapath/datapath.c
datapath/datapath.h
datapath/flow.h
datapath/table.c
datapath/table.h
datapath/tunnel.c
datapath/tunnel.h
datapath/vport-patch.c

index 98685c0..5e2821a 100644 (file)
@@ -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);
index 66ade3e..e4c6534 100644 (file)
@@ -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. */
index 61ffcd7..0764482 100644 (file)
@@ -34,7 +34,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;
index c6614e1..2806308 100644 (file)
@@ -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;
index dac5747..609d9b1 100644 (file)
@@ -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 *);
 };
index 1e40293..d2ede14 100644 (file)
@@ -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);
index 5615f6a..aa859f6 100644 (file)
@@ -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
        /*
index d27509a..8bb204b 100644 (file)
@@ -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. */