FD.io VPP  v21.06-1-gbb7418cf9
Vector Packet Processing
counter.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 /*
16  * counter.h: simple and packet/byte counters
17  *
18  * Copyright (c) 2008 Eliot Dresselhaus
19  *
20  * Permission is hereby granted, free of charge, to any person obtaining
21  * a copy of this software and associated documentation files (the
22  * "Software"), to deal in the Software without restriction, including
23  * without limitation the rights to use, copy, modify, merge, publish,
24  * distribute, sublicense, and/or sell copies of the Software, and to
25  * permit persons to whom the Software is furnished to do so, subject to
26  * the following conditions:
27  *
28  * The above copyright notice and this permission notice shall be
29  * included in all copies or substantial portions of the Software.
30  *
31  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
32  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
33  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
34  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
35  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
36  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
37  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38  */
39 
40 #ifndef included_vlib_counter_h
41 #define included_vlib_counter_h
42 
43 #include <vlib/counter_types.h>
44 
45 /** \file
46 
47  Optimized thread-safe counters.
48 
49  Each vlib_[simple|combined]_counter_main_t consists of a per-thread
50  vector of per-object counters.
51 
52  The idea is to drastically eliminate atomic operations.
53 */
54 
55 /** A collection of simple counters */
56 
57 typedef struct
58 {
59  counter_t **counters; /**< Per-thread u64 non-atomic counters */
60  char *name; /**< The counter collection's name. */
61  char *stat_segment_name; /**< Name in stat segment directory */
63 
64 /** The number of counters (not the number of per-thread counters) */
66 
67 /** Increment a simple counter
68  @param cm - (vlib_simple_counter_main_t *) simple counter main pointer
69  @param thread_index - (u32) the current cpu index
70  @param index - (u32) index of the counter to increment
71  @param increment - (u64) quantitiy to add to the counter
72 */
73 always_inline void
75  u32 thread_index, u32 index, u64 increment)
76 {
77  counter_t *my_counters;
78 
79  my_counters = cm->counters[thread_index];
80  my_counters[index] += increment;
81 }
82 
83 /** Decrement a simple counter
84  @param cm - (vlib_simple_counter_main_t *) simple counter main pointer
85  @param thread_index - (u32) the current cpu index
86  @param index - (u32) index of the counter to increment
87  @param increment - (u64) quantitiy remove from the counter value
88 */
89 always_inline void
91  u32 thread_index, u32 index, u64 decrement)
92 {
93  counter_t *my_counters;
94 
95  my_counters = cm->counters[thread_index];
96 
97  ASSERT (my_counters[index] >= decrement);
98 
99  my_counters[index] -= decrement;
100 }
101 
102 /** Set a simple counter
103  @param cm - (vlib_simple_counter_main_t *) simple counter main pointer
104  @param thread_index - (u32) the current cpu index
105  @param index - (u32) index of the counter to increment
106  @param value - (u64) quantitiy to set to the counter
107 */
108 always_inline void
111 {
112  counter_t *my_counters;
113 
114  my_counters = cm->counters[thread_index];
115  my_counters[index] = value;
116 }
117 
118 /** Get the value of a simple counter
119  Scrapes the entire set of per-thread counters. Innacurate unless
120  worker threads which might increment the counter are
121  barrier-synchronized
122 
123  @param cm - (vlib_simple_counter_main_t *) simple counter main pointer
124  @param index - (u32) index of the counter to fetch
125  @returns - (u64) current counter value
126 */
129 {
130  counter_t *my_counters;
131  counter_t v;
132  int i;
133 
134  ASSERT (index < vlib_simple_counter_n_counters (cm));
135 
136  v = 0;
137 
138  for (i = 0; i < vec_len (cm->counters); i++)
139  {
140  my_counters = cm->counters[i];
141  v += my_counters[index];
142  }
143 
144  return v;
145 }
146 
147 /** Clear a simple counter
148  Clears the set of per-thread u16 counters, and the u64 counter
149 
150  @param cm - (vlib_simple_counter_main_t *) simple counter main pointer
151  @param index - (u32) index of the counter to clear
152 */
153 always_inline void
155 {
156  counter_t *my_counters;
157  int i;
158 
159  ASSERT (index < vlib_simple_counter_n_counters (cm));
160 
161  for (i = 0; i < vec_len (cm->counters); i++)
162  {
163  my_counters = cm->counters[i];
164  my_counters[index] = 0;
165  }
166 }
167 
168 /** Add two combined counters, results in the first counter
169  @param [in,out] a - (vlib_counter_t *) dst counter
170  @param b - (vlib_counter_t *) src counter
171 */
172 
173 always_inline void
175 {
176  a->packets += b->packets;
177  a->bytes += b->bytes;
178 }
179 
180 /** Subtract combined counters, results in the first counter
181  @param [in,out] a - (vlib_counter_t *) dst counter
182  @param b - (vlib_counter_t *) src counter
183 */
184 always_inline void
186 {
187  ASSERT (a->packets >= b->packets);
188  ASSERT (a->bytes >= b->bytes);
189  a->packets -= b->packets;
190  a->bytes -= b->bytes;
191 }
192 
193 /** Clear a combined counter
194  @param a - (vlib_counter_t *) counter to clear
195 */
196 always_inline void
198 {
199  a->packets = a->bytes = 0;
200 }
201 
202 /** A collection of combined counters */
203 typedef struct
204 {
205  vlib_counter_t **counters; /**< Per-thread u64 non-atomic counter pairs */
206  char *name; /**< The counter collection's name. */
207  char *stat_segment_name; /**< Name in stat segment directory */
209 
210 /** The number of counters (not the number of per-thread counters) */
212  cm);
213 
214 /** Clear a collection of simple counters
215  @param cm - (vlib_simple_counter_main_t *) collection to clear
216 */
218 
219 /** Clear a collection of combined counters
220  @param cm - (vlib_combined_counter_main_t *) collection to clear
221 */
223 
224 /** Increment a combined counter
225  @param cm - (vlib_combined_counter_main_t *) comined counter main pointer
226  @param thread_index - (u32) the current cpu index
227  @param index - (u32) index of the counter to increment
228  @param packet_increment - (u64) number of packets to add to the counter
229  @param byte_increment - (u64) number of bytes to add to the counter
230 */
231 
232 always_inline void
235  u32 index, u64 n_packets, u64 n_bytes)
236 {
237  vlib_counter_t *my_counters;
238 
239  /* Use this CPU's counter array */
240  my_counters = cm->counters[thread_index];
241 
242  my_counters[index].packets += n_packets;
243  my_counters[index].bytes += n_bytes;
244 }
245 
246 /** Pre-fetch a per-thread combined counter for the given object index */
247 always_inline void
250 {
251  vlib_counter_t *cpu_counters;
252 
253  /*
254  * This CPU's index is assumed to already be in cache
255  */
256  cpu_counters = cm->counters[thread_index];
257  CLIB_PREFETCH (cpu_counters + index, CLIB_CACHE_LINE_BYTES, STORE);
258 }
259 
260 
261 /** Get the value of a combined counter, never called in the speed path
262  Scrapes the entire set of per-thread counters. Innacurate unless
263  worker threads which might increment the counter are
264  barrier-synchronized
265 
266  @param cm - (vlib_combined_counter_main_t *) combined counter main pointer
267  @param index - (u32) index of the combined counter to fetch
268  @param result [out] - (vlib_counter_t *) result stored here
269 */
270 
271 static inline void
273  u32 index, vlib_counter_t * result)
274 {
275  vlib_counter_t *my_counters, *counter;
276  int i;
277 
278  result->packets = 0;
279  result->bytes = 0;
280 
281  for (i = 0; i < vec_len (cm->counters); i++)
282  {
283  my_counters = cm->counters[i];
284 
285  counter = vec_elt_at_index (my_counters, index);
286  result->packets += counter->packets;
287  result->bytes += counter->bytes;
288  }
289 }
290 
291 /** Clear a combined counter
292  Clears the set of per-thread counters.
293 
294  @param cm - (vlib_combined_counter_main_t *) combined counter main pointer
295  @param index - (u32) index of the counter to clear
296 */
297 always_inline void
299 {
300  vlib_counter_t *my_counters, *counter;
301  int i;
302 
303  for (i = 0; i < vec_len (cm->counters); i++)
304  {
305  my_counters = cm->counters[i];
306 
307  counter = vec_elt_at_index (my_counters, index);
308  counter->packets = 0;
309  counter->bytes = 0;
310  }
311 }
312 
313 /** validate a simple counter
314  @param cm - (vlib_simple_counter_main_t *) pointer to the counter collection
315  @param index - (u32) index of the counter to validate
316 */
317 
319  u32 index);
321 
322 /** validate a combined counter
323  @param cm - (vlib_combined_counter_main_t *) pointer to the counter
324  collection
325  @param index - (u32) index of the counter to validate
326 */
327 
329  u32 index);
332 
334 
335 /** Obtain the number of simple or combined counters allocated.
336  A macro which reduces to to vec_len(cm->maxi), the answer in either
337  case.
338 
339  @param cm - (vlib_simple_counter_main_t) or
340  (vlib_combined_counter_main_t) the counter collection to interrogate
341  @returns vec_len(cm->maxi)
342 */
343 #define vlib_counter_len(cm) vec_len((cm)->maxi)
344 
345 #endif /* included_vlib_counter_h */
346 
347 /*
348  * fd.io coding-style-patch-verification: ON
349  *
350  * Local Variables:
351  * eval: (c-set-style "gnu")
352  * End:
353  */
static void vlib_decrement_simple_counter(vlib_simple_counter_main_t *cm, u32 thread_index, u32 index, u64 decrement)
Decrement a simple counter.
Definition: counter.h:90
void vlib_clear_combined_counters(vlib_combined_counter_main_t *cm)
Clear a collection of combined counters.
Definition: counter.c:61
a
Definition: bitmap.h:544
void vlib_validate_simple_counter(vlib_simple_counter_main_t *cm, u32 index)
validate a simple counter
Definition: counter.c:79
static void vlib_increment_combined_counter(vlib_combined_counter_main_t *cm, u32 thread_index, u32 index, u64 n_packets, u64 n_bytes)
Increment a combined counter.
Definition: counter.h:233
char * stat_segment_name
Name in stat segment directory.
Definition: counter.h:207
u32 n_bytes
u32 thread_index
unsigned long u64
Definition: types.h:89
Combined counter to hold both packets and byte differences.
Definition: counter_types.h:26
static void vlib_increment_simple_counter(vlib_simple_counter_main_t *cm, u32 thread_index, u32 index, u64 increment)
Increment a simple counter.
Definition: counter.h:74
static void vlib_counter_zero(vlib_counter_t *a)
Clear a combined counter.
Definition: counter.h:197
vlib_buffer_t ** b
vlib_counter_t ** counters
Per-thread u64 non-atomic counter pairs.
Definition: counter.h:205
unsigned int u32
Definition: types.h:88
static counter_t vlib_get_simple_counter(vlib_simple_counter_main_t *cm, u32 index)
Get the value of a simple counter Scrapes the entire set of per-thread counters.
Definition: counter.h:128
uint64_t counter_t
64bit counters
Definition: counter_types.h:22
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
static void vlib_counter_sub(vlib_counter_t *a, vlib_counter_t *b)
Subtract combined counters, results in the first counter.
Definition: counter.h:185
A collection of simple counters.
Definition: counter.h:57
static void vlib_counter_add(vlib_counter_t *a, vlib_counter_t *b)
Add two combined counters, results in the first counter.
Definition: counter.h:174
void vlib_free_combined_counter(vlib_combined_counter_main_t *cm)
Definition: counter.c:177
char * name
The counter collection&#39;s name.
Definition: counter.h:60
static void vlib_zero_combined_counter(vlib_combined_counter_main_t *cm, u32 index)
Clear a combined counter Clears the set of per-thread counters.
Definition: counter.h:298
counter_t packets
packet counter
Definition: counter_types.h:28
static void vlib_prefetch_combined_counter(const vlib_combined_counter_main_t *cm, u32 thread_index, u32 index)
Pre-fetch a per-thread combined counter for the given object index.
Definition: counter.h:248
static void vlib_set_simple_counter(vlib_simple_counter_main_t *cm, u32 thread_index, u32 index, u64 value)
Set a simple counter.
Definition: counter.h:109
static void vlib_get_combined_counter(const vlib_combined_counter_main_t *cm, u32 index, vlib_counter_t *result)
Get the value of a combined counter, never called in the speed path Scrapes the entire set of per-thr...
Definition: counter.h:272
#define CLIB_PREFETCH(addr, size, type)
Definition: cache.h:80
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:261
u32 index
Definition: flow_types.api:221
void vlib_free_simple_counter(vlib_simple_counter_main_t *cm)
Definition: counter.c:105
u32 vlib_simple_counter_n_counters(const vlib_simple_counter_main_t *cm)
The number of counters (not the number of per-thread counters)
Definition: counter.c:198
void vlib_validate_combined_counter(vlib_combined_counter_main_t *cm, u32 index)
validate a combined counter
Definition: counter.c:119
u8 value
Definition: qos.api:54
#define ASSERT(truth)
u32 vlib_combined_counter_n_counters(const vlib_combined_counter_main_t *cm)
The number of counters (not the number of per-thread counters)
Definition: counter.c:191
#define always_inline
Definition: rdma_mlx5dv.h:23
int vlib_validate_combined_counter_will_expand(vlib_combined_counter_main_t *cm, u32 index)
Definition: counter.c:146
static void vlib_zero_simple_counter(vlib_simple_counter_main_t *cm, u32 index)
Clear a simple counter Clears the set of per-thread u16 counters, and the u64 counter.
Definition: counter.h:154
counter_t bytes
byte counter
Definition: counter_types.h:29
char * stat_segment_name
Name in stat segment directory.
Definition: counter.h:61
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
char * name
The counter collection&#39;s name.
Definition: counter.h:206
A collection of combined counters.
Definition: counter.h:203
counter_t ** counters
Per-thread u64 non-atomic counters.
Definition: counter.h:59
void vlib_clear_simple_counters(vlib_simple_counter_main_t *cm)
Clear a collection of simple counters.
Definition: counter.c:44
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59