X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=datapath%2Fhwtable_dummy%2Fhwtable_dummy.c;h=a80ce6b7250ea5cf4d48ebc51592174272ce33db;hb=be25fa83e8f65d92b853bd20a3d1a594af352b92;hp=b6c5832b5a0137baf1472eecba3bdf3d9730b6e5;hpb=fcb73d77bf6509d0efd98882bbead8d8180f5d7e;p=openvswitch diff --git a/datapath/hwtable_dummy/hwtable_dummy.c b/datapath/hwtable_dummy/hwtable_dummy.c index b6c5832b..a80ce6b7 100644 --- a/datapath/hwtable_dummy/hwtable_dummy.c +++ b/datapath/hwtable_dummy/hwtable_dummy.c @@ -49,10 +49,6 @@ #define DUMMY_MAX_FLOW 8192 -/* xxx Explain need for this separate list because of RCU */ -static spinlock_t pending_free_lock; -static struct list_head pending_free_list; - /* sw_flow private data for dummy table entries. */ struct sw_flow_dummy { struct list_head node; @@ -63,43 +59,14 @@ struct sw_flow_dummy { struct sw_table_dummy { struct sw_table swt; - spinlock_t lock; unsigned int max_flows; - atomic_t n_flows; + unsigned int n_flows; struct list_head flows; struct list_head iter_flows; unsigned long int next_serial; }; -static void table_dummy_sfw_destroy(struct sw_flow_dummy *sfw) -{ - /* xxx Remove the entry from hardware. If you need to do any other - * xxx clean-up associated with the entry, do it here. - */ - - kfree(sfw); -} - -static void table_dummy_rcu_callback(struct rcu_head *rcu) -{ - struct sw_flow *flow = container_of(rcu, struct sw_flow, rcu); - - spin_lock(&pending_free_lock); - if (flow->private) { - struct sw_flow_dummy *sfw = flow->private; - list_add(&sfw->node, &pending_free_list); - flow->private = NULL; - } - spin_unlock(&pending_free_lock); - flow_free(flow); -} - -static void table_dummy_flow_deferred_free(struct sw_flow *flow) -{ - call_rcu(&flow->rcu, table_dummy_rcu_callback); -} - static struct sw_flow *table_dummy_lookup(struct sw_table *swt, const struct sw_flow_key *key) { @@ -123,7 +90,8 @@ static int table_dummy_insert(struct sw_table *swt, struct sw_flow *flow) /* xxx Do whatever needs to be done to insert an entry in hardware. * xxx If the entry can't be inserted, return 0. This stub code * xxx doesn't do anything yet, so we're going to return 0...you - * xxx shouldn't. + * xxx shouldn't (and you should update n_flows in struct + * xxx sw_table_dummy, too). */ kfree(flow->private); return 0; @@ -132,13 +100,12 @@ static int table_dummy_insert(struct sw_table *swt, struct sw_flow *flow) static int do_delete(struct sw_table *swt, struct sw_flow *flow) { - if (flow_del(flow)) { - list_del_rcu(&flow->node); - list_del_rcu(&flow->iter_node); - table_dummy_flow_deferred_free(flow); - return 1; - } - return 0; + /* xxx Remove the entry from hardware. If you need to do any other + * xxx clean-up associated with the entry, do it here. + */ + list_del_rcu(&flow->node); + list_del_rcu(&flow->iter_node); + return 1; } static int table_dummy_delete(struct sw_table *swt, @@ -148,13 +115,12 @@ 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); } - if (count) - atomic_sub(count, &td->n_flows); + td->n_flows -= count; return count; } @@ -163,12 +129,12 @@ static int table_dummy_timeout(struct datapath *dp, struct sw_table *swt) { struct sw_table_dummy *td = (struct sw_table_dummy *) swt; struct sw_flow *flow; - struct sw_flow_dummy *sfw, *n; int del_count = 0; uint64_t packet_count = 0; int i = 0; - list_for_each_entry_rcu (flow, &td->flows, node) { + mutex_lock(&dp_mutex); + list_for_each_entry (flow, &td->flows, node) { /* xxx Retrieve the packet count associated with this entry * xxx and store it in "packet_count". */ @@ -187,22 +153,11 @@ static int table_dummy_timeout(struct datapath *dp, struct sw_table *swt) } del_count += do_delete(swt, flow); } - if ((i % 50) == 0) { - msleep_interruptible(1); - } i++; } + mutex_unlock(&dp_mutex); - /* Remove any entries queued for removal */ - spin_lock_bh(&pending_free_lock); - list_for_each_entry_safe (sfw, n, &pending_free_list, node) { - list_del(&sfw->node); - table_dummy_sfw_destroy(sfw); - } - spin_unlock_bh(&pending_free_lock); - - if (del_count) - atomic_sub(del_count, &td->n_flows); + td->n_flows -= del_count; return del_count; } @@ -239,7 +194,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) { @@ -256,7 +211,7 @@ static void table_dummy_stats(struct sw_table *swt, { struct sw_table_dummy *td = (struct sw_table_dummy *) swt; stats->name = "dummy"; - stats->n_flows = atomic_read(&td->n_flows); + stats->n_flows = td->n_flows; stats->max_flows = td->max_flows; } @@ -280,15 +235,11 @@ static struct sw_table *table_dummy_create(void) swt->stats = table_dummy_stats; td->max_flows = DUMMY_MAX_FLOW; - atomic_set(&td->n_flows, 0); + 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); - spin_lock_init(&pending_free_lock); - return swt; }