blob: 7cf66ee35b205fd5d603c6e64f5d462b7ec8e000 [file] [log] [blame]
Florin Coras6cf30ad2017-04-04 23:08:23 -07001/*
2 * Copyright (c) 2017 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 <vnet/session/segment_manager.h>
17#include <vnet/session/session.h>
18#include <vnet/session/application.h>
19
20/**
21 * Counter used to build segment names
22 */
23u32 segment_name_counter = 0;
24
25/**
26 * Pool of segment managers
27 */
28segment_manager_t *segment_managers = 0;
29
30/**
Florin Corasa5464812017-04-19 13:00:05 -070031 * Process private segment index
32 */
Dave Barach2c25a622017-06-26 11:35:07 -040033u32 *private_segment_indices;
Florin Corasa5464812017-04-19 13:00:05 -070034
35/**
Florin Coras6cf30ad2017-04-04 23:08:23 -070036 * Default fifo and segment size. TODO config.
37 */
38u32 default_fifo_size = 1 << 16;
39u32 default_segment_size = 1 << 20;
40
41void
42segment_manager_get_segment_info (u32 index, u8 ** name, u32 * size)
43{
44 svm_fifo_segment_private_t *s;
Florin Corasc87c91d2017-08-16 19:55:49 -070045 s = svm_fifo_segment_get_segment (index);
Florin Coras6cf30ad2017-04-04 23:08:23 -070046 *name = s->h->segment_name;
47 *size = s->ssvm.ssvm_size;
48}
49
50always_inline int
51session_manager_add_segment_i (segment_manager_t * sm, u32 segment_size,
52 u8 * segment_name)
53{
54 svm_fifo_segment_create_args_t _ca, *ca = &_ca;
55 int rv;
56
57 memset (ca, 0, sizeof (*ca));
58
Florin Corasc87c91d2017-08-16 19:55:49 -070059 if (!sm->properties->use_private_segment)
Florin Coras6cf30ad2017-04-04 23:08:23 -070060 {
Florin Corasc87c91d2017-08-16 19:55:49 -070061 ca->segment_name = (char *) segment_name;
62 ca->segment_size = segment_size;
63 ca->rx_fifo_size = sm->properties->rx_fifo_size;
64 ca->tx_fifo_size = sm->properties->tx_fifo_size;
65 ca->preallocated_fifo_pairs = sm->properties->preallocated_fifo_pairs;
Florin Coras6cf30ad2017-04-04 23:08:23 -070066
Florin Corasc87c91d2017-08-16 19:55:49 -070067 rv = svm_fifo_segment_create (ca);
68 if (rv)
69 {
70 clib_warning ("svm_fifo_segment_create ('%s', %d) failed",
71 ca->segment_name, ca->segment_size);
72 return VNET_API_ERROR_SVM_SEGMENT_CREATE_FAIL;
73 }
74 }
75 else
76 {
77 ca->segment_name = "process-private-segment";
78 ca->segment_size = ~0;
79 ca->rx_fifo_size = sm->properties->rx_fifo_size;
80 ca->tx_fifo_size = sm->properties->tx_fifo_size;
81 ca->preallocated_fifo_pairs = sm->properties->preallocated_fifo_pairs;
82 ca->private_segment_count = sm->properties->private_segment_count;
83 ca->private_segment_size = sm->properties->private_segment_size;
84
85 if (svm_fifo_segment_create_process_private (ca))
86 clib_warning ("Failed to create process private segment");
87
88 ASSERT (vec_len (ca->new_segment_indices));
89 }
Dave Barach2c25a622017-06-26 11:35:07 -040090 vec_append (sm->segment_indices, ca->new_segment_indices);
91 vec_free (ca->new_segment_indices);
Florin Coras6cf30ad2017-04-04 23:08:23 -070092 return 0;
93}
94
95int
96session_manager_add_segment (segment_manager_t * sm)
97{
98 u8 *segment_name;
99 svm_fifo_segment_create_args_t _ca, *ca = &_ca;
100 u32 add_segment_size;
101 int rv;
102
103 memset (ca, 0, sizeof (*ca));
104 segment_name = format (0, "%d-%d%c", getpid (), segment_name_counter++, 0);
105 add_segment_size = sm->properties->add_segment_size ?
106 sm->properties->add_segment_size : default_segment_size;
107
108 rv = session_manager_add_segment_i (sm, add_segment_size, segment_name);
109 vec_free (segment_name);
110 return rv;
111}
112
113int
114session_manager_add_first_segment (segment_manager_t * sm, u32 segment_size)
115{
Florin Coras6cf30ad2017-04-04 23:08:23 -0700116 u8 *segment_name;
117 int rv;
118
Florin Coras6cf30ad2017-04-04 23:08:23 -0700119 segment_name = format (0, "%d-%d%c", getpid (), segment_name_counter++, 0);
120 rv = session_manager_add_segment_i (sm, segment_size, segment_name);
121 vec_free (segment_name);
122 return rv;
123}
124
Florin Corasc87c91d2017-08-16 19:55:49 -0700125segment_manager_t *
126segment_manager_new ()
Florin Corasa5464812017-04-19 13:00:05 -0700127{
Florin Corasc87c91d2017-08-16 19:55:49 -0700128 segment_manager_t *sm;
129 pool_get (segment_managers, sm);
130 memset (sm, 0, sizeof (*sm));
131 return sm;
Florin Corasa5464812017-04-19 13:00:05 -0700132}
133
Florin Coras6cf30ad2017-04-04 23:08:23 -0700134/**
135 * Initializes segment manager based on options provided.
136 * Returns error if svm segment allocation fails.
137 */
138int
139segment_manager_init (segment_manager_t * sm,
140 segment_manager_properties_t * properties,
141 u32 first_seg_size)
142{
143 int rv;
144
145 /* app allocates these */
146 sm->properties = properties;
147
Florin Corasa5464812017-04-19 13:00:05 -0700148 first_seg_size = first_seg_size > 0 ? first_seg_size : default_segment_size;
149
Florin Corasc87c91d2017-08-16 19:55:49 -0700150 rv = session_manager_add_first_segment (sm, first_seg_size);
151 if (rv)
Florin Coras6cf30ad2017-04-04 23:08:23 -0700152 {
Florin Corasc87c91d2017-08-16 19:55:49 -0700153 clib_warning ("Failed to allocate segment");
154 return rv;
Florin Corasa5464812017-04-19 13:00:05 -0700155 }
Florin Coras6cf30ad2017-04-04 23:08:23 -0700156
Florin Corasa5464812017-04-19 13:00:05 -0700157 clib_spinlock_init (&sm->lockp);
Florin Coras6cf30ad2017-04-04 23:08:23 -0700158 return 0;
159}
160
Florin Corasc87c91d2017-08-16 19:55:49 -0700161u8
162segment_manager_has_fifos (segment_manager_t * sm)
Dave Wallace7b749fe2017-07-05 14:30:46 -0400163{
Florin Corasc87c91d2017-08-16 19:55:49 -0700164 svm_fifo_segment_private_t *segment;
165 /* Weird, but handle it */
166 if (vec_len (sm->segment_indices) == 0)
167 return 0;
168 if (vec_len (sm->segment_indices) == 1)
Dave Wallace7b749fe2017-07-05 14:30:46 -0400169 {
Florin Corasc87c91d2017-08-16 19:55:49 -0700170 segment = svm_fifo_segment_get_segment (sm->segment_indices[0]);
171 if (svm_fifo_segment_num_fifos (segment) == 0)
172 return 0;
Dave Wallace7b749fe2017-07-05 14:30:46 -0400173 }
Florin Corasc87c91d2017-08-16 19:55:49 -0700174 if (CLIB_DEBUG)
175 {
176 svm_fifo_segment_private_t *segment;
177 int i;
178 for (i = 1; i < vec_len (sm->segment_indices); i++)
179 {
180 segment = svm_fifo_segment_get_segment (sm->segment_indices[i]);
181 if (!svm_fifo_segment_has_fifos (segment))
182 clib_warning ("segment has no fifos!");
183 }
184 }
185 return 1;
Dave Wallace7b749fe2017-07-05 14:30:46 -0400186}
187
Florin Corasc87c91d2017-08-16 19:55:49 -0700188static void
189segment_manager_del_segment (segment_manager_t * sm, u32 segment_index)
190{
191 svm_fifo_segment_private_t *fifo_segment;
192 u32 svm_segment_index;
193 clib_spinlock_lock (&sm->lockp);
194 svm_segment_index = sm->segment_indices[segment_index];
195 fifo_segment = svm_fifo_segment_get_segment (svm_segment_index);
196 svm_fifo_segment_delete (fifo_segment);
197 vec_del1 (sm->segment_indices, segment_index);
198 clib_spinlock_unlock (&sm->lockp);
199}
200
201/**
202 * Initiate disconnects for all sessions 'owned' by a segment manager
Florin Coras6cf30ad2017-04-04 23:08:23 -0700203 */
204void
Florin Corasc87c91d2017-08-16 19:55:49 -0700205segment_manager_del_sessions (segment_manager_t * sm)
Florin Coras6cf30ad2017-04-04 23:08:23 -0700206{
Dave Barach10d8cc62017-05-30 09:30:07 -0400207 int j;
Dave Wallace7b749fe2017-07-05 14:30:46 -0400208 svm_fifo_segment_private_t *fifo_segment;
Florin Corasc87c91d2017-08-16 19:55:49 -0700209 svm_fifo_t *fifo;
210
Dave Wallace7b749fe2017-07-05 14:30:46 -0400211 ASSERT (vec_len (sm->segment_indices));
Florin Coras6cf30ad2017-04-04 23:08:23 -0700212
213 /* Across all fifo segments used by the server */
214 for (j = 0; j < vec_len (sm->segment_indices); j++)
215 {
Florin Corasc87c91d2017-08-16 19:55:49 -0700216 fifo_segment = svm_fifo_segment_get_segment (sm->segment_indices[j]);
Dave Barach10d8cc62017-05-30 09:30:07 -0400217 fifo = svm_fifo_segment_get_fifo_list (fifo_segment);
Florin Coras6cf30ad2017-04-04 23:08:23 -0700218
219 /*
220 * Remove any residual sessions from the session lookup table
221 * Don't bother deleting the individual fifos, we're going to
222 * throw away the fifo segment in a minute.
223 */
Dave Barach10d8cc62017-05-30 09:30:07 -0400224 while (fifo)
Florin Coras6cf30ad2017-04-04 23:08:23 -0700225 {
Florin Coras6cf30ad2017-04-04 23:08:23 -0700226 u32 session_index, thread_index;
227 stream_session_t *session;
228
Florin Corasa5464812017-04-19 13:00:05 -0700229 session_index = fifo->master_session_index;
230 thread_index = fifo->master_thread_index;
Florin Coras6cf30ad2017-04-04 23:08:23 -0700231 session = stream_session_get (session_index, thread_index);
232
Florin Coras6cf30ad2017-04-04 23:08:23 -0700233 /* Instead of directly removing the session call disconnect */
Florin Corasc87c91d2017-08-16 19:55:49 -0700234 if (session->session_state != SESSION_STATE_CLOSED)
235 {
236 session->session_state = SESSION_STATE_CLOSED;
237 session_send_session_evt_to_thread (stream_session_handle
238 (session),
239 FIFO_EVENT_DISCONNECT,
240 thread_index);
241 }
Dave Barach10d8cc62017-05-30 09:30:07 -0400242 fifo = fifo->next;
Florin Coras6cf30ad2017-04-04 23:08:23 -0700243 }
244
Dave Barach10d8cc62017-05-30 09:30:07 -0400245 /* Instead of removing the segment, test when cleaning up disconnected
246 * sessions if the segment can be removed.
Florin Coras6cf30ad2017-04-04 23:08:23 -0700247 */
Florin Coras6cf30ad2017-04-04 23:08:23 -0700248 }
Florin Corasc87c91d2017-08-16 19:55:49 -0700249}
Florin Coras6cf30ad2017-04-04 23:08:23 -0700250
Florin Corasc87c91d2017-08-16 19:55:49 -0700251/**
252 * Removes segment manager.
253 *
254 * Since the fifos allocated in the segment keep backpointers to the sessions
255 * prior to removing the segment, we call session disconnect. This
256 * subsequently propages into transport.
257 */
258void
259segment_manager_del (segment_manager_t * sm)
260{
Dave Wallace7b749fe2017-07-05 14:30:46 -0400261
Florin Corasc87c91d2017-08-16 19:55:49 -0700262 ASSERT (vec_len (sm->segment_indices) <= 1);
263 if (vec_len (sm->segment_indices))
264 {
265 /* The first segment in the first segment manager is not removed when
266 * all fifos are removed. It can only be removed when the manager is
267 * explicitly deleted/detached by the app. */
268 if (CLIB_DEBUG)
269 {
270 svm_fifo_segment_private_t *fifo_segment;
271 fifo_segment =
272 svm_fifo_segment_get_segment (sm->segment_indices[0]);
273 ASSERT (!svm_fifo_segment_has_fifos (fifo_segment));
274 }
275 segment_manager_del_segment (sm, 0);
276 }
Florin Corasa5464812017-04-19 13:00:05 -0700277 clib_spinlock_free (&sm->lockp);
Florin Corasc87c91d2017-08-16 19:55:49 -0700278 if (CLIB_DEBUG)
279 memset (sm, 0xfe, sizeof (*sm));
Florin Coras6cf30ad2017-04-04 23:08:23 -0700280 pool_put (segment_managers, sm);
281}
282
Florin Corasc87c91d2017-08-16 19:55:49 -0700283void
284segment_manager_init_del (segment_manager_t * sm)
Florin Coras6cf30ad2017-04-04 23:08:23 -0700285{
Florin Corasc87c91d2017-08-16 19:55:49 -0700286 if (segment_manager_has_fifos (sm))
287 segment_manager_del_sessions (sm);
288 else
289 {
290 ASSERT (!sm->first_is_protected
291 || sm->app_index == SEGMENT_MANAGER_INVALID_APP_INDEX);
292 segment_manager_del (sm);
293 }
Florin Coras6cf30ad2017-04-04 23:08:23 -0700294}
295
296int
297segment_manager_alloc_session_fifos (segment_manager_t * sm,
298 svm_fifo_t ** server_rx_fifo,
299 svm_fifo_t ** server_tx_fifo,
300 u32 * fifo_segment_index)
301{
302 svm_fifo_segment_private_t *fifo_segment;
303 u32 fifo_size, sm_index;
304 u8 added_a_segment = 0;
305 int i;
306
Florin Coras6cf30ad2017-04-04 23:08:23 -0700307 ASSERT (vec_len (sm->segment_indices));
308
Florin Corasa5464812017-04-19 13:00:05 -0700309 /* Make sure we don't have multiple threads trying to allocate segments
310 * at the same time. */
311 clib_spinlock_lock (&sm->lockp);
312
313 /* Allocate svm fifos */
Florin Coras6cf30ad2017-04-04 23:08:23 -0700314again:
315 for (i = 0; i < vec_len (sm->segment_indices); i++)
316 {
317 *fifo_segment_index = sm->segment_indices[i];
Florin Corasc87c91d2017-08-16 19:55:49 -0700318 fifo_segment = svm_fifo_segment_get_segment (*fifo_segment_index);
Florin Coras6cf30ad2017-04-04 23:08:23 -0700319
320 fifo_size = sm->properties->rx_fifo_size;
321 fifo_size = (fifo_size == 0) ? default_fifo_size : fifo_size;
Dave Barach10d8cc62017-05-30 09:30:07 -0400322 *server_rx_fifo =
323 svm_fifo_segment_alloc_fifo (fifo_segment, fifo_size,
324 FIFO_SEGMENT_RX_FREELIST);
Florin Coras6cf30ad2017-04-04 23:08:23 -0700325
326 fifo_size = sm->properties->tx_fifo_size;
327 fifo_size = (fifo_size == 0) ? default_fifo_size : fifo_size;
Dave Barach10d8cc62017-05-30 09:30:07 -0400328 *server_tx_fifo =
329 svm_fifo_segment_alloc_fifo (fifo_segment, fifo_size,
330 FIFO_SEGMENT_TX_FREELIST);
Florin Coras6cf30ad2017-04-04 23:08:23 -0700331
332 if (*server_rx_fifo == 0)
333 {
334 /* This would be very odd, but handle it... */
335 if (*server_tx_fifo != 0)
336 {
Dave Barach10d8cc62017-05-30 09:30:07 -0400337 svm_fifo_segment_free_fifo (fifo_segment, *server_tx_fifo,
338 FIFO_SEGMENT_TX_FREELIST);
Florin Coras6cf30ad2017-04-04 23:08:23 -0700339 *server_tx_fifo = 0;
340 }
341 continue;
342 }
343 if (*server_tx_fifo == 0)
344 {
345 if (*server_rx_fifo != 0)
346 {
Dave Barach10d8cc62017-05-30 09:30:07 -0400347 svm_fifo_segment_free_fifo (fifo_segment, *server_rx_fifo,
348 FIFO_SEGMENT_RX_FREELIST);
Florin Coras6cf30ad2017-04-04 23:08:23 -0700349 *server_rx_fifo = 0;
350 }
351 continue;
352 }
353 break;
354 }
355
356 /* See if we're supposed to create another segment */
357 if (*server_rx_fifo == 0)
358 {
Dave Barach2c25a622017-06-26 11:35:07 -0400359 if (sm->properties->add_segment && !sm->properties->use_private_segment)
Florin Coras6cf30ad2017-04-04 23:08:23 -0700360 {
361 if (added_a_segment)
362 {
Florin Corasc87c91d2017-08-16 19:55:49 -0700363 clib_warning ("added a segment, still can't allocate a fifo");
Florin Corasf03a59a2017-06-09 21:07:32 -0700364 clib_spinlock_unlock (&sm->lockp);
Florin Coras6cf30ad2017-04-04 23:08:23 -0700365 return SESSION_ERROR_NEW_SEG_NO_SPACE;
366 }
367
368 if (session_manager_add_segment (sm))
Florin Corasa5464812017-04-19 13:00:05 -0700369 {
Florin Corasf03a59a2017-06-09 21:07:32 -0700370 clib_spinlock_unlock (&sm->lockp);
Florin Corasa5464812017-04-19 13:00:05 -0700371 return VNET_API_ERROR_URI_FIFO_CREATE_FAILED;
372 }
Florin Coras6cf30ad2017-04-04 23:08:23 -0700373
374 added_a_segment = 1;
375 goto again;
376 }
377 else
378 {
379 clib_warning ("No space to allocate fifos!");
Florin Corasf03a59a2017-06-09 21:07:32 -0700380 clib_spinlock_unlock (&sm->lockp);
Florin Coras6cf30ad2017-04-04 23:08:23 -0700381 return SESSION_ERROR_NO_SPACE;
382 }
383 }
384
Florin Coras6cf30ad2017-04-04 23:08:23 -0700385 /* Backpointers to segment manager */
386 sm_index = segment_manager_index (sm);
387 (*server_tx_fifo)->segment_manager = sm_index;
388 (*server_rx_fifo)->segment_manager = sm_index;
389
Florin Corasa5464812017-04-19 13:00:05 -0700390 clib_spinlock_unlock (&sm->lockp);
391
392 if (added_a_segment)
Florin Corasc87c91d2017-08-16 19:55:49 -0700393 return application_add_segment_notify (sm->app_index,
394 *fifo_segment_index);
Florin Corasa5464812017-04-19 13:00:05 -0700395
Florin Coras6cf30ad2017-04-04 23:08:23 -0700396 return 0;
397}
398
399void
400segment_manager_dealloc_fifos (u32 svm_segment_index, svm_fifo_t * rx_fifo,
401 svm_fifo_t * tx_fifo)
402{
403 segment_manager_t *sm;
404 svm_fifo_segment_private_t *fifo_segment;
Florin Corasc87c91d2017-08-16 19:55:49 -0700405 u32 i, segment_index = ~0;
406 u8 is_first;
Florin Coras6cf30ad2017-04-04 23:08:23 -0700407
Florin Corasa5464812017-04-19 13:00:05 -0700408 sm = segment_manager_get_if_valid (rx_fifo->segment_manager);
409
410 /* It's possible to have no segment manager if the session was removed
Florin Corasc87c91d2017-08-16 19:55:49 -0700411 * as result of a detach. */
Florin Corasa5464812017-04-19 13:00:05 -0700412 if (!sm)
413 return;
414
Florin Corasc87c91d2017-08-16 19:55:49 -0700415 fifo_segment = svm_fifo_segment_get_segment (svm_segment_index);
Dave Barach10d8cc62017-05-30 09:30:07 -0400416 svm_fifo_segment_free_fifo (fifo_segment, rx_fifo,
417 FIFO_SEGMENT_RX_FREELIST);
418 svm_fifo_segment_free_fifo (fifo_segment, tx_fifo,
419 FIFO_SEGMENT_TX_FREELIST);
Florin Coras6cf30ad2017-04-04 23:08:23 -0700420
Florin Corasc87c91d2017-08-16 19:55:49 -0700421 /*
422 * Try to remove svm segment if it has no fifos. This can be done only if
423 * the segment is not the first in the segment manager or if it is first
424 * and it is not protected. Moreover, if the segment is first and the app
425 * has detached from the segment manager, remove the segment manager.
426 */
427 if (!svm_fifo_segment_has_fifos (fifo_segment))
Florin Coras6cf30ad2017-04-04 23:08:23 -0700428 {
Florin Corasc87c91d2017-08-16 19:55:49 -0700429 is_first = sm->segment_indices[0] == svm_segment_index;
430
431 /* Remove segment if it holds no fifos or first but not protected */
432 if (!is_first || !sm->first_is_protected)
433 {
434 /* Find the segment manager segment index */
435 for (i = 0; i < vec_len (sm->segment_indices); i++)
436 if (sm->segment_indices[i] == svm_segment_index)
437 {
438 segment_index = i;
439 break;
440 }
441 ASSERT (segment_index != (u32) ~ 0);
442 segment_manager_del_segment (sm, segment_index);
443 }
444
445 /* Remove segment manager if no sessions and detached from app */
446 if (sm->app_index == SEGMENT_MANAGER_INVALID_APP_INDEX && is_first)
447 segment_manager_del (sm);
Florin Coras6cf30ad2017-04-04 23:08:23 -0700448 }
449}
450
Florin Corasa5464812017-04-19 13:00:05 -0700451/**
452 * Allocates shm queue in the first segment
453 */
454unix_shared_memory_queue_t *
455segment_manager_alloc_queue (segment_manager_t * sm, u32 queue_size)
456{
457 ssvm_shared_header_t *sh;
458 svm_fifo_segment_private_t *segment;
459 unix_shared_memory_queue_t *q;
460 void *oldheap;
461
462 ASSERT (sm->segment_indices != 0);
463
Florin Corasc87c91d2017-08-16 19:55:49 -0700464 segment = svm_fifo_segment_get_segment (sm->segment_indices[0]);
Florin Corasa5464812017-04-19 13:00:05 -0700465 sh = segment->ssvm.sh;
466
467 oldheap = ssvm_push_heap (sh);
Florin Corasc87c91d2017-08-16 19:55:49 -0700468 q = unix_shared_memory_queue_init (queue_size,
469 sizeof (session_fifo_event_t),
470 0 /* consumer pid */ ,
471 0 /* signal when queue non-empty */ );
Florin Corasa5464812017-04-19 13:00:05 -0700472 ssvm_pop_heap (oldheap);
473 return q;
474}
475
476/**
477 * Frees shm queue allocated in the first segment
478 */
479void
480segment_manager_dealloc_queue (segment_manager_t * sm,
481 unix_shared_memory_queue_t * q)
482{
483 ssvm_shared_header_t *sh;
484 svm_fifo_segment_private_t *segment;
485 void *oldheap;
486
487 ASSERT (sm->segment_indices != 0);
488
Florin Corasc87c91d2017-08-16 19:55:49 -0700489 segment = svm_fifo_segment_get_segment (sm->segment_indices[0]);
Florin Corasa5464812017-04-19 13:00:05 -0700490 sh = segment->ssvm.sh;
491
492 oldheap = ssvm_push_heap (sh);
493 unix_shared_memory_queue_free (q);
494 ssvm_pop_heap (oldheap);
495}
496
Florin Corasc87c91d2017-08-16 19:55:49 -0700497static clib_error_t *
498segment_manager_show_fn (vlib_main_t * vm, unformat_input_t * input,
499 vlib_cli_command_t * cmd)
500{
501 svm_fifo_segment_private_t *segments, *seg;
502 segment_manager_t *sm;
503 u8 show_segments = 0, verbose = 0, *name;
504 uword address;
505 u64 size;
506 u32 fifos;
507 mheap_t *heap_header;
508
509 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
510 {
511 if (unformat (input, "segments"))
512 show_segments = 1;
513 else if (unformat (input, "verbose"))
514 verbose = 1;
515 else
516 return clib_error_return (0, "unknown input `%U'",
517 format_unformat_error, input);
518 }
519 vlib_cli_output (vm, "%d segment managers allocated",
520 pool_elts (segment_managers));
521 if (verbose && pool_elts (segment_managers))
522 {
523 vlib_cli_output (vm, "%-10s%=15s%=12s", "Index", "App Index",
524 "Segments");
525
526 /* *INDENT-OFF* */
527 pool_foreach (sm, segment_managers, ({
528 vlib_cli_output (vm, "%-10d%=15d%=12d", segment_manager_index(sm),
529 sm->app_index, vec_len (sm->segment_indices));
530 }));
531 /* *INDENT-ON* */
532
533 }
534 if (show_segments)
535 {
536 segments = svm_fifo_segment_segments_pool ();
537 vlib_cli_output (vm, "%d svm fifo segments allocated",
538 pool_elts (segments));
539 vlib_cli_output (vm, "%-20s%=12s%=12s%=15s", "Name", "Size (M)",
540 "Fifos", "Address");
541
542 /* *INDENT-OFF* */
543 pool_foreach (seg, segments, ({
544 if (seg->h->flags & FIFO_SEGMENT_F_IS_PRIVATE)
545 {
546 address = pointer_to_uword (seg->ssvm.sh->heap);
547 if (seg->h->flags & FIFO_SEGMENT_F_IS_MAIN_HEAP)
548 name = format (0, "main heap");
549 else
550 name = format (0, "private heap");
551 heap_header = mheap_header (seg->ssvm.sh->heap);
552 size = heap_header->max_size;
553 }
554 else
555 {
556 address = seg->ssvm.sh->ssvm_va;
557 size = seg->ssvm.ssvm_size;
558 name = seg->ssvm.sh->name;
559 }
560 fifos = svm_fifo_segment_num_fifos (seg);
561 vlib_cli_output (vm, "%-20s%=12u%=12u%=15x", name, size << 20, fifos,
562 address);
563 if (seg->h->flags & FIFO_SEGMENT_F_IS_PRIVATE)
564 vec_free (name);
565 }));
566 /* *INDENT-ON* */
567
568 }
569 return 0;
570}
571
572 /* *INDENT-OFF* */
573VLIB_CLI_COMMAND (segment_manager_show_command, static) =
574{
575 .path = "show segment-manager",
576 .short_help = "show segment-manager [segments]",
577 .function = segment_manager_show_fn,
578};
579/* *INDENT-ON* */
580
Florin Coras6cf30ad2017-04-04 23:08:23 -0700581/*
582 * fd.io coding-style-patch-verification: ON
583 *
584 * Local Variables:
585 * eval: (c-set-style "gnu")
586 * End:
587 */