diff options
Diffstat (limited to 'src/svm')
-rw-r--r-- | src/svm/fifo_segment.c | 36 | ||||
-rw-r--r-- | src/svm/fifo_segment.h | 4 | ||||
-rw-r--r-- | src/svm/fifo_types.h | 1 | ||||
-rw-r--r-- | src/svm/message_queue.c | 47 | ||||
-rw-r--r-- | src/svm/message_queue.h | 25 | ||||
-rw-r--r-- | src/svm/queue.c | 4 | ||||
-rw-r--r-- | src/svm/ssvm.c | 13 | ||||
-rw-r--r-- | src/svm/ssvm.h | 2 | ||||
-rw-r--r-- | src/svm/svm.c | 27 | ||||
-rw-r--r-- | src/svm/svm.h | 17 | ||||
-rw-r--r-- | src/svm/svm_common.h | 6 | ||||
-rw-r--r-- | src/svm/svm_fifo.c | 30 | ||||
-rw-r--r-- | src/svm/svm_fifo.h | 130 | ||||
-rw-r--r-- | src/svm/svmdb.c | 20 | ||||
-rw-r--r-- | src/svm/svmdbtool.c | 5 | ||||
-rw-r--r-- | src/svm/svmtool.c | 4 |
16 files changed, 206 insertions, 165 deletions
diff --git a/src/svm/fifo_segment.c b/src/svm/fifo_segment.c index 2ff272e2f88..d5f62913082 100644 --- a/src/svm/fifo_segment.c +++ b/src/svm/fifo_segment.c @@ -295,7 +295,7 @@ fss_fl_chunk_bytes_sub (fifo_segment_slice_t * fss, uword size) int fifo_segment_init (fifo_segment_t * fs) { - u32 align = 8, offset = 2 * 4096, slices_sz, i; + u32 align = 8, offset = FIFO_SEGMENT_ALLOC_OVERHEAD, slices_sz, i; uword max_fifo, seg_start, seg_sz; fifo_segment_header_t *fsh; ssvm_shared_header_t *sh; @@ -312,7 +312,7 @@ fifo_segment_init (fifo_segment_t * fs) seg_start = round_pow2_u64 (pointer_to_uword (seg_data), align); fsh = uword_to_pointer (seg_start, void *); - CLIB_MEM_UNPOISON (fsh, seg_sz); + clib_mem_unpoison (fsh, seg_sz); memset (fsh, 0, sizeof (*fsh) + slices_sz); fsh->byte_index = sizeof (*fsh) + slices_sz; @@ -387,6 +387,8 @@ fifo_segment_attach (fifo_segment_main_t * sm, fifo_segment_create_args_t * a) pool_get_zero (sm->segments, fs); + fs->fs_index = fs - sm->segments; + fs->sm_index = ~0; fs->ssvm.ssvm_size = a->segment_size; fs->ssvm.my_pid = getpid (); fs->ssvm.name = format (0, "%s%c", a->segment_name, 0); @@ -779,7 +781,7 @@ fsh_slice_collect_chunks (fifo_segment_header_t * fsh, while (c) { - CLIB_MEM_UNPOISON (c, sizeof (*c)); + clib_mem_unpoison (c, sizeof (*c)); next = fs_chunk_ptr (fsh, c->next); fl_index = fs_freelist_for_size (c->length); fss_chunk_free_list_push (fsh, fss, fl_index, c); @@ -834,7 +836,7 @@ fifo_segment_cleanup (fifo_segment_t *fs) vec_free (fs->slices); - vec_foreach (fs->mqs, mq) + vec_foreach (mq, fs->mqs) svm_msg_q_cleanup (mq); vec_free (fs->mqs); @@ -868,6 +870,9 @@ fifo_segment_alloc_fifo_w_slice (fifo_segment_t * fs, u32 slice_index, svm_fifo_init (f, data_bytes); + f->segment_manager = fs->sm_index; + f->segment_index = fs->fs_index; + fss = fsh_slice_get (fsh, slice_index); pfss = fs_slice_private_get (fs, slice_index); @@ -1093,6 +1098,9 @@ fifo_segment_msg_q_alloc (fifo_segment_t *fs, u32 mq_index, size = svm_msg_q_size_to_alloc (cfg); base = fsh_alloc_aligned (fsh, size, 8); + if (!base) + return 0; + fsh->n_reserved_bytes += size; smq = svm_msg_q_init (base, cfg); @@ -1536,22 +1544,15 @@ format_fifo_segment (u8 * s, va_list * args) f64 usage; fifo_segment_mem_status_t mem_st; - indent = format_get_indent (s) + 2; - - if (fs == 0) - { - s = format (s, "%-20s%10s%15s%15s%15s%15s", "Name", "Type", - "HeapSize (M)", "ActiveFifos", "FreeFifos", "Address"); - return s; - } + indent = format_get_indent (s); fifo_segment_info (fs, &address, &size); active_fifos = fifo_segment_num_fifos (fs); free_fifos = fifo_segment_num_free_fifos (fs); - s = format (s, "%-20v%10U%15llu%15u%15u%15llx", ssvm_name (&fs->ssvm), - format_fifo_segment_type, fs, size >> 20ULL, active_fifos, - free_fifos, address); + s = format (s, "%U%v type: %U size: %U active fifos: %u", format_white_space, + 2, ssvm_name (&fs->ssvm), format_fifo_segment_type, fs, + format_memory_size, size, active_fifos); if (!verbose) return s; @@ -1560,9 +1561,8 @@ format_fifo_segment (u8 * s, va_list * args) free_chunks = fifo_segment_num_free_chunks (fs, ~0); if (free_chunks) - s = - format (s, "\n\n%UFree/Allocated chunks by size:\n", format_white_space, - indent + 2); + s = format (s, "\n\n%UFree/Allocated chunks by size:\n", + format_white_space, indent + 2); else s = format (s, "\n"); diff --git a/src/svm/fifo_segment.h b/src/svm/fifo_segment.h index de4622f6a2a..ec184207269 100644 --- a/src/svm/fifo_segment.h +++ b/src/svm/fifo_segment.h @@ -20,6 +20,8 @@ #include <svm/message_queue.h> #include <svm/svm_fifo.h> +#define FIFO_SEGMENT_ALLOC_OVERHEAD (2 * clib_mem_get_page_size ()) + typedef enum { FIFO_SEGMENT_FTYPE_NONE = -1, @@ -72,6 +74,8 @@ typedef struct fifo_slice_private_t *slices; /**< private slice information */ svm_msg_q_t *mqs; /**< private vec of attached mqs */ uword max_byte_index; /**< max byte index for segment */ + u32 sm_index; /**< owner segment manager index */ + u32 fs_index; /**< fs index in sm pool */ u8 n_slices; /**< number of fifo segment slices */ u8 flags; /**< private fifo segment flags */ u8 high_watermark; /**< memory pressure watermark high */ diff --git a/src/svm/fifo_types.h b/src/svm/fifo_types.h index 3787e5d5831..742351b1764 100644 --- a/src/svm/fifo_types.h +++ b/src/svm/fifo_types.h @@ -78,6 +78,7 @@ typedef struct svm_fifo_shr_ u32 head; /**< fifo head position/byte */ volatile u32 want_deq_ntf; /**< producer wants nudge */ volatile u32 has_deq_ntf; + u32 deq_thresh; /**< fifo threshold used for notifications */ CLIB_CACHE_LINE_ALIGN_MARK (producer); u32 tail; /**< fifo tail position/byte */ diff --git a/src/svm/message_queue.c b/src/svm/message_queue.c index a6af7962f73..ab0d230b1f0 100644 --- a/src/svm/message_queue.c +++ b/src/svm/message_queue.c @@ -243,8 +243,7 @@ svm_msg_q_lock_and_alloc_msg_w_ring (svm_msg_q_t * mq, u32 ring_index, { if (svm_msg_q_try_lock (mq)) return -1; - if (PREDICT_FALSE (svm_msg_q_is_full (mq) - || svm_msg_q_ring_is_full (mq, ring_index))) + if (PREDICT_FALSE (svm_msg_q_or_ring_is_full (mq, ring_index))) { svm_msg_q_unlock (mq); return -2; @@ -254,9 +253,8 @@ svm_msg_q_lock_and_alloc_msg_w_ring (svm_msg_q_t * mq, u32 ring_index, else { svm_msg_q_lock (mq); - while (svm_msg_q_is_full (mq) - || svm_msg_q_ring_is_full (mq, ring_index)) - svm_msg_q_wait_prod (mq); + while (svm_msg_q_or_ring_is_full (mq, ring_index)) + svm_msg_q_or_ring_wait_prod (mq, ring_index); *msg = svm_msg_q_alloc_msg_w_ring (mq, ring_index); } return 0; @@ -342,15 +340,15 @@ svm_msq_q_msg_is_valid (svm_msg_q_t * mq, svm_msg_q_msg_t * msg) return (dist1 < dist2); } -static void -svm_msg_q_add_raw (svm_msg_q_t *mq, u8 *elem) +void +svm_msg_q_add_raw (svm_msg_q_t *mq, svm_msg_q_msg_t *msg) { svm_msg_q_shared_queue_t *sq = mq->q.shr; i8 *tailp; u32 sz; tailp = (i8 *) (&sq->data[0] + sq->elsize * sq->tail); - clib_memcpy_fast (tailp, elem, sq->elsize); + clib_memcpy_fast (tailp, msg, sq->elsize); sq->tail = (sq->tail + 1) % sq->maxsize; @@ -383,7 +381,7 @@ svm_msg_q_add (svm_msg_q_t * mq, svm_msg_q_msg_t * msg, int nowait) svm_msg_q_wait_prod (mq); } - svm_msg_q_add_raw (mq, (u8 *) msg); + svm_msg_q_add_raw (mq, msg); svm_msg_q_unlock (mq); @@ -394,7 +392,7 @@ void svm_msg_q_add_and_unlock (svm_msg_q_t * mq, svm_msg_q_msg_t * msg) { ASSERT (svm_msq_q_msg_is_valid (mq, msg)); - svm_msg_q_add_raw (mq, (u8 *) msg); + svm_msg_q_add_raw (mq, msg); svm_msg_q_unlock (mq); } @@ -569,6 +567,35 @@ svm_msg_q_wait_prod (svm_msg_q_t *mq) } int +svm_msg_q_or_ring_wait_prod (svm_msg_q_t *mq, u32 ring_index) +{ + if (mq->q.evtfd == -1) + { + while (svm_msg_q_or_ring_is_full (mq, ring_index)) + pthread_cond_wait (&mq->q.shr->condvar, &mq->q.shr->mutex); + } + else + { + u64 buf; + int rv; + + while (svm_msg_q_or_ring_is_full (mq, ring_index)) + { + while ((rv = read (mq->q.evtfd, &buf, sizeof (buf))) < 0) + { + if (errno != EAGAIN) + { + clib_unix_warning ("read error"); + return rv; + } + } + } + } + + return 0; +} + +int svm_msg_q_timedwait (svm_msg_q_t *mq, double timeout) { if (mq->q.evtfd == -1) diff --git a/src/svm/message_queue.h b/src/svm/message_queue.h index bd76eda5d88..4473c44f4e3 100644 --- a/src/svm/message_queue.h +++ b/src/svm/message_queue.h @@ -193,6 +193,17 @@ void svm_msg_q_free_msg (svm_msg_q_t * mq, svm_msg_q_msg_t * msg); /** * Producer enqueue one message to queue * + * Must be called with mq locked. Prior to calling this, the producer should've + * obtained a message buffer from one of the rings. + * + * @param mq message queue + * @param msg message to be enqueued + */ +void svm_msg_q_add_raw (svm_msg_q_t *mq, svm_msg_q_msg_t *msg); + +/** + * Producer enqueue one message to queue + * * Prior to calling this, the producer should've obtained a message buffer * from one of the rings by calling @ref svm_msg_q_alloc_msg. * @@ -328,6 +339,12 @@ svm_msg_q_ring_is_full (svm_msg_q_t * mq, u32 ring_index) return (clib_atomic_load_relax_n (&ring->shr->cursize) >= ring->nitems); } +static inline u8 +svm_msg_q_or_ring_is_full (svm_msg_q_t *mq, u32 ring_index) +{ + return (svm_msg_q_is_full (mq) || svm_msg_q_ring_is_full (mq, ring_index)); +} + /** * Check if message queue is empty */ @@ -418,6 +435,14 @@ int svm_msg_q_wait (svm_msg_q_t *mq, svm_msg_q_wait_type_t type); int svm_msg_q_wait_prod (svm_msg_q_t *mq); /** + * Wait for message queue or ring event as producer + * + * Similar to @ref svm_msg_q_wait but lock (mutex or spinlock) must + * be held. Should only be called by producers. + */ +int svm_msg_q_or_ring_wait_prod (svm_msg_q_t *mq, u32 ring_index); + +/** * Timed wait for message queue event * * Must be called with mutex held. diff --git a/src/svm/queue.c b/src/svm/queue.c index 864d97e3de4..78444d8ede4 100644 --- a/src/svm/queue.c +++ b/src/svm/queue.c @@ -323,14 +323,14 @@ svm_queue_add2 (svm_queue_t * q, u8 * elem, u8 * elem2, int nowait) else svm_queue_lock (q); - if (PREDICT_FALSE (q->cursize + 1 == q->maxsize)) + if (PREDICT_FALSE (q->cursize + 1 >= q->maxsize)) { if (nowait) { svm_queue_unlock (q); return (-2); } - while (q->cursize + 1 == q->maxsize) + while (q->cursize + 1 >= q->maxsize) svm_queue_wait_inline (q); } diff --git a/src/svm/ssvm.c b/src/svm/ssvm.c index f93f40d0526..bf0a1361e4a 100644 --- a/src/svm/ssvm.c +++ b/src/svm/ssvm.c @@ -95,7 +95,7 @@ ssvm_server_init_shm (ssvm_private_t * ssvm) close (ssvm_fd); - CLIB_MEM_UNPOISON (sh, sizeof (*sh)); + clib_mem_unpoison (sh, sizeof (*sh)); sh->server_pid = ssvm->my_pid; sh->ssvm_size = ssvm->ssvm_size; sh->ssvm_va = pointer_to_uword (sh); @@ -183,6 +183,7 @@ re_map_it: return SSVM_API_ERROR_MMAP; } sh->client_pid = getpid (); + close (ssvm_fd); return 0; } @@ -226,8 +227,12 @@ ssvm_server_init_memfd (ssvm_private_t * memfd) ASSERT (vec_c_string_is_terminated (memfd->name)); - memfd->fd = clib_mem_vm_create_fd (CLIB_MEM_PAGE_SZ_DEFAULT, - (char *) memfd->name); + if (memfd->huge_page) + memfd->fd = clib_mem_vm_create_fd (CLIB_MEM_PAGE_SZ_DEFAULT_HUGE, + (char *) memfd->name); + else + memfd->fd = + clib_mem_vm_create_fd (CLIB_MEM_PAGE_SZ_DEFAULT, (char *) memfd->name); if (memfd->fd == CLIB_MEM_ERROR) { @@ -269,7 +274,7 @@ ssvm_server_init_memfd (ssvm_private_t * memfd) sh->ssvm_va = pointer_to_uword (sh); sh->type = SSVM_SEGMENT_MEMFD; - page_size = 1ULL << log2_page_size; + page_size = clib_mem_get_page_size (); sh->heap = clib_mem_create_heap (((u8 *) sh) + page_size, memfd->ssvm_size - page_size, 1 /* locked */ , "ssvm server memfd"); diff --git a/src/svm/ssvm.h b/src/svm/ssvm.h index 9bd16a9b462..ef982a1b304 100644 --- a/src/svm/ssvm.h +++ b/src/svm/ssvm.h @@ -87,7 +87,7 @@ typedef struct u8 *name; u8 numa; /**< UNUSED: numa requested at alloc time */ int is_server; - + int huge_page; union { int fd; /**< memfd segments */ diff --git a/src/svm/svm.c b/src/svm/svm.c index b844e20b4cc..d32c0a5d4db 100644 --- a/src/svm/svm.c +++ b/src/svm/svm.c @@ -327,7 +327,7 @@ svm_data_region_create (svm_map_region_args_t * a, svm_region_t * rp) return -3; } close (fd); - CLIB_MEM_UNPOISON (rp->data_base, map_size); + clib_mem_unpoison (rp->data_base, map_size); rp->backing_file = (char *) format (0, "%s%c", a->backing_file, 0); rp->flags |= SVM_FLAGS_FILE; } @@ -412,7 +412,7 @@ svm_data_region_map (svm_map_region_args_t * a, svm_region_t * rp) return -3; } close (fd); - CLIB_MEM_UNPOISON (rp->data_base, map_size); + clib_mem_unpoison (rp->data_base, map_size); } return 0; } @@ -551,7 +551,6 @@ svm_map_region (svm_map_region_args_t * a) int svm_fd; svm_region_t *rp; int deadman = 0; - u8 junk = 0; void *oldheap; int rv; int pid_holding_region_lock; @@ -582,6 +581,15 @@ svm_map_region (svm_map_region_args_t * a) vec_free (shm_name); +#ifdef __FreeBSD__ + if (ftruncate (svm_fd, a->size) < 0) + { + clib_warning ("ftruncate region size"); + close (svm_fd); + return (0); + } +#else + u8 junk = 0; if (lseek (svm_fd, a->size, SEEK_SET) == (off_t) - 1) { clib_warning ("seek region size"); @@ -594,6 +602,7 @@ svm_map_region (svm_map_region_args_t * a) close (svm_fd); return (0); } +#endif /* __FreeBSD__ */ rp = mmap (uword_to_pointer (a->baseva, void *), a->size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, svm_fd, 0); @@ -605,7 +614,7 @@ svm_map_region (svm_map_region_args_t * a) return (0); } close (svm_fd); - CLIB_MEM_UNPOISON (rp, a->size); + clib_mem_unpoison (rp, a->size); svm_region_init_mapped_region (a, rp); @@ -663,7 +672,7 @@ svm_map_region (svm_map_region_args_t * a) return (0); } - CLIB_MEM_UNPOISON (rp, MMAP_PAGESIZE); + clib_mem_unpoison (rp, MMAP_PAGESIZE); /* * We lost the footrace to create this region; make sure @@ -701,7 +710,7 @@ svm_map_region (svm_map_region_args_t * a) close (svm_fd); - CLIB_MEM_UNPOISON (rp, a->size); + clib_mem_unpoison (rp, a->size); if ((uword) rp != rp->virtual_base) { @@ -1051,7 +1060,7 @@ svm_region_unmap_internal (void *rp_arg, u8 is_client) oldheap = svm_push_pvt_heap (rp); /* nb vec_delete() in the loop */ /* Remove the caller from the list of mappers */ - CLIB_MEM_UNPOISON (rp->client_pids, vec_bytes (rp->client_pids)); + clib_mem_unpoison (rp->client_pids, vec_bytes (rp->client_pids)); for (i = 0; i < vec_len (rp->client_pids); i++) { if (rp->client_pids[i] == mypid) @@ -1184,7 +1193,7 @@ svm_region_exit_internal (u8 is_client) virtual_base = root_rp->virtual_base; virtual_size = root_rp->virtual_size; - CLIB_MEM_UNPOISON (root_rp->client_pids, vec_bytes (root_rp->client_pids)); + clib_mem_unpoison (root_rp->client_pids, vec_bytes (root_rp->client_pids)); for (i = 0; i < vec_len (root_rp->client_pids); i++) { if (root_rp->client_pids[i] == mypid) @@ -1291,12 +1300,10 @@ svm_client_scan (const char *root_path) * Snapshoot names, can't hold root rp mutex across * find_or_create. */ - /* *INDENT-OFF* */ pool_foreach (subp, mp->subregions) { name = vec_dup (subp->subregion_name); vec_add1(svm_names, name); } - /* *INDENT-ON* */ pthread_mutex_unlock (&root_rp->mutex); diff --git a/src/svm/svm.h b/src/svm/svm.h index 8bf561e9a81..cdc9d90cab0 100644 --- a/src/svm/svm.h +++ b/src/svm/svm.h @@ -43,23 +43,6 @@ svm_mem_alloc (svm_region_t * rp, uword size) return (rv); } -static inline void * -svm_mem_alloc_aligned_at_offset (svm_region_t * rp, - uword size, uword align, uword offset) -{ - clib_mem_heap_t *oldheap; - ASSERT (rp->flags & SVM_FLAGS_MHEAP); - u8 *rv; - - pthread_mutex_lock (&rp->mutex); - oldheap = clib_mem_set_heap (rp->data_heap); - rv = clib_mem_alloc_aligned_at_offset (size, align, offset, - 1 /* yes, call os_out_of_memory */ ); - clib_mem_set_heap (oldheap); - pthread_mutex_unlock (&rp->mutex); - return (rv); -} - static inline void svm_mem_free (svm_region_t * rp, void *ptr) { diff --git a/src/svm/svm_common.h b/src/svm/svm_common.h index 1f1132afdc2..0e19ffd3f76 100644 --- a/src/svm/svm_common.h +++ b/src/svm/svm_common.h @@ -19,8 +19,14 @@ #define __included_svm_common_h__ #include <stdarg.h> +#ifdef __FreeBSD__ +#include <stdint.h> +#endif /* __FreeBSD__ */ #include <pthread.h> +#ifdef __linux__ #include <sys/user.h> +#endif /* __linux__ */ +#include <vppinfra/clib.h> #include <vppinfra/types.h> #define SVM_VERSION ((1<<16) | 1) /* set to declare region ready. */ diff --git a/src/svm/svm_fifo.c b/src/svm/svm_fifo.c index 2150694ef46..49b3d1728f3 100644 --- a/src/svm/svm_fifo.c +++ b/src/svm/svm_fifo.c @@ -72,8 +72,8 @@ CLIB_MARCH_FN (svm_fifo_copy_from_chunk, void, svm_fifo_t *f, c = f_cptr (f, c->next); while ((to_copy -= n_chunk)) { - CLIB_MEM_UNPOISON (c, sizeof (*c)); - CLIB_MEM_UNPOISON (c->data, c->length); + clib_mem_unpoison (c, sizeof (*c)); + clib_mem_unpoison (c->data, c->length); n_chunk = clib_min (c->length, to_copy); clib_memcpy_fast (dst + (len - to_copy), &c->data[0], n_chunk); c = c->length <= to_copy ? f_cptr (f, c->next) : c; @@ -1010,25 +1010,26 @@ svm_fifo_enqueue_segments (svm_fifo_t * f, const svm_fifo_seg_t segs[], } else { - len = clib_min (free_count, len); + u32 n_left = clib_min (free_count, len); - if (f_pos_gt (tail + len, f_chunk_end (f_end_cptr (f)))) + if (f_pos_gt (tail + n_left, f_chunk_end (f_end_cptr (f)))) { - if (PREDICT_FALSE (f_try_chunk_alloc (f, head, tail, len))) + if (PREDICT_FALSE (f_try_chunk_alloc (f, head, tail, n_left))) { - len = f_chunk_end (f_end_cptr (f)) - tail; - if (!len) + n_left = f_chunk_end (f_end_cptr (f)) - tail; + if (!n_left) return SVM_FIFO_EGROW; } } + len = n_left; i = 0; - while (len) + while (n_left) { - u32 to_copy = clib_min (segs[i].len, len); + u32 to_copy = clib_min (segs[i].len, n_left); svm_fifo_copy_to_chunk (f, f_tail_cptr (f), tail, segs[i].data, to_copy, &f->shr->tail_chunk); - len -= to_copy; + n_left -= to_copy; tail += to_copy; i++; } @@ -1154,7 +1155,7 @@ svm_fifo_peek (svm_fifo_t * f, u32 offset, u32 len, u8 * dst) len = clib_min (cursize - offset, len); head_idx = head + offset; - CLIB_MEM_UNPOISON (f->ooo_deq, sizeof (*f->ooo_deq)); + clib_mem_unpoison (f->ooo_deq, sizeof (*f->ooo_deq)); if (!f->ooo_deq || !f_chunk_includes_pos (f->ooo_deq, head_idx)) f_update_ooo_deq (f, head_idx, head_idx + len); @@ -1280,8 +1281,8 @@ svm_fifo_provision_chunks (svm_fifo_t *f, svm_fifo_seg_t *fs, u32 n_segs, } int -svm_fifo_segments (svm_fifo_t * f, u32 offset, svm_fifo_seg_t * fs, - u32 n_segs, u32 max_bytes) +svm_fifo_segments (svm_fifo_t *f, u32 offset, svm_fifo_seg_t *fs, u32 *n_segs, + u32 max_bytes) { u32 cursize, to_read, head, tail, fs_index = 1; u32 n_bytes, head_pos, len, start; @@ -1314,7 +1315,7 @@ svm_fifo_segments (svm_fifo_t * f, u32 offset, svm_fifo_seg_t * fs, fs[0].len = clib_min (c->length - head_pos, to_read); n_bytes = fs[0].len; - while (n_bytes < to_read && fs_index < n_segs) + while (n_bytes < to_read && fs_index < *n_segs) { c = f_cptr (f, c->next); len = clib_min (c->length, to_read - n_bytes); @@ -1323,6 +1324,7 @@ svm_fifo_segments (svm_fifo_t * f, u32 offset, svm_fifo_seg_t * fs, n_bytes += len; fs_index += 1; } + *n_segs = fs_index; return n_bytes; } diff --git a/src/svm/svm_fifo.h b/src/svm/svm_fifo.h index 560628d2d07..7ea114f8702 100644 --- a/src/svm/svm_fifo.h +++ b/src/svm/svm_fifo.h @@ -34,7 +34,7 @@ typedef enum svm_fifo_deq_ntf_ SVM_FIFO_NO_DEQ_NOTIF = 0, /**< No notification requested */ SVM_FIFO_WANT_DEQ_NOTIF = 1, /**< Notify on dequeue */ SVM_FIFO_WANT_DEQ_NOTIF_IF_FULL = 2, /**< Notify on transition from full */ - SVM_FIFO_WANT_DEQ_NOTIF_IF_EMPTY = 4, /**< Notify on transition to empty */ + SVM_FIFO_WANT_DEQ_NOTIF_IF_EMPTY = 4, /**< Notify on transition to empty */ } svm_fifo_deq_ntf_t; typedef enum svm_fifo_flag_ @@ -431,8 +431,8 @@ void svm_fifo_dequeue_drop_all (svm_fifo_t * f); * @param max_bytes max bytes to be mapped to fifo segments * @return number of bytes in fifo segments or SVM_FIFO_EEMPTY */ -int svm_fifo_segments (svm_fifo_t * f, u32 offset, svm_fifo_seg_t * fs, - u32 n_segs, u32 max_bytes); +int svm_fifo_segments (svm_fifo_t *f, u32 offset, svm_fifo_seg_t *fs, + u32 *n_segs, u32 max_bytes); /** * Add io events subscriber to list * @@ -640,63 +640,6 @@ u32 svm_fifo_max_read_chunk (svm_fifo_t * f); u32 svm_fifo_max_write_chunk (svm_fifo_t * f); /** - * Fifo head chunk getter - * - * @param f fifo - * @return head chunk pointer - */ -static inline svm_fifo_chunk_t * -svm_fifo_head_chunk (svm_fifo_t * f) -{ - return f_head_cptr (f); -} - -/** - * Fifo head pointer getter - * - * @param f fifo - * @return head pointer - */ -static inline u8 * -svm_fifo_head (svm_fifo_t * f) -{ - svm_fifo_chunk_t *head_chunk; - if (!f->shr->head_chunk) - return 0; - /* load-relaxed: consumer owned index */ - head_chunk = f_head_cptr (f); - return (head_chunk->data + (f->shr->head - head_chunk->start_byte)); -} - -/** - * Fifo tail chunk getter - * - * @param f fifo - * @return tail chunk pointer - */ -static inline svm_fifo_chunk_t * -svm_fifo_tail_chunk (svm_fifo_t * f) -{ - return f_tail_cptr (f); -} - -/** - * Fifo tail pointer getter - * - * @param f fifo - * @return tail pointer - */ -static inline u8 * -svm_fifo_tail (svm_fifo_t * f) -{ - svm_fifo_chunk_t *tail_chunk; - - /* load-relaxed: producer owned index */ - tail_chunk = f_tail_cptr (f); - return (tail_chunk->data + (f->shr->tail - tail_chunk->start_byte)); -} - -/** * Fifo number of subscribers getter * * @param f fifo @@ -816,7 +759,7 @@ svm_fifo_unset_event (svm_fifo_t * f) static inline void svm_fifo_add_want_deq_ntf (svm_fifo_t * f, u8 ntf_type) { - f->shr->want_deq_ntf |= ntf_type; + __atomic_or_fetch (&f->shr->want_deq_ntf, ntf_type, __ATOMIC_RELEASE); } /** @@ -830,7 +773,21 @@ svm_fifo_add_want_deq_ntf (svm_fifo_t * f, u8 ntf_type) static inline void svm_fifo_del_want_deq_ntf (svm_fifo_t * f, u8 ntf_type) { - f->shr->want_deq_ntf &= ~ntf_type; + __atomic_and_fetch (&f->shr->want_deq_ntf, ~ntf_type, __ATOMIC_RELEASE); +} + +/** + * Get want notification flag + * + * Done atomically with acquire memory ordering + * + * @param f fifo + * @return value of want_deq_ntf flag + */ +static inline u32 +svm_fifo_get_want_deq_ntf (svm_fifo_t *f) +{ + return clib_atomic_load_acq_n (&f->shr->want_deq_ntf); } /** @@ -847,10 +804,27 @@ svm_fifo_del_want_deq_ntf (svm_fifo_t * f, u8 ntf_type) static inline void svm_fifo_clear_deq_ntf (svm_fifo_t * f) { - /* Set the flag if want_notif_if_full was the only ntf requested */ - f->shr->has_deq_ntf = - f->shr->want_deq_ntf == SVM_FIFO_WANT_DEQ_NOTIF_IF_FULL; - svm_fifo_del_want_deq_ntf (f, SVM_FIFO_WANT_DEQ_NOTIF); + u32 want_deq_ntf = svm_fifo_get_want_deq_ntf (f); + /* Set the flag if want ntf if full or empty was requested */ + if (want_deq_ntf & + (SVM_FIFO_WANT_DEQ_NOTIF_IF_FULL | SVM_FIFO_WANT_DEQ_NOTIF_IF_EMPTY)) + clib_atomic_store_rel_n (&f->shr->has_deq_ntf, 1); + if (want_deq_ntf & SVM_FIFO_WANT_DEQ_NOTIF) + svm_fifo_del_want_deq_ntf (f, SVM_FIFO_WANT_DEQ_NOTIF); +} + +/** + * Get has dequeue notification flag + * + * Done atomically with acquire memory ordering + * + * @param f fifo + * @return has_deq_ntf flag + */ +static inline u32 +svm_fifo_has_deq_ntf (svm_fifo_t *f) +{ + return clib_atomic_load_acq_n (&f->shr->has_deq_ntf); } /** @@ -881,28 +855,40 @@ svm_fifo_reset_has_deq_ntf (svm_fifo_t * f) static inline u8 svm_fifo_needs_deq_ntf (svm_fifo_t * f, u32 n_last_deq) { - u8 want_ntf = f->shr->want_deq_ntf; + u32 want_ntf = svm_fifo_get_want_deq_ntf (f); - if (PREDICT_TRUE (want_ntf == SVM_FIFO_NO_DEQ_NOTIF)) + if (want_ntf == SVM_FIFO_NO_DEQ_NOTIF) return 0; else if (want_ntf & SVM_FIFO_WANT_DEQ_NOTIF) - return 1; + return (svm_fifo_max_enqueue (f) >= f->shr->deq_thresh); if (want_ntf & SVM_FIFO_WANT_DEQ_NOTIF_IF_FULL) { u32 max_deq = svm_fifo_max_dequeue_cons (f); u32 size = f->shr->size; - if (!f->shr->has_deq_ntf && max_deq < size && - max_deq + n_last_deq >= size) + if (max_deq < size && max_deq + n_last_deq >= size && + !svm_fifo_has_deq_ntf (f)) return 1; } if (want_ntf & SVM_FIFO_WANT_DEQ_NOTIF_IF_EMPTY) { - if (!f->shr->has_deq_ntf && svm_fifo_is_empty (f)) + if (!svm_fifo_has_deq_ntf (f) && svm_fifo_is_empty (f)) return 1; } return 0; } +/** + * Set the fifo dequeue threshold which will be used for notifications. + * + * Note: If not set, by default threshold is zero, equivalent to + * generating notification on each dequeue event. + */ +static inline void +svm_fifo_set_deq_thresh (svm_fifo_t *f, u32 thresh) +{ + f->shr->deq_thresh = thresh; +} + #endif /* __included_ssvm_fifo_h__ */ /* diff --git a/src/svm/svmdb.c b/src/svm/svmdb.c index 2c3d351f0c7..3c69dbf45ba 100644 --- a/src/svm/svmdb.c +++ b/src/svm/svmdb.c @@ -281,7 +281,7 @@ local_unset_variable_nolock (svmdb_client_t * client, if (vec_len (oldvalue->notifications)) notify_value (oldvalue, SVMDB_ACTION_UNSET); /* zero length value means unset */ - _vec_len (oldvalue->value) = 0; + vec_set_len (oldvalue->value, 0); } client->shm->namespaces[namespace] = h; } @@ -317,7 +317,7 @@ local_set_variable_nolock (svmdb_client_t * client, oldvalue = pool_elt_at_index (client->shm->values, hp->value[0]); vec_alloc (oldvalue->value, vec_len (val) * elsize); clib_memcpy (oldvalue->value, val, vec_len (val) * elsize); - _vec_len (oldvalue->value) = vec_len (val); + vec_set_len (oldvalue->value, vec_len (val)); notify_value (oldvalue, SVMDB_ACTION_SET); } else @@ -328,7 +328,7 @@ local_set_variable_nolock (svmdb_client_t * client, newvalue->elsize = elsize; vec_alloc (newvalue->value, vec_len (val) * elsize); clib_memcpy (newvalue->value, val, vec_len (val) * elsize); - _vec_len (newvalue->value) = vec_len (val); + vec_set_len (newvalue->value, vec_len (val)); name = format (0, "%s%c", var, 0); hash_set_mem (h, name, newvalue - shm->values); } @@ -414,7 +414,6 @@ svmdb_local_dump_strings (svmdb_client_t * client) h = client->shm->namespaces[SVMDB_NAMESPACE_STRING]; - /* *INDENT-OFF* */ hash_foreach_mem(key, value, h, ({ svmdb_value_t *v = pool_elt_at_index (shm->values, value); @@ -422,7 +421,6 @@ svmdb_local_dump_strings (svmdb_client_t * client) fformat(stdout, "%s: %s\n", key, vec_len(v->value) ? v->value : (u8 *)"(nil)"); })); - /* *INDENT-ON* */ region_unlock (client->db_rp); } @@ -433,7 +431,7 @@ svmdb_local_serialize_strings (svmdb_client_t * client, char *filename) u8 *key; u32 value; svmdb_shm_hdr_t *shm = client->shm; - serialize_main_t _sm, *sm = &_sm; + serialize_main_t _sm = { 0 }, *sm = &_sm; clib_error_t *error = 0; u8 *sanitized_name = 0; int fd = 0; @@ -463,7 +461,6 @@ svmdb_local_serialize_strings (svmdb_client_t * client, char *filename) serialize_likely_small_unsigned_integer (sm, hash_elts (h)); - /* *INDENT-OFF* */ hash_foreach_mem(key, value, h, ({ svmdb_value_t *v = pool_elt_at_index (shm->values, value); @@ -475,7 +472,6 @@ svmdb_local_serialize_strings (svmdb_client_t * client, char *filename) serialize_cstring (sm, (char *)v->value); } })); - /* *INDENT-ON* */ region_unlock (client->db_rp); serialize_close (sm); @@ -495,7 +491,7 @@ out: int svmdb_local_unserialize_strings (svmdb_client_t * client, char *filename) { - serialize_main_t _sm, *sm = &_sm; + serialize_main_t _sm = { 0 }, *sm = &_sm; void *oldheap; clib_error_t *error = 0; u8 *key, *value; @@ -589,7 +585,7 @@ svmdb_local_get_vec_variable (svmdb_client_t * client, char *var, u32 elsize) /* Make a copy in process-local memory */ vec_alloc (copy, vec_len (rv) * elsize); clib_memcpy (copy, rv, vec_len (rv) * elsize); - _vec_len (copy) = vec_len (rv); + vec_set_len (copy, vec_len (rv)); region_unlock (client->db_rp); return (copy); } @@ -610,7 +606,6 @@ svmdb_local_dump_vecs (svmdb_client_t * client) h = client->shm->namespaces[SVMDB_NAMESPACE_VEC]; - /* *INDENT-OFF* */ hash_foreach_mem(key, value, h, ({ svmdb_value_t *v = pool_elt_at_index (shm->values, value); @@ -618,7 +613,6 @@ svmdb_local_dump_vecs (svmdb_client_t * client) format_hex_bytes, v->value, vec_len(v->value)*v->elsize, ((f64 *)(v->value))[0]); })); - /* *INDENT-ON* */ region_unlock (client->db_rp); } @@ -653,7 +647,7 @@ svmdb_local_find_or_add_vec_variable (svmdb_client_t * client, clib_memset (newvalue, 0, sizeof (*newvalue)); newvalue->elsize = 1; vec_alloc (newvalue->value, nbytes); - _vec_len (newvalue->value) = nbytes; + vec_set_len (newvalue->value, nbytes); name = format (0, "%s%c", var, 0); hash_set_mem (h, name, newvalue - shm->values); shm->namespaces[SVMDB_NAMESPACE_VEC] = h; diff --git a/src/svm/svmdbtool.c b/src/svm/svmdbtool.c index feb7eed07ef..b60b86db29d 100644 --- a/src/svm/svmdbtool.c +++ b/src/svm/svmdbtool.c @@ -248,11 +248,16 @@ static void sigaction_handler (int signum, siginfo_t * i, void *notused) { u32 action, opaque; +#ifdef __linux__ action = (u32) (uword) i->si_ptr; action >>= 28; opaque = (u32) (uword) i->si_ptr; opaque &= ~(0xF0000000); +#elif __FreeBSD__ + action = i->si_code; + opaque = 0; +#endif /* __linux__ */ clib_warning ("signal %d, action %d, opaque %x", signum, action, opaque); } diff --git a/src/svm/svmtool.c b/src/svm/svmtool.c index 60859674298..521ddab7eb3 100644 --- a/src/svm/svmtool.c +++ b/src/svm/svmtool.c @@ -72,12 +72,10 @@ format_all_svm_regions (u8 * s, va_list * args) * Snapshoot names, can't hold root rp mutex across * find_or_create. */ - /* *INDENT-OFF* */ pool_foreach (subp, mp->subregions) { name = vec_dup (subp->subregion_name); vec_add1(svm_names, name); } - /* *INDENT-ON* */ pthread_mutex_unlock (&root_rp->mutex); @@ -328,12 +326,10 @@ subregion_repair (char *chroot_path) * Snapshoot names, can't hold root rp mutex across * find_or_create. */ - /* *INDENT-OFF* */ pool_foreach (subp, mp->subregions) { name = vec_dup (subp->subregion_name); vec_add1(svm_names, name); } - /* *INDENT-ON* */ pthread_mutex_unlock (&root_rp->mutex); |