aboutsummaryrefslogtreecommitdiffstats
path: root/src/svm
diff options
context:
space:
mode:
Diffstat (limited to 'src/svm')
-rw-r--r--src/svm/fifo_segment.c36
-rw-r--r--src/svm/fifo_segment.h4
-rw-r--r--src/svm/fifo_types.h1
-rw-r--r--src/svm/message_queue.c47
-rw-r--r--src/svm/message_queue.h25
-rw-r--r--src/svm/queue.c4
-rw-r--r--src/svm/ssvm.c13
-rw-r--r--src/svm/ssvm.h2
-rw-r--r--src/svm/svm.c27
-rw-r--r--src/svm/svm.h17
-rw-r--r--src/svm/svm_common.h6
-rw-r--r--src/svm/svm_fifo.c30
-rw-r--r--src/svm/svm_fifo.h130
-rw-r--r--src/svm/svmdb.c20
-rw-r--r--src/svm/svmdbtool.c5
-rw-r--r--src/svm/svmtool.c4
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);