Add jumbo frames support to non-dpdk vhost interfaces.
[vpp.git] / vlib / vlib / dpdk_buffer.c
index dbbd580..145720d 100644 (file)
@@ -401,11 +401,13 @@ del_free_list (vlib_main_t * vm, vlib_buffer_free_list_t * f)
   for (i = 0; i < vec_len (f->unaligned_buffers); i++) {
       b = vlib_get_buffer (vm, f->unaligned_buffers[i]);
       mb = ((struct rte_mbuf *)b)-1;
+      ASSERT(rte_mbuf_refcnt_read(mb) == 1);
       rte_pktmbuf_free (mb);
   }
   for (i = 0; i < vec_len (f->aligned_buffers); i++) {
       b = vlib_get_buffer (vm, f->aligned_buffers[i]);
       mb = ((struct rte_mbuf *)b)-1;
+      ASSERT(rte_mbuf_refcnt_read(mb) == 1);
       rte_pktmbuf_free (mb);
   }
   vec_free (f->name);
@@ -446,7 +448,7 @@ fill_free_list (vlib_main_t * vm,
   vlib_buffer_t * b;
   int n, i;
   u32 bi;
-  u32 n_remaining, n_alloc;
+  u32 n_remaining = 0, n_alloc = 0;
   unsigned socket_id = rte_socket_id ? rte_socket_id() : 0;
   struct rte_mempool *rmp = vm->buffer_main->pktmbuf_pools[socket_id];
   struct rte_mbuf *mb;
@@ -722,9 +724,13 @@ vlib_buffer_free_inline (vlib_main_t * vm,
         }
       else
         {
-          mb = ((struct rte_mbuf *)b)-1;
-          rte_pktmbuf_free (mb);
-        }
+         if (PREDICT_TRUE (b->clone_count == 0))
+           {
+             mb = ((struct rte_mbuf *)b)-1;
+             ASSERT(rte_mbuf_refcnt_read(mb) == 1);
+             rte_pktmbuf_free (mb);
+           }
+       }
     }
   if (vec_len(bm->announce_list))
     {
@@ -876,6 +882,34 @@ u32 vlib_buffer_add_data (vlib_main_t * vm,
   return bi;
 }
 
+u16
+vlib_buffer_chain_append_data_with_alloc(vlib_main_t *vm,
+                             u32 free_list_index,
+                             vlib_buffer_t *first,
+                             vlib_buffer_t **last,
+                             void * data, u16 data_len) {
+  vlib_buffer_t *l = *last;
+  u32 n_buffer_bytes = vlib_buffer_free_list_buffer_size (vm, free_list_index);
+  u16 copied = 0;
+  ASSERT(n_buffer_bytes >= l->current_length + l->current_data);
+  while (data_len) {
+    u16 max = n_buffer_bytes - l->current_length - l->current_data;
+    if (max == 0) {
+      if (1 != vlib_buffer_alloc_from_free_list (vm, &l->next_buffer, 1, free_list_index))
+        return copied;
+      *last = l = vlib_buffer_chain_buffer(vm, first, l, l->next_buffer);
+      max = n_buffer_bytes - l->current_length - l->current_data;
+    }
+
+    u16 len = (data_len > max)?max:data_len;
+    rte_memcpy(vlib_buffer_get_current (l) + l->current_length, data + copied, len);
+    vlib_buffer_chain_increase_length(first, l, len);
+    data_len -= len;
+    copied += len;
+  }
+  return copied;
+}
+
 clib_error_t *
 vlib_buffer_pool_create(vlib_main_t * vm, unsigned num_mbufs,
                         unsigned mbuf_size, unsigned socket_id)