Fixed according to comments from Jesse.

--8<--------------------------cut here-------------------------->8--

Only tunneling code needs to keep ref to flow structure cached.
But upstream OVS does not have tunneling code. So we can safely
remove flow ref-counting.

Signed-off-by: Pravin B Shelar <pshe...@nicira.com>
---
 net/openvswitch/datapath.c           |   66 ++++++++++++++++------------------
 net/openvswitch/flow.c               |   36 +++++-------------
 net/openvswitch/flow.h               |    7 +---
 net/openvswitch/vport-internal_dev.c |    2 -
 net/openvswitch/vport.c              |    2 -
 5 files changed, 42 insertions(+), 71 deletions(-)

diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index bb095f8..04c4c71 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -182,41 +182,37 @@ void dp_process_received_packet(struct vport *p, struct 
sk_buff *skb)
        struct datapath *dp = p->dp;
        struct sw_flow *flow;
        struct dp_stats_percpu *stats;
+       struct sw_flow_key key;
        u64 *stats_counter;
        int error;
+       int key_len;
 
        stats = per_cpu_ptr(dp->stats_percpu, smp_processor_id());
 
-       if (!OVS_CB(skb)->flow) {
-               struct sw_flow_key key;
-               int key_len;
-
-               /* Extract flow from 'skb' into 'key'. */
-               error = flow_extract(skb, p->port_no, &key, &key_len);
-               if (unlikely(error)) {
-                       kfree_skb(skb);
-                       return;
-               }
-
-               /* Look up flow. */
-               flow = flow_tbl_lookup(rcu_dereference(dp->table),
-                                      &key, key_len);
-               if (unlikely(!flow)) {
-                       struct dp_upcall_info upcall;
-
-                       upcall.cmd = OVS_PACKET_CMD_MISS;
-                       upcall.key = &key;
-                       upcall.userdata = NULL;
-                       upcall.pid = p->upcall_pid;
-                       dp_upcall(dp, skb, &upcall);
-                       consume_skb(skb);
-                       stats_counter = &stats->n_missed;
-                       goto out;
-               }
+       /* Extract flow from 'skb' into 'key'. */
+       error = flow_extract(skb, p->port_no, &key, &key_len);
+       if (unlikely(error)) {
+               kfree_skb(skb);
+               return;
+       }
 
-               OVS_CB(skb)->flow = flow;
+       /* Look up flow. */
+       flow = flow_tbl_lookup(rcu_dereference(dp->table), &key, key_len);
+       if (unlikely(!flow)) {
+               struct dp_upcall_info upcall;
+
+               upcall.cmd = OVS_PACKET_CMD_MISS;
+               upcall.key = &key;
+               upcall.userdata = NULL;
+               upcall.pid = p->upcall_pid;
+               dp_upcall(dp, skb, &upcall);
+               consume_skb(skb);
+               stats_counter = &stats->n_missed;
+               goto out;
        }
 
+       OVS_CB(skb)->flow = flow;
+
        stats_counter = &stats->n_hit;
        flow_used(OVS_CB(skb)->flow, skb);
        execute_actions(dp, skb);
@@ -644,24 +640,24 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, 
struct genl_info *info)
 
        err = flow_extract(packet, -1, &flow->key, &key_len);
        if (err)
-               goto err_flow_put;
+               goto err_flow_free;
 
        err = flow_metadata_from_nlattrs(&flow->key.phy.priority,
                                         &flow->key.phy.in_port,
                                         a[OVS_PACKET_ATTR_KEY]);
        if (err)
-               goto err_flow_put;
+               goto err_flow_free;
 
        err = validate_actions(a[OVS_PACKET_ATTR_ACTIONS], &flow->key, 0);
        if (err)
-               goto err_flow_put;
+               goto err_flow_free;
 
        flow->hash = flow_hash(&flow->key, key_len);
 
        acts = flow_actions_alloc(a[OVS_PACKET_ATTR_ACTIONS]);
        err = PTR_ERR(acts);
        if (IS_ERR(acts))
-               goto err_flow_put;
+               goto err_flow_free;
        rcu_assign_pointer(flow->sf_acts, acts);
 
        OVS_CB(packet)->flow = flow;
@@ -678,13 +674,13 @@ static int ovs_packet_cmd_execute(struct sk_buff *skb, 
struct genl_info *info)
        local_bh_enable();
        rcu_read_unlock();
 
-       flow_put(flow);
+       flow_free(flow);
        return err;
 
 err_unlock:
        rcu_read_unlock();
-err_flow_put:
-       flow_put(flow);
+err_flow_free:
+       flow_free(flow);
 err_kfree_skb:
        kfree_skb(packet);
 err:
@@ -996,7 +992,7 @@ static int ovs_flow_cmd_new_or_set(struct sk_buff *skb, 
struct genl_info *info)
        return 0;
 
 error_free_flow:
-       flow_put(flow);
+       flow_free(flow);
 error:
        return error;
 }
diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c
index bab1336..77c16c7 100644
--- a/net/openvswitch/flow.c
+++ b/net/openvswitch/flow.c
@@ -279,9 +279,7 @@ struct sw_flow *flow_alloc(void)
                return ERR_PTR(-ENOMEM);
 
        spin_lock_init(&flow->lock);
-       atomic_set(&flow->refcnt, 1);
        flow->sf_acts = NULL;
-       flow->dead = false;
 
        return flow;
 }
@@ -339,12 +337,6 @@ struct flow_table *flow_tbl_alloc(int new_size)
        return table;
 }
 
-static void flow_free(struct sw_flow *flow)
-{
-       flow->dead = true;
-       flow_put(flow);
-}
-
 void flow_tbl_destroy(struct flow_table *table)
 {
        int i;
@@ -433,13 +425,21 @@ struct flow_table *flow_tbl_expand(struct flow_table 
*table)
        return new_table;
 }
 
+void flow_free(struct sw_flow *flow)
+{
+       if (unlikely(!flow))
+               return;
+
+       kfree((struct sf_flow_acts __force *)flow->sf_acts);
+       kmem_cache_free(flow_cache, flow);
+}
+
 /* RCU callback used by flow_deferred_free. */
 static void rcu_free_flow_callback(struct rcu_head *rcu)
 {
        struct sw_flow *flow = container_of(rcu, struct sw_flow, rcu);
 
-       flow->dead = true;
-       flow_put(flow);
+       flow_free(flow);
 }
 
 /* Schedules 'flow' to be freed after the next RCU grace period.
@@ -449,22 +449,6 @@ void flow_deferred_free(struct sw_flow *flow)
        call_rcu(&flow->rcu, rcu_free_flow_callback);
 }
 
-void flow_hold(struct sw_flow *flow)
-{
-       atomic_inc(&flow->refcnt);
-}
-
-void flow_put(struct sw_flow *flow)
-{
-       if (unlikely(!flow))
-               return;
-
-       if (atomic_dec_and_test(&flow->refcnt)) {
-               kfree((struct sf_flow_acts __force *)flow->sf_acts);
-               kmem_cache_free(flow_cache, flow);
-       }
-}
-
 /* RCU callback used by flow_deferred_free_acts. */
 static void rcu_free_acts_callback(struct rcu_head *rcu)
 {
diff --git a/net/openvswitch/flow.h b/net/openvswitch/flow.h
index 7d6abc0..b98596f 100644
--- a/net/openvswitch/flow.h
+++ b/net/openvswitch/flow.h
@@ -101,9 +101,6 @@ struct sw_flow {
        struct sw_flow_key key;
        struct sw_flow_actions __rcu *sf_acts;
 
-       atomic_t refcnt;
-       bool dead;
-
        spinlock_t lock;        /* Lock for values below. */
        unsigned long used;     /* Last used time (in jiffies). */
        u64 packet_count;       /* Number of packets matched. */
@@ -130,13 +127,11 @@ void flow_exit(void);
 
 struct sw_flow *flow_alloc(void);
 void flow_deferred_free(struct sw_flow *);
+void flow_free(struct sw_flow *flow);
 
 struct sw_flow_actions *flow_actions_alloc(const struct nlattr *);
 void flow_deferred_free_acts(struct sw_flow_actions *);
 
-void flow_hold(struct sw_flow *);
-void flow_put(struct sw_flow *);
-
 int flow_extract(struct sk_buff *, u16 in_port, struct sw_flow_key *,
                 int *key_lenp);
 void flow_used(struct sw_flow *, struct sk_buff *);
diff --git a/net/openvswitch/vport-internal_dev.c 
b/net/openvswitch/vport-internal_dev.c
index 7b8e1e9..89f7be4 100644
--- a/net/openvswitch/vport-internal_dev.c
+++ b/net/openvswitch/vport-internal_dev.c
@@ -74,8 +74,6 @@ static int internal_dev_mac_addr(struct net_device *dev, void 
*p)
 /* Called with rcu_read_lock_bh. */
 static int internal_dev_xmit(struct sk_buff *skb, struct net_device *netdev)
 {
-       OVS_CB(skb)->flow = NULL;
-
        rcu_read_lock();
        vport_receive(internal_dev_priv(netdev)->vport, skb);
        rcu_read_unlock();
diff --git a/net/openvswitch/vport.c b/net/openvswitch/vport.c
index c9488e0..25c311c 100644
--- a/net/openvswitch/vport.c
+++ b/net/openvswitch/vport.c
@@ -332,8 +332,6 @@ void vport_receive(struct vport *vport, struct sk_buff *skb)
        stats->rx_bytes += skb->len;
        write_seqcount_end(&stats->seqlock);
 
-       OVS_CB(skb)->flow = NULL;
-
        dp_process_received_packet(vport, skb);
 }
 
-- 
1.7.1

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to