Clean up the code in the sample hardware table code.
[openvswitch] / datapath / hwtable_dummy / hwtable_dummy.c
index 6692885a49333b88d65058c00e0c5bd27e5ca157..e3e0eb411857914b7ae3c0c60363057f378acb9a 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/rcupdate.h>
 #include <linux/slab.h>
 #include <linux/list.h>
+#include <linux/rculist.h>
 #include <linux/delay.h>
 #include <linux/if_arp.h>
 
 #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;
@@ -70,41 +67,13 @@ struct sw_table_dummy {
 };
 
 
-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)
 {
        struct sw_table_dummy *td = (struct sw_table_dummy *) swt;
        struct sw_flow *flow;
        list_for_each_entry (flow, &td->flows, node) {
-               if (flow_matches(&flow->key, key)) {
+               if (flow_matches_1wild(key, &flow->key)) {
                        return flow; 
                }
        }
@@ -121,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;
@@ -130,9 +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)
 {
+       /* 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);
-       table_dummy_flow_deferred_free(flow);
+       flow_deferred_free(flow);
        return 1;
 }
 
@@ -157,44 +130,33 @@ 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;
+       uint64_t byte_count = 0;
+       int reason;
 
        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".
+               /* xxx Retrieve the packet and byte counts associated with this
+                * entry xxx and store them in "packet_count" and "byte_count".
                 */
 
-               if ((packet_count > flow->packet_count)
-                    && (flow->max_idle != OFP_FLOW_PERMANENT)) {
+               if (packet_count != flow->packet_count) {
                        flow->packet_count = packet_count;
-                       flow->timeout = jiffies + HZ * flow->max_idle;
+                       flow->byte_count = byte_count;
+                       flow->used = jiffies;
                }
 
-               if (flow_timeout(flow)) {
+               reason = flow_timeout(flow);
+               if (reason >= 0) {
                        if (dp->flags & OFPC_SEND_FLOW_EXP) {
                                /* xxx Get byte count */
                                flow->byte_count = 0;
-                               dp_send_flow_expired(dp, flow);
+                               dp_send_flow_expired(dp, flow, reason);
                        }
                        del_count += do_delete(swt, flow);
                }
-               if ((i % 50) == 0) {
-                       msleep_interruptible(1);
-               }
-               i++;
-       }
-
-       /* 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);
        mutex_unlock(&dp_mutex);
 
        td->n_flows -= del_count;
@@ -229,13 +191,14 @@ static int table_dummy_iterate(struct sw_table *swt,
                               int (*callback)(struct sw_flow *, void *),
                               void *private)
 {
-       struct sw_table_dummy *tl = (struct sw_table_dummy *) swt;
+       struct sw_table_dummy *td = (struct sw_table_dummy *) swt;
        struct sw_flow *flow;
        unsigned long start;
 
        start = ~position->private[0];
-       list_for_each_entry (flow, &tl->iter_flows, iter_node) {
-               if (flow->serial <= start && flow_matches(key, &flow->key)) {
+       list_for_each_entry (flow, &td->iter_flows, iter_node) {
+               if (flow->serial <= start && flow_matches_2wild(key,
+                                                               &flow->key)) {
                        int error = callback(flow, private);
                        if (error) {
                                position->private[0] = ~flow->serial;
@@ -251,8 +214,10 @@ 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 = td->n_flows;
+       stats->wildcards = OFPFW_ALL;      /* xxx Set this appropriately */
+       stats->n_flows   = td->n_flows;
        stats->max_flows = td->max_flows;
+       stats->n_matched = swt->n_matched;
 }
 
 
@@ -280,9 +245,6 @@ static struct sw_table *table_dummy_create(void)
        INIT_LIST_HEAD(&td->iter_flows);
        td->next_serial = 0;
 
-       INIT_LIST_HEAD(&pending_free_list);
-       spin_lock_init(&pending_free_lock);
-
        return swt;
 }