FD.io VPP  v17.04-9-g99c0734
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 /** (master) create an svm fifo segment */
21 int
23 {
24  int rv;
29  void *oldheap;
30 
31  /* Allocate a fresh segment */
32  pool_get (sm->segments, s);
33  memset (s, 0, sizeof (*s));
34 
35  s->ssvm.ssvm_size = a->segment_size;
36  s->ssvm.i_am_master = 1;
37  s->ssvm.my_pid = getpid ();
38  s->ssvm.name = (u8 *) a->segment_name;
39  s->ssvm.requested_va = sm->next_baseva;
40 
41  rv = ssvm_master_init (&s->ssvm, s - sm->segments);
42 
43  if (rv)
44  {
45  _vec_len (s) = vec_len (s) - 1;
46  return (rv);
47  }
48 
49  /* Note; requested_va updated due to seg base addr randomization */
51 
52  sh = s->ssvm.sh;
53  oldheap = ssvm_push_heap (sh);
54 
55  /* Set up svm_fifo_segment shared header */
56  fsh = clib_mem_alloc (sizeof (*fsh));
57  memset (fsh, 0, sizeof (*fsh));
58  sh->opaque[0] = fsh;
59  s->h = fsh;
60  fsh->segment_name = format (0, "%s%c", a->segment_name, 0);
61 
62  /* Avoid vec_add1(...) failure when adding a fifo, etc. */
63  vec_validate (fsh->fifos, 64);
64  _vec_len (fsh->fifos) = 0;
65 
66  ssvm_pop_heap (oldheap);
67 
68  sh->ready = 1;
69  a->new_segment_index = s - sm->segments;
70  return (0);
71 }
72 
73 /** (slave) attach to an svm fifo segment */
74 int
76 {
77  int rv;
82 
83  /* Allocate a fresh segment */
84  pool_get (sm->segments, s);
85 
86  memset (s, 0, sizeof (*s));
87 
88  s->ssvm.ssvm_size = a->segment_size;
89  s->ssvm.my_pid = getpid ();
90  s->ssvm.name = (u8 *) a->segment_name;
91  s->ssvm.requested_va = sm->next_baseva;
92 
93  rv = ssvm_slave_init (&s->ssvm, sm->timeout_in_seconds);
94 
95  if (rv)
96  {
97  _vec_len (s) = vec_len (s) - 1;
98  return (rv);
99  }
100 
101  /* Fish the segment header */
102  sh = s->ssvm.sh;
103  fsh = (svm_fifo_segment_header_t *) sh->opaque[0];
104  s->h = fsh;
105 
106  a->new_segment_index = s - sm->segments;
107  return (0);
108 }
109 
110 void
112 {
114  ssvm_delete (&s->ssvm);
115  pool_put (sm->segments, s);
116 }
117 
118 svm_fifo_t *
120  u32 data_size_in_bytes)
121 {
124  svm_fifo_t *f;
125  void *oldheap;
126 
127  sh = s->ssvm.sh;
128  fsh = (svm_fifo_segment_header_t *) sh->opaque[0];
129  oldheap = ssvm_push_heap (sh);
130 
131  /* Note: this can fail, in which case: create another segment */
132  f = svm_fifo_create (data_size_in_bytes);
133  if (f == 0)
134  {
135  ssvm_pop_heap (oldheap);
136  return (0);
137  }
138 
139  vec_add1 (fsh->fifos, f);
140 
141  ssvm_pop_heap (oldheap);
142  return (f);
143 }
144 
145 void
147 {
150  void *oldheap;
151  int i;
152 
153  sh = s->ssvm.sh;
154  fsh = (svm_fifo_segment_header_t *) sh->opaque[0];
155  oldheap = ssvm_push_heap (sh);
156 
157  for (i = 0; i < vec_len (fsh->fifos); i++)
158  {
159  if (fsh->fifos[i] == f)
160  {
161  vec_delete (fsh->fifos, 1, i);
162  goto found;
163  }
164  }
165  clib_warning ("fifo 0x%llx not found in fifo table...", f);
166 
167 found:
168  clib_mem_free (f);
169  ssvm_pop_heap (oldheap);
170 }
171 
172 void
173 svm_fifo_segment_init (u64 baseva, u32 timeout_in_seconds)
174 {
176 
177  sm->next_baseva = baseva;
178  sm->timeout_in_seconds = timeout_in_seconds;
179 }
180 
181 u32
183 {
184  return s - svm_fifo_segment_main.segments;
185 }
186 
187 /*
188  * fd.io coding-style-patch-verification: ON
189  *
190  * Local Variables:
191  * eval: (c-set-style "gnu")
192  * End:
193  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:436
u64 ssvm_size
Definition: ssvm.h:77
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:343
uword requested_va
Definition: ssvm.h:81
int ssvm_master_init(ssvm_private_t *ssvm, u32 master_index)
Definition: ssvm.c:18
a
Definition: bitmap.h:516
volatile u32 ready
Definition: ssvm.h:68
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:522
ssvm_shared_header_t * sh
Definition: ssvm.h:76
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:418
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:200
void ssvm_delete(ssvm_private_t *ssvm)
Definition: ssvm.c:173
svm_fifo_segment_main_t svm_fifo_segment_main
static void * ssvm_push_heap(ssvm_shared_header_t *sh)
Definition: ssvm.h:117
unsigned long u64
Definition: types.h:89
static void ssvm_pop_heap(void *oldheap)
Definition: ssvm.h:125
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:241
int ssvm_slave_init(ssvm_private_t *ssvm, int timeout_in_seconds)
Definition: ssvm.c:104
void svm_fifo_segment_init(u64 baseva, u32 timeout_in_seconds)
svm_fifo_segment_header_t * h
u32 svm_fifo_segment_index(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)
#define clib_warning(format, args...)
Definition: error.h:59
u32 my_pid
Definition: ssvm.h:78
unsigned int u32
Definition: types.h:88
#define vec_delete(V, N, M)
Delete N elements starting at element M.
Definition: vec.h:785
static void clib_mem_free(void *p)
Definition: mem.h:176
static void * clib_mem_alloc(uword size)
Definition: mem.h:109
u8 * name
Definition: ssvm.h:80
int svm_fifo_segment_create(svm_fifo_segment_create_args_t *a)
(master) create an svm fifo segment
void svm_fifo_segment_free_fifo(svm_fifo_segment_private_t *s, svm_fifo_t *f)
svm_fifo_segment_private_t * segments
pool of segments
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
unsigned char u8
Definition: types.h:56
int svm_fifo_segment_attach(svm_fifo_segment_create_args_t *a)
(slave) attach to an svm fifo segment
volatile svm_fifo_t ** fifos
int i_am_master
Definition: ssvm.h:82
void svm_fifo_segment_delete(svm_fifo_segment_private_t *s)
svm_fifo_t * svm_fifo_create(u32 data_size_in_bytes)
create an svm fifo, in the current heap.
Definition: svm_fifo.c:20