linux_pci_device_type_t type;
vlib_pci_dev_handle_t handle;
vlib_pci_addr_t addr;
+ u32 numa_node;
/* Resource file descriptors. */
linux_pci_region_t *regions;
return &d->addr;
}
+u32
+vlib_pci_get_numa_node (vlib_main_t * vm, vlib_pci_dev_handle_t h)
+{
+ linux_pci_device_t *d = linux_pci_get_device (h);
+ return d->numa_node;
+}
+
+u32
+vlib_pci_get_num_msix_interrupts (vlib_main_t * vm, vlib_pci_dev_handle_t h)
+{
+ linux_pci_device_t *d = linux_pci_get_device (h);
+
+ if (d->type == LINUX_PCI_DEVICE_TYPE_VFIO)
+ {
+ struct vfio_irq_info ii = { 0 };
+
+ ii.argsz = sizeof (struct vfio_irq_info);
+ ii.index = VFIO_PCI_MSIX_IRQ_INDEX;
+ if (ioctl (d->fd, VFIO_DEVICE_GET_IRQ_INFO, &ii) < 0)
+ return 0;
+ return ii.count;
+ }
+ return 0;
+}
+
/* Call to allocate/initialize the pci subsystem.
This is not an init function so that users can explicitly enable
pci only when it's needed. */
vlib_pci_get_device_info (vlib_main_t * vm, vlib_pci_addr_t * addr,
clib_error_t ** error)
{
- linux_vfio_main_t *lvm = &vfio_main;
clib_error_t *err;
vlib_pci_device_info_t *di;
u8 *f = 0;
u32 tmp;
int fd;
+ u8 *tmpstr;
+ clib_bitmap_t *bmp = 0;
di = clib_mem_alloc (sizeof (vlib_pci_device_info_t));
clib_memset (di, 0, sizeof (vlib_pci_device_info_t));
di->numa_node = -1;
vec_reset_length (f);
f = format (f, "%v/numa_node%c", dev_dir_name, 0);
- err = clib_sysfs_read ((char *) f, "%u", &di->numa_node);
+ err = clib_sysfs_read ((char *) f, "%d", &di->numa_node);
if (err)
{
di->numa_node = -1;
clib_error_free (err);
}
+ 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);
+ if (clib_bitmap_count_set_bits (bmp) == 1)
+ di->numa_node = 0;
+ }
vec_reset_length (f);
f = format (f, "%v/class%c", dev_dir_name, 0);
vec_reset_length (f);
f = format (f, "%v/driver%c", dev_dir_name, 0);
di->driver_name = clib_sysfs_link_to_name ((char *) f);
+ if (!di->driver_name)
+ di->driver_name = format (0, "<NONE>%c", 0);
di->iommu_group = -1;
- if (lvm->container_fd != -1)
+ vec_reset_length (f);
+ f = format (f, "%v/iommu_group%c", dev_dir_name, 0);
+ tmpstr = clib_sysfs_link_to_name ((char *) f);
+ if (tmpstr)
{
- u8 *tmpstr;
- vec_reset_length (f);
- f = format (f, "%v/iommu_group%c", dev_dir_name, 0);
- tmpstr = clib_sysfs_link_to_name ((char *) f);
- if (tmpstr)
- {
- di->iommu_group = atoi ((char *) tmpstr);
- vec_free (tmpstr);
- }
- vec_reset_length (f);
- f = format (f, "%v/iommu_group/name%c", dev_dir_name, 0);
- err = clib_sysfs_read ((char *) f, "%s", &tmpstr);
- if (err == 0)
- {
- if (strncmp ((char *) tmpstr, "vfio-noiommu", 12) == 0)
- di->flags |= VLIB_PCI_DEVICE_INFO_F_NOIOMMU;
- vec_free (tmpstr);
- }
- else
- clib_error_free (err);
+ di->iommu_group = atoi ((char *) tmpstr);
+ vec_free (tmpstr);
+ }
+
+ vec_reset_length (f);
+ f = format (f, "%v/iommu_group/name%c", dev_dir_name, 0);
+ err = clib_sysfs_read ((char *) f, "%s", &tmpstr);
+ if (err == 0)
+ {
+ if (strncmp ((char *) tmpstr, "vfio-noiommu", 12) == 0)
+ di->flags |= VLIB_PCI_DEVICE_INFO_F_NOIOMMU;
+ vec_free (tmpstr);
}
+ else
+ clib_error_free (err);
close (fd);
di = 0;
done:
+ vec_free (bmp);
vec_free (f);
vec_free (dev_dir_name);
if (error)
clib_memset (&ifr, 0, sizeof ifr);
clib_memset (&drvinfo, 0, sizeof drvinfo);
ifr.ifr_data = (char *) &drvinfo;
- strncpy (ifr.ifr_name, e->d_name, sizeof (ifr.ifr_name));
- ifr.ifr_name[ARRAY_LEN (ifr.ifr_name) - 1] = '\0';
+ clib_strncpy (ifr.ifr_name, e->d_name, sizeof (ifr.ifr_name) - 1);
+
drvinfo.cmd = ETHTOOL_GDRVINFO;
if (ioctl (fd, SIOCETHTOOL, &ifr) < 0)
{
continue;
clib_memset (&ifr, 0, sizeof (ifr));
- strncpy (ifr.ifr_name, e->d_name, sizeof (ifr.ifr_name));
- ifr.ifr_name[ARRAY_LEN (ifr.ifr_name) - 1] = '\0';
+ clib_strncpy (ifr.ifr_name, e->d_name, sizeof (ifr.ifr_name) - 1);
+
if (ioctl (fd, SIOCGIFFLAGS, &ifr) < 0)
{
error = clib_error_return_unix (0, "ioctl fetch intf %s flags",
if (efds)
{
flags |= VFIO_IRQ_SET_DATA_EVENTFD;
- clib_memcpy (&irq_set->data, efds, data_len);
+ clib_memcpy_fast (&irq_set->data, efds, data_len);
}
else
flags |= VFIO_IRQ_SET_DATA_NONE;
goto error;
}
- s = format (0, "%s/%U/uio", sysfs_pci_dev_path,
- format_vlib_pci_addr, &di->addr);
+ s = format (0, "%s/%U/uio%c", sysfs_pci_dev_path,
+ format_vlib_pci_addr, &di->addr, 0);
foreach_directory_file ((char *) s, scan_uio_dir, p, /* scan_dirs */
1);
vec_reset_length (s);
{
vlib_buffer_pool_t *bp;
/* *INDENT-OFF* */
- vec_foreach (bp, buffer_main.buffer_pools)
+ vec_foreach (bp, vm->buffer_main->buffer_pools)
{
u32 i;
vlib_physmem_map_t *pm;
p->handle = p - lpm->linux_pci_devices;
p->addr.as_u32 = di->addr.as_u32;
p->intx_irq.fd = -1;
+ p->intx_irq.clib_file_index = -1;
+ p->numa_node = di->numa_node;
/*
* pci io bar read/write fd
*/
di->vendor_id, di->device_id, di->driver_name,
di->iommu_group);
- if (strncmp ("vfio-pci", (char *) di->driver_name, 8) == 0)
+ if (clib_strncmp ("vfio-pci", (char *) di->driver_name, 8) == 0)
err = add_device_vfio (vm, p, di, 0);
- else if (strncmp ("uio_pci_generic", (char *) di->driver_name, 8) == 0)
+ else if (clib_strncmp ("uio_pci_generic", (char *) di->driver_name, 8) == 0)
err = add_device_uio (vm, p, di, 0);
else
err = clib_error_create ("device not bound to 'vfio-pci' or "
if (p->type == LINUX_PCI_DEVICE_TYPE_UIO)
{
irq = &p->intx_irq;
- clib_file_del_by_index (&file_main, irq->clib_file_index);
+ if (irq->clib_file_index != -1)
+ clib_file_del_by_index (&file_main, irq->clib_file_index);
close (p->config_fd);
if (p->io_fd != -1)
close (p->io_fd);
err = vfio_set_irqs (vm, p, VFIO_PCI_INTX_IRQ_INDEX, 0, 0,
VFIO_IRQ_SET_ACTION_TRIGGER, 0);
clib_error_free (err);
- clib_file_del_by_index (&file_main, irq->clib_file_index);
+ if (irq->clib_file_index != -1)
+ clib_file_del_by_index (&file_main, irq->clib_file_index);
close (irq->fd);
}
{
vlib_pci_main_t *pm = &pci_main;
vlib_pci_addr_t *addr = 0, *addrs;
- clib_error_t *error;
pm->vlib_main = vm;
- if ((error = vlib_call_init_function (vm, unix_input_init)))
- return error;
-
ASSERT (sizeof (vlib_pci_addr_t) == sizeof (u32));
addrs = vlib_pci_get_all_dev_addrs ();
}
/* *INDENT-ON* */
- return error;
+ return 0;
}
-VLIB_INIT_FUNCTION (linux_pci_init);
+/* *INDENT-OFF* */
+VLIB_INIT_FUNCTION (linux_pci_init) =
+{
+ .runs_after = VLIB_INITS("unix_input_init"),
+};
+/* *INDENT-ON* */
/*
* fd.io coding-style-patch-verification: ON