diff options
41 files changed, 1106 insertions, 725 deletions
diff --git a/src/svm/ssvm.c b/src/svm/ssvm.c index 36abc208636..50552198137 100644 --- a/src/svm/ssvm.c +++ b/src/svm/ssvm.c @@ -15,17 +15,25 @@ #include <svm/ssvm.h> #include <svm/svm_common.h> +typedef int (*init_fn) (ssvm_private_t *); +typedef void (*delete_fn) (ssvm_private_t *); + +static init_fn master_init_fns[SSVM_N_SEGMENT_TYPES] = + { ssvm_master_init_shm, ssvm_master_init_memfd }; +static init_fn slave_init_fns[SSVM_N_SEGMENT_TYPES] = + { ssvm_slave_init_shm, ssvm_slave_init_memfd }; +static delete_fn delete_fns[SSVM_N_SEGMENT_TYPES] = + { ssvm_delete_shm, ssvm_delete_memfd }; + int -ssvm_master_init (ssvm_private_t * ssvm, u32 master_index) +ssvm_master_init_shm (ssvm_private_t * ssvm) { + int ssvm_fd, mh_flags = MHEAP_FLAG_DISABLE_VM | MHEAP_FLAG_THREAD_SAFE; svm_main_region_t *smr = svm_get_root_rp ()->data_base; - int ssvm_fd; - u8 *ssvm_filename; - u8 junk = 0; - int flags; + clib_mem_vm_map_t mapa = { 0 }; + u8 junk = 0, *ssvm_filename; ssvm_shared_header_t *sh; - u64 ticks = clib_cpu_time_now (); - u64 randomize_baseva; + uword page_size; void *oldheap; if (ssvm->ssvm_size == 0) @@ -36,13 +44,10 @@ ssvm_master_init (ssvm_private_t * ssvm, u32 master_index) ASSERT (vec_c_string_is_terminated (ssvm->name)); ssvm_filename = format (0, "/dev/shm/%s%c", ssvm->name, 0); - unlink ((char *) ssvm_filename); - vec_free (ssvm_filename); ssvm_fd = shm_open ((char *) ssvm->name, O_RDWR | O_CREAT | O_EXCL, 0777); - if (ssvm_fd < 0) { clib_unix_warning ("create segment '%s'", ssvm->name); @@ -68,43 +73,35 @@ ssvm_master_init (ssvm_private_t * ssvm, u32 master_index) return SSVM_API_ERROR_SET_SIZE; } - flags = MAP_SHARED; - if (ssvm->requested_va) - flags |= MAP_FIXED; - - randomize_baseva = (ticks & 15) * MMAP_PAGESIZE; - + page_size = clib_mem_vm_get_page_size (ssvm_fd); if (ssvm->requested_va) - ssvm->requested_va += randomize_baseva; - - sh = ssvm->sh = - (ssvm_shared_header_t *) mmap ((void *) ssvm->requested_va, - ssvm->ssvm_size, PROT_READ | PROT_WRITE, - flags, ssvm_fd, 0); + clib_mem_vm_randomize_va (&ssvm->requested_va, min_log2 (page_size)); - if (ssvm->sh == MAP_FAILED) + mapa.requested_va = ssvm->requested_va; + mapa.size = ssvm->ssvm_size; + mapa.fd = ssvm_fd; + if (clib_mem_vm_ext_map (&mapa)) { clib_unix_warning ("mmap"); close (ssvm_fd); return SSVM_API_ERROR_MMAP; } - close (ssvm_fd); - ssvm->my_pid = getpid (); + sh = mapa.addr; sh->master_pid = ssvm->my_pid; sh->ssvm_size = ssvm->ssvm_size; - sh->heap = mheap_alloc_with_flags - (((u8 *) sh) + MMAP_PAGESIZE, ssvm->ssvm_size - MMAP_PAGESIZE, - MHEAP_FLAG_DISABLE_VM | MHEAP_FLAG_THREAD_SAFE); - sh->ssvm_va = pointer_to_uword (sh); - sh->master_index = master_index; + sh->type = SSVM_SEGMENT_SHM; + sh->heap = mheap_alloc_with_flags (((u8 *) sh) + page_size, + ssvm->ssvm_size - page_size, mh_flags); oldheap = ssvm_push_heap (sh); - sh->name = format (0, "%s%c", ssvm->name, 0); + sh->name = format (0, "%s", ssvm->name, 0); ssvm_pop_heap (oldheap); + ssvm->sh = sh; + ssvm->my_pid = getpid (); ssvm->i_am_master = 1; /* The application has to set set sh->ready... */ @@ -112,7 +109,7 @@ ssvm_master_init (ssvm_private_t * ssvm, u32 master_index) } int -ssvm_slave_init (ssvm_private_t * ssvm, int timeout_in_seconds) +ssvm_slave_init_shm (ssvm_private_t * ssvm) { struct stat stat; int ssvm_fd = -1; @@ -121,7 +118,7 @@ ssvm_slave_init (ssvm_private_t * ssvm, int timeout_in_seconds) ASSERT (vec_c_string_is_terminated (ssvm->name)); ssvm->i_am_master = 0; - while (timeout_in_seconds-- > 0) + while (ssvm->attach_timeout-- > 0) { if (ssvm_fd < 0) ssvm_fd = shm_open ((char *) ssvm->name, O_RDWR, 0777); @@ -152,7 +149,7 @@ map_it: return SSVM_API_ERROR_MMAP; } - while (timeout_in_seconds-- > 0) + while (ssvm->attach_timeout-- > 0) { if (sh->ready) goto re_map_it; @@ -182,7 +179,7 @@ re_map_it: } void -ssvm_delete (ssvm_private_t * ssvm) +ssvm_delete_shm (ssvm_private_t * ssvm) { u8 *fn; @@ -202,8 +199,11 @@ ssvm_delete (ssvm_private_t * ssvm) munmap ((void *) ssvm->requested_va, ssvm->ssvm_size); } +/** + * Initialize memfd segment master + */ int -ssvm_master_init_memfd (ssvm_private_t * memfd, u32 master_index) +ssvm_master_init_memfd (ssvm_private_t * memfd) { uword page_size, flags = MHEAP_FLAG_DISABLE_VM | MHEAP_FLAG_THREAD_SAFE; ssvm_shared_header_t *sh; @@ -215,11 +215,11 @@ ssvm_master_init_memfd (ssvm_private_t * memfd, u32 master_index) return SSVM_API_ERROR_NO_SIZE; ASSERT (vec_c_string_is_terminated (memfd->name)); - memfd->name = format (0, "memfd svm region %d%c", master_index, 0); alloc.name = (char *) memfd->name; alloc.size = memfd->ssvm_size; alloc.flags = CLIB_MEM_VM_F_SHARED; + alloc.requested_va = memfd->requested_va; if ((err = clib_mem_vm_ext_alloc (&alloc))) { clib_error_report (err); @@ -227,33 +227,34 @@ ssvm_master_init_memfd (ssvm_private_t * memfd, u32 master_index) } memfd->fd = alloc.fd; - memfd->sh = alloc.addr; + memfd->sh = (ssvm_shared_header_t *) alloc.addr; memfd->my_pid = getpid (); memfd->i_am_master = 1; page_size = 1 << alloc.log2_page_size; - sh = (ssvm_shared_header_t *) memfd->sh; + sh = memfd->sh; sh->master_pid = memfd->my_pid; sh->ssvm_size = memfd->ssvm_size; + sh->ssvm_va = pointer_to_uword (sh); + sh->type = SSVM_SEGMENT_MEMFD; sh->heap = mheap_alloc_with_flags (((u8 *) sh) + page_size, memfd->ssvm_size - page_size, flags); - sh->ssvm_va = pointer_to_uword (sh); - sh->master_index = master_index; oldheap = ssvm_push_heap (sh); - sh->name = format (0, "%s%c", memfd->name, 0); + sh->name = format (0, "%s", memfd->name, 0); ssvm_pop_heap (oldheap); /* The application has to set set sh->ready... */ return 0; } -/* - * Subtly different than svm_slave_init. The caller - * needs to acquire a usable file descriptor for the memfd segment - * e.g. via vppinfra/socket.c:default_socket_recvmsg +/** + * Initialize memfd segment slave + * + * Subtly different than svm_slave_init. The caller needs to acquire + * a usable file descriptor for the memfd segment e.g. via + * vppinfra/socket.c:default_socket_recvmsg */ - int ssvm_slave_init_memfd (ssvm_private_t * memfd) { @@ -278,7 +279,7 @@ ssvm_slave_init_memfd (ssvm_private_t * memfd) if (clib_mem_vm_ext_map (&mapa)) { - clib_unix_warning ("slave research mmap"); + clib_unix_warning ("slave research mmap (fd %d)", mapa.fd); close (memfd->fd); return SSVM_API_ERROR_MMAP; } @@ -286,7 +287,7 @@ ssvm_slave_init_memfd (ssvm_private_t * memfd) sh = mapa.addr; memfd->requested_va = sh->ssvm_va; memfd->ssvm_size = sh->ssvm_size; - munmap (sh, page_size); + clib_mem_vm_free (sh, page_size); /* * Remap the segment at the 'right' address @@ -314,6 +315,36 @@ ssvm_delete_memfd (ssvm_private_t * memfd) close (memfd->fd); } +int +ssvm_master_init (ssvm_private_t * ssvm, ssvm_segment_type_t type) +{ + return (master_init_fns[type]) (ssvm); +} + +int +ssvm_slave_init (ssvm_private_t * ssvm, ssvm_segment_type_t type) +{ + return (slave_init_fns[type]) (ssvm); +} + +void +ssvm_delete (ssvm_private_t * ssvm) +{ + delete_fns[ssvm->sh->type] (ssvm); +} + +ssvm_segment_type_t +ssvm_type (const ssvm_private_t * ssvm) +{ + return ssvm->sh->type; +} + +u8 * +ssvm_name (const ssvm_private_t * ssvm) +{ + return ssvm->sh->name; +} + /* * fd.io coding-style-patch-verification: ON * diff --git a/src/svm/ssvm.h b/src/svm/ssvm.h index a181f2ef864..9bf009e73d2 100644 --- a/src/svm/ssvm.h +++ b/src/svm/ssvm.h @@ -45,6 +45,13 @@ #define SSVM_N_OPAQUE 7 +typedef enum ssvm_segment_type_ +{ + SSVM_SEGMENT_SHM = 0, + SSVM_SEGMENT_MEMFD, + SSVM_N_SEGMENT_TYPES /**< Private segments */ +} ssvm_segment_type_t; + typedef struct { /* Spin-lock */ @@ -68,8 +75,7 @@ typedef struct /* Set when the master application thinks it's time to make the donuts */ volatile u32 ready; - /* Needed to make unique MAC addresses, etc. */ - u32 master_index; + ssvm_segment_type_t type; } ssvm_shared_header_t; typedef struct @@ -81,8 +87,11 @@ typedef struct uword requested_va; int i_am_master; - /* Needed by memfd segments */ - int fd; + union + { + int fd; /**< memfd segments */ + int attach_timeout; /**< shm segments attach timeout (sec) */ + }; } ssvm_private_t; always_inline void @@ -145,6 +154,18 @@ ssvm_pop_heap (void *oldheap) clib_mem_set_heap (oldheap); } +static inline void * +ssvm_mem_alloc (ssvm_private_t * ssvm, uword size) +{ + u8 *oldheap; + void *rv; + + oldheap = clib_mem_set_heap (ssvm->sh->heap); + rv = clib_mem_alloc (size); + clib_mem_set_heap (oldheap); + return (rv); +} + #define foreach_ssvm_api_error \ _(NO_NAME, "No shared segment name", -100) \ _(NO_SIZE, "Size not set (master)", -101) \ @@ -162,14 +183,21 @@ typedef enum #define SSVM_API_ERROR_NO_NAME (-10) -int ssvm_master_init (ssvm_private_t * ssvm, u32 master_index); -int ssvm_slave_init (ssvm_private_t * ssvm, int timeout_in_seconds); +int ssvm_master_init (ssvm_private_t * ssvm, ssvm_segment_type_t type); +int ssvm_slave_init (ssvm_private_t * ssvm, ssvm_segment_type_t type); void ssvm_delete (ssvm_private_t * ssvm); -int ssvm_master_init_memfd (ssvm_private_t * memfd, u32 master_index); +int ssvm_master_init_shm (ssvm_private_t * ssvm); +int ssvm_slave_init_shm (ssvm_private_t * ssvm); +void ssvm_delete_shm (ssvm_private_t * ssvm); + +int ssvm_master_init_memfd (ssvm_private_t * memfd); int ssvm_slave_init_memfd (ssvm_private_t * memfd); void ssvm_delete_memfd (ssvm_private_t * memfd); +ssvm_segment_type_t ssvm_type (const ssvm_private_t * ssvm); +u8 *ssvm_name (const ssvm_private_t * ssvm); + #endif /* __included_ssvm_h__ */ /* diff --git a/src/svm/svm_fifo_segment.c b/src/svm/svm_fifo_segment.c index a56a714cc83..4d1833eee7e 100644 --- a/src/svm/svm_fifo_segment.c +++ b/src/svm/svm_fifo_segment.c @@ -58,7 +58,7 @@ allocate_new_fifo_chunk (svm_fifo_segment_header_t * fsh, static void preallocate_fifo_pairs (svm_fifo_segment_private_t * s, - svm_fifo_segment_create_args_t * a) + svm_fifo_segment_create_args_t * a, u32 protect_size) { svm_fifo_segment_header_t *fsh = s->h; u32 rx_fifo_size, tx_fifo_size, pairs_to_allocate; @@ -99,18 +99,17 @@ preallocate_fifo_pairs (svm_fifo_segment_private_t * s, /* Calculate space requirements */ pair_size = 2 * sizeof (*f) + rx_rounded_data_size + tx_rounded_data_size; - pairs_to_allocate = clib_min (s->ssvm.ssvm_size / pair_size, - a->preallocated_fifo_pairs); + if (protect_size) + protect_size += mheap_bytes (s->ssvm.sh->heap); + pairs_to_allocate = + clib_min ((s->ssvm.ssvm_size - protect_size) / pair_size, + a->preallocated_fifo_pairs); rx_fifo_size = (sizeof (*f) + rx_rounded_data_size) * pairs_to_allocate; tx_fifo_size = (sizeof (*f) + tx_rounded_data_size) * pairs_to_allocate; vec_validate_init_empty (fsh->free_fifos, clib_max (rx_freelist_index, tx_freelist_index), 0); - if (0) - clib_warning ("rx_fifo_size %u (%d mb), tx_fifo_size %u (%d mb)", - rx_fifo_size, rx_fifo_size >> 20, - tx_fifo_size, tx_fifo_size >> 20); /* Allocate rx fifo space. May fail. */ rx_fifo_space = clib_mem_alloc_aligned_at_offset @@ -164,16 +163,18 @@ preallocate_fifo_pairs (svm_fifo_segment_private_t * s, a->preallocated_fifo_pairs -= pairs_to_allocate; } -/** (master) create an svm fifo segment */ +/** + * Create an svm fifo segment and initialize as master + */ int svm_fifo_segment_create (svm_fifo_segment_create_args_t * a) { - int rv; - svm_fifo_segment_private_t *s; svm_fifo_segment_main_t *sm = &svm_fifo_segment_main; + svm_fifo_segment_private_t *s; ssvm_shared_header_t *sh; svm_fifo_segment_header_t *fsh; void *oldheap; + int rv; /* Allocate a fresh segment */ pool_get (sm->segments, s); @@ -185,16 +186,14 @@ svm_fifo_segment_create (svm_fifo_segment_create_args_t * a) s->ssvm.name = format (0, "%s%c", a->segment_name, 0); s->ssvm.requested_va = sm->next_baseva; - rv = ssvm_master_init (&s->ssvm, s - sm->segments); - - if (rv) + if ((rv = ssvm_master_init (&s->ssvm, a->segment_type))) { - _vec_len (s) = vec_len (s) - 1; + pool_put (sm->segments, s); return (rv); } /* Note: requested_va updated due to seg base addr randomization */ - sm->next_baseva = s->ssvm.requested_va + a->segment_size; + sm->next_baseva = s->ssvm.sh->ssvm_va + a->segment_size; sh = s->ssvm.sh; oldheap = ssvm_push_heap (sh); @@ -202,10 +201,8 @@ svm_fifo_segment_create (svm_fifo_segment_create_args_t * a) /* Set up svm_fifo_segment shared header */ fsh = clib_mem_alloc (sizeof (*fsh)); memset (fsh, 0, sizeof (*fsh)); - sh->opaque[0] = fsh; - s->h = fsh; - fsh->segment_name = format (0, "%s%c", a->segment_name, 0); - preallocate_fifo_pairs (s, a); + s->h = sh->opaque[0] = fsh; + preallocate_fifo_pairs (s, a, a->seg_protected_space); ssvm_pop_heap (oldheap); @@ -214,7 +211,9 @@ svm_fifo_segment_create (svm_fifo_segment_create_args_t * a) return (0); } -/** Create an svm fifo segment in process-private memory */ +/** + * Create an svm fifo segment in process-private memory + */ int svm_fifo_segment_create_process_private (svm_fifo_segment_create_args_t * a) { @@ -272,12 +271,10 @@ svm_fifo_segment_create_process_private (svm_fifo_segment_create_args_t * a) /* Set up svm_fifo_segment shared header */ fsh = clib_mem_alloc (sizeof (*fsh)); memset (fsh, 0, sizeof (*fsh)); - sh->opaque[0] = fsh; - s->h = fsh; fsh->flags = FIFO_SEGMENT_F_IS_PRIVATE; + s->h = sh->opaque[0] = fsh; if (!a->private_segment_count) fsh->flags |= FIFO_SEGMENT_F_IS_MAIN_HEAP; - fsh->segment_name = format (0, "%s%c", a->segment_name, 0); if (a->private_segment_count) { @@ -285,7 +282,7 @@ svm_fifo_segment_create_process_private (svm_fifo_segment_create_args_t * a) fsh->flags |= FIFO_SEGMENT_F_IS_PREALLOCATED; oldheap = clib_mem_get_heap (); clib_mem_set_heap (sh->heap); - preallocate_fifo_pairs (s, a); + preallocate_fifo_pairs (s, a, i == 0 ? a->seg_protected_space : 0); clib_mem_set_heap (oldheap); } sh->ready = 1; @@ -295,15 +292,15 @@ svm_fifo_segment_create_process_private (svm_fifo_segment_create_args_t * a) return (0); } -/** (slave) attach to an svm fifo segment */ +/** + * Attach as slave to an svm fifo segment + */ int svm_fifo_segment_attach (svm_fifo_segment_create_args_t * a) { - int rv; - svm_fifo_segment_private_t *s; svm_fifo_segment_main_t *sm = &svm_fifo_segment_main; - ssvm_shared_header_t *sh; - svm_fifo_segment_header_t *fsh; + svm_fifo_segment_private_t *s; + int rv; /* Allocate a fresh segment */ pool_get (sm->segments, s); @@ -313,19 +310,19 @@ svm_fifo_segment_attach (svm_fifo_segment_create_args_t * a) s->ssvm.my_pid = getpid (); s->ssvm.name = format (0, "%s%c", a->segment_name, 0); s->ssvm.requested_va = sm->next_baseva; + if (a->segment_type == SSVM_SEGMENT_MEMFD) + s->ssvm.fd = a->memfd_fd; + else + s->ssvm.attach_timeout = sm->timeout_in_seconds; - rv = ssvm_slave_init (&s->ssvm, sm->timeout_in_seconds); - - if (rv) + if ((rv = ssvm_slave_init (&s->ssvm, a->segment_type))) { _vec_len (s) = vec_len (s) - 1; return (rv); } /* Fish the segment header */ - sh = s->ssvm.sh; - fsh = (svm_fifo_segment_header_t *) sh->opaque[0]; - s->h = fsh; + s->h = s->ssvm.sh->opaque[0]; vec_add1 (a->new_segment_indices, s - sm->segments); return (0); @@ -335,6 +332,7 @@ void svm_fifo_segment_delete (svm_fifo_segment_private_t * s) { svm_fifo_segment_main_t *sm = &svm_fifo_segment_main; + if (s->h->flags & FIFO_SEGMENT_F_IS_PRIVATE) { /* Don't try to free vpp's heap! */ @@ -342,15 +340,18 @@ svm_fifo_segment_delete (svm_fifo_segment_private_t * s) mheap_free (s->ssvm.sh->heap); clib_mem_free (s->ssvm.sh); clib_mem_free (s->h); - pool_put (sm->segments, s); } else { ssvm_delete (&s->ssvm); - pool_put (sm->segments, s); } + memset (s, 0xfe, sizeof (*s)); + pool_put (sm->segments, s); } +/** + * Allocate fifo in svm segment + */ svm_fifo_t * svm_fifo_segment_alloc_fifo (svm_fifo_segment_private_t * s, u32 data_size_in_bytes, @@ -590,6 +591,53 @@ svm_fifo_segment_num_free_fifos (svm_fifo_segment_private_t * fifo_segment, return count; } +void +svm_fifo_segment_info (svm_fifo_segment_private_t * seg, uword * address, + u64 * size) +{ + if (seg->h->flags & FIFO_SEGMENT_F_IS_PRIVATE) + { + mheap_t *heap_header; + + *address = pointer_to_uword (seg->ssvm.sh->heap); + heap_header = mheap_header (seg->ssvm.sh->heap); + *size = heap_header->max_size; + } + else + { + *address = seg->ssvm.sh->ssvm_va; + *size = seg->ssvm.ssvm_size; + } +} + +mheap_t * +svm_fifo_segment_heap (svm_fifo_segment_private_t * seg) +{ + return seg->ssvm.sh->heap; +} + +u8 * +format_svm_fifo_segment_type (u8 * s, va_list * args) +{ + svm_fifo_segment_private_t *sp; + sp = va_arg (*args, svm_fifo_segment_private_t *); + ssvm_segment_type_t st = ssvm_type (&sp->ssvm); + + if ((sp->h->flags & FIFO_SEGMENT_F_IS_PRIVATE) + && !(sp->h->flags & FIFO_SEGMENT_F_IS_MAIN_HEAP)) + s = format (s, "%s", "private-heap"); + else if ((sp->h->flags & FIFO_SEGMENT_F_IS_PRIVATE) + && (sp->h->flags & FIFO_SEGMENT_F_IS_MAIN_HEAP)) + s = format (s, "%s", "main-heap"); + else if (st == SSVM_SEGMENT_MEMFD) + s = format (s, "%s", "memfd"); + else if (st == SSVM_SEGMENT_SHM) + s = format (s, "%s", "shm"); + else + s = format (s, "%s", "unknown"); + return s; +} + /** * Segment format function */ @@ -599,18 +647,14 @@ format_svm_fifo_segment (u8 * s, va_list * args) svm_fifo_segment_private_t *sp = va_arg (*args, svm_fifo_segment_private_t *); int verbose = va_arg (*args, int); - ssvm_shared_header_t *sh; - svm_fifo_segment_header_t *fsh; + svm_fifo_segment_header_t *fsh = sp->h; + u32 count, indent; svm_fifo_t *f; int i; - u32 count; - u32 indent = format_get_indent (s) + 2; - - sh = sp->ssvm.sh; - fsh = (svm_fifo_segment_header_t *) sh->opaque[0]; - s = format (s, "%USegment Heap: %U\n", format_white_space, indent, - format_mheap, sh->heap, verbose); + indent = format_get_indent (s) + 2; + s = format (s, "%U segment heap: %U\n", format_white_space, indent, + format_mheap, svm_fifo_segment_heap (sp), verbose); s = format (s, "%U segment has %u active fifos\n", format_white_space, indent, svm_fifo_segment_num_fifos (sp)); diff --git a/src/svm/svm_fifo_segment.h b/src/svm/svm_fifo_segment.h index 405df934578..0e86c25deab 100644 --- a/src/svm/svm_fifo_segment.h +++ b/src/svm/svm_fifo_segment.h @@ -34,11 +34,11 @@ typedef enum #define FIFO_SEGMENT_F_IS_PRIVATE 1 << 0 /* Private segment */ #define FIFO_SEGMENT_F_IS_MAIN_HEAP 1 << 1 /* Segment is main heap */ #define FIFO_SEGMENT_F_IS_PREALLOCATED 1 << 2 /* Segment is preallocated */ +#define FIFO_SEGMENT_F_WILL_DELETE 1 << 3 /* Segment will be removed */ typedef struct { svm_fifo_t *fifos; /**< Linked list of active RX fifos */ - u8 *segment_name; /**< Segment name */ svm_fifo_t **free_fifos; /**< Freelists, by fifo size */ u32 n_active_fifos; /**< Number of active fifos */ u8 flags; /**< Segment flags */ @@ -65,6 +65,7 @@ extern svm_fifo_segment_main_t svm_fifo_segment_main; typedef struct { + ssvm_segment_type_t segment_type; char *segment_name; u32 segment_size; u32 *new_segment_indices; @@ -72,13 +73,15 @@ typedef struct u32 tx_fifo_size; u32 preallocated_fifo_pairs; u32 private_segment_count; + u32 seg_protected_space; + int memfd_fd; } svm_fifo_segment_create_args_t; static inline svm_fifo_segment_private_t * svm_fifo_segment_get_segment (u32 segment_index) { svm_fifo_segment_main_t *ssm = &svm_fifo_segment_main; - return vec_elt_at_index (ssm->segments, segment_index); + return pool_elt_at_index (ssm->segments, segment_index); } static inline u8 @@ -120,9 +123,13 @@ u32 svm_fifo_segment_index (svm_fifo_segment_private_t * s); u32 svm_fifo_segment_num_fifos (svm_fifo_segment_private_t * fifo_segment); u32 svm_fifo_segment_num_free_fifos (svm_fifo_segment_private_t * fifo_segment, u32 fifo_size_in_bytes); +void svm_fifo_segment_info (svm_fifo_segment_private_t * seg, uword * address, + u64 * size); svm_fifo_segment_private_t *svm_fifo_segment_segments_pool (void); + format_function_t format_svm_fifo_segment; +format_function_t format_svm_fifo_segment_type; #endif /* __included_ssvm_fifo_segment_h__ */ diff --git a/src/tests/vnet/session/tcp_echo.c b/src/tests/vnet/session/tcp_echo.c index 3fef65ae304..a5ad35ae80a 100644 --- a/src/tests/vnet/session/tcp_echo.c +++ b/src/tests/vnet/session/tcp_echo.c @@ -125,9 +125,9 @@ typedef struct /* convenience */ svm_fifo_segment_main_t *segment_main; -} uri_tcp_test_main_t; +} echo_main_t; -uri_tcp_test_main_t uri_tcp_test_main; +echo_main_t echo_main; #if CLIB_DEBUG > 0 #define NITER 10000 @@ -138,11 +138,11 @@ uri_tcp_test_main_t uri_tcp_test_main; static u8 * format_api_error (u8 * s, va_list * args) { - uri_tcp_test_main_t *utm = &uri_tcp_test_main; + echo_main_t *em = &echo_main; i32 error = va_arg (*args, u32); uword *p; - p = hash_get (utm->error_string_by_error_number, -error); + p = hash_get (em->error_string_by_error_number, -error); if (p) s = format (s, "%s", p[0]); @@ -152,19 +152,19 @@ format_api_error (u8 * s, va_list * args) } static void -init_error_string_table (uri_tcp_test_main_t * utm) +init_error_string_table (echo_main_t * em) { - utm->error_string_by_error_number = hash_create (0, sizeof (uword)); + em->error_string_by_error_number = hash_create (0, sizeof (uword)); -#define _(n,v,s) hash_set (utm->error_string_by_error_number, -v, s); +#define _(n,v,s) hash_set (em->error_string_by_error_number, -v, s); foreach_vnet_api_error; #undef _ - hash_set (utm->error_string_by_error_number, 99, "Misc"); + hash_set (em->error_string_by_error_number, 99, "Misc"); } int -wait_for_state_change (uri_tcp_test_main_t * utm, connection_state_t state) +wait_for_state_change (echo_main_t * em, connection_state_t state) { #if CLIB_DEBUG > 0 #define TIMEOUT 600.0 @@ -172,15 +172,15 @@ wait_for_state_change (uri_tcp_test_main_t * utm, connection_state_t state) #define TIMEOUT 600.0 #endif - f64 timeout = clib_time_now (&utm->clib_time) + TIMEOUT; + f64 timeout = clib_time_now (&em->clib_time) + TIMEOUT; - while (clib_time_now (&utm->clib_time) < timeout) + while (clib_time_now (&em->clib_time) < timeout) { - if (utm->state == state) + if (em->state == state) return 0; - if (utm->state == STATE_FAILED) + if (em->state == STATE_FAILED) return -1; - if (utm->time_to_stop == 1) + if (em->time_to_stop == 1) return 0; } clib_warning ("timeout waiting for STATE_READY"); @@ -188,7 +188,7 @@ wait_for_state_change (uri_tcp_test_main_t * utm, connection_state_t state) } void -application_send_attach (uri_tcp_test_main_t * utm) +application_send_attach (echo_main_t * em) { vl_api_application_attach_t *bmp; u32 fifo_size = 4 << 20; @@ -196,7 +196,7 @@ application_send_attach (uri_tcp_test_main_t * utm) memset (bmp, 0, sizeof (*bmp)); bmp->_vl_msg_id = ntohs (VL_API_APPLICATION_ATTACH); - bmp->client_index = utm->my_client_index; + bmp->client_index = em->my_client_index; bmp->context = ntohl (0xfeedface); bmp->options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_ACCEPT_REDIRECT | APP_OPTIONS_FLAGS_ADD_SEGMENT; @@ -205,14 +205,14 @@ application_send_attach (uri_tcp_test_main_t * utm) bmp->options[APP_OPTIONS_TX_FIFO_SIZE] = fifo_size; bmp->options[APP_OPTIONS_ADD_SEGMENT_SIZE] = 128 << 20; bmp->options[APP_OPTIONS_SEGMENT_SIZE] = 256 << 20; - vl_msg_api_send_shmem (utm->vl_input_queue, (u8 *) & bmp); + vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & bmp); } int -application_attach (uri_tcp_test_main_t * utm) +application_attach (echo_main_t * em) { - application_send_attach (utm); - if (wait_for_state_change (utm, STATE_ATTACHED)) + application_send_attach (em); + if (wait_for_state_change (em, STATE_ATTACHED)) { clib_warning ("timeout waiting for STATE_ATTACHED"); return -1; @@ -221,31 +221,81 @@ application_attach (uri_tcp_test_main_t * utm) } void -application_detach (uri_tcp_test_main_t * utm) +application_detach (echo_main_t * em) { vl_api_application_detach_t *bmp; bmp = vl_msg_api_alloc (sizeof (*bmp)); memset (bmp, 0, sizeof (*bmp)); bmp->_vl_msg_id = ntohs (VL_API_APPLICATION_DETACH); - bmp->client_index = utm->my_client_index; + bmp->client_index = em->my_client_index; bmp->context = ntohl (0xfeedface); - vl_msg_api_send_shmem (utm->vl_input_queue, (u8 *) & bmp); + vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & bmp); + + clib_warning ("Sent detach"); +} + +static int +memfd_segment_attach (void) +{ + ssvm_private_t _ssvm = { 0 }, *ssvm = &_ssvm; + clib_error_t *error; + int rv; + + if ((error = vl_socket_client_recv_fd_msg (&ssvm->fd, 5))) + { + clib_error_report (error); + return -1; + } + + if ((rv = ssvm_slave_init_memfd (ssvm))) + return rv; + + return 0; +} + +static int +fifo_segment_attach (char *name, u32 size, ssvm_segment_type_t type) +{ + svm_fifo_segment_create_args_t _a, *a = &_a; + clib_error_t *error; + int rv; + + memset (a, 0, sizeof (*a)); + a->segment_name = (char *) name; + a->segment_size = size; + a->segment_type = type; + + if (type == SSVM_SEGMENT_MEMFD) + { + if ((error = vl_socket_client_recv_fd_msg (&a->memfd_fd, 5))) + { + clib_error_report (error); + return -1; + } + } + + if ((rv = svm_fifo_segment_attach (a))) + { + clib_warning ("svm_fifo_segment_attach ('%s') failed", name); + return rv; + } + + return 0; } static void vl_api_application_attach_reply_t_handler (vl_api_application_attach_reply_t * mp) { - uri_tcp_test_main_t *utm = &uri_tcp_test_main; - svm_fifo_segment_create_args_t _a, *a = &_a; - int rv; + echo_main_t *em = &echo_main; + ssvm_segment_type_t seg_type; if (mp->retval) { clib_warning ("attach failed: %U", format_api_error, clib_net_to_host_u32 (mp->retval)); - utm->state = STATE_FAILED; + em->state = STATE_FAILED; return; } @@ -255,24 +305,31 @@ vl_api_application_attach_reply_t_handler (vl_api_application_attach_reply_t * return; } - memset (a, 0, sizeof (*a)); - a->segment_name = (char *) mp->segment_name; - a->segment_size = mp->segment_size; - - ASSERT (mp->app_event_queue_address); + seg_type = em->use_sock_api ? SSVM_SEGMENT_MEMFD : SSVM_SEGMENT_SHM; - /* Attach to the segment vpp created */ - rv = svm_fifo_segment_attach (a); - if (rv) + /* Attach to fifo segment */ + if (fifo_segment_attach ((char *) mp->segment_name, mp->segment_size, + seg_type)) { - clib_warning ("svm_fifo_segment_attach ('%s') failed", - mp->segment_name); + em->state = STATE_FAILED; return; } - utm->our_event_queue = - uword_to_pointer (mp->app_event_queue_address, svm_queue_t *); - utm->state = STATE_ATTACHED; + /* If we're using memfd segments, read and attach to event qs segment */ + if (seg_type == SSVM_SEGMENT_MEMFD) + { + if (memfd_segment_attach ()) + { + clib_warning ("failed to attach to evt q segment"); + em->state = STATE_FAILED; + return; + } + } + + ASSERT (mp->app_event_queue_address); + em->our_event_queue = uword_to_pointer (mp->app_event_queue_address, + svm_queue_t *); + em->state = STATE_ATTACHED; } static void @@ -286,7 +343,7 @@ vl_api_application_detach_reply_t_handler (vl_api_application_detach_reply_t * static void stop_signal (int signum) { - uri_tcp_test_main_t *um = &uri_tcp_test_main; + echo_main_t *um = &echo_main; um->time_to_stop = 1; } @@ -294,7 +351,7 @@ stop_signal (int signum) static void stats_signal (int signum) { - uri_tcp_test_main_t *um = &uri_tcp_test_main; + echo_main_t *um = &echo_main; um->time_to_print_stats = 1; } @@ -318,31 +375,41 @@ vlib_cli_output (struct vlib_main_t *vm, char *fmt, ...) int connect_to_vpp (char *name) { - uri_tcp_test_main_t *utm = &uri_tcp_test_main; + echo_main_t *em = &echo_main; api_main_t *am = &api_main; - if (utm->use_sock_api) + if (em->use_sock_api) { - if (vl_socket_client_connect ((char *) utm->socket_name, name, + if (vl_socket_client_connect ((char *) em->socket_name, name, 0 /* default rx, tx buffer */ )) - return -1; + { + clib_warning ("socket connect failed"); + return -1; + } - return vl_socket_client_init_shm (0); + if (vl_socket_client_init_shm (0)) + { + clib_warning ("init shm api failed"); + return -1; + } } else { if (vl_client_connect_to_vlib ("/vpe-api", name, 32) < 0) - return -1; - utm->vl_input_queue = am->shmem_hdr->vl_input_queue; - utm->my_client_index = am->my_client_index; + { + clib_warning ("shmem connect failed"); + return -1; + } } + em->vl_input_queue = am->shmem_hdr->vl_input_queue; + em->my_client_index = am->my_client_index; return 0; } void -disconnect_from_vpp (uri_tcp_test_main_t * utm) +disconnect_from_vpp (echo_main_t * em) { - if (utm->use_sock_api) + if (em->use_sock_api) vl_socket_client_disconnect (); else vl_client_disconnect_from_vlib (); @@ -370,13 +437,13 @@ vl_api_map_another_segment_t_handler (vl_api_map_another_segment_t * mp) } static void -session_print_stats (uri_tcp_test_main_t * utm, session_t * session) +session_print_stats (echo_main_t * em, session_t * session) { f64 deltat; u64 bytes; - deltat = clib_time_now (&utm->clib_time) - session->start; - bytes = utm->i_am_master ? session->bytes_received : utm->bytes_to_send; + deltat = clib_time_now (&em->clib_time) - session->start; + bytes = em->i_am_master ? session->bytes_received : em->bytes_to_send; fformat (stdout, "Finished in %.6f\n", deltat); fformat (stdout, "%.4f Gbit/second\n", (bytes * 8.0) / deltat / 1e9); } @@ -384,19 +451,19 @@ session_print_stats (uri_tcp_test_main_t * utm, session_t * session) static void vl_api_disconnect_session_t_handler (vl_api_disconnect_session_t * mp) { - uri_tcp_test_main_t *utm = &uri_tcp_test_main; + echo_main_t *em = &echo_main; session_t *session = 0; vl_api_disconnect_session_reply_t *rmp; uword *p; int rv = 0; - p = hash_get (utm->session_index_by_vpp_handles, mp->handle); + p = hash_get (em->session_index_by_vpp_handles, mp->handle); if (p) { - session = pool_elt_at_index (utm->sessions, p[0]); - hash_unset (utm->session_index_by_vpp_handles, mp->handle); - pool_put (utm->sessions, session); + session = pool_elt_at_index (em->sessions, p[0]); + hash_unset (em->session_index_by_vpp_handles, mp->handle); + pool_put (em->sessions, session); } else { @@ -404,7 +471,7 @@ vl_api_disconnect_session_t_handler (vl_api_disconnect_session_t * mp) rv = -11; } -// utm->time_to_stop = 1; +// em->time_to_stop = 1; rmp = vl_msg_api_alloc (sizeof (*rmp)); memset (rmp, 0, sizeof (*rmp)); @@ -412,27 +479,27 @@ vl_api_disconnect_session_t_handler (vl_api_disconnect_session_t * mp) rmp->_vl_msg_id = ntohs (VL_API_DISCONNECT_SESSION_REPLY); rmp->retval = rv; rmp->handle = mp->handle; - vl_msg_api_send_shmem (utm->vl_input_queue, (u8 *) & rmp); + vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & rmp); if (session) - session_print_stats (utm, session); + session_print_stats (em, session); } static void vl_api_reset_session_t_handler (vl_api_reset_session_t * mp) { - uri_tcp_test_main_t *utm = &uri_tcp_test_main; + echo_main_t *em = &echo_main; vl_api_reset_session_reply_t *rmp; uword *p; int rv = 0; - p = hash_get (utm->session_index_by_vpp_handles, mp->handle); + p = hash_get (em->session_index_by_vpp_handles, mp->handle); if (p) { clib_warning ("got reset"); /* Cleanup later */ - utm->time_to_stop = 1; + em->time_to_stop = 1; } else { @@ -445,12 +512,11 @@ vl_api_reset_session_t_handler (vl_api_reset_session_t * mp) rmp->_vl_msg_id = ntohs (VL_API_RESET_SESSION_REPLY); rmp->retval = rv; rmp->handle = mp->handle; - vl_msg_api_send_shmem (utm->vl_input_queue, (u8 *) & rmp); + vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & rmp); } void -client_handle_fifo_event_rx (uri_tcp_test_main_t * utm, - session_fifo_event_t * e) +client_handle_fifo_event_rx (echo_main_t * em, session_fifo_event_t * e) { svm_fifo_t *rx_fifo; int n_read, bytes, i; @@ -465,27 +531,26 @@ client_handle_fifo_event_rx (uri_tcp_test_main_t * utm, do { n_read = svm_fifo_dequeue_nowait (rx_fifo, - clib_min (vec_len (utm->rx_buf), - bytes), utm->rx_buf); + clib_min (vec_len (em->rx_buf), + bytes), em->rx_buf); if (n_read > 0) { bytes -= n_read; - if (utm->test_return_packets) + if (em->test_return_packets) { for (i = 0; i < n_read; i++) { - if (utm->rx_buf[i] - != ((utm->client_bytes_received + i) & 0xff)) + if (em->rx_buf[i] + != ((em->client_bytes_received + i) & 0xff)) { clib_warning ("error at byte %lld, 0x%x not 0x%x", - utm->client_bytes_received + i, - utm->rx_buf[i], - ((utm->client_bytes_received + - i) & 0xff)); + em->client_bytes_received + i, + em->rx_buf[i], + ((em->client_bytes_received + i) & 0xff)); } } } - utm->client_bytes_received += n_read; + em->client_bytes_received += n_read; } else { @@ -501,15 +566,15 @@ client_handle_fifo_event_rx (uri_tcp_test_main_t * utm, } void -client_handle_event_queue (uri_tcp_test_main_t * utm) +client_handle_event_queue (echo_main_t * em) { session_fifo_event_t _e, *e = &_e;; - svm_queue_sub (utm->our_event_queue, (u8 *) e, SVM_Q_WAIT, 0); + svm_queue_sub (em->our_event_queue, (u8 *) e, SVM_Q_WAIT, 0); switch (e->event_type) { case FIFO_EVENT_APP_RX: - client_handle_fifo_event_rx (utm, e); + client_handle_fifo_event_rx (em, e); break; case FIFO_EVENT_DISCONNECT: @@ -525,16 +590,16 @@ static void * client_rx_thread_fn (void *arg) { session_fifo_event_t _e, *e = &_e; - uri_tcp_test_main_t *utm = &uri_tcp_test_main; + echo_main_t *em = &echo_main; - utm->client_bytes_received = 0; + em->client_bytes_received = 0; while (1) { - svm_queue_sub (utm->our_event_queue, (u8 *) e, SVM_Q_WAIT, 0); + svm_queue_sub (em->our_event_queue, (u8 *) e, SVM_Q_WAIT, 0); switch (e->event_type) { case FIFO_EVENT_APP_RX: - client_handle_fifo_event_rx (utm, e); + client_handle_fifo_event_rx (em, e); break; case FIFO_EVENT_DISCONNECT: @@ -544,7 +609,7 @@ client_rx_thread_fn (void *arg) break; } - if (PREDICT_FALSE (utm->time_to_stop == 1)) + if (PREDICT_FALSE (em->time_to_stop == 1)) break; } pthread_exit (0); @@ -554,7 +619,7 @@ client_rx_thread_fn (void *arg) static void vl_api_connect_session_reply_t_handler (vl_api_connect_session_reply_t * mp) { - uri_tcp_test_main_t *utm = &uri_tcp_test_main; + echo_main_t *em = &echo_main; session_t *session; u32 session_index; svm_fifo_t *rx_fifo, *tx_fifo; @@ -564,7 +629,7 @@ vl_api_connect_session_reply_t_handler (vl_api_connect_session_reply_t * mp) { clib_warning ("connection failed with code: %U", format_api_error, clib_net_to_host_u32 (mp->retval)); - utm->state = STATE_FAILED; + em->state = STATE_FAILED; return; } else @@ -574,15 +639,15 @@ vl_api_connect_session_reply_t_handler (vl_api_connect_session_reply_t * mp) clib_net_to_host_u16 (mp->lcl_port)); } - utm->vpp_event_queue = + em->vpp_event_queue = uword_to_pointer (mp->vpp_event_queue_address, svm_queue_t *); /* * Setup session */ - pool_get (utm->sessions, session); - session_index = session - utm->sessions; + pool_get (em->sessions, session); + session_index = session - em->sessions; rx_fifo = uword_to_pointer (mp->server_rx_fifo, svm_fifo_t *); rx_fifo->client_session_index = session_index; @@ -592,17 +657,17 @@ vl_api_connect_session_reply_t_handler (vl_api_connect_session_reply_t * mp) session->server_rx_fifo = rx_fifo; session->server_tx_fifo = tx_fifo; session->vpp_session_handle = mp->handle; - session->start = clib_time_now (&utm->clib_time); + session->start = clib_time_now (&em->clib_time); /* Save handle */ - utm->connected_session_index = session_index; - utm->state = STATE_READY; + em->connected_session_index = session_index; + em->state = STATE_READY; /* Add it to lookup table */ - hash_set (utm->session_index_by_vpp_handles, mp->handle, session_index); + hash_set (em->session_index_by_vpp_handles, mp->handle, session_index); /* Start RX thread */ - rv = pthread_create (&utm->client_rx_thread_handle, + rv = pthread_create (&em->client_rx_thread_handle, NULL /*attr */ , client_rx_thread_fn, 0); if (rv) { @@ -612,10 +677,9 @@ vl_api_connect_session_reply_t_handler (vl_api_connect_session_reply_t * mp) } static void -send_test_chunk (uri_tcp_test_main_t * utm, svm_fifo_t * tx_fifo, int mypid, - u32 bytes) +send_test_chunk (echo_main_t * em, svm_fifo_t * tx_fifo, int mypid, u32 bytes) { - u8 *test_data = utm->connect_test_data; + u8 *test_data = em->connect_test_data; u64 bytes_sent = 0; int test_buf_offset = 0; u32 bytes_to_snd; @@ -627,7 +691,7 @@ send_test_chunk (uri_tcp_test_main_t * utm, svm_fifo_t * tx_fifo, int mypid, if (bytes_to_snd > vec_len (test_data)) bytes_to_snd = vec_len (test_data); - while (bytes_to_snd > 0 && !utm->time_to_stop) + while (bytes_to_snd > 0 && !em->time_to_stop) { actual_write = (bytes_to_snd > queue_max_chunk) ? queue_max_chunk : bytes_to_snd; @@ -646,7 +710,7 @@ send_test_chunk (uri_tcp_test_main_t * utm, svm_fifo_t * tx_fifo, int mypid, evt.fifo = tx_fifo; evt.event_type = FIFO_EVENT_APP_TX; - svm_queue_add (utm->vpp_event_queue, + svm_queue_add (em->vpp_event_queue, (u8 *) & evt, 0 /* do wait for mutex */ ); } } @@ -654,71 +718,71 @@ send_test_chunk (uri_tcp_test_main_t * utm, svm_fifo_t * tx_fifo, int mypid, } void -client_send_data (uri_tcp_test_main_t * utm) +client_send_data (echo_main_t * em) { - u8 *test_data = utm->connect_test_data; + u8 *test_data = em->connect_test_data; int mypid = getpid (); session_t *session; svm_fifo_t *tx_fifo; u32 n_iterations, leftover; int i; - session = pool_elt_at_index (utm->sessions, utm->connected_session_index); + session = pool_elt_at_index (em->sessions, em->connected_session_index); tx_fifo = session->server_tx_fifo; ASSERT (vec_len (test_data) > 0); - vec_validate (utm->rx_buf, vec_len (test_data) - 1); - n_iterations = utm->bytes_to_send / vec_len (test_data); + vec_validate (em->rx_buf, vec_len (test_data) - 1); + n_iterations = em->bytes_to_send / vec_len (test_data); for (i = 0; i < n_iterations; i++) { - send_test_chunk (utm, tx_fifo, mypid, 0); - if (utm->time_to_stop) + send_test_chunk (em, tx_fifo, mypid, 0); + if (em->time_to_stop) break; } - leftover = utm->bytes_to_send % vec_len (test_data); + leftover = em->bytes_to_send % vec_len (test_data); if (leftover) - send_test_chunk (utm, tx_fifo, mypid, leftover); + send_test_chunk (em, tx_fifo, mypid, leftover); - if (!utm->drop_packets) + if (!em->drop_packets) { - f64 timeout = clib_time_now (&utm->clib_time) + 10; + f64 timeout = clib_time_now (&em->clib_time) + 10; /* Wait for the outstanding packets */ - while (utm->client_bytes_received < + while (em->client_bytes_received < vec_len (test_data) * n_iterations + leftover) { - if (clib_time_now (&utm->clib_time) > timeout) + if (clib_time_now (&em->clib_time) > timeout) { clib_warning ("timed out waiting for the missing packets"); break; } } } - utm->time_to_stop = 1; + em->time_to_stop = 1; } void -client_send_connect (uri_tcp_test_main_t * utm) +client_send_connect (echo_main_t * em) { vl_api_connect_uri_t *cmp; cmp = vl_msg_api_alloc (sizeof (*cmp)); memset (cmp, 0, sizeof (*cmp)); cmp->_vl_msg_id = ntohs (VL_API_CONNECT_URI); - cmp->client_index = utm->my_client_index; + cmp->client_index = em->my_client_index; cmp->context = ntohl (0xfeedface); - memcpy (cmp->uri, utm->connect_uri, vec_len (utm->connect_uri)); - vl_msg_api_send_shmem (utm->vl_input_queue, (u8 *) & cmp); + memcpy (cmp->uri, em->connect_uri, vec_len (em->connect_uri)); + vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & cmp); } int -client_connect (uri_tcp_test_main_t * utm) +client_connect (echo_main_t * em) { - client_send_connect (utm); - if (wait_for_state_change (utm, STATE_READY)) + client_send_connect (em); + if (wait_for_state_change (em, STATE_READY)) { clib_warning ("Connect failed"); return -1; @@ -727,26 +791,26 @@ client_connect (uri_tcp_test_main_t * utm) } void -client_send_disconnect (uri_tcp_test_main_t * utm) +client_send_disconnect (echo_main_t * em) { session_t *connected_session; vl_api_disconnect_session_t *dmp; - connected_session = pool_elt_at_index (utm->sessions, - utm->connected_session_index); + connected_session = pool_elt_at_index (em->sessions, + em->connected_session_index); dmp = vl_msg_api_alloc (sizeof (*dmp)); memset (dmp, 0, sizeof (*dmp)); dmp->_vl_msg_id = ntohs (VL_API_DISCONNECT_SESSION); - dmp->client_index = utm->my_client_index; + dmp->client_index = em->my_client_index; dmp->handle = connected_session->vpp_session_handle; - vl_msg_api_send_shmem (utm->vl_input_queue, (u8 *) & dmp); + vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & dmp); } int -client_disconnect (uri_tcp_test_main_t * utm) +client_disconnect (echo_main_t * em) { - client_send_disconnect (utm); + client_send_disconnect (em); clib_warning ("Sent disconnect"); - if (wait_for_state_change (utm, STATE_START)) + if (wait_for_state_change (em, STATE_START)) { clib_warning ("Disconnect failed"); return -1; @@ -755,58 +819,57 @@ client_disconnect (uri_tcp_test_main_t * utm) } static void -client_run (uri_tcp_test_main_t * utm) +client_run (echo_main_t * em) { int i; - if (application_attach (utm)) + if (application_attach (em)) return; - if (client_connect (utm)) + if (client_connect (em)) { - application_detach (utm); + application_detach (em); return; } /* Init test data */ - vec_validate (utm->connect_test_data, 128 * 1024 - 1); - for (i = 0; i < vec_len (utm->connect_test_data); i++) - utm->connect_test_data[i] = i & 0xff; + vec_validate (em->connect_test_data, 128 * 1024 - 1); + for (i = 0; i < vec_len (em->connect_test_data); i++) + em->connect_test_data[i] = i & 0xff; /* Start send */ - client_send_data (utm); + client_send_data (em); - /* Disconnect */ - client_disconnect (utm); - - application_detach (utm); + /* Disconnect and detach */ + client_disconnect (em); + application_detach (em); } static void vl_api_bind_uri_reply_t_handler (vl_api_bind_uri_reply_t * mp) { - uri_tcp_test_main_t *utm = &uri_tcp_test_main; + echo_main_t *em = &echo_main; if (mp->retval) { clib_warning ("bind failed: %U", format_api_error, clib_net_to_host_u32 (mp->retval)); - utm->state = STATE_FAILED; + em->state = STATE_FAILED; return; } - utm->state = STATE_READY; + em->state = STATE_READY; } static void vl_api_unbind_uri_reply_t_handler (vl_api_unbind_uri_reply_t * mp) { - uri_tcp_test_main_t *utm = &uri_tcp_test_main; + echo_main_t *em = &echo_main; if (mp->retval != 0) clib_warning ("returned %d", ntohl (mp->retval)); - utm->state = STATE_START; + em->state = STATE_START; } u8 * @@ -895,7 +958,7 @@ format_ip46_address (u8 * s, va_list * args) static void vl_api_accept_session_t_handler (vl_api_accept_session_t * mp) { - uri_tcp_test_main_t *utm = &uri_tcp_test_main; + echo_main_t *em = &echo_main; vl_api_accept_session_reply_t *rmp; svm_fifo_t *rx_fifo, *tx_fifo; session_t *session; @@ -904,17 +967,17 @@ vl_api_accept_session_t_handler (vl_api_accept_session_t * mp) u8 *ip_str; if (start_time == 0.0) - start_time = clib_time_now (&utm->clib_time); + start_time = clib_time_now (&em->clib_time); ip_str = format (0, "%U", format_ip46_address, &mp->ip, mp->is_ip4); clib_warning ("Accepted session from: %s:%d", ip_str, clib_net_to_host_u16 (mp->port)); - utm->vpp_event_queue = + em->vpp_event_queue = uword_to_pointer (mp->vpp_event_queue_address, svm_queue_t *); /* Allocate local session and set it up */ - pool_get (utm->sessions, session); - session_index = session - utm->sessions; + pool_get (em->sessions, session); + session_index = session - em->sessions; rx_fifo = uword_to_pointer (mp->server_rx_fifo, svm_fifo_t *); rx_fifo->client_session_index = session_index; @@ -925,17 +988,17 @@ vl_api_accept_session_t_handler (vl_api_accept_session_t * mp) session->server_tx_fifo = tx_fifo; /* Add it to lookup table */ - hash_set (utm->session_index_by_vpp_handles, mp->handle, session_index); + hash_set (em->session_index_by_vpp_handles, mp->handle, session_index); - utm->state = STATE_READY; + em->state = STATE_READY; /* Stats printing */ - if (pool_elts (utm->sessions) && (pool_elts (utm->sessions) % 20000) == 0) + if (pool_elts (em->sessions) && (pool_elts (em->sessions) % 20000) == 0) { - f64 now = clib_time_now (&utm->clib_time); + f64 now = clib_time_now (&em->clib_time); fformat (stdout, "%d active sessions in %.2f seconds, %.2f/sec...\n", - pool_elts (utm->sessions), now - start_time, - (f64) pool_elts (utm->sessions) / (now - start_time)); + pool_elts (em->sessions), now - start_time, + (f64) pool_elts (em->sessions) / (now - start_time)); } /* @@ -946,15 +1009,14 @@ vl_api_accept_session_t_handler (vl_api_accept_session_t * mp) rmp->_vl_msg_id = ntohs (VL_API_ACCEPT_SESSION_REPLY); rmp->handle = mp->handle; rmp->context = mp->context; - vl_msg_api_send_shmem (utm->vl_input_queue, (u8 *) & rmp); + vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & rmp); session->bytes_received = 0; - session->start = clib_time_now (&utm->clib_time); + session->start = clib_time_now (&em->clib_time); } void -server_handle_fifo_event_rx (uri_tcp_test_main_t * utm, - session_fifo_event_t * e) +server_handle_fifo_event_rx (echo_main_t * em, session_fifo_event_t * e) { svm_fifo_t *rx_fifo, *tx_fifo; int n_read; @@ -964,9 +1026,9 @@ server_handle_fifo_event_rx (uri_tcp_test_main_t * utm, int rv; u32 max_dequeue, offset, max_transfer, rx_buf_len; - rx_buf_len = vec_len (utm->rx_buf); + rx_buf_len = vec_len (em->rx_buf); rx_fifo = e->fifo; - session = &utm->sessions[rx_fifo->client_session_index]; + session = &em->sessions[rx_fifo->client_session_index]; tx_fifo = session->server_tx_fifo; max_dequeue = svm_fifo_max_dequeue (rx_fifo); @@ -982,7 +1044,7 @@ server_handle_fifo_event_rx (uri_tcp_test_main_t * utm, do { max_transfer = clib_min (rx_buf_len, max_dequeue); - n_read = svm_fifo_dequeue_nowait (rx_fifo, max_transfer, utm->rx_buf); + n_read = svm_fifo_dequeue_nowait (rx_fifo, max_transfer, em->rx_buf); if (n_read > 0) { max_dequeue -= n_read; @@ -990,20 +1052,20 @@ server_handle_fifo_event_rx (uri_tcp_test_main_t * utm, } /* Reflect if a non-drop session */ - if (!utm->drop_packets && n_read > 0) + if (!em->drop_packets && n_read > 0) { offset = 0; do { rv = svm_fifo_enqueue_nowait (tx_fifo, n_read, - &utm->rx_buf[offset]); + &em->rx_buf[offset]); if (rv > 0) { n_read -= rv; offset += rv; } } - while ((rv <= 0 || n_read > 0) && !utm->time_to_stop); + while ((rv <= 0 || n_read > 0) && !em->time_to_stop); /* If event wasn't set, add one */ if (svm_fifo_set_event (tx_fifo)) @@ -1012,26 +1074,26 @@ server_handle_fifo_event_rx (uri_tcp_test_main_t * utm, evt.fifo = tx_fifo; evt.event_type = FIFO_EVENT_APP_TX; - q = utm->vpp_event_queue; + q = em->vpp_event_queue; svm_queue_add (q, (u8 *) & evt, 1 /* do wait for mutex */ ); } } } - while ((n_read < 0 || max_dequeue > 0) && !utm->time_to_stop); + while ((n_read < 0 || max_dequeue > 0) && !em->time_to_stop); } void -server_handle_event_queue (uri_tcp_test_main_t * utm) +server_handle_event_queue (echo_main_t * em) { session_fifo_event_t _e, *e = &_e; while (1) { - svm_queue_sub (utm->our_event_queue, (u8 *) e, SVM_Q_WAIT, 0); + svm_queue_sub (em->our_event_queue, (u8 *) e, SVM_Q_WAIT, 0); switch (e->event_type) { case FIFO_EVENT_APP_RX: - server_handle_fifo_event_rx (utm, e); + server_handle_fifo_event_rx (em, e); break; case FIFO_EVENT_DISCONNECT: @@ -1041,35 +1103,35 @@ server_handle_event_queue (uri_tcp_test_main_t * utm) clib_warning ("unknown event type %d", e->event_type); break; } - if (PREDICT_FALSE (utm->time_to_stop == 1)) + if (PREDICT_FALSE (em->time_to_stop == 1)) break; - if (PREDICT_FALSE (utm->time_to_print_stats == 1)) + if (PREDICT_FALSE (em->time_to_print_stats == 1)) { - utm->time_to_print_stats = 0; - fformat (stdout, "%d connections\n", pool_elts (utm->sessions)); + em->time_to_print_stats = 0; + fformat (stdout, "%d connections\n", pool_elts (em->sessions)); } } } void -server_send_listen (uri_tcp_test_main_t * utm) +server_send_listen (echo_main_t * em) { vl_api_bind_uri_t *bmp; bmp = vl_msg_api_alloc (sizeof (*bmp)); memset (bmp, 0, sizeof (*bmp)); bmp->_vl_msg_id = ntohs (VL_API_BIND_URI); - bmp->client_index = utm->my_client_index; + bmp->client_index = em->my_client_index; bmp->context = ntohl (0xfeedface); - memcpy (bmp->uri, utm->uri, vec_len (utm->uri)); - vl_msg_api_send_shmem (utm->vl_input_queue, (u8 *) & bmp); + memcpy (bmp->uri, em->uri, vec_len (em->uri)); + vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & bmp); } int -server_listen (uri_tcp_test_main_t * utm) +server_listen (echo_main_t * em) { - server_send_listen (utm); - if (wait_for_state_change (utm, STATE_READY)) + server_send_listen (em); + if (wait_for_state_change (em, STATE_READY)) { clib_warning ("timeout waiting for STATE_READY"); return -1; @@ -1078,7 +1140,7 @@ server_listen (uri_tcp_test_main_t * utm) } void -server_send_unbind (uri_tcp_test_main_t * utm) +server_send_unbind (echo_main_t * em) { vl_api_unbind_uri_t *ump; @@ -1086,16 +1148,16 @@ server_send_unbind (uri_tcp_test_main_t * utm) memset (ump, 0, sizeof (*ump)); ump->_vl_msg_id = ntohs (VL_API_UNBIND_URI); - ump->client_index = utm->my_client_index; - memcpy (ump->uri, utm->uri, vec_len (utm->uri)); - vl_msg_api_send_shmem (utm->vl_input_queue, (u8 *) & ump); + ump->client_index = em->my_client_index; + memcpy (ump->uri, em->uri, vec_len (em->uri)); + vl_msg_api_send_shmem (em->vl_input_queue, (u8 *) & ump); } int -server_unbind (uri_tcp_test_main_t * utm) +server_unbind (echo_main_t * em) { - server_send_unbind (utm); - if (wait_for_state_change (utm, STATE_START)) + server_send_unbind (em); + if (wait_for_state_change (em, STATE_START)) { clib_warning ("timeout waiting for STATE_START"); return -1; @@ -1104,7 +1166,7 @@ server_unbind (uri_tcp_test_main_t * utm) } void -server_run (uri_tcp_test_main_t * utm) +server_run (echo_main_t * em) { session_t *session; int i; @@ -1112,26 +1174,26 @@ server_run (uri_tcp_test_main_t * utm) /* $$$$ hack preallocation */ for (i = 0; i < 200000; i++) { - pool_get (utm->sessions, session); + pool_get (em->sessions, session); memset (session, 0, sizeof (*session)); } for (i = 0; i < 200000; i++) - pool_put_index (utm->sessions, i); + pool_put_index (em->sessions, i); - if (application_attach (utm)) + if (application_attach (em)) return; /* Bind to uri */ - if (server_listen (utm)) + if (server_listen (em)) return; /* Enter handle event loop */ - server_handle_event_queue (utm); + server_handle_event_queue (em); /* Cleanup */ - server_send_unbind (utm); + server_send_unbind (em); - application_detach (utm); + application_detach (em); fformat (stdout, "Test complete...\n"); } @@ -1140,7 +1202,7 @@ static void vl_api_disconnect_session_reply_t_handler (vl_api_disconnect_session_reply_t * mp) { - uri_tcp_test_main_t *utm = &uri_tcp_test_main; + echo_main_t *em = &echo_main; session_t *session; if (mp->retval) @@ -1149,13 +1211,13 @@ vl_api_disconnect_session_reply_t_handler (vl_api_disconnect_session_reply_t * ntohl (mp->retval)); } - utm->state = STATE_START; - session = pool_elt_at_index (utm->sessions, utm->connected_session_index); + em->state = STATE_START; + session = pool_elt_at_index (em->sessions, em->connected_session_index); if (session) - session_print_stats (utm, session); + session_print_stats (em, session); } -#define foreach_uri_msg \ +#define foreach_tcp_echo_msg \ _(BIND_URI_REPLY, bind_uri_reply) \ _(UNBIND_URI_REPLY, unbind_uri_reply) \ _(ACCEPT_SESSION, accept_session) \ @@ -1168,7 +1230,7 @@ _(APPLICATION_DETACH_REPLY, application_detach_reply) \ _(MAP_ANOTHER_SEGMENT, map_another_segment) \ void -uri_api_hookup (uri_tcp_test_main_t * utm) +tcp_echo_api_hookup (echo_main_t * em) { #define _(N,n) \ vl_msg_api_set_handlers(VL_API_##N, #n, \ @@ -1177,23 +1239,24 @@ uri_api_hookup (uri_tcp_test_main_t * utm) vl_api_##n##_t_endian, \ vl_api_##n##_t_print, \ sizeof(vl_api_##n##_t), 1); - foreach_uri_msg; + foreach_tcp_echo_msg; #undef _ } int main (int argc, char **argv) { - uri_tcp_test_main_t *utm = &uri_tcp_test_main; + int i_am_master = 1, drop_packets = 0, test_return_packets = 0; + echo_main_t *em = &echo_main; unformat_input_t _argv, *a = &_argv; u8 *chroot_prefix; u8 *heap, *uri = 0; u8 *bind_uri = (u8 *) "tcp://0.0.0.0/1234"; u8 *connect_uri = (u8 *) "tcp://6.0.1.2/1234"; u64 bytes_to_send = 64 << 10, mbytes; + char *app_name; u32 tmp; mheap_t *h; - int i_am_master = 1, drop_packets = 0, test_return_packets = 0; clib_mem_init (0, 256 << 20); @@ -1203,17 +1266,17 @@ main (int argc, char **argv) /* make the main heap thread-safe */ h->flags |= MHEAP_FLAG_THREAD_SAFE; - vec_validate (utm->rx_buf, 128 << 10); + vec_validate (em->rx_buf, 128 << 10); - utm->session_index_by_vpp_handles = hash_create (0, sizeof (uword)); + em->session_index_by_vpp_handles = hash_create (0, sizeof (uword)); - utm->my_pid = getpid (); - utm->configured_segment_size = 1 << 20; - utm->socket_name = 0; - utm->use_sock_api = 1; + em->my_pid = getpid (); + em->configured_segment_size = 1 << 20; + em->socket_name = 0; + em->use_sock_api = 1; - clib_time_init (&utm->clib_time); - init_error_string_table (utm); + clib_time_init (&em->clib_time); + init_error_string_table (em); svm_fifo_segment_init (0x200000000ULL, 20); unformat_init_command_line (a, argv); @@ -1226,9 +1289,9 @@ main (int argc, char **argv) else if (unformat (a, "uri %s", &uri)) ; else if (unformat (a, "segment-size %dM", &tmp)) - utm->configured_segment_size = tmp << 20; + em->configured_segment_size = tmp << 20; else if (unformat (a, "segment-size %dG", &tmp)) - utm->configured_segment_size = tmp << 30; + em->configured_segment_size = tmp << 30; else if (unformat (a, "master")) i_am_master = 1; else if (unformat (a, "slave")) @@ -1245,10 +1308,10 @@ main (int argc, char **argv) { bytes_to_send = mbytes << 30; } - else if (unformat (a, "socket-name %s", &utm->socket_name)) + else if (unformat (a, "socket-name %s", &em->socket_name)) ; else if (unformat (a, "use-svm-api")) - utm->use_sock_api = 0; + em->use_sock_api = 0; else { fformat (stderr, "%s: usage [master|slave]\n"); @@ -1256,32 +1319,32 @@ main (int argc, char **argv) } } - if (!utm->socket_name) - utm->socket_name = format (0, "%s%c", API_SOCKET_FILE, 0); + if (!em->socket_name) + em->socket_name = format (0, "%s%c", API_SOCKET_FILE, 0); if (uri) { - utm->uri = format (0, "%s%c", uri, 0); - utm->connect_uri = format (0, "%s%c", uri, 0); + em->uri = format (0, "%s%c", uri, 0); + em->connect_uri = format (0, "%s%c", uri, 0); } else { - utm->uri = format (0, "%s%c", bind_uri, 0); - utm->connect_uri = format (0, "%s%c", connect_uri, 0); + em->uri = format (0, "%s%c", bind_uri, 0); + em->connect_uri = format (0, "%s%c", connect_uri, 0); } - utm->i_am_master = i_am_master; - utm->segment_main = &svm_fifo_segment_main; - utm->drop_packets = drop_packets; - utm->test_return_packets = test_return_packets; - utm->bytes_to_send = bytes_to_send; - utm->time_to_stop = 0; + em->i_am_master = i_am_master; + em->segment_main = &svm_fifo_segment_main; + em->drop_packets = drop_packets; + em->test_return_packets = test_return_packets; + em->bytes_to_send = bytes_to_send; + em->time_to_stop = 0; setup_signal_handlers (); - uri_api_hookup (utm); + tcp_echo_api_hookup (em); - if (connect_to_vpp (i_am_master ? "tcp_echo_server" : "tcp_echo_client") < - 0) + app_name = i_am_master ? "tcp_echo_server" : "tcp_echo_client"; + if (connect_to_vpp (app_name) < 0) { svm_region_exit (); fformat (stderr, "Couldn't connect to vpe, exiting...\n"); @@ -1289,11 +1352,11 @@ main (int argc, char **argv) } if (i_am_master == 0) - client_run (utm); + client_run (em); else - server_run (utm); + server_run (em); - disconnect_from_vpp (utm); + disconnect_from_vpp (em); exit (0); } diff --git a/src/tests/vnet/session/udp_echo.c b/src/tests/vnet/session/udp_echo.c index 07e72376732..e92bf4067ea 100644 --- a/src/tests/vnet/session/udp_echo.c +++ b/src/tests/vnet/session/udp_echo.c @@ -851,7 +851,7 @@ vl_api_connect_session_reply_t_handler (vl_api_connect_session_reply_t * mp) utm->state = STATE_READY; } -#define foreach_uri_msg \ +#define foreach_tcp_echo_msg \ _(BIND_URI_REPLY, bind_uri_reply) \ _(CONNECT_URI, connect_uri) \ _(CONNECT_SESSION_REPLY, connect_session_reply) \ @@ -863,7 +863,7 @@ _(APPLICATION_ATTACH_REPLY, application_attach_reply) \ _(APPLICATION_DETACH_REPLY, application_detach_reply) \ void -uri_api_hookup (uri_udp_test_main_t * utm) +tcp_echo_api_hookup (uri_udp_test_main_t * utm) { #define _(N,n) \ vl_msg_api_set_handlers(VL_API_##N, #n, \ @@ -872,7 +872,7 @@ uri_api_hookup (uri_udp_test_main_t * utm) vl_api_##n##_t_endian, \ vl_api_##n##_t_print, \ sizeof(vl_api_##n##_t), 1); - foreach_uri_msg; + foreach_tcp_echo_msg; #undef _ } @@ -1044,15 +1044,16 @@ int main (int argc, char **argv) { uri_udp_test_main_t *utm = &uri_udp_test_main; + u8 *bind_name = (u8 *) "udp://0.0.0.0/1234"; unformat_input_t _argv, *a = &_argv; + int i_am_master = 1; + session_t *session; u8 *chroot_prefix; + char *app_name; + mheap_t *h; u8 *heap; - u8 *bind_name = (u8 *) "udp://0.0.0.0/1234"; u32 tmp; - mheap_t *h; - session_t *session; int i; - int i_am_master = 1; clib_mem_init (0, 256 << 20); @@ -1065,7 +1066,6 @@ main (int argc, char **argv) vec_validate (utm->rx_buf, 8192); utm->session_index_by_vpp_handles = hash_create (0, sizeof (uword)); - utm->my_pid = getpid (); utm->configured_segment_size = 1 << 20; @@ -1101,14 +1101,13 @@ main (int argc, char **argv) utm->uri = format (0, "%s%c", bind_name, 0); utm->i_am_master = i_am_master; utm->segment_main = &svm_fifo_segment_main; - utm->connect_uri = format (0, "udp://6.0.1.2/1234%c", 0); setup_signal_handlers (); + tcp_echo_api_hookup (utm); - uri_api_hookup (utm); - - if (connect_to_vpp (i_am_master ? "uri_udp_master" : "uri_udp_slave") < 0) + app_name = i_am_master ? "udp_echo_master" : "udp_echo_slave"; + if (connect_to_vpp (app_name) < 0) { svm_region_exit (); fformat (stderr, "Couldn't connect to vpe, exiting...\n"); diff --git a/src/vcl/vppcom.c b/src/vcl/vppcom.c index 3ba94be4895..29e5a108d0e 100644 --- a/src/vcl/vppcom.c +++ b/src/vcl/vppcom.c @@ -1633,7 +1633,6 @@ vppcom_session_disconnect (u32 session_index) { if (is_server) { - svm_fifo_segment_main_t *sm = &svm_fifo_segment_main; svm_fifo_segment_private_t *seg; VCL_LOCK_AND_GET_SESSION (session_index, &session); @@ -1649,7 +1648,7 @@ vppcom_session_disconnect (u32 session_index) session->server_tx_fifo, session->server_tx_fifo->refcnt); - seg = vec_elt_at_index (sm->segments, session->sm_seg_index); + seg = svm_fifo_segment_get_segment (session->sm_seg_index); svm_fifo_segment_free_fifo (seg, session->server_rx_fifo, FIFO_SEGMENT_RX_FREELIST); svm_fifo_segment_free_fifo (seg, session->server_tx_fifo, diff --git a/src/vlibapi/api_common.h b/src/vlibapi/api_common.h index 055164812de..3d55e2acdd6 100644 --- a/src/vlibapi/api_common.h +++ b/src/vlibapi/api_common.h @@ -72,6 +72,7 @@ typedef struct vl_api_registration_ u32 server_index; /**< Socket client only: server index */ } vl_api_registration_t; +#define VL_API_INVALID_FI ((u32)~0) /** Trace configuration for a single message */ typedef struct diff --git a/src/vlibmemory/api.h b/src/vlibmemory/api.h index e86b88cdf9e..8d2b191fb81 100644 --- a/src/vlibmemory/api.h +++ b/src/vlibmemory/api.h @@ -61,6 +61,44 @@ vl_api_client_index_to_registration (u32 index) return (vl_mem_api_client_index_to_registration (index)); } +always_inline u32 +vl_api_registration_file_index (vl_api_registration_t * reg) +{ + return reg->clib_file_index; +} + +always_inline clib_file_t * +vl_api_registration_file (vl_api_registration_t * reg) +{ + return clib_file_get (&file_main, vl_api_registration_file_index (reg)); +} + +always_inline void +vl_api_registration_del_file (vl_api_registration_t * reg) +{ + clib_file_t *cf = vl_api_registration_file (reg); + if (cf) + clib_file_del (&file_main, cf); +} + +always_inline clib_error_t * +vl_api_send_fd_msg (vl_api_registration_t * reg, int fd_to_send) +{ + clib_file_t *cf = vl_api_registration_file (reg); + if (cf) + return vl_sock_api_send_fd_msg (cf->file_descriptor, fd_to_send); + return 0; +} + +always_inline clib_error_t * +vl_api_recv_fd_msg (vl_api_registration_t * reg, int *fd_to_recv, u32 wait) +{ + clib_file_t *cf = vl_api_registration_file (reg); + if (cf) + return vl_sock_api_recv_fd_msg (cf->file_descriptor, fd_to_recv, wait); + return 0; +} + /* * vl_api_clnt process data used by transports (socket api in particular) */ diff --git a/src/vlibmemory/memory_api.c b/src/vlibmemory/memory_api.c index 752f50717b0..0ee1384f22b 100644 --- a/src/vlibmemory/memory_api.c +++ b/src/vlibmemory/memory_api.c @@ -198,6 +198,7 @@ vl_api_memclnt_create_t_handler (vl_api_memclnt_create_t * mp) regp->vl_api_registration_pool_index = regpp - am->vl_clients; regp->vlib_rp = svm; regp->shmem_hdr = am->shmem_hdr; + regp->clib_file_index = am->shmem_hdr->clib_file_index; q = regp->vl_input_queue = (svm_queue_t *) (uword) mp->input_queue; @@ -273,7 +274,7 @@ vl_api_memclnt_delete_t_handler (vl_api_memclnt_delete_t * mp) return; } - regpp = am->vl_clients + client_index; + regpp = pool_elt_at_index (am->vl_clients, client_index); if (!pool_is_free (am->vl_clients, regpp)) { @@ -509,11 +510,54 @@ send_memclnt_keepalive (vl_api_registration_t * regp, f64 now) am->shmem_hdr = save_shmem_hdr; } +static void +vl_mem_send_client_keepalive_w_reg (api_main_t * am, f64 now, + vl_api_registration_t ** regpp, + u32 ** dead_indices, + u32 ** confused_indices) +{ + vl_api_registration_t *regp = *regpp; + if (regp) + { + /* If we haven't heard from this client recently... */ + if (regp->last_heard < (now - 10.0)) + { + if (regp->unanswered_pings == 2) + { + svm_queue_t *q; + q = regp->vl_input_queue; + if (kill (q->consumer_pid, 0) >= 0) + { + clib_warning ("REAPER: lazy binary API client '%s'", + regp->name); + regp->unanswered_pings = 0; + regp->last_heard = now; + } + else + { + clib_warning ("REAPER: binary API client '%s' died", + regp->name); + vec_add1 (*dead_indices, regpp - am->vl_clients); + } + } + else + send_memclnt_keepalive (regp, now); + } + else + regp->unanswered_pings = 0; + } + else + { + clib_warning ("NULL client registration index %d", + regpp - am->vl_clients); + vec_add1 (*confused_indices, regpp - am->vl_clients); + } +} + void vl_mem_api_dead_client_scan (api_main_t * am, vl_shmem_hdr_t * shm, f64 now) { vl_api_registration_t **regpp; - vl_api_registration_t *regp; static u32 *dead_indices; static u32 *confused_indices; @@ -521,46 +565,12 @@ vl_mem_api_dead_client_scan (api_main_t * am, vl_shmem_hdr_t * shm, f64 now) vec_reset_length (confused_indices); /* *INDENT-OFF* */ - pool_foreach (regpp, am->vl_clients, - ({ - regp = *regpp; - if (regp) - { - /* If we haven't heard from this client recently... */ - if (regp->last_heard < (now - 10.0)) - { - if (regp->unanswered_pings == 2) - { - svm_queue_t *q; - q = regp->vl_input_queue; - if (kill (q->consumer_pid, 0) >=0) - { - clib_warning ("REAPER: lazy binary API client '%s'", - regp->name); - regp->unanswered_pings = 0; - regp->last_heard = now; - } - else - { - clib_warning ("REAPER: binary API client '%s' died", - regp->name); - vec_add1(dead_indices, regpp - am->vl_clients); - } - } - else - send_memclnt_keepalive (regp, now); - } - else - regp->unanswered_pings = 0; - } - else - { - clib_warning ("NULL client registration index %d", - regpp - am->vl_clients); - vec_add1 (confused_indices, regpp - am->vl_clients); - } + pool_foreach (regpp, am->vl_clients, ({ + vl_mem_send_client_keepalive_w_reg (am, now, regpp, &dead_indices, + &confused_indices); })); /* *INDENT-ON* */ + /* This should "never happen," but if it does, fix it... */ if (PREDICT_FALSE (vec_len (confused_indices) > 0)) { @@ -702,24 +712,26 @@ vl_mem_api_client_index_to_registration (u32 handle) vl_api_registration_t **regpp; vl_api_registration_t *regp; api_main_t *am = &api_main; + vl_shmem_hdr_t *shmem_hdr; u32 index; index = vl_msg_api_handle_get_index (handle); - if ((am->shmem_hdr->application_restarts & VL_API_EPOCH_MASK) - != vl_msg_api_handle_get_epoch (handle)) + regpp = am->vl_clients + index; + + if (pool_is_free (am->vl_clients, regpp)) { vl_msg_api_increment_missing_client_counter (); return 0; } + regp = *regpp; - regpp = am->vl_clients + index; - - if (pool_is_free (am->vl_clients, regpp)) + shmem_hdr = (vl_shmem_hdr_t *) regp->shmem_hdr; + if (!vl_msg_api_handle_is_valid (handle, shmem_hdr->application_restarts)) { vl_msg_api_increment_missing_client_counter (); return 0; } - regp = *regpp; + return (regp); } diff --git a/src/vlibmemory/memory_api.h b/src/vlibmemory/memory_api.h index 58f47d1313a..4cda04b3d9f 100644 --- a/src/vlibmemory/memory_api.h +++ b/src/vlibmemory/memory_api.h @@ -58,6 +58,13 @@ vl_msg_api_handle_from_index_and_epoch (u32 index, u32 epoch) return handle; } +static inline u8 +vl_msg_api_handle_is_valid (u32 handle, u32 restarts) +{ + u32 epoch = vl_msg_api_handle_get_epoch (handle); + return ((restarts & VL_API_EPOCH_MASK) == epoch); +} + #define VL_MEM_API_LOG_Q_LEN(fmt,qlen) \ if (TRACE_VLIB_MEMORY_QUEUE) \ do { \ diff --git a/src/vlibmemory/memory_client.c b/src/vlibmemory/memory_client.c index deb913b63e3..9f533019c87 100644 --- a/src/vlibmemory/memory_client.c +++ b/src/vlibmemory/memory_client.c @@ -190,8 +190,8 @@ vl_client_connect (const char *name, int ctx_quota, int input_queue_size) pthread_mutex_lock (&svm->mutex); oldheap = svm_push_data_heap (svm); - vl_input_queue = - svm_queue_init (input_queue_size, sizeof (uword), getpid (), 0); + vl_input_queue = svm_queue_init (input_queue_size, sizeof (uword), + getpid (), 0); pthread_mutex_unlock (&svm->mutex); svm_pop_heap (oldheap); @@ -289,7 +289,6 @@ vl_client_disconnect (void) * Have to be careful here, in case the client is disconnecting * because e.g. the vlib process died, or is unresponsive. */ - begin = time (0); while (1) { @@ -362,7 +361,6 @@ vl_client_install_client_message_handlers (void) #undef _ } - int vl_client_api_map (const char *region_name) { @@ -381,6 +379,12 @@ vl_client_api_unmap (void) vl_unmap_shmem (); } +u8 +vl_mem_client_is_connected (void) +{ + return (memory_client_main.connected_to_vlib != 0); +} + static int connect_to_vlib_internal (const char *svm_name, const char *client_name, @@ -444,8 +448,8 @@ vl_client_connect_to_vlib_no_map (const char *svm_name, 0 /* dont map */ ); } -void -vl_client_disconnect_from_vlib (void) +static void +disconnect_from_vlib_internal (u8 do_unmap) { memory_client_main_t *mm = &memory_client_main; api_main_t *am = &api_main; @@ -462,11 +466,24 @@ vl_client_disconnect_from_vlib (void) if (mm->connected_to_vlib) { vl_client_disconnect (); - vl_client_api_unmap (); + if (do_unmap) + vl_client_api_unmap (); } memset (mm, 0, sizeof (*mm)); } +void +vl_client_disconnect_from_vlib (void) +{ + disconnect_from_vlib_internal (1); +} + +void +vl_client_disconnect_from_vlib_no_unmap (void) +{ + disconnect_from_vlib_internal (0); +} + static void vl_api_get_first_msg_id_reply_t_handler (vl_api_get_first_msg_id_reply_t * mp) { diff --git a/src/vlibmemory/memory_client.h b/src/vlibmemory/memory_client.h index 5b4f090af9a..3fcca9e4b89 100644 --- a/src/vlibmemory/memory_client.h +++ b/src/vlibmemory/memory_client.h @@ -25,6 +25,7 @@ void vl_client_disconnect (void); int vl_client_api_map (const char *region_name); void vl_client_api_unmap (void); void vl_client_disconnect_from_vlib (void); +void vl_client_disconnect_from_vlib_no_unmap (void); int vl_client_connect_to_vlib (const char *svm_name, const char *client_name, int rx_queue_size); int vl_client_connect_to_vlib_no_rx_pthread (const char *svm_name, @@ -34,6 +35,7 @@ int vl_client_connect_to_vlib_no_map (const char *svm_name, const char *client_name, int rx_queue_size); void vl_client_install_client_message_handlers (void); +u8 vl_mem_client_is_connected (void); #endif /* SRC_VLIBMEMORY_MEMORY_CLIENT_H_ */ diff --git a/src/vlibmemory/memory_shared.c b/src/vlibmemory/memory_shared.c index 5b7d735dab9..488a302bbba 100644 --- a/src/vlibmemory/memory_shared.c +++ b/src/vlibmemory/memory_shared.c @@ -230,6 +230,25 @@ vl_msg_api_alloc_as_if_client_or_null (int nbytes) return vl_msg_api_alloc_internal (nbytes, 0, 1 /* may_return_null */ ); } +void * +vl_mem_api_alloc_as_if_client_w_reg (vl_api_registration_t * reg, int nbytes) +{ + api_main_t *am = &api_main; + vl_shmem_hdr_t *save_shmem_hdr = am->shmem_hdr; + svm_region_t *vlib_rp, *save_vlib_rp = am->vlib_rp; + void *msg; + + vlib_rp = am->vlib_rp = reg->vlib_rp; + am->shmem_hdr = (void *) vlib_rp->user_ctx; + + msg = vl_msg_api_alloc_internal (nbytes, 0, 0 /* may_return_null */ ); + + am->shmem_hdr = save_shmem_hdr; + am->vlib_rp = save_vlib_rp; + + return msg; +} + void vl_msg_api_free (void *a) { @@ -464,6 +483,7 @@ vl_init_shmem (svm_region_t * vlib_rp, vl_api_shm_elem_config_t * config, vec_validate (shmem_hdr, 0); shmem_hdr->version = VL_SHM_VERSION; + shmem_hdr->clib_file_index = VL_API_INVALID_FI; /* Set up the queue and msg ring allocator */ vl_api_mem_config (shmem_hdr, config); diff --git a/src/vlibmemory/memory_shared.h b/src/vlibmemory/memory_shared.h index 8a7667c14d3..deaa62166ae 100644 --- a/src/vlibmemory/memory_shared.h +++ b/src/vlibmemory/memory_shared.h @@ -99,6 +99,9 @@ typedef struct vl_shmem_hdr_ /* Number of garbage-collected messages */ u32 garbage_collects; + + /* Socket file index used to bootstrap shmem region */ + u32 clib_file_index; } vl_shmem_hdr_t; #define VL_SHM_VERSION 2 @@ -109,6 +112,8 @@ void *vl_msg_api_alloc (int nbytes); void *vl_msg_api_alloc_or_null (int nbytes); void *vl_msg_api_alloc_as_if_client (int nbytes); void *vl_msg_api_alloc_as_if_client_or_null (int nbytes); +void *vl_mem_api_alloc_as_if_client_w_reg (vl_api_registration_t * reg, + int nbytes); void vl_msg_api_free (void *a); int vl_map_shmem (const char *region_name, int is_vlib); void vl_unmap_shmem (void); diff --git a/src/vlibmemory/socket_api.c b/src/vlibmemory/socket_api.c index 9c099b9b0b7..8527f1be919 100644 --- a/src/vlibmemory/socket_api.c +++ b/src/vlibmemory/socket_api.c @@ -52,7 +52,6 @@ vl_sock_api_dump_clients (vlib_main_t * vm, api_main_t * am) { vl_api_registration_t *reg; socket_main_t *sm = &socket_main; - clib_file_main_t *fm = &file_main; clib_file_t *f; /* @@ -68,9 +67,8 @@ vl_sock_api_dump_clients (vlib_main_t * vm, api_main_t * am) pool_foreach (reg, sm->registration_pool, ({ if (reg->registration_type == REGISTRATION_TYPE_SOCKET_SERVER) { - f = pool_elt_at_index (fm->file_pool, reg->clib_file_index); - vlib_cli_output (vm, "%20s %8d", - reg->name, f->file_descriptor); + f = vl_api_registration_file (reg); + vlib_cli_output (vm, "%20s %8d", reg->name, f->file_descriptor); } })); /* *INDENT-ON* */ @@ -86,9 +84,10 @@ vl_socket_api_send (vl_api_registration_t * rp, u8 * elem) u16 msg_id = ntohs (*(u16 *) elem); api_main_t *am = &api_main; msgbuf_t *mb = (msgbuf_t *) (elem - offsetof (msgbuf_t, data)); - clib_file_t *cf = clib_file_get (&file_main, rp->clib_file_index); vl_api_registration_t *sock_rp; + clib_file_t *cf; + cf = vl_api_registration_file (rp); ASSERT (rp->registration_type > REGISTRATION_TYPE_SHMEM); if (msg_id >= vec_len (am->api_trace_cfg)) @@ -380,7 +379,6 @@ socksvr_accept_ready (clib_file_t * uf) clib_error_t *error; error = clib_socket_accept (sock, &client); - if (error) return error; @@ -441,8 +439,7 @@ vl_api_sockclnt_delete_t_handler (vl_api_sockclnt_delete_t * mp) vl_api_send_msg (regp, (u8 *) rp); - clib_file_del (&file_main, file_main.file_pool + regp->clib_file_index); - + vl_api_registration_del_file (regp); vl_socket_free_registration_index (mp->index); } else @@ -451,8 +448,8 @@ vl_api_sockclnt_delete_t_handler (vl_api_sockclnt_delete_t * mp) } } -static clib_error_t * -send_fd_msg (int socket_fd, int fd_to_share) +clib_error_t * +vl_sock_api_send_fd_msg (int socket_fd, int fd_to_share) { struct msghdr mh = { 0 }; struct iovec iov[1]; @@ -535,6 +532,7 @@ vl_api_sock_init_shm_t_handler (vl_api_sock_init_shm_t * mp) svm_region_t *vlib_rp; clib_file_t *cf; vl_api_shm_elem_config_t *config = 0; + vl_shmem_hdr_t *shmem_hdr; int rv; regp = vl_api_client_index_to_registration (mp->client_index); @@ -559,7 +557,7 @@ vl_api_sock_init_shm_t_handler (vl_api_sock_init_shm_t * mp) memfd->i_am_master = 1; memfd->name = format (0, "%s%c", regp->name, 0); - if ((rv = ssvm_master_init_memfd (memfd, mp->client_index))) + if ((rv = ssvm_master_init_memfd (memfd))) goto reply; /* Remember to close this fd when the socket connection goes away */ @@ -584,6 +582,11 @@ vl_api_sock_init_shm_t_handler (vl_api_sock_init_shm_t * mp) vlib_rp = (svm_region_t *) a->baseva; vl_init_shmem (vlib_rp, config, 1 /* is_vlib (dont-care) */ , 1 /* is_private */ ); + + /* Remember who created this. Needs to be post vl_init_shmem */ + shmem_hdr = (vl_shmem_hdr_t *) vlib_rp->user_ctx; + shmem_hdr->clib_file_index = vl_api_registration_file_index (regp); + vec_add1 (am->vlib_private_rps, vlib_rp); memfd->sh->ready = 1; vec_free (config); @@ -607,11 +610,11 @@ reply: * We need the reply message to make it out the back door * before we send the magic fd message so force a flush */ - cf = clib_file_get (&file_main, regp->clib_file_index); + cf = vl_api_registration_file (regp); cf->write_function (cf); /* Send the magic "here's your sign (aka fd)" socket message */ - send_fd_msg (cf->file_descriptor, memfd->fd); + vl_sock_api_send_fd_msg (cf->file_descriptor, memfd->fd); } /* @@ -640,7 +643,7 @@ vl_api_memfd_segment_create_t_handler (vl_api_memfd_segment_create_t * mp) memfd->name = format (0, "%s%c", regp->name, 0); /* Set up a memfd segment of the requested size */ - if ((rv = ssvm_master_init_memfd (memfd, mp->client_index))) + if ((rv = ssvm_master_init_memfd (memfd))) goto reply; /* Remember to close this fd when the socket connection goes away */ @@ -662,11 +665,11 @@ reply: * We need the reply message to make it out the back door * before we send the magic fd message. */ - cf = file_main.file_pool + regp->clib_file_index; + cf = vl_api_registration_file (regp); cf->write_function (cf); /* send the magic "here's your sign (aka fd)" socket message */ - send_fd_msg (cf->file_descriptor, memfd->fd); + vl_sock_api_send_fd_msg (cf->file_descriptor, memfd->fd); } #define foreach_vlib_api_msg \ @@ -741,7 +744,6 @@ vl_sock_api_init (vlib_main_t * vm) static clib_error_t * socket_exit (vlib_main_t * vm) { - clib_file_main_t *fm = &file_main; socket_main_t *sm = &socket_main; vl_api_registration_t *rp; @@ -751,9 +753,9 @@ socket_exit (vlib_main_t * vm) u32 index; /* *INDENT-OFF* */ pool_foreach (rp, sm->registration_pool, ({ - clib_file_del (fm, fm->file_pool + rp->clib_file_index); - index = rp->vl_api_registration_pool_index; - vl_socket_free_registration_index (index); + vl_api_registration_del_file (rp); + index = rp->vl_api_registration_pool_index; + vl_socket_free_registration_index (index); })); /* *INDENT-ON* */ } diff --git a/src/vlibmemory/socket_api.h b/src/vlibmemory/socket_api.h index 5cb3c058d5f..d12b427a6a4 100644 --- a/src/vlibmemory/socket_api.h +++ b/src/vlibmemory/socket_api.h @@ -77,6 +77,9 @@ void vl_socket_process_api_msg (clib_file_t * uf, vl_api_registration_t * rp, i8 * input_v); void vl_sock_api_dump_clients (vlib_main_t * vm, api_main_t * am); clib_error_t *vl_sock_api_init (vlib_main_t * vm); +clib_error_t *vl_sock_api_send_fd_msg (int socket_fd, int fd_to_share); +clib_error_t *vl_sock_api_recv_fd_msg (int socket_fd, int *fd_to_share, + u32 wait); #endif /* SRC_VLIBMEMORY_SOCKET_API_H_ */ diff --git a/src/vlibmemory/socket_client.c b/src/vlibmemory/socket_client.c index 44d21228bfe..a49d335e732 100644 --- a/src/vlibmemory/socket_client.c +++ b/src/vlibmemory/socket_client.c @@ -158,6 +158,12 @@ void vl_socket_client_disconnect (void) { socket_client_main_t *scm = &socket_client_main; + + if (vl_mem_client_is_connected ()) + { + vl_client_disconnect_from_vlib_no_unmap (); + ssvm_delete_memfd (&scm->memfd_segment); + } if (scm->socket_fd && (close (scm->socket_fd) < 0)) clib_unix_warning ("close"); scm->socket_fd = 0; @@ -170,19 +176,21 @@ vl_socket_client_enable_disable (int enable) scm->socket_enable = enable; } -static clib_error_t * -receive_fd_msg (int socket_fd, int *my_fd) +clib_error_t * +vl_sock_api_recv_fd_msg (int socket_fd, int *my_fd, u32 wait) { + socket_client_main_t *scm = &socket_client_main; char msgbuf[16]; char ctl[CMSG_SPACE (sizeof (int)) + CMSG_SPACE (sizeof (struct ucred))]; struct msghdr mh = { 0 }; struct iovec iov[1]; - ssize_t size; + ssize_t size = 0; struct ucred *cr = 0; struct cmsghdr *cmsg; pid_t pid __attribute__ ((unused)); uid_t uid __attribute__ ((unused)); gid_t gid __attribute__ ((unused)); + f64 timeout; iov[0].iov_base = msgbuf; iov[0].iov_len = 5; @@ -193,8 +201,15 @@ receive_fd_msg (int socket_fd, int *my_fd) memset (ctl, 0, sizeof (ctl)); - /* receive the incoming message */ - size = recvmsg (socket_fd, &mh, 0); + if (wait != ~0) + { + timeout = clib_time_now (&scm->clib_time) + wait; + while (size != 5 && clib_time_now (&scm->clib_time) < timeout) + size = recvmsg (socket_fd, &mh, MSG_DONTWAIT); + } + else + size = recvmsg (socket_fd, &mh, 0); + if (size != 5) { return (size == 0) ? clib_error_return (0, "disconnected") : @@ -228,11 +243,11 @@ static void vl_api_sock_init_shm_reply_t_handler (vl_api_sock_init_shm_reply_t * mp) { socket_client_main_t *scm = &socket_client_main; - int my_fd = -1; - clib_error_t *error; + ssvm_private_t *memfd = &scm->memfd_segment; i32 retval = ntohl (mp->retval); - ssvm_private_t memfd; api_main_t *am = &api_main; + clib_error_t *error; + int my_fd = -1; u8 *new_name; if (retval) @@ -244,25 +259,26 @@ static void vl_api_sock_init_shm_reply_t_handler /* * Check the socket for the magic fd */ - error = receive_fd_msg (scm->socket_fd, &my_fd); + error = vl_sock_api_recv_fd_msg (scm->socket_fd, &my_fd, 5); if (error) { + clib_error_report (error); retval = -99; return; } - memset (&memfd, 0, sizeof (memfd)); - memfd.fd = my_fd; + memset (memfd, 0, sizeof (*memfd)); + memfd->fd = my_fd; /* Note: this closes memfd.fd */ - retval = ssvm_slave_init_memfd (&memfd); + retval = ssvm_slave_init_memfd (memfd); if (retval) clib_warning ("WARNING: segment map returned %d", retval); /* * Pivot to the memory client segment that vpp just created */ - am->vlib_rp = (void *) (memfd.requested_va + MMAP_PAGESIZE); + am->vlib_rp = (void *) (memfd->requested_va + MMAP_PAGESIZE); am->shmem_hdr = (void *) am->vlib_rp->user_ctx; new_name = format (0, "%v[shm]%c", scm->name, 0); @@ -392,6 +408,15 @@ vl_socket_client_init_shm (vl_api_shm_elem_config_t * config) return 0; } +clib_error_t * +vl_socket_client_recv_fd_msg (int *fd_to_recv, u32 wait) +{ + socket_client_main_t *scm = &socket_client_main; + if (!scm->socket_fd) + return clib_error_return (0, "no socket"); + return vl_sock_api_recv_fd_msg (scm->client_socket.fd, fd_to_recv, wait); +} + /* * fd.io coding-style-patch-verification: ON * diff --git a/src/vlibmemory/socket_client.h b/src/vlibmemory/socket_client.h index 10191db6410..74be5a96f53 100644 --- a/src/vlibmemory/socket_client.h +++ b/src/vlibmemory/socket_client.h @@ -38,6 +38,7 @@ typedef struct u8 *name; clib_time_t clib_time; + ssvm_private_t memfd_segment; } socket_client_main_t; extern socket_client_main_t socket_client_main; @@ -52,6 +53,7 @@ int vl_socket_client_write (void); void vl_socket_client_enable_disable (int enable); void *vl_socket_client_msg_alloc (int nbytes); int vl_socket_client_init_shm (vl_api_shm_elem_config_t * config); +clib_error_t *vl_socket_client_recv_fd_msg (int *fd_to_recv, u32 wait); #endif /* SRC_VLIBMEMORY_SOCKET_CLIENT_H_ */ diff --git a/src/vnet/api_errno.h b/src/vnet/api_errno.h index 11e5d4f03f1..be2100a5c29 100644 --- a/src/vnet/api_errno.h +++ b/src/vnet/api_errno.h @@ -97,7 +97,7 @@ _(BFD_NOTSUPP, -104, "BFD feature not supported") \ _(ADDRESS_IN_USE, -105, "Address in use") \ _(ADDRESS_NOT_IN_USE, -106, "Address not in use") \ _(QUEUE_FULL, -107, "Queue full") \ -_(UNKNOWN_URI_TYPE, -108, "Unknown URI type") \ +_(APP_UNSUPPORTED_CFG, -108, "Unsupported application config") \ _(URI_FIFO_CREATE_FAILED, -109, "URI FIFO segment create failed") \ _(LISP_RLOC_LOCAL, -110, "RLOC address is local") \ _(BFD_EAGAIN, -111, "BFD object cannot be manipulated at this time") \ diff --git a/src/vnet/sctp/builtin_client.c b/src/vnet/sctp/builtin_client.c index 4e50c0ae2ea..12f053297c2 100644 --- a/src/vnet/sctp/builtin_client.c +++ b/src/vnet/sctp/builtin_client.c @@ -438,21 +438,16 @@ static clib_error_t * attach_builtin_test_clients_app (u8 * appns_id, u64 appns_flags, u64 appns_secret) { - u32 segment_name_length, prealloc_fifos, segment_size = 2 << 20; + u32 prealloc_fifos, segment_size = 2 << 20; tclient_main_t *tm = &tclient_main; vnet_app_attach_args_t _a, *a = &_a; - u8 segment_name[128]; u64 options[16]; clib_error_t *error = 0; - segment_name_length = ARRAY_LEN (segment_name); - memset (a, 0, sizeof (*a)); memset (options, 0, sizeof (options)); a->api_client_index = tm->my_client_index; - a->segment_name = segment_name; - a->segment_name_length = segment_name_length; a->session_cb_vft = &builtin_clients; prealloc_fifos = tm->prealloc_fifos ? tm->expected_connections : 1; diff --git a/src/vnet/sctp/builtin_server.c b/src/vnet/sctp/builtin_server.c index 81267e78434..e67c4abad9b 100644 --- a/src/vnet/sctp/builtin_server.c +++ b/src/vnet/sctp/builtin_server.c @@ -95,7 +95,7 @@ builtin_sctp_session_connected_callback (u32 app_index, u32 api_context, int builtin_sctp_add_segment_callback (u32 client_index, - const u8 * seg_name, u32 seg_size) + const ssvm_private_t * fs) { clib_warning ("called..."); return -1; @@ -270,7 +270,6 @@ static int server_attach (u8 * appns_id, u64 appns_flags, u64 appns_secret) { builtin_server_main_t *bsm = &builtin_server_main; - u8 segment_name[128]; u64 options[APP_OPTIONS_N_OPTIONS]; vnet_app_attach_args_t _a, *a = &_a; u32 segment_size = 512 << 20; @@ -305,8 +304,6 @@ server_attach (u8 * appns_id, u64 appns_flags, u64 appns_secret) a->options[APP_OPTIONS_FLAGS] |= appns_flags; a->options[APP_OPTIONS_NAMESPACE_SECRET] = appns_secret; } - a->segment_name = segment_name; - a->segment_name_length = ARRAY_LEN (segment_name); if (vnet_application_attach (a)) { diff --git a/src/vnet/session/application.c b/src/vnet/session/application.c index 8090e75a6dc..13ccdd7cbc8 100644 --- a/src/vnet/session/application.c +++ b/src/vnet/session/application.c @@ -227,18 +227,56 @@ application_verify_cb_fns (session_cb_vft_t * cb_fns) clib_warning ("No session reset callback function provided"); } +/** + * Check app config for given segment type + * + * Returns 1 on success and 0 otherwise + */ +static u8 +application_verify_cfg (ssvm_segment_type_t st) +{ + u8 is_valid; + if (st == SSVM_SEGMENT_MEMFD) + { + is_valid = (session_manager_get_evt_q_segment () != 0); + if (!is_valid) + clib_warning ("memfd seg: vpp's event qs IN binary api svm region"); + return is_valid; + } + else if (st == SSVM_SEGMENT_SHM) + { + is_valid = (session_manager_get_evt_q_segment () == 0); + if (!is_valid) + clib_warning ("shm seg: vpp's event qs NOT IN binary api svm region"); + return is_valid; + } + else + return 1; +} + int application_init (application_t * app, u32 api_client_index, u64 * options, session_cb_vft_t * cb_fns) { - segment_manager_t *sm; - segment_manager_properties_t *props; + ssvm_segment_type_t st = SSVM_SEGMENT_MEMFD; u32 app_evt_queue_size, first_seg_size; - u32 default_rx_fifo_size = 16 << 10, default_tx_fifo_size = 16 << 10; + segment_manager_properties_t *props; + vl_api_registration_t *reg; + segment_manager_t *sm; int rv; - app_evt_queue_size = options[APP_OPTIONS_EVT_QUEUE_SIZE] > 0 ? - options[APP_OPTIONS_EVT_QUEUE_SIZE] : default_app_evt_queue_size; + /* + * Make sure we support the requested configuration + */ + reg = vl_api_client_index_to_registration (api_client_index); + if (!reg) + return VNET_API_ERROR_APP_UNSUPPORTED_CFG; + + if (vl_api_registration_file_index (reg) == ~0) + st = SSVM_SEGMENT_SHM; + + if (!application_verify_cfg (st)) + return VNET_API_ERROR_APP_UNSUPPORTED_CFG; /* * Setup segment manager @@ -247,21 +285,27 @@ application_init (application_t * app, u32 api_client_index, u64 * options, sm->app_index = app->index; props = segment_manager_properties_alloc (); app->sm_properties = segment_manager_properties_index (props); - props->add_segment_size = options[APP_OPTIONS_ADD_SEGMENT_SIZE]; - props->rx_fifo_size = options[APP_OPTIONS_RX_FIFO_SIZE]; - props->rx_fifo_size = - props->rx_fifo_size ? props->rx_fifo_size : default_rx_fifo_size; - props->tx_fifo_size = options[APP_OPTIONS_TX_FIFO_SIZE]; - props->tx_fifo_size = - props->tx_fifo_size ? props->tx_fifo_size : default_tx_fifo_size; - props->add_segment = props->add_segment_size != 0; + if (options[APP_OPTIONS_ADD_SEGMENT_SIZE]) + { + props->add_segment_size = options[APP_OPTIONS_ADD_SEGMENT_SIZE]; + props->add_segment = 1; + } + if (options[APP_OPTIONS_RX_FIFO_SIZE]) + props->rx_fifo_size = options[APP_OPTIONS_RX_FIFO_SIZE]; + if (options[APP_OPTIONS_TX_FIFO_SIZE]) + props->tx_fifo_size = options[APP_OPTIONS_TX_FIFO_SIZE]; props->preallocated_fifo_pairs = options[APP_OPTIONS_PREALLOC_FIFO_PAIRS]; - props->use_private_segment = options[APP_OPTIONS_FLAGS] - & APP_OPTIONS_FLAGS_IS_BUILTIN; props->private_segment_count = options[APP_OPTIONS_PRIVATE_SEGMENT_COUNT]; + if (options[APP_OPTIONS_FLAGS] & APP_OPTIONS_FLAGS_IS_BUILTIN) + props->segment_type = SSVM_N_SEGMENT_TYPES; + else + props->segment_type = st; + app_evt_queue_size = options[APP_OPTIONS_EVT_QUEUE_SIZE] > 0 ? + options[APP_OPTIONS_EVT_QUEUE_SIZE] : default_app_evt_queue_size; first_seg_size = options[APP_OPTIONS_SEGMENT_SIZE]; - if ((rv = segment_manager_init (sm, app->sm_properties, first_seg_size))) + if ((rv = segment_manager_init (sm, app->sm_properties, first_seg_size, + app_evt_queue_size))) return rv; sm->first_is_protected = 1; @@ -478,15 +522,13 @@ int application_add_segment_notify (u32 app_index, u32 fifo_segment_index) { application_t *app = application_get (app_index); - u32 seg_size = 0; - u8 *seg_name; + svm_fifo_segment_private_t *fs; /* Send an API message to the external app, to map new segment */ ASSERT (app->cb_fns.add_segment_callback); - segment_manager_get_segment_info (fifo_segment_index, &seg_name, &seg_size); - return app->cb_fns.add_segment_callback (app->api_client_index, seg_name, - seg_size); + fs = segment_manager_get_segment (fifo_segment_index); + return app->cb_fns.add_segment_callback (app->api_client_index, &fs->ssvm); } u8 diff --git a/src/vnet/session/application.h b/src/vnet/session/application.h index fd6454f21af..afe738f199c 100644 --- a/src/vnet/session/application.h +++ b/src/vnet/session/application.h @@ -30,8 +30,8 @@ typedef enum typedef struct _stream_session_cb_vft { /** Notify server of new segment */ - int (*add_segment_callback) (u32 api_client_index, const u8 * seg_name, - u32 seg_size); + int (*add_segment_callback) (u32 api_client_index, + const ssvm_private_t * ssvm_seg); /** Notify server of newly accepted session */ int (*session_accept_callback) (stream_session_t * new_session); diff --git a/src/vnet/session/application_interface.c b/src/vnet/session/application_interface.c index ec317896f14..f2a13be6144 100644 --- a/src/vnet/session/application_interface.c +++ b/src/vnet/session/application_interface.c @@ -413,11 +413,11 @@ session_validate_namespace (u8 * namespace_id, u64 secret, u32 * app_ns_index) clib_error_t * vnet_application_attach (vnet_app_attach_args_t * a) { + svm_fifo_segment_private_t *fs; application_t *app = 0; segment_manager_t *sm; - u8 *seg_name; - u64 secret; u32 app_ns_index = 0; + u64 secret; int rv; app = application_lookup (a->api_client_index); @@ -437,16 +437,15 @@ vnet_application_attach (vnet_app_attach_args_t * a) a->app_event_queue_address = pointer_to_uword (app->event_queue); sm = segment_manager_get (app->first_segment_manager); - segment_manager_get_segment_info (sm->segment_indices[0], - &seg_name, &a->segment_size); + fs = segment_manager_get_segment (sm->segment_indices[0]); if (application_is_proxy (app)) application_setup_proxy (app); - a->segment_name_length = vec_len (seg_name); - a->segment_name = seg_name; - ASSERT (vec_len (a->segment_name) <= 128); + ASSERT (vec_len (fs->ssvm.name) <= 128); + a->segment = &fs->ssvm; a->app_index = app->index; + return 0; } diff --git a/src/vnet/session/application_interface.h b/src/vnet/session/application_interface.h index 68973a9f938..8db318fa413 100644 --- a/src/vnet/session/application_interface.h +++ b/src/vnet/session/application_interface.h @@ -39,9 +39,7 @@ typedef struct _vnet_app_attach_args_t /* * Results */ - u8 *segment_name; - u32 segment_name_length; - u32 segment_size; + ssvm_private_t *segment; u64 app_event_queue_address; u32 app_index; } vnet_app_attach_args_t; diff --git a/src/vnet/session/segment_manager.c b/src/vnet/session/segment_manager.c index dc3e4c9e648..c3a794b7fc4 100644 --- a/src/vnet/session/segment_manager.c +++ b/src/vnet/session/segment_manager.c @@ -49,6 +49,9 @@ segment_manager_properties_alloc (void) segment_manager_properties_t *props; pool_get (segment_manager_properties_pool, props); memset (props, 0, sizeof (*props)); + props->add_segment_size = default_segment_size; + props->rx_fifo_size = default_fifo_size; + props->tx_fifo_size = default_fifo_size; return props; } @@ -73,53 +76,64 @@ segment_manager_properties_index (segment_manager_properties_t * p) return p - segment_manager_properties_pool; } +svm_fifo_segment_private_t * +segment_manager_get_segment (u32 segment_index) +{ + return svm_fifo_segment_get_segment (segment_index); +} + void segment_manager_get_segment_info (u32 index, u8 ** name, u32 * size) { svm_fifo_segment_private_t *s; s = svm_fifo_segment_get_segment (index); - *name = s->h->segment_name; + *name = s->ssvm.name; *size = s->ssvm.ssvm_size; } always_inline int -session_manager_add_segment_i (segment_manager_t * sm, u32 segment_size, - u8 * segment_name) +segment_manager_add_segment_i (segment_manager_t * sm, u32 segment_size, + u32 protected_space) { - svm_fifo_segment_create_args_t _ca, *ca = &_ca; + svm_fifo_segment_create_args_t _ca = { 0 }, *ca = &_ca; segment_manager_properties_t *props; - int rv; - memset (ca, 0, sizeof (*ca)); props = segment_manager_properties_get (sm->properties_index); - if (!props->use_private_segment) + + /* Not configured for addition of new segments and not first */ + if (!props->add_segment && !segment_size) { - ca->segment_name = (char *) segment_name; - ca->segment_size = segment_size; - ca->rx_fifo_size = props->rx_fifo_size; - ca->tx_fifo_size = props->tx_fifo_size; - ca->preallocated_fifo_pairs = props->preallocated_fifo_pairs; - - rv = svm_fifo_segment_create (ca); - if (rv) + clib_warning ("cannot allocate new segment"); + return VNET_API_ERROR_INVALID_VALUE; + } + + ca->segment_size = segment_size ? segment_size : props->add_segment_size; + ca->rx_fifo_size = props->rx_fifo_size; + ca->tx_fifo_size = props->tx_fifo_size; + ca->preallocated_fifo_pairs = props->preallocated_fifo_pairs; + ca->seg_protected_space = protected_space ? protected_space : 0; + + if (props->segment_type != SSVM_N_SEGMENT_TYPES) + { + ca->segment_name = (char *) format (0, "%d-%d%c", getpid (), + segment_name_counter++, 0); + ca->segment_type = props->segment_type; + if (svm_fifo_segment_create (ca)) { clib_warning ("svm_fifo_segment_create ('%s', %d) failed", ca->segment_name, ca->segment_size); return VNET_API_ERROR_SVM_SEGMENT_CREATE_FAIL; } + vec_free (ca->segment_name); } else { - u32 rx_fifo_size, tx_fifo_size, rx_rounded_data_size, - tx_rounded_data_size; + u32 rx_fifo_size, tx_fifo_size; + u32 rx_rounded_data_size, tx_rounded_data_size; u32 approx_segment_count; u64 approx_total_size; ca->segment_name = "process-private-segment"; - ca->segment_size = segment_size; - ca->rx_fifo_size = props->rx_fifo_size; - ca->tx_fifo_size = props->tx_fifo_size; - ca->preallocated_fifo_pairs = props->preallocated_fifo_pairs; ca->private_segment_count = props->private_segment_count; /* Calculate space requirements */ @@ -131,61 +145,44 @@ session_manager_add_segment_i (segment_manager_t * sm, u32 segment_size, approx_total_size = (u64) ca->preallocated_fifo_pairs * (rx_fifo_size + tx_fifo_size); - approx_segment_count = (approx_total_size + (ca->segment_size - 1)) - / (u64) ca->segment_size; + approx_segment_count = (approx_total_size + protected_space + + (ca->segment_size - + 1)) / (u64) ca->segment_size; /* The user asked us to figure it out... */ - if (ca->private_segment_count == 0) + if (ca->private_segment_count == 0 + || approx_segment_count < ca->private_segment_count) { ca->private_segment_count = approx_segment_count; } /* Follow directions, but issue a warning */ - else if (approx_segment_count != ca->private_segment_count) + else if (approx_segment_count < ca->private_segment_count) { clib_warning ("Honoring segment count %u, calculated count was %u", ca->private_segment_count, approx_segment_count); } + else if (approx_segment_count > ca->private_segment_count) + { + clib_warning ("Segment count too low %u, calculated %u.", + ca->private_segment_count, approx_segment_count); + return VNET_API_ERROR_INVALID_VALUE; + } if (svm_fifo_segment_create_process_private (ca)) clib_warning ("Failed to create process private segment"); ASSERT (vec_len (ca->new_segment_indices)); } + vec_append (sm->segment_indices, ca->new_segment_indices); vec_free (ca->new_segment_indices); return 0; } int -session_manager_add_segment (segment_manager_t * sm) +segment_manager_add_segment (segment_manager_t * sm) { - svm_fifo_segment_create_args_t _ca, *ca = &_ca; - segment_manager_properties_t *props; - u32 add_segment_size; - u8 *segment_name; - int rv; - - memset (ca, 0, sizeof (*ca)); - props = segment_manager_properties_get (sm->properties_index); - segment_name = format (0, "%d-%d%c", getpid (), segment_name_counter++, 0); - add_segment_size = props->add_segment_size ? - props->add_segment_size : default_segment_size; - - rv = session_manager_add_segment_i (sm, add_segment_size, segment_name); - vec_free (segment_name); - return rv; -} - -int -session_manager_add_first_segment (segment_manager_t * sm, u32 segment_size) -{ - u8 *segment_name; - int rv; - - segment_name = format (0, "%d-%d%c", getpid (), segment_name_counter++, 0); - rv = session_manager_add_segment_i (sm, segment_size, segment_name); - vec_free (segment_name); - return rv; + return segment_manager_add_segment_i (sm, 0, 0); } segment_manager_t * @@ -203,14 +200,18 @@ segment_manager_new () */ int segment_manager_init (segment_manager_t * sm, u32 props_index, - u32 first_seg_size) + u32 first_seg_size, u32 evt_q_size) { + u32 protected_space; int rv; - /* app allocates these */ sm->properties_index = props_index; + + protected_space = max_pow2 (sizeof (svm_queue_t) + + evt_q_size * sizeof (session_fifo_event_t)); + protected_space = round_pow2_u64 (protected_space, CLIB_CACHE_LINE_BYTES); first_seg_size = first_seg_size > 0 ? first_seg_size : default_segment_size; - rv = session_manager_add_first_segment (sm, first_seg_size); + rv = segment_manager_add_segment_i (sm, first_seg_size, protected_space); if (rv) { clib_warning ("Failed to allocate segment"); @@ -257,7 +258,7 @@ segment_manager_del_segment (segment_manager_t * sm, u32 segment_index) svm_fifo_segment_private_t *fifo_segment; u32 svm_segment_index; clib_spinlock_lock (&sm->lockp); - svm_segment_index = sm->segment_indices[segment_index]; + svm_segment_index = vec_elt (sm->segment_indices, segment_index); fifo_segment = svm_fifo_segment_get_segment (svm_segment_index); if (!fifo_segment || ((fifo_segment->h->flags & FIFO_SEGMENT_F_IS_PREALLOCATED) @@ -307,8 +308,7 @@ segment_manager_del_sessions (segment_manager_t * sm) if (session->session_state != SESSION_STATE_CLOSED) { session->session_state = SESSION_STATE_CLOSED; - session_send_session_evt_to_thread (session_handle - (session), + session_send_session_evt_to_thread (session_handle (session), FIFO_EVENT_DISCONNECT, thread_index); } @@ -371,8 +371,8 @@ segment_manager_init_del (segment_manager_t * sm) int segment_manager_alloc_session_fifos (segment_manager_t * sm, - svm_fifo_t ** server_rx_fifo, - svm_fifo_t ** server_tx_fifo, + svm_fifo_t ** rx_fifo, + svm_fifo_t ** tx_fifo, u32 * fifo_segment_index) { svm_fifo_segment_private_t *fifo_segment; @@ -392,39 +392,37 @@ segment_manager_alloc_session_fifos (segment_manager_t * sm, again: for (i = 0; i < vec_len (sm->segment_indices); i++) { - *fifo_segment_index = sm->segment_indices[i]; + *fifo_segment_index = vec_elt (sm->segment_indices, i); fifo_segment = svm_fifo_segment_get_segment (*fifo_segment_index); fifo_size = props->rx_fifo_size; fifo_size = (fifo_size == 0) ? default_fifo_size : fifo_size; - *server_rx_fifo = - svm_fifo_segment_alloc_fifo (fifo_segment, fifo_size, - FIFO_SEGMENT_RX_FREELIST); + *rx_fifo = svm_fifo_segment_alloc_fifo (fifo_segment, fifo_size, + FIFO_SEGMENT_RX_FREELIST); fifo_size = props->tx_fifo_size; fifo_size = (fifo_size == 0) ? default_fifo_size : fifo_size; - *server_tx_fifo = - svm_fifo_segment_alloc_fifo (fifo_segment, fifo_size, - FIFO_SEGMENT_TX_FREELIST); + *tx_fifo = svm_fifo_segment_alloc_fifo (fifo_segment, fifo_size, + FIFO_SEGMENT_TX_FREELIST); - if (*server_rx_fifo == 0) + if (*rx_fifo == 0) { /* This would be very odd, but handle it... */ - if (*server_tx_fifo != 0) + if (*tx_fifo != 0) { - svm_fifo_segment_free_fifo (fifo_segment, *server_tx_fifo, + svm_fifo_segment_free_fifo (fifo_segment, *tx_fifo, FIFO_SEGMENT_TX_FREELIST); - *server_tx_fifo = 0; + *tx_fifo = 0; } continue; } - if (*server_tx_fifo == 0) + if (*tx_fifo == 0) { - if (*server_rx_fifo != 0) + if (*rx_fifo != 0) { - svm_fifo_segment_free_fifo (fifo_segment, *server_rx_fifo, + svm_fifo_segment_free_fifo (fifo_segment, *rx_fifo, FIFO_SEGMENT_RX_FREELIST); - *server_rx_fifo = 0; + *rx_fifo = 0; } continue; } @@ -432,9 +430,9 @@ again: } /* See if we're supposed to create another segment */ - if (*server_rx_fifo == 0) + if (*rx_fifo == 0) { - if (props->add_segment && !props->use_private_segment) + if (props->add_segment && !props->segment_type) { if (added_a_segment) { @@ -443,7 +441,7 @@ again: return SESSION_ERROR_NEW_SEG_NO_SPACE; } - if (session_manager_add_segment (sm)) + if (segment_manager_add_segment (sm)) { clib_spinlock_unlock (&sm->lockp); return VNET_API_ERROR_URI_FIFO_CREATE_FAILED; @@ -462,8 +460,8 @@ again: /* Backpointers to segment manager */ sm_index = segment_manager_index (sm); - (*server_tx_fifo)->segment_manager = sm_index; - (*server_rx_fifo)->segment_manager = sm_index; + (*tx_fifo)->segment_manager = sm_index; + (*rx_fifo)->segment_manager = sm_index; clib_spinlock_unlock (&sm->lockp); @@ -577,14 +575,12 @@ segment_manager_show_fn (vlib_main_t * vm, unformat_input_t * input, { svm_fifo_segment_private_t *segments, *seg; segment_manager_t *sm; - u8 show_segments = 0, verbose = 0, *name; + u8 show_segments = 0, verbose = 0; uword address; u64 size; u32 active_fifos; u32 free_fifos; - mheap_t *heap_header; - while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT) { if (unformat (input, "segments")) @@ -615,37 +611,20 @@ segment_manager_show_fn (vlib_main_t * vm, unformat_input_t * input, segments = svm_fifo_segment_segments_pool (); vlib_cli_output (vm, "%d svm fifo segments allocated", pool_elts (segments)); - vlib_cli_output (vm, "%-25s%15s%16s%16s%16s", "Name", + vlib_cli_output (vm, "%-15s%10s%15s%15s%15s%15s", "Name", "Type", "HeapSize (M)", "ActiveFifos", "FreeFifos", "Address"); /* *INDENT-OFF* */ pool_foreach (seg, segments, ({ - if (seg->h->flags & FIFO_SEGMENT_F_IS_PRIVATE) - { - address = pointer_to_uword (seg->ssvm.sh->heap); - if (seg->h->flags & FIFO_SEGMENT_F_IS_MAIN_HEAP) - name = format (0, "main heap"); - else - name = format (0, "private heap"); - heap_header = mheap_header (seg->ssvm.sh->heap); - size = heap_header->max_size; - } - else - { - address = seg->ssvm.sh->ssvm_va; - size = seg->ssvm.ssvm_size; - name = seg->ssvm.sh->name; - } + svm_fifo_segment_info (seg, &address, &size); active_fifos = svm_fifo_segment_num_fifos (seg); free_fifos = svm_fifo_segment_num_free_fifos (seg, ~0 /* size */); - vlib_cli_output (vm, "%-25v%15llu%16u%16u%16llx", - name, size >> 20ULL, active_fifos, free_fifos, - address); + vlib_cli_output (vm, "%-15v%10U%15llu%15u%15u%15llx", + ssvm_name (&seg->ssvm), format_svm_fifo_segment_type, + seg, size >> 20ULL, active_fifos, free_fifos, + address); if (verbose) - vlib_cli_output (vm, "%U", - format_svm_fifo_segment, seg, verbose); - if (seg->h->flags & FIFO_SEGMENT_F_IS_PRIVATE) - vec_free (name); + vlib_cli_output (vm, "%U", format_svm_fifo_segment, seg, verbose); })); /* *INDENT-ON* */ diff --git a/src/vnet/session/segment_manager.h b/src/vnet/session/segment_manager.h index 41e2308928f..b2a792d206b 100644 --- a/src/vnet/session/segment_manager.h +++ b/src/vnet/session/segment_manager.h @@ -36,8 +36,8 @@ typedef struct _segment_manager_properties /** Flag that indicates if additional segments should be created */ u8 add_segment; - /** Use private memory segment instead of shared memory */ - u8 use_private_segment; + /** Segment type: if set to SSVM_N_TYPES, private segments are used */ + ssvm_segment_type_t segment_type; /** Use one or more private mheaps, instead of the global heap */ u32 private_segment_count; @@ -93,13 +93,13 @@ segment_manager_index (segment_manager_t * sm) } segment_manager_t *segment_manager_new (); -int -segment_manager_init (segment_manager_t * sm, u32 props_index, u32 seg_size); +int segment_manager_init (segment_manager_t * sm, u32 props_index, + u32 seg_size, u32 evt_queue_size); -void segment_manager_get_segment_info (u32 index, u8 ** name, u32 * size); -int -session_manager_add_first_segment (segment_manager_t * sm, u32 segment_size); -int session_manager_add_segment (segment_manager_t * sm); +svm_fifo_segment_private_t *segment_manager_get_segment (u32 segment_index); +int segment_manager_add_first_segment (segment_manager_t * sm, + u32 segment_size); +int segment_manager_add_segment (segment_manager_t * sm); void segment_manager_del_sessions (segment_manager_t * sm); void segment_manager_del (segment_manager_t * sm); void segment_manager_init_del (segment_manager_t * sm); @@ -112,8 +112,8 @@ segment_manager_alloc_session_fifos (segment_manager_t * sm, void segment_manager_dealloc_fifos (u32 svm_segment_index, svm_fifo_t * rx_fifo, svm_fifo_t * tx_fifo); -svm_queue_t *segment_manager_alloc_queue (segment_manager_t * - sm, u32 queue_size); +svm_queue_t *segment_manager_alloc_queue (segment_manager_t * sm, + u32 queue_size); void segment_manager_dealloc_queue (segment_manager_t * sm, svm_queue_t * q); void segment_manager_app_detach (segment_manager_t * sm); diff --git a/src/vnet/session/session.c b/src/vnet/session/session.c index adcbb2924d8..be98e712e9b 100644 --- a/src/vnet/session/session.c +++ b/src/vnet/session/session.c @@ -961,32 +961,66 @@ stream_session_cleanup (stream_session_t * s) } /** - * Allocate vpp event queue (once) per worker thread + * Allocate event queues in the shared-memory segment + * + * That can either be a newly created memfd segment, that will need to be + * mapped by all stack users, or the binary api's svm region. The latter is + * assumed to be already mapped. NOTE that this assumption DOES NOT hold if + * api clients bootstrap shm api over sockets (i.e. use memfd segments) and + * vpp uses api svm region for event queues. */ void -session_vpp_event_queue_allocate (session_manager_main_t * smm, - u32 thread_index) +session_vpp_event_queues_allocate (session_manager_main_t * smm) { + u32 evt_q_length = 2048, evt_size = sizeof (session_fifo_event_t); + ssvm_private_t *eqs = &smm->evt_qs_segment; api_main_t *am = &api_main; + u64 eqs_size = 64 << 20; + pid_t vpp_pid = getpid (); void *oldheap; - u32 event_queue_length = 2048; + int i; + + if (smm->configured_event_queue_length) + evt_q_length = smm->configured_event_queue_length; - if (smm->vpp_event_queues[thread_index] == 0) + if (smm->evt_qs_use_memfd_seg) { - /* Allocate event fifo in the /vpe-api shared-memory segment */ - oldheap = svm_push_data_heap (am->vlib_rp); + if (smm->evt_qs_segment_size) + eqs_size = smm->evt_qs_segment_size; - if (smm->configured_event_queue_length) - event_queue_length = smm->configured_event_queue_length; + eqs->ssvm_size = eqs_size; + eqs->i_am_master = 1; + eqs->my_pid = vpp_pid; + eqs->name = format (0, "%s%c", "evt-qs-segment", 0); + eqs->requested_va = smm->session_baseva; - smm->vpp_event_queues[thread_index] = - svm_queue_init - (event_queue_length, - sizeof (session_fifo_event_t), 0 /* consumer pid */ , - 0 /* (do not) send signal when queue non-empty */ ); + ssvm_master_init (eqs, SSVM_SEGMENT_MEMFD); + } + + if (smm->evt_qs_use_memfd_seg) + oldheap = ssvm_push_heap (eqs->sh); + else + oldheap = svm_push_data_heap (am->vlib_rp); - svm_pop_heap (oldheap); + for (i = 0; i < vec_len (smm->vpp_event_queues); i++) + { + smm->vpp_event_queues[i] = svm_queue_init (evt_q_length, evt_size, + vpp_pid, 0); } + + if (smm->evt_qs_use_memfd_seg) + ssvm_pop_heap (oldheap); + else + svm_pop_heap (oldheap); +} + +ssvm_private_t * +session_manager_get_evt_q_segment (void) +{ + session_manager_main_t *smm = &session_manager_main; + if (smm->evt_qs_use_memfd_seg) + return &smm->evt_qs_segment; + return 0; } /** @@ -1076,10 +1110,6 @@ session_manager_main_enable (vlib_main_t * vm) if (num_threads < 1) return clib_error_return (0, "n_thread_stacks not set"); - /* $$$ config parameters */ - svm_fifo_segment_init (0x200000000ULL /* first segment base VA */ , - 20 /* timeout in seconds */ ); - /* configure per-thread ** vectors */ vec_validate (smm->sessions, num_threads - 1); vec_validate (smm->tx_buffers, num_threads - 1); @@ -1117,9 +1147,12 @@ session_manager_main_enable (vlib_main_t * vm) vec_validate (smm->last_event_poll_by_thread, num_threads - 1); #endif - /* Allocate vpp event queues */ - for (i = 0; i < vec_len (smm->vpp_event_queues); i++) - session_vpp_event_queue_allocate (smm, i); + /* Allocate vpp event queues segment and queue */ + session_vpp_event_queues_allocate (smm); + + /* Initialize fifo segment main baseva and timeout */ + svm_fifo_segment_init (smm->session_baseva + smm->evt_qs_segment_size, + smm->segment_timeout); /* Preallocate sessions */ if (smm->preallocated_sessions) @@ -1192,6 +1225,9 @@ clib_error_t * session_manager_main_init (vlib_main_t * vm) { session_manager_main_t *smm = &session_manager_main; + smm->session_baseva = 0x200000000ULL; + smm->segment_timeout = 20; + smm->evt_qs_segment_size = 64 << 20; smm->is_enabled = 0; return 0; } @@ -1272,6 +1308,8 @@ session_config_fn (vlib_main_t * vm, unformat_input_t * input) else if (unformat (input, "local-endpoints-table-buckets %d", &smm->local_endpoints_table_buckets)) ; + else if (unformat (input, "evt_qs_memfd_seg")) + smm->evt_qs_use_memfd_seg = 1; else return clib_error_return (0, "unknown input `%U'", format_unformat_error, input); diff --git a/src/vnet/session/session.h b/src/vnet/session/session.h index 5e017c6c852..98e8acb79c1 100644 --- a/src/vnet/session/session.h +++ b/src/vnet/session/session.h @@ -149,6 +149,9 @@ struct _session_manager_main /** vpp fifo event queue */ svm_queue_t **vpp_event_queues; + /** Event queues memfd segment initialized only if so configured */ + ssvm_private_t evt_qs_segment; + /** Unique segment name counter */ u32 unique_segment_name_counter; @@ -170,7 +173,13 @@ struct _session_manager_main * Config parameters */ - /** session table size parameters */ + /** Session ssvm segment configs*/ + uword session_baseva; + u32 segment_timeout; + u32 evt_qs_segment_size; + u8 evt_qs_use_memfd_seg; + + /** Session table size parameters */ u32 configured_v4_session_table_buckets; u32 configured_v4_session_table_memory; u32 configured_v4_halfopen_table_buckets; @@ -443,6 +452,7 @@ void stream_session_cleanup (stream_session_t * s); void session_send_session_evt_to_thread (u64 session_handle, fifo_event_type_t evt_type, u32 thread_index); +ssvm_private_t *session_manager_get_evt_q_segment (void); u8 *format_stream_session (u8 * s, va_list * args); uword unformat_stream_session (unformat_input_t * input, va_list * args); diff --git a/src/vnet/session/session_api.c b/src/vnet/session/session_api.c index eeda839a2fb..5201ec60751 100755 --- a/src/vnet/session/session_api.c +++ b/src/vnet/session/session_api.c @@ -58,25 +58,54 @@ _(SESSION_RULE_ADD_DEL, session_rule_add_del) \ _(SESSION_RULES_DUMP, session_rules_dump) \ static int -send_add_segment_callback (u32 api_client_index, const u8 * segment_name, - u32 segment_size) +session_send_memfd_fd (vl_api_registration_t * reg, const ssvm_private_t * sp) +{ + clib_error_t *error; + if (vl_api_registration_file_index (reg) == VL_API_INVALID_FI) + { + clib_warning ("can't send memfd fd"); + return -1; + } + error = vl_api_send_fd_msg (reg, sp->fd); + if (error) + { + clib_error_report (error); + return -1; + } + return 0; +} + +static int +send_add_segment_callback (u32 api_client_index, const ssvm_private_t * sp) { vl_api_map_another_segment_t *mp; - svm_queue_t *q; + vl_api_registration_t *reg; - q = vl_api_client_index_to_input_queue (api_client_index); + reg = vl_mem_api_client_index_to_registration (api_client_index); + if (!reg) + { + clib_warning ("no registration: %u", api_client_index); + return -1; + } - if (!q) - return -1; + if (ssvm_type (sp) == SSVM_SEGMENT_MEMFD + && vl_api_registration_file_index (reg) == VL_API_INVALID_FI) + { + clib_warning ("can't send memfd fd"); + return -1; + } mp = vl_msg_api_alloc_as_if_client (sizeof (*mp)); memset (mp, 0, sizeof (*mp)); mp->_vl_msg_id = clib_host_to_net_u16 (VL_API_MAP_ANOTHER_SEGMENT); - mp->segment_size = segment_size; - strncpy ((char *) mp->segment_name, (char *) segment_name, + mp->segment_size = sp->ssvm_size; + strncpy ((char *) mp->segment_name, (char *) sp->name, sizeof (mp->segment_name) - 1); - vl_msg_api_send_shmem (q, (u8 *) & mp); + vl_msg_api_send_shmem (reg->vl_input_queue, (u8 *) & mp); + + if (ssvm_type (sp) == SSVM_SEGMENT_MEMFD) + return session_send_memfd_fd (reg, sp); return 0; } @@ -84,20 +113,23 @@ send_add_segment_callback (u32 api_client_index, const u8 * segment_name, static int send_session_accept_callback (stream_session_t * s) { - vl_api_accept_session_t *mp; - svm_queue_t *q, *vpp_queue; application_t *server = application_get (s->app_index); - transport_connection_t *tc; transport_proto_vft_t *tp_vft; + vl_api_accept_session_t *mp; + vl_api_registration_t *reg; + transport_connection_t *tc; stream_session_t *listener; + svm_queue_t *vpp_queue; - q = vl_api_client_index_to_input_queue (server->api_client_index); vpp_queue = session_manager_get_vpp_event_queue (s->thread_index); + reg = vl_mem_api_client_index_to_registration (server->api_client_index); + if (!reg) + { + clib_warning ("no registration: %u", server->api_client_index); + return -1; + } - if (!q) - return -1; - - mp = vl_msg_api_alloc_as_if_client (sizeof (*mp)); + mp = vl_mem_api_alloc_as_if_client_w_reg (reg, sizeof (*mp)); memset (mp, 0, sizeof (*mp)); mp->_vl_msg_id = clib_host_to_net_u16 (VL_API_ACCEPT_SESSION); @@ -123,7 +155,7 @@ send_session_accept_callback (stream_session_t * s) mp->port = tc->rmt_port; mp->is_ip4 = tc->is_ip4; clib_memcpy (&mp->ip, &tc->rmt_ip, sizeof (tc->rmt_ip)); - vl_msg_api_send_shmem (q, (u8 *) & mp); + vl_msg_api_send_shmem (reg->vl_input_queue, (u8 *) & mp); return 0; } @@ -131,39 +163,43 @@ send_session_accept_callback (stream_session_t * s) static void send_session_disconnect_callback (stream_session_t * s) { - vl_api_disconnect_session_t *mp; - svm_queue_t *q; application_t *app = application_get (s->app_index); + vl_api_disconnect_session_t *mp; + vl_api_registration_t *reg; - q = vl_api_client_index_to_input_queue (app->api_client_index); - - if (!q) - return; + reg = vl_mem_api_client_index_to_registration (app->api_client_index); + if (!reg) + { + clib_warning ("no registration: %u", app->api_client_index); + return; + } - mp = vl_msg_api_alloc_as_if_client (sizeof (*mp)); + mp = vl_mem_api_alloc_as_if_client_w_reg (reg, sizeof (*mp)); memset (mp, 0, sizeof (*mp)); mp->_vl_msg_id = clib_host_to_net_u16 (VL_API_DISCONNECT_SESSION); mp->handle = session_handle (s); - vl_msg_api_send_shmem (q, (u8 *) & mp); + vl_msg_api_send_shmem (reg->vl_input_queue, (u8 *) & mp); } static void send_session_reset_callback (stream_session_t * s) { - vl_api_reset_session_t *mp; - svm_queue_t *q; application_t *app = application_get (s->app_index); + vl_api_registration_t *reg; + vl_api_reset_session_t *mp; - q = vl_api_client_index_to_input_queue (app->api_client_index); - - if (!q) - return; + reg = vl_mem_api_client_index_to_registration (app->api_client_index); + if (!reg) + { + clib_warning ("no registration: %u", app->api_client_index); + return; + } - mp = vl_msg_api_alloc_as_if_client (sizeof (*mp)); + mp = vl_mem_api_alloc_as_if_client_w_reg (reg, sizeof (*mp)); memset (mp, 0, sizeof (*mp)); mp->_vl_msg_id = clib_host_to_net_u16 (VL_API_RESET_SESSION); mp->handle = session_handle (s); - vl_msg_api_send_shmem (q, (u8 *) & mp); + vl_msg_api_send_shmem (reg->vl_input_queue, (u8 *) & mp); } int @@ -171,18 +207,20 @@ send_session_connected_callback (u32 app_index, u32 api_context, stream_session_t * s, u8 is_fail) { vl_api_connect_session_reply_t *mp; - svm_queue_t *q; - application_t *app; - svm_queue_t *vpp_queue; transport_connection_t *tc; + vl_api_registration_t *reg; + svm_queue_t *vpp_queue; + application_t *app; app = application_get (app_index); - q = vl_api_client_index_to_input_queue (app->api_client_index); - - if (!q) - return -1; + reg = vl_mem_api_client_index_to_registration (app->api_client_index); + if (!reg) + { + clib_warning ("no registration: %u", app->api_client_index); + return -1; + } - mp = vl_msg_api_alloc_as_if_client (sizeof (*mp)); + mp = vl_mem_api_alloc_as_if_client_w_reg (reg, sizeof (*mp)); mp->_vl_msg_id = clib_host_to_net_u16 (VL_API_CONNECT_SESSION_REPLY); mp->context = api_context; @@ -208,7 +246,7 @@ send_session_connected_callback (u32 app_index, u32 api_context, done: mp->retval = is_fail ? clib_host_to_net_u32 (VNET_API_ERROR_SESSION_CONNECT) : 0; - vl_msg_api_send_shmem (q, (u8 *) & mp); + vl_msg_api_send_shmem (reg->vl_input_queue, (u8 *) & mp); return 0; } @@ -310,7 +348,9 @@ static void vl_api_application_attach_t_handler (vl_api_application_attach_t * mp) { vl_api_application_attach_reply_t *rmp; + ssvm_private_t *segp, *evt_q_segment; vnet_app_attach_args_t _a, *a = &_a; + vl_api_registration_t *reg; clib_error_t *error = 0; int rv = 0; @@ -354,18 +394,30 @@ done: REPLY_MACRO2 (VL_API_APPLICATION_ATTACH_REPLY, ({ if (!rv) { + segp = a->segment; rmp->segment_name_length = 0; - rmp->segment_size = a->segment_size; - if (a->segment_name_length) + rmp->segment_size = segp->ssvm_size; + if (vec_len (segp->name)) { - memcpy (rmp->segment_name, a->segment_name, - a->segment_name_length); - rmp->segment_name_length = a->segment_name_length; + memcpy (rmp->segment_name, segp->name, vec_len (segp->name)); + rmp->segment_name_length = vec_len (segp->name); } rmp->app_event_queue_address = a->app_event_queue_address; } })); /* *INDENT-ON* */ + + if (rv) + return; + + reg = vl_api_client_index_to_registration (mp->client_index); + + /* Send fifo segment fd if needed */ + if (ssvm_type (a->segment) == SSVM_SEGMENT_MEMFD) + session_send_memfd_fd (reg, a->segment); + /* Send event queues segment */ + if ((evt_q_segment = session_manager_get_evt_q_segment ())) + session_send_memfd_fd (reg, evt_q_segment); } static void diff --git a/src/vnet/session/session_test.c b/src/vnet/session/session_test.c index 64657c11da0..a9a902d27bc 100644 --- a/src/vnet/session/session_test.c +++ b/src/vnet/session/session_test.c @@ -103,7 +103,6 @@ session_test_basic (vlib_main_t * vm, unformat_input_t * input) { session_endpoint_t server_sep = SESSION_ENDPOINT_NULL; u64 options[APP_OPTIONS_N_OPTIONS], bind4_handle, bind6_handle; - u8 segment_name[128]; clib_error_t *error = 0; u32 server_index; @@ -117,7 +116,6 @@ session_test_basic (vlib_main_t * vm, unformat_input_t * input) .options = options, .namespace_id = 0, .session_cb_vft = &dummy_session_cbs, - .segment_name = segment_name, }; error = vnet_application_attach (&attach_args); @@ -178,7 +176,6 @@ session_test_namespace (vlib_main_t * vm, unformat_input_t * input) clib_error_t *error = 0; u8 *ns_id = format (0, "appns1"), intf_mac[6]; app_namespace_t *app_ns; - u8 segment_name[128]; application_t *server; stream_session_t *s; int code; @@ -197,7 +194,6 @@ session_test_namespace (vlib_main_t * vm, unformat_input_t * input) .options = options, .namespace_id = 0, .session_cb_vft = &dummy_session_cbs, - .segment_name = segment_name, }; vnet_bind_args_t bind_args = { @@ -781,7 +777,7 @@ session_test_rules (vlib_main_t * vm, unformat_input_t * input) transport_connection_t *tc; u32 dummy_port = 1111; clib_error_t *error = 0; - u8 segment_name[128], is_filtered = 0, *ns_id = format (0, "appns1"); + u8 is_filtered = 0, *ns_id = format (0, "appns1"); stream_session_t *listener, *s; app_namespace_t *default_ns = app_namespace_get_default (); u32 local_ns_index = default_ns->local_table_index; @@ -809,7 +805,6 @@ session_test_rules (vlib_main_t * vm, unformat_input_t * input) .options = options, .namespace_id = 0, .session_cb_vft = &dummy_session_cbs, - .segment_name = segment_name, }; vnet_bind_args_t bind_args = { @@ -1342,7 +1337,7 @@ session_test_proxy (vlib_main_t * vm, unformat_input_t * input) u32 server_index, app_index; u32 dummy_server_api_index = ~0, sw_if_index = 0; clib_error_t *error = 0; - u8 segment_name[128], intf_mac[6], sst, is_filtered = 0; + u8 intf_mac[6], sst, is_filtered = 0; stream_session_t *s; transport_connection_t *tc; u16 lcl_port = 1234, rmt_port = 4321; @@ -1407,7 +1402,6 @@ session_test_proxy (vlib_main_t * vm, unformat_input_t * input) .options = options, .namespace_id = 0, .session_cb_vft = &dummy_session_cbs, - .segment_name = segment_name, }; attach_args.api_client_index = dummy_server_api_index; diff --git a/src/vnet/tcp/builtin_client.c b/src/vnet/tcp/builtin_client.c index b073459c52e..2784591731e 100644 --- a/src/vnet/tcp/builtin_client.c +++ b/src/vnet/tcp/builtin_client.c @@ -296,8 +296,8 @@ create_api_loopback (tclient_main_t * tm) shmem_hdr = am->shmem_hdr; tm->vl_input_queue = shmem_hdr->vl_input_queue; - tm->my_client_index = - vl_api_memclnt_create_internal ("tcp_test_client", tm->vl_input_queue); + tm->my_client_index = vl_api_memclnt_create_internal ("tcp_test_client", + tm->vl_input_queue); return 0; } @@ -429,21 +429,16 @@ static clib_error_t * attach_builtin_test_clients_app (u8 * appns_id, u64 appns_flags, u64 appns_secret) { - u32 segment_name_length, prealloc_fifos, segment_size = 2 << 20; + u32 prealloc_fifos, segment_size = 2 << 20; tclient_main_t *tm = &tclient_main; vnet_app_attach_args_t _a, *a = &_a; - u8 segment_name[128]; u64 options[16]; clib_error_t *error = 0; - segment_name_length = ARRAY_LEN (segment_name); - memset (a, 0, sizeof (*a)); memset (options, 0, sizeof (options)); a->api_client_index = tm->my_client_index; - a->segment_name = segment_name; - a->segment_name_length = segment_name_length; a->session_cb_vft = &builtin_clients; prealloc_fifos = tm->prealloc_fifos ? tm->expected_connections : 1; diff --git a/src/vnet/tcp/builtin_http_server.c b/src/vnet/tcp/builtin_http_server.c index 356cfd86b91..5510f8ad34c 100644 --- a/src/vnet/tcp/builtin_http_server.c +++ b/src/vnet/tcp/builtin_http_server.c @@ -466,8 +466,7 @@ builtin_session_connected_callback (u32 app_index, u32 api_context, } static int -builtin_add_segment_callback (u32 client_index, - const u8 * seg_name, u32 seg_size) +builtin_add_segment_callback (u32 client_index, const ssvm_private_t * sp) { clib_warning ("called..."); return -1; @@ -509,7 +508,6 @@ static int server_attach () { http_server_main_t *hsm = &http_server_main; - u8 segment_name[128]; u64 options[APP_OPTIONS_N_OPTIONS]; vnet_app_attach_args_t _a, *a = &_a; u32 segment_size = 128 << 20; @@ -530,8 +528,6 @@ server_attach () hsm->fifo_size ? hsm->fifo_size : 32 << 10; a->options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN; a->options[APP_OPTIONS_PREALLOC_FIFO_PAIRS] = hsm->prealloc_fifos; - a->segment_name = segment_name; - a->segment_name_length = ARRAY_LEN (segment_name); if (vnet_application_attach (a)) { diff --git a/src/vnet/tcp/builtin_proxy.c b/src/vnet/tcp/builtin_proxy.c index a0a41b91b31..a4827bff56d 100644 --- a/src/vnet/tcp/builtin_proxy.c +++ b/src/vnet/tcp/builtin_proxy.c @@ -139,8 +139,7 @@ server_connected_callback (u32 app_index, u32 api_context, } static int -server_add_segment_callback (u32 client_index, - const u8 * seg_name, u32 seg_size) +server_add_segment_callback (u32 client_index, const ssvm_private_t * sp) { clib_warning ("called..."); return -1; @@ -382,7 +381,6 @@ static int server_attach () { builtin_proxy_main_t *bpm = &builtin_proxy_main; - u8 segment_name[128]; u64 options[APP_OPTIONS_N_OPTIONS]; vnet_app_attach_args_t _a, *a = &_a; u32 segment_size = 512 << 20; @@ -404,9 +402,6 @@ server_attach () a->options[APP_OPTIONS_FLAGS] = APP_OPTIONS_FLAGS_IS_BUILTIN; - a->segment_name = segment_name; - a->segment_name_length = ARRAY_LEN (segment_name); - if (vnet_application_attach (a)) { clib_warning ("failed to attach server"); @@ -422,18 +417,12 @@ active_open_attach (void) { builtin_proxy_main_t *bpm = &builtin_proxy_main; vnet_app_attach_args_t _a, *a = &_a; - u8 segment_name[128]; - u32 segment_name_length; u64 options[16]; - segment_name_length = ARRAY_LEN (segment_name); - memset (a, 0, sizeof (*a)); memset (options, 0, sizeof (options)); a->api_client_index = bpm->active_open_client_index; - a->segment_name = segment_name; - a->segment_name_length = segment_name_length; a->session_cb_vft = &builtin_clients; options[APP_OPTIONS_ACCEPT_COOKIE] = 0x12345678; diff --git a/src/vnet/tcp/builtin_server.c b/src/vnet/tcp/builtin_server.c index eafef8227e2..2ea9068a597 100644 --- a/src/vnet/tcp/builtin_server.c +++ b/src/vnet/tcp/builtin_server.c @@ -95,8 +95,7 @@ builtin_session_connected_callback (u32 app_index, u32 api_context, } int -builtin_add_segment_callback (u32 client_index, - const u8 * seg_name, u32 seg_size) +builtin_add_segment_callback (u32 client_index, const ssvm_private_t * sp) { clib_warning ("called..."); return -1; @@ -271,7 +270,6 @@ static int server_attach (u8 * appns_id, u64 appns_flags, u64 appns_secret) { builtin_server_main_t *bsm = &builtin_server_main; - u8 segment_name[128]; u64 options[APP_OPTIONS_N_OPTIONS]; vnet_app_attach_args_t _a, *a = &_a; u32 segment_size = 512 << 20; @@ -306,8 +304,6 @@ server_attach (u8 * appns_id, u64 appns_flags, u64 appns_secret) a->options[APP_OPTIONS_FLAGS] |= appns_flags; a->options[APP_OPTIONS_NAMESPACE_SECRET] = appns_secret; } - a->segment_name = segment_name; - a->segment_name_length = ARRAY_LEN (segment_name); if (vnet_application_attach (a)) { diff --git a/src/vnet/tcp/tcp_debug.h b/src/vnet/tcp/tcp_debug.h index 5d4f7d6879d..e0db7f4f0fa 100755 --- a/src/vnet/tcp/tcp_debug.h +++ b/src/vnet/tcp/tcp_debug.h @@ -19,7 +19,7 @@ #include <vlib/vlib.h> #define TCP_DEBUG (1) -#define TCP_DEBUG_SM (0) +#define TCP_DEBUG_SM (1) #define TCP_DEBUG_CC (0) #define TCP_DEBUG_CC_STAT (1) #define TCP_DEBUG_BUFFER_ALLOCATION (0) diff --git a/src/vnet/tcp/tcp_input.c b/src/vnet/tcp/tcp_input.c index b0ea24ff8ef..86bce4895b6 100644 --- a/src/vnet/tcp/tcp_input.c +++ b/src/vnet/tcp/tcp_input.c @@ -2382,6 +2382,7 @@ tcp46_rcv_process_inline (vlib_main_t * vm, vlib_node_runtime_t * node, /* Switch state to ESTABLISHED */ tc0->state = TCP_STATE_ESTABLISHED; + TCP_EVT_DBG (TCP_EVT_STATE_CHANGE, tc0); /* Initialize session variables */ tc0->snd_una = vnet_buffer (b0)->tcp.ack_number; @@ -2389,12 +2390,12 @@ tcp46_rcv_process_inline (vlib_main_t * vm, vlib_node_runtime_t * node, << tc0->rcv_opts.wscale; tc0->snd_wl1 = vnet_buffer (b0)->tcp.seq_number; tc0->snd_wl2 = vnet_buffer (b0)->tcp.ack_number; - stream_session_accept_notify (&tc0->connection); /* Reset SYN-ACK retransmit and SYN_RCV establish timers */ tcp_retransmit_timer_reset (tc0); tcp_timer_reset (tc0, TCP_TIMER_ESTABLISH); - TCP_EVT_DBG (TCP_EVT_STATE_CHANGE, tc0); + + stream_session_accept_notify (&tc0->connection); break; case TCP_STATE_ESTABLISHED: /* We can get packets in established state here because they diff --git a/src/vnet/udp/builtin_server.c b/src/vnet/udp/builtin_server.c index 73914cbc143..4c9573e7f82 100644 --- a/src/vnet/udp/builtin_server.c +++ b/src/vnet/udp/builtin_server.c @@ -110,18 +110,12 @@ static int attach_builtin_uri_server () { vnet_app_attach_args_t _a, *a = &_a; - u8 segment_name[128]; - u32 segment_name_length; u64 options[16]; - segment_name_length = ARRAY_LEN (segment_name); - memset (a, 0, sizeof (*a)); memset (options, 0, sizeof (options)); a->api_client_index = ~0; - a->segment_name = segment_name; - a->segment_name_length = segment_name_length; a->session_cb_vft = &builtin_server; options[APP_OPTIONS_ACCEPT_COOKIE] = 0x12345678; diff --git a/src/vppinfra/linux/mem.c b/src/vppinfra/linux/mem.c index 3c449226273..350ccf855ce 100644 --- a/src/vppinfra/linux/mem.c +++ b/src/vppinfra/linux/mem.c @@ -61,7 +61,7 @@ clib_mem_vm_get_log2_page_size (int fd) return min_log2 (clib_mem_vm_get_page_size (fd)); } -static void +void clib_mem_vm_randomize_va (uword * requested_va, u32 log2_page_size) { u8 bit_mask = 15; diff --git a/src/vppinfra/mem.h b/src/vppinfra/mem.h index b566e8d8895..028289c50a5 100644 --- a/src/vppinfra/mem.h +++ b/src/vppinfra/mem.h @@ -360,8 +360,9 @@ typedef struct uword requested_va; /**< Request fixed position mapping */ void *addr; /**< Pointer to mapped memory, if successful */ } clib_mem_vm_map_t; -clib_error_t *clib_mem_vm_ext_map (clib_mem_vm_map_t * a); +clib_error_t *clib_mem_vm_ext_map (clib_mem_vm_map_t * a); +void clib_mem_vm_randomize_va (uword * requested_va, u32 log2_page_size); #include <vppinfra/error.h> /* clib_panic */ |