Line data Source code
1 : /* SPDX-License-Identifier: Apache-2.0
2 : * Copyright(c) 2021 Cisco Systems, Inc.
3 : */
4 :
5 : #include <vppinfra/clib.h>
6 : #include <vlib/vlib.h>
7 : #include <vppinfra/vector/mask_compare.h>
8 : #include <vppinfra/vector/compress.h>
9 :
10 : static_always_inline u32
11 7344990 : enqueue_one (vlib_main_t *vm, vlib_node_runtime_t *node,
12 : vlib_frame_bitmap_t used_elt_bmp, u16 next_index, u32 *buffers,
13 : u16 *nexts, u32 n_buffers, u32 n_left, u32 *tmp, u8 maybe_aux,
14 : u32 *aux_data, u32 *tmp_aux)
15 : {
16 : vlib_frame_bitmap_t match_bmp;
17 : vlib_frame_t *f;
18 : u32 n_extracted, n_free;
19 : u32 *to, *to_aux;
20 :
21 7344990 : f = vlib_get_next_frame_internal (vm, node, next_index, 0);
22 :
23 7344980 : maybe_aux = maybe_aux && f->aux_offset;
24 :
25 7344980 : n_free = VLIB_FRAME_SIZE - f->n_vectors;
26 :
27 : /* if frame contains enough space for worst case scenario, we can avoid
28 : * use of tmp */
29 7344980 : if (n_free >= n_left)
30 : {
31 7331930 : to = (u32 *) vlib_frame_vector_args (f) + f->n_vectors;
32 7331930 : if (maybe_aux)
33 0 : to_aux = (u32 *) vlib_frame_aux_args (f) + f->n_vectors;
34 : }
35 : else
36 : {
37 13051 : to = tmp;
38 13051 : if (maybe_aux)
39 0 : to_aux = tmp_aux;
40 : }
41 7344980 : clib_mask_compare_u16 (next_index, nexts, match_bmp, n_buffers);
42 7344980 : n_extracted = clib_compress_u32 (to, buffers, match_bmp, n_buffers);
43 7344980 : if (maybe_aux)
44 0 : clib_compress_u32 (to_aux, aux_data, match_bmp, n_buffers);
45 7344980 : vlib_frame_bitmap_or (used_elt_bmp, match_bmp);
46 :
47 7344980 : if (to != tmp)
48 : {
49 : /* indices already written to frame, just close it */
50 7331930 : vlib_put_next_frame (vm, node, next_index, n_free - n_extracted);
51 : }
52 13051 : else if (n_free >= n_extracted)
53 : {
54 : /* enough space in the existing frame */
55 25 : to = (u32 *) vlib_frame_vector_args (f) + f->n_vectors;
56 25 : vlib_buffer_copy_indices (to, tmp, n_extracted);
57 25 : if (maybe_aux)
58 : {
59 0 : to_aux = (u32 *) vlib_frame_aux_args (f) + f->n_vectors;
60 0 : vlib_buffer_copy_indices (to_aux, tmp_aux, n_extracted);
61 : }
62 25 : vlib_put_next_frame (vm, node, next_index, n_free - n_extracted);
63 : }
64 : else
65 : {
66 : /* full frame */
67 13026 : to = (u32 *) vlib_frame_vector_args (f) + f->n_vectors;
68 13026 : vlib_buffer_copy_indices (to, tmp, n_free);
69 13026 : if (maybe_aux)
70 : {
71 0 : to_aux = (u32 *) vlib_frame_aux_args (f) + f->n_vectors;
72 0 : vlib_buffer_copy_indices (to_aux, tmp_aux, n_free);
73 : }
74 13026 : vlib_put_next_frame (vm, node, next_index, 0);
75 :
76 : /* second frame */
77 13026 : u32 n_2nd_frame = n_extracted - n_free;
78 13026 : f = vlib_get_next_frame_internal (vm, node, next_index, 1);
79 13026 : to = vlib_frame_vector_args (f);
80 13026 : vlib_buffer_copy_indices (to, tmp + n_free, n_2nd_frame);
81 13026 : if (maybe_aux)
82 : {
83 0 : to_aux = vlib_frame_aux_args (f);
84 0 : vlib_buffer_copy_indices (to_aux, tmp_aux + n_free, n_2nd_frame);
85 : }
86 13026 : vlib_put_next_frame (vm, node, next_index,
87 : VLIB_FRAME_SIZE - n_2nd_frame);
88 : }
89 :
90 7344980 : return n_left - n_extracted;
91 : }
92 :
93 : static_always_inline void
94 6926650 : vlib_buffer_enqueue_to_next_fn_inline (vlib_main_t *vm,
95 : vlib_node_runtime_t *node, u32 *buffers,
96 : u32 *aux_data, u16 *nexts, uword count,
97 : u8 maybe_aux)
98 : {
99 : u32 tmp[VLIB_FRAME_SIZE];
100 : u32 tmp_aux[VLIB_FRAME_SIZE];
101 : u32 n_left;
102 : u16 next_index;
103 :
104 7123370 : while (count >= VLIB_FRAME_SIZE)
105 : {
106 196725 : vlib_frame_bitmap_t used_elt_bmp = {};
107 196725 : n_left = VLIB_FRAME_SIZE;
108 196725 : u32 off = 0;
109 :
110 196725 : next_index = nexts[0];
111 196725 : n_left = enqueue_one (vm, node, used_elt_bmp, next_index, buffers, nexts,
112 : VLIB_FRAME_SIZE, n_left, tmp, maybe_aux, aux_data,
113 : tmp_aux);
114 :
115 209873 : while (n_left)
116 : {
117 14191 : while (PREDICT_FALSE (used_elt_bmp[off] == ~0))
118 : {
119 1042 : off++;
120 1042 : ASSERT (off < ARRAY_LEN (used_elt_bmp));
121 : }
122 :
123 13149 : next_index =
124 13149 : nexts[off * 64 + count_trailing_zeros (~used_elt_bmp[off])];
125 13149 : n_left = enqueue_one (vm, node, used_elt_bmp, next_index, buffers,
126 : nexts, VLIB_FRAME_SIZE, n_left, tmp, maybe_aux,
127 : aux_data, tmp_aux);
128 : }
129 :
130 196724 : buffers += VLIB_FRAME_SIZE;
131 196724 : if (maybe_aux)
132 0 : aux_data += VLIB_FRAME_SIZE;
133 196724 : nexts += VLIB_FRAME_SIZE;
134 196724 : count -= VLIB_FRAME_SIZE;
135 : }
136 :
137 6926650 : if (count)
138 : {
139 6729920 : vlib_frame_bitmap_t used_elt_bmp = {};
140 6729920 : next_index = nexts[0];
141 6729920 : n_left = count;
142 6729920 : u32 off = 0;
143 :
144 6729920 : n_left = enqueue_one (vm, node, used_elt_bmp, next_index, buffers, nexts,
145 : count, n_left, tmp, maybe_aux, aux_data, tmp_aux);
146 :
147 7135110 : while (n_left)
148 : {
149 495704 : while (PREDICT_FALSE (used_elt_bmp[off] == ~0))
150 : {
151 90510 : off++;
152 90510 : ASSERT (off < ARRAY_LEN (used_elt_bmp));
153 : }
154 :
155 405194 : next_index =
156 405194 : nexts[off * 64 + count_trailing_zeros (~used_elt_bmp[off])];
157 : n_left =
158 405194 : enqueue_one (vm, node, used_elt_bmp, next_index, buffers, nexts,
159 : count, n_left, tmp, maybe_aux, aux_data, tmp_aux);
160 : }
161 : }
162 6926650 : }
163 :
164 : void __clib_section (".vlib_buffer_enqueue_to_next_fn")
165 6926650 : CLIB_MULTIARCH_FN (vlib_buffer_enqueue_to_next_fn)
166 : (vlib_main_t *vm, vlib_node_runtime_t *node, u32 *buffers, u16 *nexts,
167 : uword count)
168 : {
169 6926650 : vlib_buffer_enqueue_to_next_fn_inline (vm, node, buffers, NULL, nexts, count,
170 : 0 /* maybe_aux */);
171 6926650 : }
172 :
173 2236 : CLIB_MARCH_FN_REGISTRATION (vlib_buffer_enqueue_to_next_fn);
174 :
175 : void __clib_section (".vlib_buffer_enqueue_to_next_with_aux_fn")
176 0 : CLIB_MULTIARCH_FN (vlib_buffer_enqueue_to_next_with_aux_fn)
177 : (vlib_main_t *vm, vlib_node_runtime_t *node, u32 *buffers, u32 *aux_data,
178 : u16 *nexts, uword count)
179 : {
180 0 : vlib_buffer_enqueue_to_next_fn_inline (vm, node, buffers, aux_data, nexts,
181 : count, 1 /* maybe_aux */);
182 0 : }
183 :
184 2236 : CLIB_MARCH_FN_REGISTRATION (vlib_buffer_enqueue_to_next_with_aux_fn);
185 :
186 : static_always_inline void
187 97 : vlib_buffer_enqueue_to_single_next_fn_inline (vlib_main_t *vm,
188 : vlib_node_runtime_t *node,
189 : u32 *buffers, u32 *aux_data,
190 : u16 next_index, u32 count,
191 : u8 with_aux)
192 : {
193 : u32 *to_next, *to_next_aux, n_left_to_next, n_enq;
194 :
195 97 : if (with_aux)
196 0 : vlib_get_next_frame_with_aux (vm, node, next_index, to_next, to_next_aux,
197 : n_left_to_next);
198 : else
199 97 : vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
200 :
201 97 : if (PREDICT_TRUE (n_left_to_next >= count))
202 : {
203 97 : vlib_buffer_copy_indices (to_next, buffers, count);
204 97 : if (with_aux)
205 0 : vlib_buffer_copy_indices (to_next_aux, aux_data, count);
206 97 : n_left_to_next -= count;
207 97 : vlib_put_next_frame (vm, node, next_index, n_left_to_next);
208 97 : return;
209 : }
210 :
211 0 : n_enq = n_left_to_next;
212 0 : next:
213 0 : vlib_buffer_copy_indices (to_next, buffers, n_enq);
214 0 : if (with_aux)
215 0 : vlib_buffer_copy_indices (to_next_aux, aux_data, n_enq);
216 0 : n_left_to_next -= n_enq;
217 :
218 0 : if (PREDICT_FALSE (count > n_enq))
219 : {
220 0 : count -= n_enq;
221 0 : buffers += n_enq;
222 0 : if (with_aux)
223 0 : aux_data += n_enq;
224 :
225 0 : vlib_put_next_frame (vm, node, next_index, n_left_to_next);
226 0 : if (with_aux)
227 0 : vlib_get_next_frame_with_aux (vm, node, next_index, to_next,
228 : to_next_aux, n_left_to_next);
229 : else
230 0 : vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
231 0 : n_enq = clib_min (n_left_to_next, count);
232 0 : goto next;
233 : }
234 0 : vlib_put_next_frame (vm, node, next_index, n_left_to_next);
235 : }
236 :
237 : void __clib_section (".vlib_buffer_enqueue_to_single_next_fn")
238 97 : CLIB_MULTIARCH_FN (vlib_buffer_enqueue_to_single_next_fn)
239 : (vlib_main_t *vm, vlib_node_runtime_t *node, u32 *buffers, u16 next_index,
240 : u32 count)
241 : {
242 97 : vlib_buffer_enqueue_to_single_next_fn_inline (
243 : vm, node, buffers, NULL, next_index, count, 0 /* with_aux */);
244 97 : }
245 2236 : CLIB_MARCH_FN_REGISTRATION (vlib_buffer_enqueue_to_single_next_fn);
246 :
247 : void __clib_section (".vlib_buffer_enqueue_to_single_next_with_aux_fn")
248 0 : CLIB_MULTIARCH_FN (vlib_buffer_enqueue_to_single_next_with_aux_fn)
249 : (vlib_main_t *vm, vlib_node_runtime_t *node, u32 *buffers, u32 *aux_data,
250 : u16 next_index, u32 count)
251 : {
252 0 : vlib_buffer_enqueue_to_single_next_fn_inline (
253 : vm, node, buffers, aux_data, next_index, count, 1 /* with_aux */);
254 0 : }
255 2236 : CLIB_MARCH_FN_REGISTRATION (vlib_buffer_enqueue_to_single_next_with_aux_fn);
256 :
257 : static inline vlib_frame_queue_elt_t *
258 656 : vlib_get_frame_queue_elt (vlib_frame_queue_main_t *fqm, u32 index,
259 : int dont_wait)
260 : {
261 : vlib_frame_queue_t *fq;
262 : u64 nelts, tail, new_tail;
263 :
264 656 : fq = vec_elt (fqm->vlib_frame_queues, index);
265 656 : ASSERT (fq);
266 656 : nelts = fq->nelts;
267 :
268 656 : retry:
269 656 : tail = __atomic_load_n (&fq->tail, __ATOMIC_ACQUIRE);
270 656 : new_tail = tail + 1;
271 :
272 656 : if (new_tail >= fq->head + nelts)
273 : {
274 0 : if (dont_wait)
275 0 : return 0;
276 :
277 : /* Wait until a ring slot is available */
278 0 : while (new_tail >= fq->head + nelts)
279 0 : vlib_worker_thread_barrier_check ();
280 : }
281 :
282 656 : if (!__atomic_compare_exchange_n (&fq->tail, &tail, new_tail, 0 /* weak */,
283 : __ATOMIC_RELAXED, __ATOMIC_RELAXED))
284 0 : goto retry;
285 :
286 656 : return fq->elts + (new_tail & (nelts - 1));
287 : }
288 :
289 : static_always_inline u32
290 613 : vlib_buffer_enqueue_to_thread_inline (vlib_main_t *vm,
291 : vlib_node_runtime_t *node,
292 : vlib_frame_queue_main_t *fqm,
293 : u32 *buffer_indices, u16 *thread_indices,
294 : u32 n_packets, int drop_on_congestion,
295 : int with_aux, u32 *aux_data)
296 : {
297 613 : u32 drop_list[VLIB_FRAME_SIZE], n_drop = 0;
298 613 : vlib_frame_bitmap_t mask, used_elts = {};
299 613 : vlib_frame_queue_elt_t *hf = 0;
300 : u16 thread_index;
301 613 : u32 n_comp, off = 0, n_left = n_packets;
302 :
303 613 : thread_index = thread_indices[0];
304 :
305 656 : more:
306 656 : clib_mask_compare_u16 (thread_index, thread_indices, mask, n_packets);
307 656 : hf = vlib_get_frame_queue_elt (fqm, thread_index, drop_on_congestion);
308 :
309 656 : n_comp = clib_compress_u32 (hf ? hf->buffer_index : drop_list + n_drop,
310 : buffer_indices, mask, n_packets);
311 655 : if (with_aux)
312 0 : clib_compress_u32 (hf ? hf->aux_data : drop_list + n_drop, aux_data, mask,
313 : n_packets);
314 :
315 655 : if (hf)
316 : {
317 655 : if (node->flags & VLIB_NODE_FLAG_TRACE)
318 607 : hf->maybe_trace = 1;
319 655 : hf->n_vectors = n_comp;
320 655 : __atomic_store_n (&hf->valid, 1, __ATOMIC_RELEASE);
321 655 : vlib_get_main_by_index (thread_index)->check_frame_queues = 1;
322 : }
323 : else
324 0 : n_drop += n_comp;
325 :
326 656 : n_left -= n_comp;
327 :
328 656 : if (n_left)
329 : {
330 43 : vlib_frame_bitmap_or (used_elts, mask);
331 :
332 43 : while (PREDICT_FALSE (used_elts[off] == ~0))
333 : {
334 0 : off++;
335 0 : ASSERT (off < ARRAY_LEN (used_elts));
336 : }
337 :
338 43 : thread_index =
339 43 : thread_indices[off * 64 + count_trailing_zeros (~used_elts[off])];
340 43 : goto more;
341 : }
342 :
343 613 : if (drop_on_congestion && n_drop)
344 0 : vlib_buffer_free (vm, drop_list, n_drop);
345 :
346 613 : return n_packets - n_drop;
347 : }
348 :
349 : u32 __clib_section (".vlib_buffer_enqueue_to_thread_fn")
350 613 : CLIB_MULTIARCH_FN (vlib_buffer_enqueue_to_thread_fn)
351 : (vlib_main_t *vm, vlib_node_runtime_t *node, u32 frame_queue_index,
352 : u32 *buffer_indices, u16 *thread_indices, u32 n_packets,
353 : int drop_on_congestion)
354 : {
355 613 : vlib_thread_main_t *tm = vlib_get_thread_main ();
356 : vlib_frame_queue_main_t *fqm;
357 613 : u32 n_enq = 0;
358 :
359 613 : fqm = vec_elt_at_index (tm->frame_queue_mains, frame_queue_index);
360 :
361 683 : while (n_packets >= VLIB_FRAME_SIZE)
362 : {
363 70 : n_enq += vlib_buffer_enqueue_to_thread_inline (
364 : vm, node, fqm, buffer_indices, thread_indices, VLIB_FRAME_SIZE,
365 : drop_on_congestion, 0 /* with_aux */, NULL);
366 70 : buffer_indices += VLIB_FRAME_SIZE;
367 70 : thread_indices += VLIB_FRAME_SIZE;
368 70 : n_packets -= VLIB_FRAME_SIZE;
369 : }
370 :
371 613 : if (n_packets == 0)
372 70 : return n_enq;
373 :
374 543 : n_enq += vlib_buffer_enqueue_to_thread_inline (
375 : vm, node, fqm, buffer_indices, thread_indices, n_packets,
376 : drop_on_congestion, 0 /* with_aux */, NULL);
377 :
378 543 : return n_enq;
379 : }
380 :
381 : u32 __clib_section (".vlib_buffer_enqueue_to_thread_with_aux_fn")
382 0 : CLIB_MULTIARCH_FN (vlib_buffer_enqueue_to_thread_with_aux_fn)
383 : (vlib_main_t *vm, vlib_node_runtime_t *node, u32 frame_queue_index,
384 : u32 *buffer_indices, u32 *aux, u16 *thread_indices, u32 n_packets,
385 : int drop_on_congestion)
386 : {
387 0 : vlib_thread_main_t *tm = vlib_get_thread_main ();
388 : vlib_frame_queue_main_t *fqm;
389 0 : u32 n_enq = 0;
390 :
391 0 : fqm = vec_elt_at_index (tm->frame_queue_mains, frame_queue_index);
392 :
393 0 : while (n_packets >= VLIB_FRAME_SIZE)
394 : {
395 0 : n_enq += vlib_buffer_enqueue_to_thread_inline (
396 : vm, node, fqm, buffer_indices, thread_indices, VLIB_FRAME_SIZE,
397 : drop_on_congestion, 1 /* with_aux */, aux);
398 0 : buffer_indices += VLIB_FRAME_SIZE;
399 0 : thread_indices += VLIB_FRAME_SIZE;
400 0 : n_packets -= VLIB_FRAME_SIZE;
401 : }
402 :
403 0 : if (n_packets == 0)
404 0 : return n_enq;
405 :
406 0 : n_enq += vlib_buffer_enqueue_to_thread_inline (
407 : vm, node, fqm, buffer_indices, thread_indices, n_packets,
408 : drop_on_congestion, 1 /* with_aux */, aux);
409 :
410 0 : return n_enq;
411 : }
412 :
413 2236 : CLIB_MARCH_FN_REGISTRATION (vlib_buffer_enqueue_to_thread_fn);
414 2236 : CLIB_MARCH_FN_REGISTRATION (vlib_buffer_enqueue_to_thread_with_aux_fn);
415 :
416 : static_always_inline u32
417 2058870 : vlib_frame_queue_dequeue_inline (vlib_main_t *vm, vlib_frame_queue_main_t *fqm,
418 : u8 with_aux)
419 : {
420 2058870 : u32 thread_id = vm->thread_index;
421 2058870 : vlib_frame_queue_t *fq = fqm->vlib_frame_queues[thread_id];
422 2058870 : u32 mask = fq->nelts - 1;
423 : vlib_frame_queue_elt_t *elt;
424 2058870 : u32 n_free, n_copy, *from, *from_aux, *to = 0, *to_aux = 0, processed = 0,
425 2058870 : vectors = 0;
426 2058870 : vlib_frame_t *f = 0;
427 :
428 2058870 : ASSERT (fq);
429 2058870 : ASSERT (vm == vlib_global_main.vlib_mains[thread_id]);
430 :
431 2059240 : if (PREDICT_FALSE (fqm->node_index == ~0))
432 0 : return 0;
433 : /*
434 : * Gather trace data for frame queues
435 : */
436 2059240 : if (PREDICT_FALSE (fq->trace))
437 : {
438 : frame_queue_trace_t *fqt;
439 : frame_queue_nelt_counter_t *fqh;
440 : u32 elix;
441 :
442 0 : fqt = &fqm->frame_queue_traces[thread_id];
443 :
444 0 : fqt->nelts = fq->nelts;
445 0 : fqt->head = fq->head;
446 0 : fqt->tail = fq->tail;
447 0 : fqt->threshold = fq->vector_threshold;
448 0 : fqt->n_in_use = fqt->tail - fqt->head;
449 0 : if (fqt->n_in_use >= fqt->nelts)
450 : {
451 : // if beyond max then use max
452 0 : fqt->n_in_use = fqt->nelts - 1;
453 : }
454 :
455 : /* Record the number of elements in use in the histogram */
456 0 : fqh = &fqm->frame_queue_histogram[thread_id];
457 0 : fqh->count[fqt->n_in_use]++;
458 :
459 : /* Record a snapshot of the elements in use */
460 0 : for (elix = 0; elix < fqt->nelts; elix++)
461 : {
462 0 : elt = fq->elts + ((fq->head + 1 + elix) & (mask));
463 : if (1 || elt->valid)
464 : {
465 0 : fqt->n_vectors[elix] = elt->n_vectors;
466 : }
467 : }
468 0 : fqt->written = 1;
469 : }
470 :
471 : while (1)
472 : {
473 2059860 : if (fq->head == fq->tail)
474 2059210 : break;
475 :
476 650 : elt = fq->elts + ((fq->head + 1) & mask);
477 :
478 650 : if (!__atomic_load_n (&elt->valid, __ATOMIC_ACQUIRE))
479 0 : break;
480 :
481 650 : from = elt->buffer_index + elt->offset;
482 650 : if (with_aux)
483 0 : from_aux = elt->aux_data + elt->offset;
484 650 : ASSERT (elt->offset + elt->n_vectors <= VLIB_FRAME_SIZE);
485 :
486 650 : if (f == 0)
487 : {
488 607 : f = vlib_get_frame_to_node (vm, fqm->node_index);
489 614 : to = vlib_frame_vector_args (f);
490 613 : if (with_aux)
491 0 : to_aux = vlib_frame_aux_args (f);
492 613 : n_free = VLIB_FRAME_SIZE;
493 : }
494 :
495 656 : if (elt->maybe_trace)
496 604 : f->frame_flags |= VLIB_NODE_FLAG_TRACE;
497 :
498 656 : n_copy = clib_min (n_free, elt->n_vectors);
499 :
500 656 : vlib_buffer_copy_indices (to, from, n_copy);
501 657 : to += n_copy;
502 657 : if (with_aux)
503 : {
504 0 : vlib_buffer_copy_indices (to_aux, from_aux, n_copy);
505 0 : to_aux += n_copy;
506 : }
507 :
508 657 : n_free -= n_copy;
509 657 : vectors += n_copy;
510 :
511 657 : if (n_free == 0)
512 : {
513 73 : f->n_vectors = VLIB_FRAME_SIZE;
514 73 : vlib_put_frame_to_node (vm, fqm->node_index, f);
515 73 : f = 0;
516 : }
517 :
518 657 : if (n_copy < elt->n_vectors)
519 : {
520 : /* not empty - leave it on the ring */
521 10 : elt->n_vectors -= n_copy;
522 10 : elt->offset += n_copy;
523 : }
524 : else
525 : {
526 : /* empty - reset and bump head */
527 647 : u32 sz = STRUCT_OFFSET_OF (vlib_frame_queue_elt_t, end_of_reset);
528 647 : clib_memset (elt, 0, sz);
529 646 : __atomic_store_n (&fq->head, fq->head + 1, __ATOMIC_RELEASE);
530 646 : processed++;
531 : }
532 :
533 : /* Limit the number of packets pushed into the graph */
534 656 : if (vectors >= fq->vector_threshold)
535 33 : break;
536 : }
537 :
538 2059240 : if (f)
539 : {
540 537 : f->n_vectors = VLIB_FRAME_SIZE - n_free;
541 537 : vlib_put_frame_to_node (vm, fqm->node_index, f);
542 : }
543 :
544 2059160 : return processed;
545 : }
546 :
547 : u32 __clib_section (".vlib_frame_queue_dequeue_fn")
548 2058800 : CLIB_MULTIARCH_FN (vlib_frame_queue_dequeue_fn)
549 : (vlib_main_t *vm, vlib_frame_queue_main_t *fqm)
550 : {
551 2058800 : return vlib_frame_queue_dequeue_inline (vm, fqm, 0 /* with_aux */);
552 : }
553 :
554 2236 : CLIB_MARCH_FN_REGISTRATION (vlib_frame_queue_dequeue_fn);
555 :
556 : u32 __clib_section (".vlib_frame_queue_dequeue_with_aux_fn")
557 0 : CLIB_MULTIARCH_FN (vlib_frame_queue_dequeue_with_aux_fn)
558 : (vlib_main_t *vm, vlib_frame_queue_main_t *fqm)
559 : {
560 0 : return vlib_frame_queue_dequeue_inline (vm, fqm, 1 /* with_aux */);
561 : }
562 :
563 2236 : CLIB_MARCH_FN_REGISTRATION (vlib_frame_queue_dequeue_with_aux_fn);
564 :
565 : #ifndef CLIB_MARCH_VARIANT
566 : vlib_buffer_func_main_t vlib_buffer_func_main;
567 :
568 : static clib_error_t *
569 559 : vlib_buffer_funcs_init (vlib_main_t *vm)
570 : {
571 559 : vlib_buffer_func_main_t *bfm = &vlib_buffer_func_main;
572 559 : bfm->buffer_enqueue_to_next_fn =
573 559 : CLIB_MARCH_FN_POINTER (vlib_buffer_enqueue_to_next_fn);
574 559 : bfm->buffer_enqueue_to_next_with_aux_fn =
575 559 : CLIB_MARCH_FN_POINTER (vlib_buffer_enqueue_to_next_with_aux_fn);
576 559 : bfm->buffer_enqueue_to_single_next_fn =
577 559 : CLIB_MARCH_FN_POINTER (vlib_buffer_enqueue_to_single_next_fn);
578 559 : bfm->buffer_enqueue_to_single_next_with_aux_fn =
579 559 : CLIB_MARCH_FN_POINTER (vlib_buffer_enqueue_to_single_next_with_aux_fn);
580 559 : bfm->buffer_enqueue_to_thread_fn =
581 559 : CLIB_MARCH_FN_POINTER (vlib_buffer_enqueue_to_thread_fn);
582 559 : bfm->buffer_enqueue_to_thread_with_aux_fn =
583 559 : CLIB_MARCH_FN_POINTER (vlib_buffer_enqueue_to_thread_with_aux_fn);
584 559 : return 0;
585 : }
586 :
587 1119 : VLIB_INIT_FUNCTION (vlib_buffer_funcs_init);
588 : #endif
|