FD.io VPP  v18.01.2-1-g9b554f3
Vector Packet Processing
svm_fifo_segment.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 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 #include <svm/svm_fifo_segment.h>
17 
19 
20 static void
22  u32 data_size_in_bytes, int chunk_size)
23 {
24  int freelist_index;
25  u32 size;
26  u8 *fifo_space;
27  u32 rounded_data_size;
28  svm_fifo_t *f;
29  int i;
30 
31  rounded_data_size = (1 << (max_log2 (data_size_in_bytes)));
32  freelist_index = max_log2 (rounded_data_size)
34 
35  /* Calculate space requirement $$$ round-up data_size_in_bytes */
36  size = (sizeof (*f) + rounded_data_size) * chunk_size;
37 
38  /* Allocate fifo space. May fail. */
40  (size, CLIB_CACHE_LINE_BYTES, 0 /* align_offset */ ,
41  0 /* os_out_of_memory */ );
42 
43  /* Out of space.. */
44  if (fifo_space == 0)
45  return;
46 
47  /* Carve fifo space */
48  f = (svm_fifo_t *) fifo_space;
49  for (i = 0; i < chunk_size; i++)
50  {
51  f->freelist_index = freelist_index;
52  f->next = fsh->free_fifos[freelist_index];
53  fsh->free_fifos[freelist_index] = f;
54  fifo_space += sizeof (*f) + rounded_data_size;
55  f = (svm_fifo_t *) fifo_space;
56  }
57 }
58 
59 static void
62 {
63  svm_fifo_segment_header_t *fsh = s->h;
64  u32 rx_fifo_size, tx_fifo_size, pairs_to_allocate;
65  u32 rx_rounded_data_size, tx_rounded_data_size, pair_size;
66  svm_fifo_t *f;
67  u8 *rx_fifo_space, *tx_fifo_space;
68  int rx_freelist_index, tx_freelist_index;
69  int i;
70 
71  /* Parameter check */
72  if (a->rx_fifo_size == 0 || a->tx_fifo_size == 0
73  || a->preallocated_fifo_pairs == 0)
74  return;
75 
78  {
79  clib_warning ("rx fifo_size out of range %d", a->rx_fifo_size);
80  return;
81  }
82 
85  {
86  clib_warning ("tx fifo_size out of range %d", a->rx_fifo_size);
87  return;
88  }
89 
90  rx_rounded_data_size = (1 << (max_log2 (a->rx_fifo_size)));
91 
92  rx_freelist_index = max_log2 (a->rx_fifo_size)
94 
95  tx_rounded_data_size = (1 << (max_log2 (a->rx_fifo_size)));
96 
97  tx_freelist_index = max_log2 (a->tx_fifo_size)
99 
100  /* Calculate space requirements */
101  pair_size = 2 * sizeof (*f) + rx_rounded_data_size + tx_rounded_data_size;
102  pairs_to_allocate = clib_min (s->ssvm.ssvm_size / pair_size,
104  rx_fifo_size = (sizeof (*f) + rx_rounded_data_size) * pairs_to_allocate;
105  tx_fifo_size = (sizeof (*f) + tx_rounded_data_size) * pairs_to_allocate;
106 
108  clib_max (rx_freelist_index, tx_freelist_index),
109  0);
110  if (0)
111  clib_warning ("rx_fifo_size %u (%d mb), tx_fifo_size %u (%d mb)",
112  rx_fifo_size, rx_fifo_size >> 20,
113  tx_fifo_size, tx_fifo_size >> 20);
114 
115  /* Allocate rx fifo space. May fail. */
116  rx_fifo_space = clib_mem_alloc_aligned_at_offset
117  (rx_fifo_size, CLIB_CACHE_LINE_BYTES, 0 /* align_offset */ ,
118  0 /* os_out_of_memory */ );
119 
120  /* Same for TX */
121  tx_fifo_space = clib_mem_alloc_aligned_at_offset
122  (tx_fifo_size, CLIB_CACHE_LINE_BYTES, 0 /* align_offset */ ,
123  0 /* os_out_of_memory */ );
124 
125  /* Make sure it worked. Clean up if it didn't... */
126  if (rx_fifo_space == 0 || tx_fifo_space == 0)
127  {
128  if (rx_fifo_space)
129  clib_mem_free (rx_fifo_space);
130  else
131  clib_warning ("rx fifo preallocation failure: size %d npairs %d",
133 
134  if (tx_fifo_space)
135  clib_mem_free (tx_fifo_space);
136  else
137  clib_warning ("tx fifo preallocation failure: size %d nfifos %d",
139  return;
140  }
141 
142  /* Carve rx fifo space */
143  f = (svm_fifo_t *) rx_fifo_space;
144  for (i = 0; i < pairs_to_allocate; i++)
145  {
146  f->freelist_index = rx_freelist_index;
147  f->next = fsh->free_fifos[rx_freelist_index];
148  fsh->free_fifos[rx_freelist_index] = f;
149  rx_fifo_space += sizeof (*f) + rx_rounded_data_size;
150  f = (svm_fifo_t *) rx_fifo_space;
151  }
152  /* Carve tx fifo space */
153  f = (svm_fifo_t *) tx_fifo_space;
154  for (i = 0; i < pairs_to_allocate; i++)
155  {
156  f->freelist_index = tx_freelist_index;
157  f->next = fsh->free_fifos[tx_freelist_index];
158  fsh->free_fifos[tx_freelist_index] = f;
159  tx_fifo_space += sizeof (*f) + tx_rounded_data_size;
160  f = (svm_fifo_t *) tx_fifo_space;
161  }
162 
163  /* Account for the pairs allocated */
164  a->preallocated_fifo_pairs -= pairs_to_allocate;
165 }
166 
167 /** (master) create an svm fifo segment */
168 int
170 {
171  int rv;
176  void *oldheap;
177 
178  /* Allocate a fresh segment */
179  pool_get (sm->segments, s);
180  memset (s, 0, sizeof (*s));
181 
182  s->ssvm.ssvm_size = a->segment_size;
183  s->ssvm.i_am_master = 1;
184  s->ssvm.my_pid = getpid ();
185  s->ssvm.name = format (0, "%s%c", a->segment_name, 0);
186  s->ssvm.requested_va = sm->next_baseva;
187 
188  rv = ssvm_master_init (&s->ssvm, s - sm->segments);
189 
190  if (rv)
191  {
192  _vec_len (s) = vec_len (s) - 1;
193  return (rv);
194  }
195 
196  /* Note: requested_va updated due to seg base addr randomization */
198 
199  sh = s->ssvm.sh;
200  oldheap = ssvm_push_heap (sh);
201 
202  /* Set up svm_fifo_segment shared header */
203  fsh = clib_mem_alloc (sizeof (*fsh));
204  memset (fsh, 0, sizeof (*fsh));
205  sh->opaque[0] = fsh;
206  s->h = fsh;
207  fsh->segment_name = format (0, "%s%c", a->segment_name, 0);
208  preallocate_fifo_pairs (s, a);
209 
210  ssvm_pop_heap (oldheap);
211 
212  sh->ready = 1;
213  vec_add1 (a->new_segment_indices, s - sm->segments);
214  return (0);
215 }
216 
217 /** Create an svm fifo segment in process-private memory */
218 int
220 {
225  void *oldheap;
226  u8 **heaps = 0;
228  int segment_count = 1;
229  u32 rnd_size = 0;
230  int i;
231 
232  if (a->private_segment_count)
233  {
234  u8 *heap;
235  u32 pagesize = clib_mem_get_page_size ();
236  rnd_size = (a->segment_size + (pagesize - 1)) & ~pagesize;
237 
238  for (i = 0; i < a->private_segment_count; i++)
239  {
240  heap = mheap_alloc (0, rnd_size);
241  if (heap == 0)
242  {
243  clib_unix_warning ("mheap alloc");
244  return -1;
245  }
246  heap_header = mheap_header (heap);
247  heap_header->flags |= MHEAP_FLAG_THREAD_SAFE;
248  vec_add1 (heaps, heap);
249  }
250  segment_count = a->private_segment_count;
251  }
252 
253  /* Allocate segments */
254  for (i = 0; i < segment_count; i++)
255  {
256  pool_get (sm->segments, s);
257  memset (s, 0, sizeof (*s));
258 
259  s->ssvm.ssvm_size = rnd_size;
260  s->ssvm.i_am_master = 1;
261  s->ssvm.my_pid = getpid ();
262  s->ssvm.name = format (0, "%s%c", a->segment_name, 0);
263  s->ssvm.requested_va = ~0;
264 
265  /* Allocate a [sic] shared memory header, in process memory... */
266  sh = clib_mem_alloc_aligned (sizeof (*sh), CLIB_CACHE_LINE_BYTES);
267  s->ssvm.sh = sh;
268 
269  memset (sh, 0, sizeof (*sh));
270  sh->heap = a->private_segment_count ? heaps[i] : clib_mem_get_heap ();
271 
272  /* Set up svm_fifo_segment shared header */
273  fsh = clib_mem_alloc (sizeof (*fsh));
274  memset (fsh, 0, sizeof (*fsh));
275  sh->opaque[0] = fsh;
276  s->h = fsh;
278  if (!a->private_segment_count)
280  fsh->segment_name = format (0, "%s%c", a->segment_name, 0);
281 
282  if (a->private_segment_count)
283  {
284  if (i != 0)
286  oldheap = clib_mem_get_heap ();
287  clib_mem_set_heap (sh->heap);
288  preallocate_fifo_pairs (s, a);
289  clib_mem_set_heap (oldheap);
290  }
291  sh->ready = 1;
292  vec_add1 (a->new_segment_indices, s - sm->segments);
293  }
294  vec_free (heaps);
295  return (0);
296 }
297 
298 /** (slave) attach to an svm fifo segment */
299 int
301 {
302  int rv;
307 
308  /* Allocate a fresh segment */
309  pool_get (sm->segments, s);
310  memset (s, 0, sizeof (*s));
311 
312  s->ssvm.ssvm_size = a->segment_size;
313  s->ssvm.my_pid = getpid ();
314  s->ssvm.name = format (0, "%s%c", a->segment_name, 0);
315  s->ssvm.requested_va = sm->next_baseva;
316 
317  rv = ssvm_slave_init (&s->ssvm, sm->timeout_in_seconds);
318 
319  if (rv)
320  {
321  _vec_len (s) = vec_len (s) - 1;
322  return (rv);
323  }
324 
325  /* Fish the segment header */
326  sh = s->ssvm.sh;
327  fsh = (svm_fifo_segment_header_t *) sh->opaque[0];
328  s->h = fsh;
329 
330  vec_add1 (a->new_segment_indices, s - sm->segments);
331  return (0);
332 }
333 
334 void
336 {
339  {
340  /* Don't try to free vpp's heap! */
341  if (!(s->h->flags & FIFO_SEGMENT_F_IS_MAIN_HEAP))
342  mheap_free (s->ssvm.sh->heap);
343  clib_mem_free (s->ssvm.sh);
344  clib_mem_free (s->h);
345  pool_put (sm->segments, s);
346  }
347  else
348  {
349  ssvm_delete (&s->ssvm);
350  pool_put (sm->segments, s);
351  }
352 }
353 
354 svm_fifo_t *
356  u32 data_size_in_bytes,
357  svm_fifo_segment_freelist_t list_index)
358 {
361  svm_fifo_t *f;
362  void *oldheap;
363  int freelist_index;
364 
365  /*
366  * 4K minimum. It's not likely that anything good will happen
367  * with a smaller FIFO.
368  */
369  if (data_size_in_bytes < FIFO_SEGMENT_MIN_FIFO_SIZE ||
370  data_size_in_bytes > FIFO_SEGMENT_MAX_FIFO_SIZE)
371  {
372  clib_warning ("fifo size out of range %d", data_size_in_bytes);
373  return 0;
374  }
375 
376  freelist_index = max_log2 (data_size_in_bytes)
378 
379  sh = s->ssvm.sh;
380  fsh = (svm_fifo_segment_header_t *) sh->opaque[0];
381 
382  ssvm_lock_non_recursive (sh, 1);
383  oldheap = ssvm_push_heap (sh);
384 
385  switch (list_index)
386  {
389  vec_validate_init_empty (fsh->free_fifos, freelist_index, 0);
390 
391  f = fsh->free_fifos[freelist_index];
392  if (PREDICT_FALSE (f == 0))
393  {
394  allocate_new_fifo_chunk (fsh, data_size_in_bytes,
396  f = fsh->free_fifos[freelist_index];
397  }
398  if (PREDICT_TRUE (f != 0))
399  {
400  fsh->free_fifos[freelist_index] = f->next;
401  /* (re)initialize the fifo, as in svm_fifo_create */
402  memset (f, 0, sizeof (*f));
403  f->nitems = data_size_in_bytes;
404  f->ooos_list_head = OOO_SEGMENT_INVALID_INDEX;
405  f->refcnt = 1;
406  f->freelist_index = freelist_index;
407  goto found;
408  }
409  /* FALLTHROUGH */
411  break;
412 
413  default:
414  clib_warning ("ignore bogus freelist %d", list_index);
415  break;
416  }
417 
418  /* Note: this can fail, in which case: create another segment */
419  f = svm_fifo_create (data_size_in_bytes);
420  if (PREDICT_FALSE (f == 0))
421  {
422  ssvm_pop_heap (oldheap);
424  return (0);
425  }
426  f->freelist_index = freelist_index;
427 
428 found:
429  /* If rx_freelist add to active fifos list. When cleaning up segment,
430  * we need a list of active sessions that should be disconnected. Since
431  * both rx and tx fifos keep pointers to the session, it's enough to track
432  * only one. */
433  if (list_index == FIFO_SEGMENT_RX_FREELIST)
434  {
435  if (fsh->fifos)
436  {
437  fsh->fifos->prev = f;
438  f->next = fsh->fifos;
439  }
440  fsh->fifos = f;
441  }
442  fsh->n_active_fifos++;
443 
444  ssvm_pop_heap (oldheap);
446  return (f);
447 }
448 
449 void
451  svm_fifo_segment_freelist_t list_index)
452 {
455  void *oldheap;
456  int freelist_index;
457 
458  ASSERT (f->refcnt > 0);
459 
460  if (--f->refcnt > 0)
461  return;
462 
463  sh = s->ssvm.sh;
464  fsh = (svm_fifo_segment_header_t *) sh->opaque[0];
465 
466  freelist_index = f->freelist_index;
467 
468  ASSERT (freelist_index < vec_len (fsh->free_fifos));
469 
470  ssvm_lock_non_recursive (sh, 2);
471  oldheap = ssvm_push_heap (sh);
472 
473  switch (list_index)
474  {
476  /* Remove from active list */
477  if (f->prev)
478  f->prev->next = f->next;
479  else
480  fsh->fifos = f->next;
481  if (f->next)
482  f->next->prev = f->prev;
483  /* Fall through: we add only rx fifos to active pool */
485  /* Add to free list */
486  f->next = fsh->free_fifos[freelist_index];
487  f->prev = 0;
488  fsh->free_fifos[freelist_index] = f;
489  break;
491  break;
492 
493  default:
494  clib_warning ("ignore bogus freelist %d", list_index);
495  break;
496  }
497 
498  if (CLIB_DEBUG)
499  {
500  f->master_session_index = ~0;
501  f->master_thread_index = ~0;
502  }
503 
504  fsh->n_active_fifos--;
505  ssvm_pop_heap (oldheap);
507 }
508 
509 void
510 svm_fifo_segment_init (u64 baseva, u32 timeout_in_seconds)
511 {
513 
514  sm->next_baseva = baseva;
515  sm->timeout_in_seconds = timeout_in_seconds;
516 }
517 
518 u32
520 {
521  return s - svm_fifo_segment_main.segments;
522 }
523 
524 /**
525  * Retrieve svm segments pool. Used only for debug purposes.
526  */
529 {
531  return sm->segments;
532 }
533 
534 /**
535  * Get number of active fifos
536  */
537 u32
539 {
540  return fifo_segment->h->n_active_fifos;
541 }
542 
543 u32
545  u32 fifo_size_in_bytes)
546 {
549  svm_fifo_t *f;
550  int i;
551  u32 count = 0, rounded_data_size, freelist_index;
552 
553  sh = fifo_segment->ssvm.sh;
554  fsh = (svm_fifo_segment_header_t *) sh->opaque[0];
555 
556  /* Count all free fifos? */
557  if (fifo_size_in_bytes == ~0)
558  {
559  for (i = 0; i < vec_len (fsh->free_fifos); i++)
560  {
561  f = fsh->free_fifos[i];
562  if (f == 0)
563  continue;
564 
565  while (f)
566  {
567  f = f->next;
568  count++;
569  }
570  }
571  return count;
572  }
573 
574  rounded_data_size = (1 << (max_log2 (fifo_size_in_bytes)));
575  freelist_index = max_log2 (rounded_data_size)
577 
578  if (freelist_index > vec_len (fsh->free_fifos))
579  return 0;
580 
581  f = fsh->free_fifos[freelist_index];
582  if (f == 0)
583  return 0;
584 
585  while (f)
586  {
587  f = f->next;
588  count++;
589  }
590  return count;
591 }
592 
593 /**
594  * Segment format function
595  */
596 u8 *
597 format_svm_fifo_segment (u8 * s, va_list * args)
598 {
600  = va_arg (*args, svm_fifo_segment_private_t *);
601  int verbose = va_arg (*args, int);
604  svm_fifo_t *f;
605  int i;
606  u32 count;
607  u32 indent = format_get_indent (s) + 2;
608 
609  sh = sp->ssvm.sh;
610  fsh = (svm_fifo_segment_header_t *) sh->opaque[0];
611 
612  s = format (s, "%USegment Heap: %U\n", format_white_space, indent,
613  format_mheap, sh->heap, verbose);
614  s = format (s, "%U segment has %u active fifos\n",
616 
617  for (i = 0; i < vec_len (fsh->free_fifos); i++)
618  {
619  f = fsh->free_fifos[i];
620  if (f == 0)
621  continue;
622  count = 0;
623  while (f)
624  {
625  f = f->next;
626  count++;
627  }
628 
629  s = format (s, "%U%-5u Kb: %u free",
630  format_white_space, indent + 2,
631  1 << (i + max_log2 (FIFO_SEGMENT_MIN_FIFO_SIZE) - 10),
632  count);
633  }
634  return s;
635 }
636 
637 /*
638  * fd.io coding-style-patch-verification: ON
639  *
640  * Local Variables:
641  * eval: (c-set-style "gnu")
642  * End:
643  */
u64 ssvm_size
Definition: ssvm.h:77
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:337
#define clib_min(x, y)
Definition: clib.h:340
uword requested_va
Definition: ssvm.h:81
static void * clib_mem_alloc_aligned_at_offset(uword size, uword align, uword align_offset, int os_out_of_memory_on_failure)
Definition: mem.h:75
int ssvm_master_init(ssvm_private_t *ssvm, u32 master_index)
Definition: ssvm.c:19
a
Definition: bitmap.h:516
#define PREDICT_TRUE(x)
Definition: clib.h:106
volatile u32 ready
Definition: ssvm.h:68
void * mheap_alloc(void *memory, uword size)
Definition: mheap.c:947
svm_fifo_segment_freelist_t
void * opaque[SSVM_N_OPAQUE]
Definition: ssvm.h:65
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:518
#define FIFO_SEGMENT_F_IS_PREALLOCATED
static mheap_t * mheap_header(u8 *v)
static u32 format_get_indent(u8 *s)
Definition: format.h:72
ssvm_shared_header_t * sh
Definition: ssvm.h:76
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
#define MHEAP_FLAG_THREAD_SAFE
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:225
u8 * format_mheap(u8 *s, va_list *va)
Definition: mheap.c:1162
void ssvm_delete(ssvm_private_t *ssvm)
Definition: ssvm.c:185
svm_fifo_segment_main_t svm_fifo_segment_main
struct _svm_fifo svm_fifo_t
u8 * format_white_space(u8 *s, va_list *va)
Definition: std-formats.c:113
static void * ssvm_push_heap(ssvm_shared_header_t *sh)
Definition: ssvm.h:134
unsigned long u64
Definition: types.h:89
#define mheap_free(v)
Definition: mheap.h:62
static void ssvm_pop_heap(void *oldheap)
Definition: ssvm.h:142
#define FIFO_SEGMENT_MIN_FIFO_SIZE
int svm_fifo_segment_create_process_private(svm_fifo_segment_create_args_t *a)
Create an svm fifo segment in process-private memory.
u32 svm_fifo_segment_num_fifos(svm_fifo_segment_private_t *fifo_segment)
Get number of active fifos.
u8 * segment_name
Segment name.
svm_fifo_t * fifos
Linked list of active RX fifos.
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:271
svm_fifo_t ** free_fifos
Freelists, by fifo size.
int ssvm_slave_init(ssvm_private_t *ssvm, int timeout_in_seconds)
Definition: ssvm.c:115
void svm_fifo_segment_init(u64 baseva, u32 timeout_in_seconds)
#define PREDICT_FALSE(x)
Definition: clib.h:105
svm_fifo_segment_header_t * h
#define FIFO_SEGMENT_F_IS_PRIVATE
#define FIFO_SEGMENT_ALLOC_CHUNK_SIZE
u32 svm_fifo_segment_index(svm_fifo_segment_private_t *s)
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:336
u32 n_active_fifos
Number of active fifos.
static void * clib_mem_set_heap(void *heap)
Definition: mem.h:226
#define clib_warning(format, args...)
Definition: error.h:59
static void allocate_new_fifo_chunk(svm_fifo_segment_header_t *fsh, u32 data_size_in_bytes, int chunk_size)
u32 my_pid
Definition: ssvm.h:78
#define FIFO_SEGMENT_F_IS_MAIN_HEAP
#define OOO_SEGMENT_INVALID_INDEX
Definition: svm_fifo.h:40
static void * clib_mem_get_heap(void)
Definition: mem.h:220
#define FIFO_SEGMENT_MAX_FIFO_SIZE
#define ASSERT(truth)
unsigned int u32
Definition: types.h:88
u64 size
Definition: vhost-user.h:76
static void clib_mem_free(void *p)
Definition: mem.h:179
size_t count
Definition: vapi.c:42
static heap_header_t * heap_header(void *v)
Definition: heap.h:161
static void * clib_mem_alloc(uword size)
Definition: mem.h:112
void svm_fifo_segment_free_fifo(svm_fifo_segment_private_t *s, svm_fifo_t *f, svm_fifo_segment_freelist_t list_index)
#define clib_max(x, y)
Definition: clib.h:333
u8 * name
Definition: ssvm.h:80
int svm_fifo_segment_create(svm_fifo_segment_create_args_t *a)
(master) create an svm fifo segment
svm_fifo_segment_private_t * segments
pool of segments
svm_fifo_segment_private_t * svm_fifo_segment_segments_pool(void)
Retrieve svm segments pool.
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
static void preallocate_fifo_pairs(svm_fifo_segment_private_t *s, svm_fifo_segment_create_args_t *a)
unsigned char u8
Definition: types.h:56
static uword max_log2(uword x)
Definition: clib.h:236
#define clib_unix_warning(format, args...)
Definition: error.h:68
static void * clib_mem_alloc_aligned(uword size, uword align)
Definition: mem.h:120
u32 svm_fifo_segment_num_free_fifos(svm_fifo_segment_private_t *fifo_segment, u32 fifo_size_in_bytes)
static void ssvm_unlock_non_recursive(ssvm_shared_header_t *h)
Definition: ssvm.h:126
#define vec_validate_init_empty(V, I, INIT)
Make sure vector is long enough for given index and initialize empty space (no header, unspecified alignment)
Definition: vec.h:481
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:67
uword clib_mem_get_page_size(void)
Definition: mem_mheap.c:110
int svm_fifo_segment_attach(svm_fifo_segment_create_args_t *a)
(slave) attach to an svm fifo segment
u8 * format_svm_fifo_segment(u8 *s, va_list *args)
Segment format function.
int i_am_master
Definition: ssvm.h:82
static void ssvm_lock_non_recursive(ssvm_shared_header_t *h, u32 tag)
Definition: ssvm.h:105
void svm_fifo_segment_delete(svm_fifo_segment_private_t *s)
svm_fifo_t * svm_fifo_segment_alloc_fifo(svm_fifo_segment_private_t *s, u32 data_size_in_bytes, svm_fifo_segment_freelist_t list_index)
svm_fifo_t * svm_fifo_create(u32 data_size_in_bytes)
create an svm fifo, in the current heap.
Definition: svm_fifo.c:194