X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=datapath%2Fflow_table.c;h=b20adcb34e750ff3ed97302f2a5d714227dd1f50;hb=b0f3a2feef9889d7e23f7941858c0c40b0505d87;hp=85976514183fd97f80a8c9b37d66ec16fe23b599;hpb=5c89b171e28fb9b1a60992ea65e226273b474c5a;p=sliver-openvswitch.git diff --git a/datapath/flow_table.c b/datapath/flow_table.c index 859765141..b20adcb34 100644 --- a/datapath/flow_table.c +++ b/datapath/flow_table.c @@ -73,7 +73,7 @@ void ovs_flow_mask_key(struct sw_flow_key *dst, const struct sw_flow_key *src, *d++ = *s++ & *m++; } -struct sw_flow *ovs_flow_alloc(void) +struct sw_flow *ovs_flow_alloc(bool percpu_stats) { struct sw_flow *flow; int cpu; @@ -85,11 +85,30 @@ struct sw_flow *ovs_flow_alloc(void) 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); + flow->stats.is_percpu = percpu_stats; + if (!percpu_stats) { + flow->stats.stat = kzalloc(sizeof(*flow->stats.stat), GFP_KERNEL); + if (!flow->stats.stat) + goto err; + + spin_lock_init(&flow->stats.stat->lock); + } else { + flow->stats.cpu_stats = alloc_percpu(struct flow_stats); + if (!flow->stats.cpu_stats) + goto err; + + for_each_possible_cpu(cpu) { + struct flow_stats *cpu_stats; + + cpu_stats = per_cpu_ptr(flow->stats.cpu_stats, cpu); + spin_lock_init(&cpu_stats->lock); + } + } return flow; +err: + kfree(flow); + return ERR_PTR(-ENOMEM); } int ovs_flow_tbl_count(struct flow_table *table) @@ -123,6 +142,10 @@ static struct flex_array *alloc_buckets(unsigned int n_buckets) static void flow_free(struct sw_flow *flow) { kfree((struct sf_flow_acts __force *)flow->sf_acts); + if (flow->stats.is_percpu) + free_percpu(flow->stats.cpu_stats); + else + kfree(flow->stats.stat); kmem_cache_free(flow_cache, flow); }