diff options
Diffstat (limited to 'net/openvswitch/flow.c')
-rw-r--r-- | net/openvswitch/flow.c | 29 |
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, | |||
102 | void ovs_flow_stats_get(struct sw_flow *flow, struct ovs_flow_stats *ovs_stats, | 103 | void 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 | ||
131 | static void stats_reset(struct flow_stats *stats) | 126 | static void stats_reset(struct flow_stats *stats) |
@@ -140,25 +135,17 @@ static void stats_reset(struct flow_stats *stats) | |||
140 | 135 | ||
141 | void ovs_flow_stats_clear(struct sw_flow *flow) | 136 | void 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 | ||
164 | static int check_header(struct sk_buff *skb, int len) | 151 | static int check_header(struct sk_buff *skb, int len) |