From: Ben Pfaff Date: Mon, 16 Mar 2009 18:37:34 +0000 (-0700) Subject: datapath: Speed up ioctl fast paths. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=876d3efc253cb6507ef47c2fa0f267a11722d8a9;p=openvswitch datapath: Speed up ioctl fast paths. synchronize_rcu() was causing some common datapath ioctls to take up to approx. 1 second (!) in some cases, which was killing our performance. Use call_rcu() instead. --- diff --git a/datapath/datapath.c b/datapath/datapath.c index e636c8ad..8b26d5a0 100644 --- a/datapath/datapath.c +++ b/datapath/datapath.c @@ -794,8 +794,7 @@ static int set_flow_actions(struct datapath *dp, struct odp_flow __user *ufp) goto error_free_actions; old_acts = rcu_dereference(flow->sf_acts); rcu_assign_pointer(flow->sf_acts, new_acts); - synchronize_rcu(); /* XXX expensive! */ - kfree(old_acts); + flow_deferred_free_acts(old_acts); return 0; @@ -883,9 +882,13 @@ static int add_flow(struct datapath *dp, struct odp_flow __user *ufp) /* Replace 'old_flow' by 'flow'. */ struct sw_flow *old_flow = *rcu_dereference(bucket); rcu_assign_pointer(*bucket, flow); - synchronize_rcu(); /* XXX expensive! */ + + /* XXX These statistics might lose a few packets, since other + * CPUs can be using this flow. We used to synchronize_rcu() + * to make sure that we get completely accurate stats, but that + * blows our performance, badly. */ error = put_stats(old_flow, ufp) ? -EFAULT : 0; - flow_free(old_flow); + flow_deferred_free(old_flow); } return error; @@ -951,10 +954,14 @@ static int del_or_query_flow(struct datapath *dp, error = dp_table_delete(table, flow); if (error) goto error; + + /* XXX These statistics might lose a few packets, since other + * CPUs can be using this flow. We used to synchronize_rcu() + * to make sure that we get completely accurate stats, but that + * blows our performance, badly. */ dp->n_flows--; - synchronize_rcu(); /* XXX expensive! */ error = answer_query(flow, ufp); - flow_free(flow); + flow_deferred_free(flow); } else { error = answer_query(flow, ufp); }