vcl svm: segments improvements 80/29380/6
authorFlorin Coras <fcoras@cisco.com>
Sun, 11 Oct 2020 18:05:04 +0000 (11:05 -0700)
committerDave Barach <openvpp@barachs.net>
Mon, 12 Oct 2020 15:03:01 +0000 (15:03 +0000)
Type: improvement

Signed-off-by: Florin Coras <fcoras@cisco.com>
Change-Id: I717c64666972bb4e440cb3d1180a5cb26ee25577

src/svm/svm_fifo.c
src/svm/svm_fifo.h
src/vcl/vcl_private.h
src/vcl/vppcom.c

index 2cce2bf..22cb64e 100644 (file)
@@ -1136,10 +1136,11 @@ svm_fifo_fill_chunk_list (svm_fifo_t * f)
 }
 
 int
-svm_fifo_segments (svm_fifo_t * f, 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, n_bytes, head_pos, len;
+  u32 cursize, to_read, head, tail, fs_index = 1;
+  u32 n_bytes, head_pos, len, start;
   svm_fifo_chunk_t *c;
 
   f_load_head_tail_cons (f, &head, &tail);
@@ -1150,22 +1151,32 @@ svm_fifo_segments (svm_fifo_t * f, svm_fifo_seg_t * fs, u32 n_segs,
   if (PREDICT_FALSE (cursize == 0))
     return SVM_FIFO_EEMPTY;
 
-  to_read = clib_min (cursize, max_bytes);
+  if (offset >= cursize)
+    return SVM_FIFO_EEMPTY;
+
+  to_read = clib_min (cursize - offset, max_bytes);
+  start = head + offset;
+
+  if (!f->head_chunk)
+    f->head_chunk = svm_fifo_find_chunk (f, head);
 
   c = f->head_chunk;
-  head_pos = head - c->start_byte;
+
+  while (!f_chunk_includes_pos (c, start))
+    c = c->next;
+
+  head_pos = start - c->start_byte;
   fs[0].data = c->data + head_pos;
-  fs[0].len = c->length - head_pos;
+  fs[0].len = clib_min (c->length - head_pos, cursize - offset);
   n_bytes = fs[0].len;
-  c = c->next;
 
   while (n_bytes < to_read && fs_index < n_segs)
     {
+      c = c->next;
       len = clib_min (c->length, to_read - n_bytes);
       fs[fs_index].data = c->data;
       fs[fs_index].len = len;
       n_bytes += len;
-      c = c->next;
       fs_index += 1;
     }
 
index 93ef006..408d99a 100644 (file)
@@ -357,13 +357,14 @@ void svm_fifo_dequeue_drop_all (svm_fifo_t * f);
  * data is consumed.
  *
  * @param f            fifo
+ * @param offset       offset from where to retrieve segments
  * @param fs           array of fifo segments allocated by caller
  * @param n_segs       number of fifo segments in array
  * @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, 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
  *
index 51bdd65..89151fa 100644 (file)
@@ -184,6 +184,8 @@ typedef struct
   int libc_epfd;
   svm_msg_q_t *our_evt_q;
   vcl_session_msg_t *accept_evts_fifo;
+  /** bytes delivered as segment but not yet freed */
+  u32 rx_bytes_pending;
 #if VCL_ELOG
   elog_track_t elog_track;
 #endif
index 56f50ad..f1bb2b0 100644 (file)
@@ -1983,8 +1983,26 @@ vppcom_session_read_segments (uint32_t session_handle,
        }
     }
 
-  n_read = svm_fifo_segments (rx_fifo, (svm_fifo_seg_t *) ds, n_segments,
-                             max_bytes);
+  n_read = svm_fifo_segments (rx_fifo, s->rx_bytes_pending,
+                             (svm_fifo_seg_t *) ds, n_segments, max_bytes);
+  if (n_read < 0)
+    return VPPCOM_EAGAIN;
+
+  if (svm_fifo_max_dequeue_cons (rx_fifo) == n_read)
+    {
+      svm_fifo_unset_event (s->rx_fifo);
+      if (svm_fifo_max_dequeue_cons (rx_fifo) != n_read
+         && svm_fifo_set_event (s->rx_fifo)
+         && VCL_SESS_ATTR_TEST (s->attr, VCL_SESS_ATTR_NONBLOCK))
+       {
+         session_event_t *e;
+         vec_add2 (wrk->unhandled_evts_vector, e, 1);
+         e->event_type = SESSION_IO_EVT_RX;
+         e->session_index = s->session_index;
+       }
+    }
+
+  s->rx_bytes_pending += n_read;
   return n_read;
 }
 
@@ -1999,19 +2017,9 @@ vppcom_session_free_segments (uint32_t session_handle, uint32_t n_bytes)
     return;
 
   svm_fifo_dequeue_drop (s->rx_fifo, n_bytes);
-  if (svm_fifo_is_empty_cons (s->rx_fifo))
-    {
-      svm_fifo_unset_event (s->rx_fifo);
-      if (!svm_fifo_is_empty_cons (s->rx_fifo)
-         && svm_fifo_set_event (s->rx_fifo)
-         && VCL_SESS_ATTR_TEST (s->attr, VCL_SESS_ATTR_NONBLOCK))
-       {
-         session_event_t *e;
-         vec_add2 (wrk->unhandled_evts_vector, e, 1);
-         e->event_type = SESSION_IO_EVT_RX;
-         e->session_index = s->session_index;
-       }
-    }
+
+  ASSERT (s->rx_bytes_pending < n_bytes);
+  s->rx_bytes_pending -= n_bytes;
 }
 
 static u8