datapath: Per cpu flow stats.
[sliver-openvswitch.git] / datapath / flow_table.c
index b014d92..c2a7aa5 100644 (file)
@@ -76,15 +76,19 @@ void ovs_flow_mask_key(struct sw_flow_key *dst, const struct sw_flow_key *src,
 struct sw_flow *ovs_flow_alloc(void)
 {
        struct sw_flow *flow;
+       int cpu;
 
        flow = kmem_cache_alloc(flow_cache, GFP_KERNEL);
        if (!flow)
                return ERR_PTR(-ENOMEM);
 
-       spin_lock_init(&flow->lock);
        flow->sf_acts = NULL;
        flow->mask = NULL;
 
+       memset(flow->stats, 0, num_possible_cpus() * sizeof(struct sw_flow_stats));
+       for_each_possible_cpu(cpu)
+               spin_lock_init(&flow->stats[cpu].lock);
+
        return flow;
 }
 
@@ -575,11 +579,15 @@ int ovs_flow_tbl_insert(struct flow_table *table, struct sw_flow *flow,
  * Returns zero if successful or a negative error code. */
 int ovs_flow_init(void)
 {
+       int flow_size;
+
        BUILD_BUG_ON(__alignof__(struct sw_flow_key) % __alignof__(long));
        BUILD_BUG_ON(sizeof(struct sw_flow_key) % sizeof(long));
 
-       flow_cache = kmem_cache_create("sw_flow", sizeof(struct sw_flow), 0,
-                                       0, NULL);
+       flow_size = sizeof(struct sw_flow) +
+                   (num_possible_cpus() * sizeof(struct sw_flow_stats));
+
+       flow_cache = kmem_cache_create("sw_flow", flow_size, 0, 0, NULL);
        if (flow_cache == NULL)
                return -ENOMEM;