blob: a747ea9f966a4a89396329e73c394073e389855c [file] [log] [blame]
Ed Warnickecb9cada2015-12-08 15:45:58 -07001/*
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 * buffer.h: VLIB buffers
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_buffer_h
41#define included_vlib_buffer_h
42
43#include <vppinfra/types.h>
44#include <vppinfra/cache.h>
45#include <vppinfra/serialize.h>
46#include <vppinfra/vector.h>
Damjan Marion6b0f5892017-07-27 04:01:24 -040047#include <vppinfra/lock.h>
Ed Warnickecb9cada2015-12-08 15:45:58 -070048#include <vlib/error.h> /* for vlib_error_t */
Damjan Marion19010202016-03-24 17:17:47 +010049
Dave Barach9b8ffd92016-07-08 08:13:45 -040050#include <vlib/config.h> /* for __PRE_DATA_SIZE */
Damjan Marion19010202016-03-24 17:17:47 +010051#define VLIB_BUFFER_PRE_DATA_SIZE __PRE_DATA_SIZE
Ed Warnickecb9cada2015-12-08 15:45:58 -070052
Damjan Marion5de3fec2019-02-06 14:22:32 +010053#define VLIB_BUFFER_DEFAULT_DATA_SIZE (2048)
54
Damjan Marionbd0da972018-10-31 10:59:02 +010055/* Minimum buffer chain segment size. Does not apply to last buffer in chain.
56 Dataplane code can safely asume that specified amount of data is not split
57 into 2 chained buffers */
58#define VLIB_BUFFER_MIN_CHAIN_SEG_SIZE (128)
59
60/* Amount of head buffer data copied to each replica head buffer */
61#define VLIB_BUFFER_CLONE_HEAD_SIZE (256)
62
Ed Warnickecb9cada2015-12-08 15:45:58 -070063/** \file
64 vlib buffer structure definition and a few select
65 access methods. This structure and the buffer allocation
Dave Barach9b8ffd92016-07-08 08:13:45 -040066 mechanism should perhaps live in vnet, but it would take a lot
Ed Warnickecb9cada2015-12-08 15:45:58 -070067 of typing to make it so.
68*/
Dave Barach9b8ffd92016-07-08 08:13:45 -040069
Damjan Mariondac03522018-02-01 15:30:13 +010070/**
71 * Buffer Flags
72 */
73#define foreach_vlib_buffer_flag \
Damjan Marion36eb7c22019-01-18 20:45:30 +010074 _( 0, IS_TRACED, 0) \
Benoît Ganne43543172019-10-21 15:13:54 +020075 _( 1, NEXT_PRESENT, "next-present") \
Damjan Marion36eb7c22019-01-18 20:45:30 +010076 _( 2, TOTAL_LENGTH_VALID, 0) \
77 _( 3, EXT_HDR_VALID, "ext-hdr-valid")
Damjan Mariondac03522018-02-01 15:30:13 +010078
79/* NOTE: only buffer generic flags should be defined here, please consider
80 using user flags. i.e. src/vnet/buffer.h */
81
82enum
83{
84#define _(bit, name, v) VLIB_BUFFER_##name = (1 << (bit)),
85 foreach_vlib_buffer_flag
86#undef _
87};
88
89enum
90{
91#define _(bit, name, v) VLIB_BUFFER_LOG2_##name = (bit),
92 foreach_vlib_buffer_flag
93#undef _
94};
95
96 /* User defined buffer flags. */
97#define LOG2_VLIB_BUFFER_FLAG_USER(n) (32 - (n))
98#define VLIB_BUFFER_FLAG_USER(n) (1 << LOG2_VLIB_BUFFER_FLAG_USER(n))
Damjan Marion36eb7c22019-01-18 20:45:30 +010099#define VLIB_BUFFER_FLAGS_ALL (0x0f)
Damjan Mariondac03522018-02-01 15:30:13 +0100100
Benoît Gannef89bbbe2021-03-04 14:31:03 +0100101/** \brief Compile time buffer trajectory tracing option
102 Turn this on if you run into "bad monkey" contexts,
103 and you want to know exactly which nodes they've visited...
104 See vlib/main.c...
105*/
106#ifndef VLIB_BUFFER_TRACE_TRAJECTORY
107#define VLIB_BUFFER_TRACE_TRAJECTORY 0
108#endif /* VLIB_BUFFER_TRACE_TRAJECTORY */
109
Damjan Marionbf236632023-10-13 09:59:00 +0000110#define vlib_buffer_template_fields \
111 /** signed offset in data[], pre_data[] that we are currently \
112 * processing. If negative current header points into predata area. */ \
113 i16 current_data; \
114 \
115 /** Nbytes between current data and the end of this buffer. */ \
116 u16 current_length; \
117 /** buffer flags: \
118 <br> VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list \
119 index, <br> VLIB_BUFFER_IS_TRACED: trace this buffer. <br> \
120 VLIB_BUFFER_NEXT_PRESENT: this is a multi-chunk buffer. <br> \
121 VLIB_BUFFER_TOTAL_LENGTH_VALID: as it says <br> \
122 VLIB_BUFFER_EXT_HDR_VALID: buffer contains valid external buffer manager \
123 header, set to avoid adding it to a flow report <br> \
124 VLIB_BUFFER_FLAG_USER(n): user-defined bit N \
125 */ \
126 u32 flags; \
127 \
128 /** Generic flow identifier */ \
129 u32 flow_id; \
130 \
131 /** Reference count for this buffer. */ \
132 volatile u8 ref_count; \
133 \
134 /** index of buffer pool this buffer belongs. */ \
135 u8 buffer_pool_index; \
136 \
137 /** Error code for buffers to be enqueued to error handler. */ \
138 vlib_error_t error; \
139 \
140 /** Next buffer for this linked-list of buffers. Only valid if \
141 * VLIB_BUFFER_NEXT_PRESENT flag is set. */ \
142 u32 next_buffer; \
143 \
144 /** The following fields can be in a union because once a packet enters \
145 * the punt path, it is no longer on a feature arc */ \
146 union \
147 { \
148 /** Used by feature subgraph arcs to visit enabled feature nodes */ \
149 u32 current_config_index; \
150 /* the reason the packet once punted */ \
151 u32 punt_reason; \
152 }; \
153 \
154 /** Opaque data used by sub-graphs for their own purposes. */ \
155 u32 opaque[10];
156
157typedef struct
158{
159 CLIB_ALIGN_MARK (align_mark, 64);
160 vlib_buffer_template_fields
161} vlib_buffer_template_t;
162
163STATIC_ASSERT_SIZEOF (vlib_buffer_template_t, 64);
164
Damjan Marion9a8a12a2019-01-23 16:52:10 +0100165/** VLIB buffer representation. */
166typedef union
Dave Barach9b8ffd92016-07-08 08:13:45 -0400167{
Damjan Marionbf236632023-10-13 09:59:00 +0000168 CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
Damjan Marion9a8a12a2019-01-23 16:52:10 +0100169 struct
170 {
Neale Ranns76b56492018-09-28 15:16:14 +0000171 union
172 {
Damjan Marionbf236632023-10-13 09:59:00 +0000173 struct
174 {
175 vlib_buffer_template_fields
176 };
177 vlib_buffer_template_t template;
Neale Ranns76b56492018-09-28 15:16:14 +0000178 };
Damjan Marion072401e2017-07-13 18:53:27 +0200179
Damjan Marionbf236632023-10-13 09:59:00 +0000180 /* Data above is initialized or zeroed on alloc, data bellow is not
181 * and it is app responsibility to ensure data is valid */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700182
Damjan Marion6807b772020-11-13 10:46:32 +0100183 /** start of 2nd half (2nd cacheline on systems where cacheline size is 64) */
184 CLIB_ALIGN_MARK (second_half, 64);
Damjan Marion9a8a12a2019-01-23 16:52:10 +0100185
Dave Baracha638c182019-06-21 18:24:07 -0400186 /** Specifies trace buffer handle if VLIB_PACKET_IS_TRACED flag is
Damjan Marion9a8a12a2019-01-23 16:52:10 +0100187 * set. */
Dave Baracha638c182019-06-21 18:24:07 -0400188 u32 trace_handle;
Damjan Marion9a8a12a2019-01-23 16:52:10 +0100189
190 /** Only valid for first buffer in chain. Current length plus total length
191 * given here give total number of bytes in buffer chain. */
192 u32 total_length_not_including_first_buffer;
193
194 /**< More opaque data, see ../vnet/vnet/buffer.h */
195 u32 opaque2[14];
196
Benoît Gannef89bbbe2021-03-04 14:31:03 +0100197#if VLIB_BUFFER_TRACE_TRAJECTORY > 0
198 /** trace trajectory data - we use a specific cacheline for that in the
199 * buffer when it is compiled-in */
200#define VLIB_BUFFER_TRACE_TRAJECTORY_MAX 31
201#define VLIB_BUFFER_TRACE_TRAJECTORY_SZ 64
202#define VLIB_BUFFER_TRACE_TRAJECTORY_INIT(b) (b)->trajectory_nb = 0
203 CLIB_ALIGN_MARK (trajectory, 64);
204 u16 trajectory_nb;
205 u16 trajectory_trace[VLIB_BUFFER_TRACE_TRAJECTORY_MAX];
206#else /* VLIB_BUFFER_TRACE_TRAJECTORY */
207#define VLIB_BUFFER_TRACE_TRAJECTORY_SZ 0
208#define VLIB_BUFFER_TRACE_TRAJECTORY_INIT(b)
209#endif /* VLIB_BUFFER_TRACE_TRAJECTORY */
210
Damjan Marion6807b772020-11-13 10:46:32 +0100211 /** start of buffer headroom */
212 CLIB_ALIGN_MARK (headroom, 64);
Damjan Marion9a8a12a2019-01-23 16:52:10 +0100213
214 /** Space for inserting data before buffer start. Packet rewrite string
215 * will be rewritten backwards and may extend back before
216 * buffer->data[0]. Must come directly before packet data. */
217 u8 pre_data[VLIB_BUFFER_PRE_DATA_SIZE];
218
219 /** Packet data */
Benoît Ganne049d0b42020-04-24 11:48:04 +0200220 u8 data[];
Damjan Marion9a8a12a2019-01-23 16:52:10 +0100221 };
222#ifdef CLIB_HAVE_VEC128
223 u8x16 as_u8x16[4];
224#endif
225#ifdef CLIB_HAVE_VEC256
Damjan Marion22f23ae2019-01-24 15:36:57 +0100226 u8x32 as_u8x32[2];
Damjan Marion9a8a12a2019-01-23 16:52:10 +0100227#endif
228#ifdef CLIB_HAVE_VEC512
Damjan Marion22f23ae2019-01-24 15:36:57 +0100229 u8x64 as_u8x64[1];
Damjan Marion9a8a12a2019-01-23 16:52:10 +0100230#endif
231} vlib_buffer_t;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700232
Benoît Gannef89bbbe2021-03-04 14:31:03 +0100233STATIC_ASSERT_SIZEOF (vlib_buffer_t, 128 + VLIB_BUFFER_TRACE_TRAJECTORY_SZ +
234 VLIB_BUFFER_PRE_DATA_SIZE);
Damjan Marion6807b772020-11-13 10:46:32 +0100235STATIC_ASSERT (VLIB_BUFFER_PRE_DATA_SIZE % CLIB_CACHE_LINE_BYTES == 0,
236 "VLIB_BUFFER_PRE_DATA_SIZE must be divisible by cache line size");
237
Damjan Marion19010202016-03-24 17:17:47 +0100238#define VLIB_BUFFER_HDR_SIZE (sizeof(vlib_buffer_t) - VLIB_BUFFER_PRE_DATA_SIZE)
Damjan Marion2d725c62023-11-13 12:18:24 +0000239#define VLIB_BUFFER_INVALID_INDEX 0xffffffff
Damjan Marion19010202016-03-24 17:17:47 +0100240
Ed Warnickecb9cada2015-12-08 15:45:58 -0700241/** \brief Prefetch buffer metadata.
242 The first 64 bytes of buffer contains most header information
243
244 @param b - (vlib_buffer_t *) pointer to the buffer
245 @param type - LOAD, STORE. In most cases, STORE is the right answer
246*/
247
248#define vlib_prefetch_buffer_header(b,type) CLIB_PREFETCH (b, 64, type)
Damjan Mariond30bf012018-11-18 23:48:43 +0100249#define vlib_prefetch_buffer_data(b,type) \
250 CLIB_PREFETCH (vlib_buffer_get_current(b), CLIB_CACHE_LINE_BYTES, type)
Ed Warnickecb9cada2015-12-08 15:45:58 -0700251
Ed Warnickecb9cada2015-12-08 15:45:58 -0700252always_inline void
253vlib_buffer_struct_is_sane (vlib_buffer_t * b)
254{
255 ASSERT (sizeof (b[0]) % 64 == 0);
256
257 /* Rewrite data must be before and contiguous with packet data. */
258 ASSERT (b->pre_data + VLIB_BUFFER_PRE_DATA_SIZE == b->data);
259}
260
Damjan Marion8f499362018-10-22 13:07:02 +0200261always_inline uword
262vlib_buffer_get_va (vlib_buffer_t * b)
263{
264 return pointer_to_uword (b->data);
265}
266
Ed Warnickecb9cada2015-12-08 15:45:58 -0700267/** \brief Get pointer to current data to process
268
269 @param b - (vlib_buffer_t *) pointer to the buffer
270 @return - (void *) (b->data + b->current_data)
Dave Barach9b8ffd92016-07-08 08:13:45 -0400271*/
Ed Warnickecb9cada2015-12-08 15:45:58 -0700272
273always_inline void *
274vlib_buffer_get_current (vlib_buffer_t * b)
275{
276 /* Check bounds. */
277 ASSERT ((signed) b->current_data >= (signed) -VLIB_BUFFER_PRE_DATA_SIZE);
278 return b->data + b->current_data;
279}
280
Damjan Marion8f499362018-10-22 13:07:02 +0200281always_inline uword
282vlib_buffer_get_current_va (vlib_buffer_t * b)
283{
284 return vlib_buffer_get_va (b) + b->current_data;
285}
286
Ed Warnickecb9cada2015-12-08 15:45:58 -0700287/** \brief Advance current data pointer by the supplied (signed!) amount
288
289 @param b - (vlib_buffer_t *) pointer to the buffer
290 @param l - (word) signed increment
Dave Barach9b8ffd92016-07-08 08:13:45 -0400291*/
Ed Warnickecb9cada2015-12-08 15:45:58 -0700292always_inline void
293vlib_buffer_advance (vlib_buffer_t * b, word l)
294{
295 ASSERT (b->current_length >= l);
296 b->current_data += l;
297 b->current_length -= l;
Damjan Marionbd0da972018-10-31 10:59:02 +0100298
299 ASSERT ((b->flags & VLIB_BUFFER_NEXT_PRESENT) == 0 ||
300 b->current_length >= VLIB_BUFFER_MIN_CHAIN_SEG_SIZE);
Ed Warnickecb9cada2015-12-08 15:45:58 -0700301}
302
Filip Tehlar816f4372017-04-26 16:09:06 +0200303/** \brief Check if there is enough space in buffer to advance
304
305 @param b - (vlib_buffer_t *) pointer to the buffer
306 @param l - (word) size to check
307 @return - 0 if there is less space than 'l' in buffer
308*/
309always_inline u8
310vlib_buffer_has_space (vlib_buffer_t * b, word l)
311{
312 return b->current_length >= l;
313}
314
Ed Warnickecb9cada2015-12-08 15:45:58 -0700315/** \brief Reset current header & length to state they were in when
316 packet was received.
317
318 @param b - (vlib_buffer_t *) pointer to the buffer
319*/
320
321always_inline void
322vlib_buffer_reset (vlib_buffer_t * b)
323{
324 b->current_length += clib_max (b->current_data, 0);
325 b->current_data = 0;
326}
327
328/** \brief Get pointer to buffer's opaque data array
329
330 @param b - (vlib_buffer_t *) pointer to the buffer
331 @return - (void *) b->opaque
332*/
333always_inline void *
334vlib_get_buffer_opaque (vlib_buffer_t * b)
Dave Barach9b8ffd92016-07-08 08:13:45 -0400335{
336 return (void *) b->opaque;
337}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700338
339/** \brief Get pointer to buffer's opaque2 data array
340
341 @param b - (vlib_buffer_t *) pointer to the buffer
342 @return - (void *) b->opaque2
343*/
344always_inline void *
345vlib_get_buffer_opaque2 (vlib_buffer_t * b)
Dave Barach9b8ffd92016-07-08 08:13:45 -0400346{
347 return (void *) b->opaque2;
348}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700349
Dave Barach68b0fb02017-02-28 15:15:56 -0500350/** \brief Get pointer to the end of buffer's data
351 * @param b pointer to the buffer
352 * @return pointer to tail of packet's data
353 */
354always_inline u8 *
355vlib_buffer_get_tail (vlib_buffer_t * b)
356{
357 return b->data + b->current_data + b->current_length;
358}
359
360/** \brief Append uninitialized data to buffer
361 * @param b pointer to the buffer
362 * @param size number of uninitialized bytes
363 * @return pointer to beginning of uninitialized data
364 */
365always_inline void *
Eyal Barid3d42412018-11-05 13:29:25 +0200366vlib_buffer_put_uninit (vlib_buffer_t * b, u16 size)
Dave Barach68b0fb02017-02-28 15:15:56 -0500367{
368 void *p = vlib_buffer_get_tail (b);
369 /* XXX make sure there's enough space */
370 b->current_length += size;
371 return p;
372}
373
374/** \brief Prepend uninitialized data to buffer
375 * @param b pointer to the buffer
376 * @param size number of uninitialized bytes
377 * @return pointer to beginning of uninitialized data
378 */
379always_inline void *
380vlib_buffer_push_uninit (vlib_buffer_t * b, u8 size)
381{
382 ASSERT (b->current_data + VLIB_BUFFER_PRE_DATA_SIZE >= size);
383 b->current_data -= size;
384 b->current_length += size;
385
386 return vlib_buffer_get_current (b);
387}
388
389/** \brief Make head room, typically for packet headers
390 * @param b pointer to the buffer
391 * @param size number of head room bytes
392 * @return pointer to start of buffer (current data)
393 */
394always_inline void *
395vlib_buffer_make_headroom (vlib_buffer_t * b, u8 size)
396{
Dave Barach68b0fb02017-02-28 15:15:56 -0500397 b->current_data += size;
398 return vlib_buffer_get_current (b);
399}
400
Dave Baracha638c182019-06-21 18:24:07 -0400401/** \brief Construct a trace handle from thread and pool index
402 * @param thread Thread id
403 * @param pool_index Pool index
404 * @return trace handle
405 */
406always_inline u32
407vlib_buffer_make_trace_handle (u32 thread, u32 pool_index)
408{
409 u32 rv;
410 ASSERT (thread < 0xff);
411 ASSERT (pool_index < 0x00FFFFFF);
412 rv = (thread << 24) | (pool_index & 0x00FFFFFF);
413 return rv;
414}
415
416/** \brief Extract the thread id from a trace handle
417 * @param trace_handle the trace handle
418 * @return the thread id
419 */
420always_inline u32
421vlib_buffer_get_trace_thread (vlib_buffer_t * b)
422{
423 u32 trace_handle = b->trace_handle;
424
425 return trace_handle >> 24;
426}
427
428/** \brief Extract the trace (pool) index from a trace handle
429 * @param trace_handle the trace handle
430 * @return the trace index
431 */
432always_inline u32
433vlib_buffer_get_trace_index (vlib_buffer_t * b)
434{
435 u32 trace_handle = b->trace_handle;
436 return trace_handle & 0x00FFFFFF;
437}
438
Dave Barach68b0fb02017-02-28 15:15:56 -0500439/** \brief Retrieve bytes from buffer head
440 * @param b pointer to the buffer
441 * @param size number of bytes to pull
442 * @return pointer to start of buffer (current data)
443 */
444always_inline void *
445vlib_buffer_pull (vlib_buffer_t * b, u8 size)
446{
447 if (b->current_length + VLIB_BUFFER_PRE_DATA_SIZE < size)
448 return 0;
449
450 void *data = vlib_buffer_get_current (b);
451 vlib_buffer_advance (b, size);
452 return data;
453}
454
Ed Warnickecb9cada2015-12-08 15:45:58 -0700455/* Forward declaration. */
456struct vlib_main_t;
457
Damjan Marionb6e8b1a2019-03-12 18:14:15 +0100458#define VLIB_BUFFER_POOL_PER_THREAD_CACHE_SZ 512
459
Dave Barach9b8ffd92016-07-08 08:13:45 -0400460typedef struct
461{
Damjan Marion910d3692019-01-21 11:48:34 +0100462 CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
Damjan Marionb6e8b1a2019-03-12 18:14:15 +0100463 u32 cached_buffers[VLIB_BUFFER_POOL_PER_THREAD_CACHE_SZ];
464 u32 n_cached;
Damjan Marion910d3692019-01-21 11:48:34 +0100465} vlib_buffer_pool_thread_t;
Damjan Marionb6e8b1a2019-03-12 18:14:15 +0100466
Damjan Marion878c6092017-01-04 13:19:27 +0100467typedef struct
468{
Damjan Marion04a7f052017-07-10 15:06:17 +0200469 CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
Damjan Marion149ba772017-10-12 13:09:26 +0200470 uword start;
471 uword size;
Damjan Marion65dc34b2023-10-06 10:59:32 +0200472 u8 log2_page_size;
Damjan Marion910d3692019-01-21 11:48:34 +0100473 u8 index;
Damjan Marion65dc34b2023-10-06 10:59:32 +0200474 u8 numa_node;
Damjan Marion68b4da62018-09-30 18:26:20 +0200475 u32 physmem_map_index;
Damjan Marion910d3692019-01-21 11:48:34 +0100476 u32 data_size;
Damjan Marion65dc34b2023-10-06 10:59:32 +0200477 u32 alloc_size;
Damjan Marion910d3692019-01-21 11:48:34 +0100478 u32 n_buffers;
Damjan Marionb6e8b1a2019-03-12 18:14:15 +0100479 u32 n_avail;
Damjan Mariond1274cb2018-03-13 21:32:17 +0100480 u32 *buffers;
Damjan Marion910d3692019-01-21 11:48:34 +0100481 u8 *name;
Damjan Mariond1274cb2018-03-13 21:32:17 +0100482 clib_spinlock_t lock;
Damjan Marion910d3692019-01-21 11:48:34 +0100483
484 /* per-thread data */
485 vlib_buffer_pool_thread_t *threads;
486
487 /* buffer metadata template */
Damjan Marionbf236632023-10-13 09:59:00 +0000488 vlib_buffer_template_t buffer_template;
Damjan Marion149ba772017-10-12 13:09:26 +0200489} vlib_buffer_pool_t;
490
Damjan Marionb592d1b2019-02-28 23:16:11 +0100491#define VLIB_BUFFER_MAX_NUMA_NODES 32
492
Benoît Gannee09a2332021-03-09 15:37:49 +0100493typedef u32 (vlib_buffer_alloc_free_callback_t) (struct vlib_main_t *vm,
494 u8 buffer_pool_index,
495 u32 *buffers, u32 n_buffers);
496
Damjan Marion149ba772017-10-12 13:09:26 +0200497typedef struct
498{
499 CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
Damjan Marion04a7f052017-07-10 15:06:17 +0200500 /* Virtual memory address and size of buffer memory, used for calculating
501 buffer index */
502 uword buffer_mem_start;
503 uword buffer_mem_size;
Damjan Marion149ba772017-10-12 13:09:26 +0200504 vlib_buffer_pool_t *buffer_pools;
Damjan Marion04a7f052017-07-10 15:06:17 +0200505
Benoît Gannee09a2332021-03-09 15:37:49 +0100506 vlib_buffer_alloc_free_callback_t *alloc_callback_fn;
507 vlib_buffer_alloc_free_callback_t *free_callback_fn;
508
Damjan Marionb592d1b2019-02-28 23:16:11 +0100509 u8 default_buffer_pool_index_for_numa[VLIB_BUFFER_MAX_NUMA_NODES];
Ed Warnickecb9cada2015-12-08 15:45:58 -0700510
Damjan Marion910d3692019-01-21 11:48:34 +0100511 /* config */
512 u32 buffers_per_numa;
513 u16 ext_hdr_size;
Damjan Marion5de3fec2019-02-06 14:22:32 +0100514 u32 default_data_size;
Nathan Skrzypczak61559022020-11-23 16:25:21 +0100515 clib_mem_page_sz_t log2_page_size;
Damjan Marion910d3692019-01-21 11:48:34 +0100516
Benoît Gannee09a2332021-03-09 15:37:49 +0100517 /* Hash table mapping buffer index into number
518 0 => allocated but free, 1 => allocated and not-free.
519 If buffer index is not in hash table then this buffer
520 has never been allocated. */
521 uword *buffer_known_hash;
522 clib_spinlock_t buffer_known_hash_lockp;
523
Damjan Marion910d3692019-01-21 11:48:34 +0100524 /* logging */
525 vlib_log_class_t log_default;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700526} vlib_buffer_main_t;
527
Damjan Marion49d66f12017-07-20 18:10:35 +0200528clib_error_t *vlib_buffer_main_init (struct vlib_main_t *vm);
Damjan Marion878c6092017-01-04 13:19:27 +0100529
Benoît Gannee09a2332021-03-09 15:37:49 +0100530format_function_t format_vlib_buffer_pool_all;
531
532int vlib_buffer_set_alloc_free_callback (
533 struct vlib_main_t *vm, vlib_buffer_alloc_free_callback_t *alloc_callback_fn,
534 vlib_buffer_alloc_free_callback_t *free_callback_fn);
535
Damjan Marion910d3692019-01-21 11:48:34 +0100536extern u16 __vlib_buffer_external_hdr_size;
537#define VLIB_BUFFER_SET_EXT_HDR_SIZE(x) \
538static void __clib_constructor \
539vnet_buffer_set_ext_hdr_size() \
540{ \
541 if (__vlib_buffer_external_hdr_size) \
542 clib_error ("buffer external header space already set"); \
543 __vlib_buffer_external_hdr_size = CLIB_CACHE_LINE_ROUND (x); \
544}
Dave Barach9b8ffd92016-07-08 08:13:45 -0400545
Damjan Marion910d3692019-01-21 11:48:34 +0100546#endif /* included_vlib_buffer_h */
Damjan Marion04a7f052017-07-10 15:06:17 +0200547
Dave Barach9b8ffd92016-07-08 08:13:45 -0400548/*
549 * fd.io coding-style-patch-verification: ON
550 *
551 * Local Variables:
552 * eval: (c-set-style "gnu")
553 * End:
554 */