aboutsummaryrefslogtreecommitdiffstats
path: root/net/openvswitch/flow.c
diff options
context:
space:
mode:
authorDavid Vrabel <david.vrabel@citrix.com>2014-04-07 08:52:12 -0400
committerDavid Vrabel <david.vrabel@citrix.com>2014-04-07 08:52:12 -0400
commit2c5cb2770392fb9c5d8518688c8bc61986d70dc6 (patch)
treeb19210e709de6ee0d22b67ef605a569500cf1a18 /net/openvswitch/flow.c
parentcd979883b9ede90643e019f33cb317933eb867b4 (diff)
parent683b6c6f82a60fabf47012581c2cfbf1b037ab95 (diff)
Merge commit '683b6c6f82a60fabf47012581c2cfbf1b037ab95' into stable/for-linus-3.15
This merge of the irq-core-for-linus branch broke the ARM build when Xen is enabled. Conflicts: drivers/xen/events/events_base.c
Diffstat (limited to 'net/openvswitch/flow.c')
-rw-r--r--net/openvswitch/flow.c29
1 files changed, 8 insertions, 21 deletions
diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c
index 16f4b46161d4..2998989e76db 100644
--- a/net/openvswitch/flow.c
+++ b/net/openvswitch/flow.c
@@ -73,6 +73,7 @@ void ovs_flow_stats_update(struct sw_flow *flow, struct sk_buff *skb)
73 73
74 if ((flow->key.eth.type == htons(ETH_P_IP) || 74 if ((flow->key.eth.type == htons(ETH_P_IP) ||
75 flow->key.eth.type == htons(ETH_P_IPV6)) && 75 flow->key.eth.type == htons(ETH_P_IPV6)) &&
76 flow->key.ip.frag != OVS_FRAG_TYPE_LATER &&
76 flow->key.ip.proto == IPPROTO_TCP && 77 flow->key.ip.proto == IPPROTO_TCP &&
77 likely(skb->len >= skb_transport_offset(skb) + sizeof(struct tcphdr))) { 78 likely(skb->len >= skb_transport_offset(skb) + sizeof(struct tcphdr))) {
78 tcp_flags = TCP_FLAGS_BE16(tcp_hdr(skb)); 79 tcp_flags = TCP_FLAGS_BE16(tcp_hdr(skb));
@@ -91,7 +92,7 @@ static void stats_read(struct flow_stats *stats,
91 unsigned long *used, __be16 *tcp_flags) 92 unsigned long *used, __be16 *tcp_flags)
92{ 93{
93 spin_lock(&stats->lock); 94 spin_lock(&stats->lock);
94 if (time_after(stats->used, *used)) 95 if (!*used || time_after(stats->used, *used))
95 *used = stats->used; 96 *used = stats->used;
96 *tcp_flags |= stats->tcp_flags; 97 *tcp_flags |= stats->tcp_flags;
97 ovs_stats->n_packets += stats->packet_count; 98 ovs_stats->n_packets += stats->packet_count;
@@ -102,30 +103,24 @@ static void stats_read(struct flow_stats *stats,
102void ovs_flow_stats_get(struct sw_flow *flow, struct ovs_flow_stats *ovs_stats, 103void ovs_flow_stats_get(struct sw_flow *flow, struct ovs_flow_stats *ovs_stats,
103 unsigned long *used, __be16 *tcp_flags) 104 unsigned long *used, __be16 *tcp_flags)
104{ 105{
105 int cpu, cur_cpu; 106 int cpu;
106 107
107 *used = 0; 108 *used = 0;
108 *tcp_flags = 0; 109 *tcp_flags = 0;
109 memset(ovs_stats, 0, sizeof(*ovs_stats)); 110 memset(ovs_stats, 0, sizeof(*ovs_stats));
110 111
112 local_bh_disable();
111 if (!flow->stats.is_percpu) { 113 if (!flow->stats.is_percpu) {
112 stats_read(flow->stats.stat, ovs_stats, used, tcp_flags); 114 stats_read(flow->stats.stat, ovs_stats, used, tcp_flags);
113 } else { 115 } else {
114 cur_cpu = get_cpu();
115 for_each_possible_cpu(cpu) { 116 for_each_possible_cpu(cpu) {
116 struct flow_stats *stats; 117 struct flow_stats *stats;
117 118
118 if (cpu == cur_cpu)
119 local_bh_disable();
120
121 stats = per_cpu_ptr(flow->stats.cpu_stats, cpu); 119 stats = per_cpu_ptr(flow->stats.cpu_stats, cpu);
122 stats_read(stats, ovs_stats, used, tcp_flags); 120 stats_read(stats, ovs_stats, used, tcp_flags);
123
124 if (cpu == cur_cpu)
125 local_bh_enable();
126 } 121 }
127 put_cpu();
128 } 122 }
123 local_bh_enable();
129} 124}
130 125
131static void stats_reset(struct flow_stats *stats) 126static void stats_reset(struct flow_stats *stats)
@@ -140,25 +135,17 @@ static void stats_reset(struct flow_stats *stats)
140 135
141void ovs_flow_stats_clear(struct sw_flow *flow) 136void ovs_flow_stats_clear(struct sw_flow *flow)
142{ 137{
143 int cpu, cur_cpu; 138 int cpu;
144 139
140 local_bh_disable();
145 if (!flow->stats.is_percpu) { 141 if (!flow->stats.is_percpu) {
146 stats_reset(flow->stats.stat); 142 stats_reset(flow->stats.stat);
147 } else { 143 } else {
148 cur_cpu = get_cpu();
149
150 for_each_possible_cpu(cpu) { 144 for_each_possible_cpu(cpu) {
151
152 if (cpu == cur_cpu)
153 local_bh_disable();
154
155 stats_reset(per_cpu_ptr(flow->stats.cpu_stats, cpu)); 145 stats_reset(per_cpu_ptr(flow->stats.cpu_stats, cpu));
156
157 if (cpu == cur_cpu)
158 local_bh_enable();
159 } 146 }
160 put_cpu();
161 } 147 }
148 local_bh_enable();
162} 149}
163 150
164static int check_header(struct sk_buff *skb, int len) 151static int check_header(struct sk_buff *skb, int len)