linux-cp: populate mapping vif-sw_if_index only for default-ns
[vpp.git] / src / vlib / linux / pci.c
index 9661827..29ca3d9 100644 (file)
@@ -38,6 +38,8 @@
  */
 
 #include <vppinfra/linux/sysfs.h>
+#include <vppinfra/bitmap.h>
+#include <vppinfra/unix.h>
 
 #include <vlib/vlib.h>
 #include <vlib/pci/pci.h>
@@ -53,6 +55,7 @@
 #include <linux/ethtool.h>
 #include <linux/sockios.h>
 #include <linux/vfio.h>
+#include <limits.h>
 #include <sys/eventfd.h>
 
 #define SYSFS_DEVICES_PCI "/sys/devices/pci"
@@ -238,7 +241,8 @@ vlib_pci_get_device_info (vlib_main_t * vm, vlib_pci_addr_t * addr,
 
   /* You can only read more that 64 bytes of config space as root; so we try to
      read the full space but fall back to just the first 64 bytes. */
-  if (read (fd, &di->config, sizeof (di->config)) < sizeof (di->config))
+  if (read (fd, &di->config, sizeof (di->config)) <
+      sizeof (vlib_pci_config_hdr_t))
     {
       err = clib_error_return_unix (0, "read `%s'", f);
       close (fd);
@@ -256,11 +260,7 @@ vlib_pci_get_device_info (vlib_main_t * vm, vlib_pci_addr_t * addr,
     }
   if (di->numa_node == -1)
     {
-      /* if '/sys/bus/pci/devices/<device id>/numa_node' returns -1 and
-         it is a SMP system, set numa_node to 0. */
-      if ((err = clib_sysfs_read ("/sys/devices/system/node/online", "%U",
-                                 unformat_bitmap_list, &bmp)))
-       clib_error_free (err);
+      bmp = os_get_online_cpu_node_bitmap ();
       if (clib_bitmap_count_set_bits (bmp) == 1)
        di->numa_node = 0;
     }
@@ -647,33 +647,14 @@ vfio_set_irqs (vlib_main_t * vm, linux_pci_device_t * p, u32 index, u32 start,
 {
   int data_len = efds ? count * sizeof (int) : 0;
   u8 buf[sizeof (struct vfio_irq_set) + data_len];
-  struct vfio_irq_info ii = { 0 };
   struct vfio_irq_set *irq_set = (struct vfio_irq_set *) buf;
 
-
-  ii.argsz = sizeof (struct vfio_irq_info);
-  ii.index = index;
-
-  if (ioctl (p->fd, VFIO_DEVICE_GET_IRQ_INFO, &ii) < 0)
-    return clib_error_return_unix (0, "ioctl(VFIO_DEVICE_GET_IRQ_INFO) "
-                                  "'%U'", format_vlib_pci_addr, &p->addr);
-
-  log_debug (p, "%s index:%u count:%u flags: %s%s%s%s(0x%x)", __func__,
-            ii.index, ii.count,
-            ii.flags & VFIO_IRQ_INFO_EVENTFD ? "eventfd " : "",
-            ii.flags & VFIO_IRQ_INFO_MASKABLE ? "maskable " : "",
-            ii.flags & VFIO_IRQ_INFO_AUTOMASKED ? "automasked " : "",
-            ii.flags & VFIO_IRQ_INFO_NORESIZE ? "noresize " : "", ii.flags);
-
-  if (ii.count < start + count)
-    return clib_error_return_unix (0, "vfio_set_irq: unexistng interrupt on "
-                                  "'%U'", format_vlib_pci_addr, &p->addr);
-
-
   if (efds)
     {
+      int *data = (int *) irq_set->data;
       flags |= VFIO_IRQ_SET_DATA_EVENTFD;
-      clib_memcpy_fast (&irq_set->data, efds, data_len);
+      for (u32 i = 0; i < count; i++)
+       data[i] = efds[i];
     }
   else
     flags |= VFIO_IRQ_SET_DATA_NONE;
@@ -688,11 +669,11 @@ vfio_set_irqs (vlib_main_t * vm, linux_pci_device_t * p, u32 index, u32 start,
   irq_set->flags = flags;
 
   if (ioctl (p->fd, VFIO_DEVICE_SET_IRQS, irq_set) < 0)
-    return clib_error_return_unix (0, "%U:ioctl(VFIO_DEVICE_SET_IRQS) "
-                                  "[index = %u, start = %u, count = %u, "
-                                  "flags = 0x%x]",
+    return clib_error_return_unix (0, "%U:ioctl(VFIO_DEVICE_SET_IRQS)\n%U",
                                   format_vlib_pci_addr, &p->addr,
-                                  index, start, count, flags);
+                                  format_vfio_irq_set, irq_set);
+
+  log_debug (p, "%s:\n%U", __func__, format_vfio_irq_set, irq_set);
   return 0;
 }
 
@@ -884,6 +865,27 @@ vlib_pci_register_intx_handler (vlib_main_t * vm, vlib_pci_dev_handle_t h,
   return 0;
 }
 
+clib_error_t *
+vlib_pci_unregister_intx_handler (vlib_main_t *vm, vlib_pci_dev_handle_t h)
+{
+  linux_pci_device_t *p = linux_pci_get_device (h);
+  linux_pci_irq_t *irq = &p->intx_irq;
+
+  if (irq->intx_handler == 0)
+    return 0;
+
+  clib_file_del_by_index (&file_main, irq->clib_file_index);
+  if (p->type == LINUX_PCI_DEVICE_TYPE_VFIO)
+    {
+      close (irq->fd);
+      irq->fd = -1;
+    }
+
+  irq->intx_handler = 0;
+
+  return 0;
+}
+
 clib_error_t *
 vlib_pci_register_msix_handler (vlib_main_t * vm, vlib_pci_dev_handle_t h,
                                u32 start, u32 count,
@@ -897,10 +899,8 @@ vlib_pci_register_msix_handler (vlib_main_t * vm, vlib_pci_dev_handle_t h,
     return clib_error_return (0, "vfio driver is needed for MSI-X interrupt "
                              "support");
 
-  /* *INDENT-OFF* */
   vec_validate_init_empty (p->msix_irqs, start + count - 1, (linux_pci_irq_t)
                           { .fd = -1});
-  /* *INDENT-ON* */
 
   for (i = start; i < start + count; i++)
     {
@@ -941,6 +941,33 @@ error:
   return err;
 }
 
+clib_error_t *
+vlib_pci_unregister_msix_handler (vlib_main_t *vm, vlib_pci_dev_handle_t h,
+                                 u32 start, u32 count)
+{
+  clib_error_t *err = 0;
+  linux_pci_device_t *p = linux_pci_get_device (h);
+  u32 i;
+
+  if (p->type != LINUX_PCI_DEVICE_TYPE_VFIO)
+    return clib_error_return (0, "vfio driver is needed for MSI-X interrupt "
+                                "support");
+
+  for (i = start; i < start + count; i++)
+    {
+      linux_pci_irq_t *irq = vec_elt_at_index (p->msix_irqs, i);
+
+      if (irq->fd != -1)
+       {
+         clib_file_del_by_index (&file_main, irq->clib_file_index);
+         close (irq->fd);
+         irq->fd = -1;
+       }
+    }
+
+  return err;
+}
+
 clib_error_t *
 vlib_pci_enable_msix_irq (vlib_main_t * vm, vlib_pci_dev_handle_t h,
                          u16 start, u16 count)
@@ -953,9 +980,9 @@ vlib_pci_enable_msix_irq (vlib_main_t * vm, vlib_pci_dev_handle_t h,
     return clib_error_return (0, "vfio driver is needed for MSI-X interrupt "
                              "support");
 
-  for (i = start; i < start + count; i++)
+  for (i = 0; i < count; i++)
     {
-      linux_pci_irq_t *irq = vec_elt_at_index (p->msix_irqs, i);
+      linux_pci_irq_t *irq = vec_elt_at_index (p->msix_irqs, start + i);
       fds[i] = irq->fd;
     }
 
@@ -1051,7 +1078,6 @@ add_device_vfio (vlib_main_t * vm, linux_pci_device_t * p,
   if (p->supports_va_dma)
     {
       vlib_buffer_pool_t *bp;
-      /* *INDENT-OFF* */
       vec_foreach (bp, vm->buffer_main->buffer_pools)
        {
          u32 i;
@@ -1060,7 +1086,6 @@ add_device_vfio (vlib_main_t * vm, linux_pci_device_t * p,
          for (i = 0; i < pm->n_pages; i++)
            vfio_map_physmem_page (vm, pm->base + (i << pm->log2_page_size));
        }
-      /* *INDENT-ON* */
     }
 
   if (r && r->init_function)
@@ -1213,10 +1238,8 @@ vlib_pci_map_region_int (vlib_main_t * vm, vlib_pci_dev_handle_t h,
       return error;
     }
 
-  /* *INDENT-OFF* */
   vec_validate_init_empty (p->regions, bar,
                           (linux_pci_region_t) { .fd = -1});
-  /* *INDENT-ON* */
   if (p->type == LINUX_PCI_DEVICE_TYPE_UIO)
     p->regions[bar].fd = fd;
   p->regions[bar].addr = *result;
@@ -1397,7 +1420,6 @@ vlib_pci_device_close (vlib_main_t * vm, vlib_pci_dev_handle_t h)
          err = vfio_set_irqs (vm, p, VFIO_PCI_MSIX_IRQ_INDEX, 0, 0,
                               VFIO_IRQ_SET_ACTION_TRIGGER, 0);
          clib_error_free (err);
-          /* *INDENT-OFF* */
          vec_foreach (irq, p->msix_irqs)
            {
              if (irq->fd == -1)
@@ -1405,12 +1427,10 @@ vlib_pci_device_close (vlib_main_t * vm, vlib_pci_dev_handle_t h)
              clib_file_del_by_index (&file_main, irq->clib_file_index);
              close (irq->fd);
            }
-          /* *INDENT-ON* */
          vec_free (p->msix_irqs);
        }
     }
 
-  /* *INDENT-OFF* */
   vec_foreach (res, p->regions)
     {
       if (res->size == 0)
@@ -1419,7 +1439,6 @@ vlib_pci_device_close (vlib_main_t * vm, vlib_pci_dev_handle_t h)
       if (res->fd != -1)
         close (res->fd);
     }
-  /* *INDENT-ON* */
   vec_free (p->regions);
 
   close (p->fd);
@@ -1542,28 +1561,27 @@ linux_pci_init (vlib_main_t * vm)
 
   ASSERT (sizeof (vlib_pci_addr_t) == sizeof (u32));
 
-  addrs = vlib_pci_get_all_dev_addrs ();
-  /* *INDENT-OFF* */
-  vec_foreach (addr, addrs)
+  if (pm->pci_device_registrations)
     {
-      vlib_pci_device_info_t *d;
-      if ((d = vlib_pci_get_device_info (vm, addr, 0)))
+      addrs = vlib_pci_get_all_dev_addrs ();
+      vec_foreach (addr, addrs)
        {
-         init_device_from_registered (vm, d);
-         vlib_pci_free_device_info (d);
+         vlib_pci_device_info_t *d;
+         if ((d = vlib_pci_get_device_info (vm, addr, 0)))
+           {
+             init_device_from_registered (vm, d);
+             vlib_pci_free_device_info (d);
+           }
        }
     }
-  /* *INDENT-ON* */
 
   return 0;
 }
 
-/* *INDENT-OFF* */
 VLIB_INIT_FUNCTION (linux_pci_init) =
 {
   .runs_after = VLIB_INITS("unix_input_init"),
 };
-/* *INDENT-ON* */
 
 /*
  * fd.io coding-style-patch-verification: ON