Get rid of unnecessary synchronization in tables.
authorBen Pfaff <blp@nicira.com>
Mon, 21 Jul 2008 20:54:01 +0000 (13:54 -0700)
committerBen Pfaff <blp@nicira.com>
Mon, 21 Jul 2008 20:59:54 +0000 (13:59 -0700)
The table insert and delete functions are already fully serialized
on dp_mutex (and genl_mutex), so there's no need for them to use
additional spinlocks.

datapath/hwtable_dummy/hwtable_dummy.c
datapath/table-hash.c
datapath/table-linear.c

index 449b94bf80ec24c30907da83369d4f6d0a08b117..6f7ed8c180a6a441477e367cbe6a0d49e47574ad 100644 (file)
@@ -62,7 +62,6 @@ struct sw_flow_dummy {
 struct sw_table_dummy {
        struct sw_table swt;
 
-       spinlock_t lock;
        unsigned int max_flows;
        atomic_t n_flows;
        struct list_head flows;
@@ -147,7 +146,7 @@ static int table_dummy_delete(struct sw_table *swt,
        struct sw_flow *flow;
        unsigned int count = 0;
 
-       list_for_each_entry_rcu (flow, &td->flows, node) {
+       list_for_each_entry (flow, &td->flows, node) {
                if (flow_del_matches(&flow->key, key, strict)
                    && (!strict || (flow->priority == priority)))
                        count += do_delete(swt, flow);
@@ -168,7 +167,7 @@ static int table_dummy_timeout(struct datapath *dp, struct sw_table *swt)
        int i = 0;
 
        mutex_lock(&dp_mutex);
-       list_for_each_entry_rcu (flow, &td->flows, node) {
+       list_for_each_entry (flow, &td->flows, node) {
                /* xxx Retrieve the packet count associated with this entry
                 * xxx and store it in "packet_count".
                 */
@@ -240,7 +239,7 @@ static int table_dummy_iterate(struct sw_table *swt,
        unsigned long start;
 
        start = ~position->private[0];
-       list_for_each_entry_rcu (flow, &tl->iter_flows, iter_node) {
+       list_for_each_entry (flow, &tl->iter_flows, iter_node) {
                if (flow->serial <= start && flow_matches(key, &flow->key)) {
                        int error = callback(flow, private);
                        if (error) {
@@ -284,7 +283,6 @@ static struct sw_table *table_dummy_create(void)
        atomic_set(&td->n_flows, 0);
        INIT_LIST_HEAD(&td->flows);
        INIT_LIST_HEAD(&td->iter_flows);
-       spin_lock_init(&td->lock);
        td->next_serial = 0;
 
        INIT_LIST_HEAD(&pending_free_list);
index c972fbccc844bd54a66ee6fa139dc1dbd395e3af..b7475e3b974f646854b94ad93159b07b0d1cdbfc 100644 (file)
@@ -21,7 +21,6 @@ static void kmem_free(void *, size_t);
 
 struct sw_table_hash {
        struct sw_table swt;
-       spinlock_t lock;
        struct crc32 crc32;
        atomic_t n_flows;
        unsigned int bucket_mask; /* Number of buckets minus 1. */
@@ -47,13 +46,11 @@ static int table_hash_insert(struct sw_table *swt, struct sw_flow *flow)
 {
        struct sw_table_hash *th = (struct sw_table_hash *) swt;
        struct sw_flow **bucket;
-       unsigned long int flags;
        int retval;
 
        if (flow->key.wildcards != 0)
                return 0;
 
-       spin_lock_irqsave(&th->lock, flags);
        bucket = find_bucket(swt, &flow->key);
        if (*bucket == NULL) {
                atomic_inc(&th->n_flows);
@@ -70,7 +67,6 @@ static int table_hash_insert(struct sw_table *swt, struct sw_flow *flow)
                        retval = 0;
                }
        }
-       spin_unlock_irqrestore(&th->lock, flags);
        return retval;
 }
 
@@ -225,7 +221,6 @@ struct sw_table *table_hash_create(unsigned int polynomial,
        swt->iterate = table_hash_iterate;
        swt->stats = table_hash_stats;
 
-       spin_lock_init(&th->lock);
        crc32_init(&th->crc32, polynomial);
        atomic_set(&th->n_flows, 0);
 
index 04587e5f5bb24596d21f9e9203cb15bf5daf4a04..e40929963738c18ad514c2fd5ceec013a3f70e36 100644 (file)
@@ -15,7 +15,6 @@
 struct sw_table_linear {
        struct sw_table swt;
 
-       spinlock_t lock;
        unsigned int max_flows;
        atomic_t n_flows;
        struct list_head flows;
@@ -38,7 +37,6 @@ static struct sw_flow *table_linear_lookup(struct sw_table *swt,
 static int table_linear_insert(struct sw_table *swt, struct sw_flow *flow)
 {
        struct sw_table_linear *tl = (struct sw_table_linear *) swt;
-       unsigned long int flags;
        struct sw_flow *f;
 
 
@@ -46,8 +44,7 @@ static int table_linear_insert(struct sw_table *swt, struct sw_flow *flow)
         * always be placed behind those with equal priority.  Just replace 
         * any flows that match exactly.
         */
-       spin_lock_irqsave(&tl->lock, flags);
-       list_for_each_entry_rcu (f, &tl->flows, node) {
+       list_for_each_entry (f, &tl->flows, node) {
                if (f->priority == flow->priority
                                && f->key.wildcards == flow->key.wildcards
                                && flow_matches(&f->key, &flow->key)
@@ -55,7 +52,6 @@ static int table_linear_insert(struct sw_table *swt, struct sw_flow *flow)
                        flow->serial = f->serial;
                        list_replace_rcu(&f->node, &flow->node);
                        list_replace_rcu(&f->iter_node, &flow->iter_node);
-                       spin_unlock_irqrestore(&tl->lock, flags);
                        flow_deferred_free(f);
                        return 1;
                }
@@ -66,7 +62,6 @@ static int table_linear_insert(struct sw_table *swt, struct sw_flow *flow)
 
        /* Make sure there's room in the table. */
        if (atomic_read(&tl->n_flows) >= tl->max_flows) {
-               spin_unlock_irqrestore(&tl->lock, flags);
                return 0;
        }
        atomic_inc(&tl->n_flows);
@@ -75,7 +70,6 @@ static int table_linear_insert(struct sw_table *swt, struct sw_flow *flow)
        flow->serial = tl->next_serial++;
        list_add_tail_rcu(&flow->node, &f->node);
        list_add_rcu(&flow->iter_node, &tl->iter_flows);
-       spin_unlock_irqrestore(&tl->lock, flags);
        return 1;
 }
 
@@ -97,7 +91,7 @@ static int table_linear_delete(struct sw_table *swt,
        struct sw_flow *flow;
        unsigned int count = 0;
 
-       list_for_each_entry_rcu (flow, &tl->flows, node) {
+       list_for_each_entry (flow, &tl->flows, node) {
                if (flow_del_matches(&flow->key, key, strict)
                                && (!strict || (flow->priority == priority)))
                        count += do_delete(swt, flow);
@@ -114,7 +108,7 @@ static int table_linear_timeout(struct datapath *dp, struct sw_table *swt)
        int count = 0;
 
        mutex_lock(&dp_mutex);
-       list_for_each_entry_rcu (flow, &tl->flows, node) {
+       list_for_each_entry (flow, &tl->flows, node) {
                if (flow_timeout(flow)) {
                        count += do_delete(swt, flow);
                        if (dp->flags & OFPC_SEND_FLOW_EXP)
@@ -152,7 +146,7 @@ static int table_linear_iterate(struct sw_table *swt,
        unsigned long start;
 
        start = position->private[0];
-       list_for_each_entry_rcu (flow, &tl->iter_flows, iter_node) {
+       list_for_each_entry (flow, &tl->iter_flows, iter_node) {
                if (flow->serial >= start && flow_matches(key, &flow->key)) {
                        int error = callback(flow, private);
                        if (error) {
@@ -196,7 +190,6 @@ struct sw_table *table_linear_create(unsigned int max_flows)
        atomic_set(&tl->n_flows, 0);
        INIT_LIST_HEAD(&tl->flows);
        INIT_LIST_HEAD(&tl->iter_flows);
-       spin_lock_init(&tl->lock);
        tl->next_serial = 0;
 
        return swt;