rdma: use per-thread buffer template
[vpp.git] / src / plugins / rdma / device.c
index 532f4f5..29d9842 100644 (file)
@@ -324,7 +324,7 @@ rdma_async_event_init (rdma_device_t * rd)
   t.file_descriptor = rd->ctx->async_fd;
   t.error_function = rdma_async_event_error_ready;
   t.private_data = rd->dev_instance;
-  t.description = format (0, "%s async event", rd->name);
+  t.description = format (0, "%v async event", rd->name);
 
   rd->async_event_clib_file_index = clib_file_add (&file_main, &t);
   return 0;
@@ -534,16 +534,21 @@ rdma_dev_init (vlib_main_t * vm, rdma_device_t * rd, u32 rxq_size,
 
   ethernet_mac_address_generate (rd->hwaddr.bytes);
 
+  /*
+   * /!\ WARNING /!\ creation order is important
+   * We *must* create TX queues *before* RX queues, otherwise we will receive
+   * the broacast packets we sent
+   */
+  for (i = 0; i < tm->n_vlib_mains; i++)
+    if ((err = rdma_txq_init (vm, rd, i, txq_size)))
+      return err;
+
   for (i = 0; i < rxq_num; i++)
     if ((err = rdma_rxq_init (vm, rd, i, rxq_size)))
       return err;
   if ((err = rdma_rxq_finalize (vm, rd)))
     return err;
 
-  for (i = 0; i < tm->n_vlib_mains; i++)
-    if ((err = rdma_txq_init (vm, rd, i, txq_size)))
-      return err;
-
   if ((rd->mr = ibv_reg_mr (rd->pd, (void *) bm->buffer_mem_start,
                            bm->buffer_mem_size,
                            IBV_ACCESS_LOCAL_WRITE)) == 0)
@@ -561,6 +566,9 @@ sysfs_path_to_pci_addr (char *path, vlib_pci_addr_t * addr)
   u8 *s;
 
   s = clib_sysfs_link_to_name (path);
+  if (!s)
+    return 0;
+
   unformat_init_string (&in, (char *) s, strlen ((char *) s));
   rv = unformat (&in, "%U", unformat_vlib_pci_addr, addr);
   unformat_free (&in);
@@ -581,8 +589,8 @@ rdma_create_if (vlib_main_t * vm, rdma_create_if_args_t * args)
   u16 qid;
   int i;
 
-  args->rxq_size = args->rxq_size ? args->rxq_size : 2 * VLIB_FRAME_SIZE;
-  args->txq_size = args->txq_size ? args->txq_size : 2 * VLIB_FRAME_SIZE;
+  args->rxq_size = args->rxq_size ? args->rxq_size : 1024;
+  args->txq_size = args->txq_size ? args->txq_size : 1024;
   args->rxq_num = args->rxq_num ? args->rxq_num : 1;
 
   if (!is_pow2 (args->rxq_num))
@@ -603,6 +611,19 @@ rdma_create_if (vlib_main_t * vm, rdma_create_if_args_t * args)
       goto err0;
     }
 
+  switch (args->mode)
+    {
+    case RDMA_MODE_AUTO:
+      break;
+    case RDMA_MODE_IBV:
+      break;
+    case RDMA_MODE_DV:
+      args->rv = VNET_API_ERROR_INVALID_VALUE;
+      args->error = clib_error_return (0, "unsupported mode");
+      goto err0;
+      break;
+    }
+
   dev_list = ibv_get_device_list (&n_devs);
   if (n_devs == 0)
     {
@@ -624,12 +645,21 @@ rdma_create_if (vlib_main_t * vm, rdma_create_if_args_t * args)
   pool_get_zero (rm->devices, rd);
   rd->dev_instance = rd - rm->devices;
   rd->per_interface_next_index = VNET_DEVICE_INPUT_NEXT_ETHERNET_INPUT;
-  rd->name = format (0, "%s", args->name);
   rd->linux_ifname = format (0, "%s", args->ifname);
 
+  if (!args->name || 0 == args->name[0])
+    rd->name = format (0, "%s/%d", args->ifname, rd->dev_instance);
+  else
+    rd->name = format (0, "%s", args->name);
+
   rd->pci = vlib_pci_get_device_info (vm, &pci_addr, &args->error);
   if (!rd->pci)
     goto err2;
+
+  /* if we failed to parse NUMA node, default to 0 */
+  if (-1 == rd->pci->numa_node)
+    rd->pci->numa_node = 0;
+
   rd->pool = vlib_buffer_pool_get_default_for_numa (vm, rd->pci->numa_node);
 
   if (strncmp ((char *) rd->pci->driver_name, "mlx5_core", 9))
@@ -736,15 +766,9 @@ rdma_set_interface_next_node (vnet_main_t * vnm, u32 hw_if_index,
   rdma_main_t *rm = &rdma_main;
   vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index);
   rdma_device_t *rd = pool_elt_at_index (rm->devices, hw->dev_instance);
-
-  /* Shut off redirection */
-  if (node_index == ~0)
-    {
-      rd->per_interface_next_index = node_index;
-      return;
-    }
-
   rd->per_interface_next_index =
+    ~0 ==
+    node_index ? VNET_DEVICE_INPUT_NEXT_ETHERNET_INPUT :
     vlib_node_add_next (vlib_get_main (), rdma_input_node.index, node_index);
 }
 
@@ -772,13 +796,32 @@ clib_error_t *
 rdma_init (vlib_main_t * vm)
 {
   rdma_main_t *rm = &rdma_main;
+  vlib_thread_main_t *tm = vlib_get_thread_main ();
 
   rm->log_class = vlib_log_register_class ("rdma", 0);
 
+  /* vlib_buffer_t template */
+  vec_validate_aligned (rm->per_thread_data, tm->n_vlib_mains - 1,
+                       CLIB_CACHE_LINE_BYTES);
+
+  for (int i = 0; i < tm->n_vlib_mains; i++)
+    {
+      rdma_per_thread_data_t *ptd = vec_elt_at_index (rm->per_thread_data, i);
+      clib_memset (&ptd->buffer_template, 0, sizeof (vlib_buffer_t));
+      ptd->buffer_template.flags = VLIB_BUFFER_TOTAL_LENGTH_VALID;
+      ptd->buffer_template.ref_count = 1;
+      vnet_buffer (&ptd->buffer_template)->sw_if_index[VLIB_TX] = (u32) ~ 0;
+    }
+
   return 0;
 }
 
-VLIB_INIT_FUNCTION (rdma_init);
+/* *INDENT-OFF* */
+VLIB_INIT_FUNCTION (rdma_init) =
+{
+  .runs_after = VLIB_INITS ("pci_bus_init"),
+};
+/* *INDENT-OFF* */
 
 /*
  * fd.io coding-style-patch-verification: ON