pci: don't unbind resources on exit
unbind operations must be done before starting eal application Signed-off-by: Intel
This commit is contained in:
parent
0a45657a67
commit
a22f5ce8fc
@ -95,7 +95,9 @@ struct rte_pci_driver my_driver = {
|
||||
.name = "test_driver",
|
||||
.devinit = my_driver_init,
|
||||
.id_table = my_driver_id,
|
||||
#ifdef RTE_EAL_UNBIND_PORTS
|
||||
.drv_flags = RTE_PCI_DRV_NEED_IGB_UIO,
|
||||
#endif
|
||||
};
|
||||
|
||||
struct rte_pci_driver my_driver2 = {
|
||||
@ -182,5 +184,11 @@ test_pci(void)
|
||||
}
|
||||
|
||||
test_pci_run = 1;
|
||||
if (driver_registered == 1) {
|
||||
rte_eal_pci_unregister(&my_driver);
|
||||
rte_eal_pci_unregister(&my_driver2);
|
||||
driver_registered = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -141,10 +141,6 @@ rte_eal_pci_probe(void)
|
||||
|
||||
TAILQ_FOREACH(dev, &device_list, next)
|
||||
pci_probe_all_drivers(dev);
|
||||
#ifdef RTE_EAL_UNBIND_PORTS
|
||||
if (atexit(rte_eal_pci_exit) != 0)
|
||||
RTE_LOG(ERR, EAL, "atexit failure\n");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -186,6 +182,13 @@ rte_eal_pci_register(struct rte_pci_driver *driver)
|
||||
TAILQ_INSERT_TAIL(&driver_list, driver, next);
|
||||
}
|
||||
|
||||
/* unregister a driver */
|
||||
void
|
||||
rte_eal_pci_unregister(struct rte_pci_driver *driver)
|
||||
{
|
||||
TAILQ_REMOVE(&driver_list, driver, next);
|
||||
}
|
||||
|
||||
void
|
||||
rte_eal_pci_set_blacklist(struct rte_pci_addr *blacklist, unsigned size)
|
||||
{
|
||||
|
@ -141,7 +141,6 @@ struct rte_pci_device {
|
||||
struct rte_pci_id id; /**< PCI ID. */
|
||||
struct rte_pci_resource mem_resource[PCI_MAX_RESOURCE]; /**< PCI Memory Resource */
|
||||
struct rte_intr_handle intr_handle; /**< Interrupt handle */
|
||||
char previous_dr[PATH_MAX]; /**< path for pre-dpdk driver*/
|
||||
const struct rte_pci_driver *driver; /**< Associated driver */
|
||||
unsigned int blacklisted:1; /**< Device is blacklisted */
|
||||
};
|
||||
@ -183,16 +182,13 @@ struct rte_pci_driver {
|
||||
uint32_t drv_flags; /**< Flags contolling handling of device. */
|
||||
};
|
||||
|
||||
/**< Device needs igb_uio kernel module */
|
||||
#ifdef RTE_EAL_UNBIND_PORTS
|
||||
/** Device needs igb_uio kernel module */
|
||||
#define RTE_PCI_DRV_NEED_IGB_UIO 0x0001
|
||||
/**< Device driver must be registered several times until failure */
|
||||
#endif
|
||||
/** Device driver must be registered several times until failure */
|
||||
#define RTE_PCI_DRV_MULTIPLE 0x0002
|
||||
|
||||
/**
|
||||
* Perform clean up of pci drivers on application exits.
|
||||
* */
|
||||
void rte_eal_pci_exit(void);
|
||||
|
||||
/**
|
||||
* Probe the PCI bus for registered drivers.
|
||||
*
|
||||
@ -220,6 +216,15 @@ void rte_eal_pci_dump(void);
|
||||
*/
|
||||
void rte_eal_pci_register(struct rte_pci_driver *driver);
|
||||
|
||||
/**
|
||||
* Unregister a PCI driver.
|
||||
*
|
||||
* @param driver
|
||||
* A pointer to a rte_pci_driver structure describing the driver
|
||||
* to be unregistered.
|
||||
*/
|
||||
void rte_eal_pci_unregister(struct rte_pci_driver *driver);
|
||||
|
||||
/**
|
||||
* Register a list of PCI locations that will be blacklisted (not used by DPDK).
|
||||
*
|
||||
|
@ -88,15 +88,6 @@ struct uio_map {
|
||||
uint64_t phaddr;
|
||||
};
|
||||
|
||||
#define PROC_MODULES "/proc/modules"
|
||||
|
||||
#define IGB_UIO_NAME "igb_uio"
|
||||
|
||||
#define UIO_DRV_PATH "/sys/bus/pci/drivers/%s"
|
||||
|
||||
/* maximum time to wait that /dev/uioX appears */
|
||||
#define UIO_DEV_WAIT_TIMEOUT 3 /* seconds */
|
||||
|
||||
/*
|
||||
* For multi-process we need to reproduce all PCI mappings in secondary
|
||||
* processes, so save them in a tailq.
|
||||
@ -115,6 +106,19 @@ TAILQ_HEAD(uio_res_list, uio_resource);
|
||||
static struct uio_res_list *uio_res_list = NULL;
|
||||
static int pci_parse_sysfs_value(const char *filename, uint64_t *val);
|
||||
|
||||
/* forward prototype of function called in pci_switch_module below */
|
||||
static int pci_uio_map_resource(struct rte_pci_device *dev);
|
||||
|
||||
#ifdef RTE_EAL_UNBIND_PORTS
|
||||
#define PROC_MODULES "/proc/modules"
|
||||
|
||||
#define IGB_UIO_NAME "igb_uio"
|
||||
|
||||
#define UIO_DRV_PATH "/sys/bus/pci/drivers/%s"
|
||||
|
||||
/* maximum time to wait that /dev/uioX appears */
|
||||
#define UIO_DEV_WAIT_TIMEOUT 3 /* seconds */
|
||||
|
||||
/*
|
||||
* Check that a kernel module is loaded. Returns 0 on success, or if the
|
||||
* parameter is NULL, or -1 if the module is not loaded.
|
||||
@ -162,9 +166,6 @@ pci_bind_device(struct rte_pci_device *dev, char dr_path[])
|
||||
char dev_bind[PATH_MAX];
|
||||
struct rte_pci_addr *loc = &dev->addr;
|
||||
|
||||
RTE_LOG(DEBUG, EAL, "bind PCI device "PCI_PRI_FMT"\n",
|
||||
loc->domain, loc->bus, loc->devid, loc->function);
|
||||
|
||||
n = rte_snprintf(dev_bind, sizeof(dev_bind), "%s/bind", dr_path);
|
||||
if ((n < 0) || (n >= (int)sizeof(buf))) {
|
||||
RTE_LOG(ERR, EAL, "Cannot rte_snprintf device bind path\n");
|
||||
@ -173,7 +174,7 @@ pci_bind_device(struct rte_pci_device *dev, char dr_path[])
|
||||
|
||||
f = fopen(dev_bind, "w");
|
||||
if (f == NULL) {
|
||||
RTE_LOG(ERR, EAL, "Cannot open %s\n", dev->previous_dr);
|
||||
RTE_LOG(ERR, EAL, "Cannot open %s\n", dev_bind);
|
||||
return -1;
|
||||
}
|
||||
n = rte_snprintf(buf, sizeof(buf), PCI_PRI_FMT "\n",
|
||||
@ -188,8 +189,6 @@ pci_bind_device(struct rte_pci_device *dev, char dr_path[])
|
||||
return -1;
|
||||
}
|
||||
|
||||
RTE_LOG(DEBUG, EAL, "Device bound\n");
|
||||
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
@ -237,43 +236,130 @@ pci_uio_bind_device(struct rte_pci_device *dev, const char *module_name)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* open devname: it can take some time to
|
||||
* appear, so we wait some time before returning an error
|
||||
*/
|
||||
static int uio_open(const char *devname)
|
||||
/* unbind kernel driver for this device */
|
||||
static int
|
||||
pci_unbind_kernel_driver(struct rte_pci_device *dev)
|
||||
{
|
||||
int n, fd;
|
||||
int n;
|
||||
FILE *f;
|
||||
char filename[PATH_MAX];
|
||||
char buf[BUFSIZ];
|
||||
struct rte_pci_addr *loc = &dev->addr;
|
||||
|
||||
for (n=0; n < UIO_DEV_WAIT_TIMEOUT*10; n++) {
|
||||
fd = open(devname, O_RDWR);
|
||||
if (fd >= 0)
|
||||
return fd;
|
||||
/* open /sys/bus/pci/devices/AAAA:BB:CC.D/driver */
|
||||
rte_snprintf(filename, sizeof(filename),
|
||||
SYSFS_PCI_DEVICES "/" PCI_PRI_FMT "/driver/unbind",
|
||||
loc->domain, loc->bus, loc->devid, loc->function);
|
||||
|
||||
if (errno != ENOENT)
|
||||
break;
|
||||
usleep(100000);
|
||||
f = fopen(filename, "w");
|
||||
if (f == NULL) /* device was not bound */
|
||||
return 0;
|
||||
|
||||
n = rte_snprintf(buf, sizeof(buf), PCI_PRI_FMT "\n",
|
||||
loc->domain, loc->bus, loc->devid, loc->function);
|
||||
if ((n < 0) || (n >= (int)sizeof(buf))) {
|
||||
RTE_LOG(ERR, EAL, "%s(): rte_snprintf failed\n", __func__);
|
||||
goto error;
|
||||
}
|
||||
if (fwrite(buf, n, 1, f) == 0) {
|
||||
RTE_LOG(ERR, EAL, "%s(): could not write to %s\n", __func__,
|
||||
filename);
|
||||
goto error;
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
fclose(f);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
pci_switch_module(struct rte_pci_driver *dr, struct rte_pci_device *dev,
|
||||
int uio_status, const char *module_name)
|
||||
{
|
||||
if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
|
||||
/* check that our driver is loaded */
|
||||
if (uio_status != 0 &&
|
||||
(uio_status = pci_uio_check_module(module_name)) != 0)
|
||||
rte_exit(EXIT_FAILURE, "The %s module is required by the "
|
||||
"%s driver\n", module_name, dr->name);
|
||||
|
||||
/* unbind current driver, bind ours */
|
||||
if (pci_unbind_kernel_driver(dev) < 0)
|
||||
return -1;
|
||||
if (pci_uio_bind_device(dev, module_name) < 0)
|
||||
return -1;
|
||||
}
|
||||
/* map the NIC resources */
|
||||
if (pci_uio_map_resource(dev) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* ifdef EAL_UNBIND_PORTS */
|
||||
|
||||
/* map a particular resource from a file */
|
||||
static void *
|
||||
pci_mmap(int fd, void *addr, off_t offset, size_t size)
|
||||
pci_map_resource(struct rte_pci_device *dev, void *requested_addr,
|
||||
const char *devname, off_t offset, size_t size)
|
||||
{
|
||||
int fd;
|
||||
void *mapaddr;
|
||||
|
||||
/* Map the PCI memory resource of device */
|
||||
mapaddr = mmap(addr, size, PROT_READ | PROT_WRITE, MAP_SHARED,
|
||||
fd, offset);
|
||||
if (mapaddr == MAP_FAILED || (addr != NULL && mapaddr != addr)) {
|
||||
RTE_LOG(ERR, EAL, "%s(): cannot mmap %zd@0x%lx: %s\n",
|
||||
__func__, size, offset, strerror(errno));
|
||||
return NULL;
|
||||
#ifdef RTE_EAL_UNBIND_PORTS
|
||||
/*
|
||||
* open devname, and mmap it: it can take some time to
|
||||
* appear, so we wait some time before returning an error
|
||||
*/
|
||||
unsigned n;
|
||||
fd = dev->intr_handle.fd;
|
||||
for (n = 0; n < UIO_DEV_WAIT_TIMEOUT*10 && fd < 0; n++) {
|
||||
errno = 0;
|
||||
if ((fd = open(devname, O_RDWR)) < 0 && errno != ENOENT)
|
||||
break;
|
||||
usleep(100000);
|
||||
}
|
||||
#else
|
||||
/*
|
||||
* open devname, to mmap it
|
||||
*/
|
||||
fd = open(devname, O_RDWR);
|
||||
#endif
|
||||
if (fd < 0) {
|
||||
RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
|
||||
devname, strerror(errno));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
RTE_LOG(DEBUG, EAL, "PCI memory mapped at %p\n", mapaddr);
|
||||
/* Map the PCI memory resource of device */
|
||||
mapaddr = mmap(requested_addr, size, PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED, fd, offset);
|
||||
if (mapaddr == MAP_FAILED ||
|
||||
(requested_addr != NULL && mapaddr != requested_addr)) {
|
||||
RTE_LOG(ERR, EAL, "%s(): cannot mmap(%s(%d), %p, 0x%lx, 0x%lx):"
|
||||
" %s (%p)\n", __func__, devname, fd, requested_addr,
|
||||
(unsigned long)size, (unsigned long)offset,
|
||||
strerror(errno), mapaddr);
|
||||
close(fd);
|
||||
goto fail;
|
||||
}
|
||||
if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
|
||||
/* save fd if in primary process */
|
||||
dev->intr_handle.fd = fd;
|
||||
dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
|
||||
} else {
|
||||
/* fd is not needed in slave process, close it */
|
||||
dev->intr_handle.fd = -1;
|
||||
dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
|
||||
close(fd);
|
||||
}
|
||||
|
||||
RTE_LOG(DEBUG, EAL, " PCI memory mapped at %p\n", mapaddr);
|
||||
|
||||
return mapaddr;
|
||||
|
||||
fail:
|
||||
@ -394,12 +480,11 @@ pci_uio_map_resource(struct rte_pci_device *dev)
|
||||
struct uio_resource *uio_res;
|
||||
struct uio_map *maps;
|
||||
|
||||
RTE_LOG(DEBUG, EAL, "map PCI resource for device "PCI_PRI_FMT"\n",
|
||||
loc->domain, loc->bus, loc->devid, loc->function);
|
||||
dev->intr_handle.fd = -1;
|
||||
|
||||
/* secondary processes - use already recorded details */
|
||||
if (rte_eal_process_type() != RTE_PROC_PRIMARY)
|
||||
return pci_uio_map_restore(dev);
|
||||
return (pci_uio_map_secondary(dev));
|
||||
|
||||
/* depending on kernel version, uio can be located in uio/uioX
|
||||
* or uio:uioX */
|
||||
@ -424,8 +509,10 @@ pci_uio_map_resource(struct rte_pci_device *dev)
|
||||
|
||||
/* take the first file starting with "uio" */
|
||||
while ((e = readdir(dir)) != NULL) {
|
||||
int shortprefix_len = sizeof("uio") - 1; /* format could be uio%d ...*/
|
||||
int longprefix_len = sizeof("uio:uio") - 1; /* ... or uio:uio%d */
|
||||
/* format could be uio%d ...*/
|
||||
int shortprefix_len = sizeof("uio") - 1;
|
||||
/* ... or uio:uio%d */
|
||||
int longprefix_len = sizeof("uio:uio") - 1;
|
||||
char *endptr;
|
||||
|
||||
if (strncmp(e->d_name, "uio", 3) != 0)
|
||||
@ -541,12 +628,14 @@ pci_parse_sysfs_resource(const char *filename, struct rte_pci_device *dev)
|
||||
for (i = 0; i<PCI_MAX_RESOURCE; i++) {
|
||||
|
||||
if (fgets(buf, sizeof(buf), f) == NULL) {
|
||||
RTE_LOG(ERR, EAL, "%s(): cannot read resource\n", __func__);
|
||||
RTE_LOG(ERR, EAL,
|
||||
"%s(): cannot read resource\n", __func__);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (rte_strsplit(buf, sizeof(buf), res_info.ptrs, 3, ' ') != 3) {
|
||||
RTE_LOG(ERR, EAL, "%s(): bad resource format\n", __func__);
|
||||
RTE_LOG(ERR, EAL,
|
||||
"%s(): bad resource format\n", __func__);
|
||||
goto error;
|
||||
}
|
||||
errno = 0;
|
||||
@ -554,7 +643,8 @@ pci_parse_sysfs_resource(const char *filename, struct rte_pci_device *dev)
|
||||
end_addr = strtoull(res_info.end_addr, NULL, 16);
|
||||
flags = strtoull(res_info.flags, NULL, 16);
|
||||
if (errno != 0) {
|
||||
RTE_LOG(ERR, EAL, "%s(): bad resource format\n", __func__);
|
||||
RTE_LOG(ERR, EAL,
|
||||
"%s(): bad resource format\n", __func__);
|
||||
goto error;
|
||||
}
|
||||
|
||||
@ -612,13 +702,13 @@ pci_parse_sysfs_value(const char *filename, uint64_t *val)
|
||||
static int
|
||||
pci_addr_comparison(struct rte_pci_addr *addr, struct rte_pci_addr *addr2)
|
||||
{
|
||||
uint64_t dev_addr = (addr->domain << 24) + (addr->bus << 16) + (addr->devid << 8) + addr->function;
|
||||
uint64_t dev_addr2 = (addr2->domain << 24) + (addr2->bus << 16) + (addr2->devid << 8) + addr2->function;
|
||||
uint64_t dev_addr = (addr->domain << 24) + (addr->bus << 16) + (addr->devid << 8) + addr->function;
|
||||
uint64_t dev_addr2 = (addr2->domain << 24) + (addr2->bus << 16) + (addr2->devid << 8) + addr2->function;
|
||||
|
||||
if (dev_addr > dev_addr2)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
if (dev_addr > dev_addr2)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -793,104 +883,6 @@ error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* unbind kernel driver for this device */
|
||||
static int
|
||||
pci_unbind_kernel_driver(struct rte_pci_device *dev)
|
||||
{
|
||||
int n;
|
||||
FILE *f;
|
||||
char filename[PATH_MAX];
|
||||
char buf[BUFSIZ];
|
||||
struct rte_pci_addr *loc = &dev->addr;
|
||||
|
||||
/* open /sys/bus/pci/devices/AAAA:BB:CC.D/driver */
|
||||
rte_snprintf(filename, sizeof(filename),
|
||||
SYSFS_PCI_DEVICES "/" PCI_PRI_FMT "/driver/unbind",
|
||||
loc->domain, loc->bus, loc->devid, loc->function);
|
||||
|
||||
RTE_LOG(DEBUG, EAL, "unbind kernel driver %s\n", filename);
|
||||
|
||||
f = fopen(filename, "w");
|
||||
if (f == NULL) /* device was not bound */
|
||||
return 0;
|
||||
|
||||
n = rte_snprintf(buf, sizeof(buf), PCI_PRI_FMT "\n",
|
||||
loc->domain, loc->bus, loc->devid, loc->function);
|
||||
if ((n < 0) || (n >= (int)sizeof(buf))) {
|
||||
RTE_LOG(ERR, EAL, "%s(): rte_snprintf failed\n", __func__);
|
||||
goto error;
|
||||
}
|
||||
if (fwrite(buf, n, 1, f) == 0) {
|
||||
RTE_LOG(ERR, EAL, "%s(): could not write to %s\n", __func__,
|
||||
filename);
|
||||
goto error;
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
fclose(f);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
pci_exit_process(struct rte_pci_device *dev)
|
||||
{
|
||||
if (munmap(dev->mem_resource.addr, dev->mem_resource.len) == -1){
|
||||
RTE_LOG(ERR, EAL, "Error with munmap\n");
|
||||
return -1;
|
||||
}
|
||||
if (close(dev->intr_handle.fd) == -1){
|
||||
RTE_LOG(ERR, EAL, "Error closing interrupt handle\n");
|
||||
return -1;
|
||||
}
|
||||
if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
|
||||
if (pci_unbind_kernel_driver(dev) < 0){
|
||||
RTE_LOG(ERR, EAL, "Error unbinding\n");
|
||||
return -1;
|
||||
}
|
||||
if (pci_bind_device(dev, dev->previous_dr) < 0){
|
||||
RTE_LOG(ERR, EAL, "Error binding\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
pci_get_previous_driver_path(struct rte_pci_device *dev)
|
||||
{
|
||||
int n;
|
||||
char dev_path[PATH_MAX];
|
||||
char dr_path[PATH_MAX];
|
||||
struct rte_pci_addr *loc = &dev->addr;
|
||||
|
||||
n = rte_snprintf(dev_path, sizeof(dev_path), SYSFS_PCI_DEVICES "/"
|
||||
PCI_PRI_FMT "/driver", loc->domain, loc->bus, loc->devid, loc->function );
|
||||
if ((n < 0) || (n >= (int)sizeof(dev_path)))
|
||||
RTE_LOG(ERR, EAL, "Cannot rte_snprintf device filepath\n");
|
||||
|
||||
n = readlink(dev_path, dr_path, sizeof(dr_path));
|
||||
if ((n < 0) || (n >= (int)sizeof(dr_path))){
|
||||
RTE_LOG(ERR, EAL, "Cannot readlink driver filepath\n");
|
||||
dev->previous_dr[0] = '\0';
|
||||
return;
|
||||
}
|
||||
dr_path[n] = '\0';
|
||||
|
||||
if (dr_path[0] != '/')
|
||||
n = rte_snprintf(dev->previous_dr, sizeof(dev->previous_dr),
|
||||
SYSFS_PCI_DEVICES "/" PCI_PRI_FMT "/%s",
|
||||
loc->domain, loc->bus, loc->devid, loc->function, dr_path);
|
||||
else
|
||||
n = rte_snprintf(dev->previous_dr, sizeof(dev->previous_dr),
|
||||
"%s", dr_path);
|
||||
if ((n < 0) || (n >= (int)sizeof(dev_path)))
|
||||
RTE_LOG(ERR, EAL, "Cannot rte_snprintf driver filepath\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* If vendor/device ID match, call the devinit() function of the
|
||||
* driver.
|
||||
@ -899,11 +891,13 @@ int
|
||||
rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr, struct rte_pci_device *dev)
|
||||
{
|
||||
struct rte_pci_id *id_table;
|
||||
#ifdef RTE_EAL_UNBIND_PORTS
|
||||
const char *module_name = NULL;
|
||||
int uio_status = -1;
|
||||
|
||||
if (dr->drv_flags & RTE_PCI_DRV_NEED_IGB_UIO)
|
||||
module_name = IGB_UIO_NAME;
|
||||
#endif
|
||||
|
||||
for (id_table = dr->id_table ; id_table->vendor_id != 0; id_table++) {
|
||||
|
||||
@ -921,35 +915,19 @@ rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr, struct rte_pci_device *d
|
||||
id_table->subsystem_device_id != PCI_ANY_ID)
|
||||
continue;
|
||||
|
||||
RTE_LOG(DEBUG, EAL, "probe driver: %x:%x %s\n", dev->id.vendor_id,
|
||||
RTE_LOG(DEBUG, EAL, " probe driver: %x:%x %s\n", dev->id.vendor_id,
|
||||
dev->id.device_id, dr->name);
|
||||
|
||||
/* reference driver structure */
|
||||
dev->driver = dr;
|
||||
|
||||
/* no initialization when blacklisted, return without error */
|
||||
if (dev->blacklisted)
|
||||
if (dev->blacklisted) {
|
||||
RTE_LOG(DEBUG, EAL, " Device is blacklisted, not initializing\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef RTE_EAL_UNBIND_PORTS
|
||||
/* Unbind PCI devices if needed */
|
||||
if (module_name != NULL) {
|
||||
|
||||
if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
|
||||
/* check that our driver is loaded */
|
||||
if (uio_status != 0 &&
|
||||
(uio_status = pci_uio_check_module(module_name)) != 0)
|
||||
rte_exit(EXIT_FAILURE, "The %s module is required by the "
|
||||
"%s driver\n", module_name, dr->name);
|
||||
|
||||
/* unbind current driver, bind ours */
|
||||
pci_get_previous_driver_path(dev);
|
||||
if (pci_unbind_kernel_driver(dev) < 0)
|
||||
return -1;
|
||||
if (pci_uio_bind_device(dev, module_name) < 0)
|
||||
return -1;
|
||||
}
|
||||
/* map the NIC resources */
|
||||
if (pci_uio_map_resource(dev) < 0)
|
||||
if (module_name != NULL)
|
||||
if (pci_switch_module(dr, dev, uio_status, module_name) < 0)
|
||||
return -1;
|
||||
#else
|
||||
/* just map the NIC resources */
|
||||
@ -975,20 +953,6 @@ rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr, struct rte_pci_device *d
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*Start the exit process for each dev in use*/
|
||||
void
|
||||
rte_eal_pci_exit(void)
|
||||
{
|
||||
struct rte_pci_device *dev = NULL;
|
||||
|
||||
TAILQ_FOREACH(dev, &device_list, next){
|
||||
if (dev->previous_dr[0] == '\0')
|
||||
continue;
|
||||
if(pci_exit_process(dev) == 1)
|
||||
RTE_LOG(ERR, EAL, "Exit process failure\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* Init the PCI EAL subsystem */
|
||||
int
|
||||
rte_eal_pci_init(void)
|
||||
|
@ -278,7 +278,9 @@ static struct eth_driver rte_em_pmd = {
|
||||
{
|
||||
.name = "rte_em_pmd",
|
||||
.id_table = pci_id_em_map,
|
||||
#ifdef RTE_EAL_UNBIND_PORTS
|
||||
.drv_flags = RTE_PCI_DRV_NEED_IGB_UIO,
|
||||
#endif
|
||||
},
|
||||
.eth_dev_init = eth_em_dev_init,
|
||||
.dev_private_size = sizeof(struct e1000_adapter),
|
||||
|
@ -484,7 +484,9 @@ static struct eth_driver rte_igb_pmd = {
|
||||
{
|
||||
.name = "rte_igb_pmd",
|
||||
.id_table = pci_id_igb_map,
|
||||
#ifdef RTE_EAL_UNBIND_PORTS
|
||||
.drv_flags = RTE_PCI_DRV_NEED_IGB_UIO,
|
||||
#endif
|
||||
},
|
||||
.eth_dev_init = eth_igb_dev_init,
|
||||
.dev_private_size = sizeof(struct e1000_adapter),
|
||||
@ -497,7 +499,9 @@ static struct eth_driver rte_igbvf_pmd = {
|
||||
{
|
||||
.name = "rte_igbvf_pmd",
|
||||
.id_table = pci_id_igbvf_map,
|
||||
#ifdef RTE_EAL_UNBIND_PORTS
|
||||
.drv_flags = RTE_PCI_DRV_NEED_IGB_UIO,
|
||||
#endif
|
||||
},
|
||||
.eth_dev_init = eth_igbvf_dev_init,
|
||||
.dev_private_size = sizeof(struct e1000_adapter),
|
||||
|
@ -769,7 +769,9 @@ static struct eth_driver rte_ixgbe_pmd = {
|
||||
{
|
||||
.name = "rte_ixgbe_pmd",
|
||||
.id_table = pci_id_ixgbe_map,
|
||||
#ifdef RTE_EAL_UNBIND_PORTS
|
||||
.drv_flags = RTE_PCI_DRV_NEED_IGB_UIO,
|
||||
#endif
|
||||
},
|
||||
.eth_dev_init = eth_ixgbe_dev_init,
|
||||
.dev_private_size = sizeof(struct ixgbe_adapter),
|
||||
@ -782,7 +784,9 @@ static struct eth_driver rte_ixgbevf_pmd = {
|
||||
{
|
||||
.name = "rte_ixgbevf_pmd",
|
||||
.id_table = pci_id_ixgbevf_map,
|
||||
#ifdef RTE_EAL_UNBIND_PORTS
|
||||
.drv_flags = RTE_PCI_DRV_NEED_IGB_UIO,
|
||||
#endif
|
||||
},
|
||||
.eth_dev_init = eth_ixgbevf_dev_init,
|
||||
.dev_private_size = sizeof(struct ixgbe_adapter),
|
||||
|
@ -174,13 +174,20 @@ def check_modules():
|
||||
sys.exit(1)
|
||||
depmod_output = check_output(["depmod", "-n", modpath]).splitlines()
|
||||
for line in depmod_output:
|
||||
if not line.startswith(mod):
|
||||
if not line.startswith("alias"):
|
||||
continue
|
||||
if line.endswith(mod+".ko:"):
|
||||
if not line.endswith(mod):
|
||||
continue
|
||||
lineparts = line.split()
|
||||
module_dev_ids.append({"Vendor": int(lineparts[1],0),
|
||||
"Device": int(lineparts[2],0)})
|
||||
if not(lineparts[1].startswith("pci:")):
|
||||
continue;
|
||||
else:
|
||||
lineparts[1] = lineparts[1][4:]
|
||||
vendor = lineparts[1][:9]
|
||||
device = lineparts[1][9:18]
|
||||
if vendor.startswith("v") and device.startswith("d"):
|
||||
module_dev_ids.append({"Vendor": int(vendor[1:],16),
|
||||
"Device": int(device[1:],16)})
|
||||
|
||||
def is_supported_device(dev_id):
|
||||
'''return true if device is supported by igb_uio, false otherwise'''
|
||||
|
@ -325,11 +325,49 @@ grep_meminfo()
|
||||
}
|
||||
|
||||
#
|
||||
# List all hugepage file references
|
||||
# Calls pci_unbind.py --status to show the NIC and what they
|
||||
# are all bound to, in terms of drivers.
|
||||
#
|
||||
ls_mnt_huge()
|
||||
show_nics()
|
||||
{
|
||||
ls -lh /mnt/huge
|
||||
if /sbin/lsmod | grep -q igb_uio ; then
|
||||
${RTE_SDK}/tools/pci_unbind.py --status
|
||||
else
|
||||
echo "# Please load the 'igb_uio' kernel module before querying or "
|
||||
echo "# adjusting NIC device bindings"
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# Uses pci_unbind.py to move devices to work with igb_uio
|
||||
#
|
||||
bind_nics()
|
||||
{
|
||||
if /sbin/lsmod | grep -q igb_uio ; then
|
||||
${RTE_SDK}/tools/pci_unbind.py --status
|
||||
echo ""
|
||||
echo -n "Enter PCI address of device to bind to IGB UIO driver: "
|
||||
read PCI_PATH
|
||||
sudo ${RTE_SDK}/tools/pci_unbind.py -b igb_uio $PCI_PATH && echo "OK"
|
||||
else
|
||||
echo "# Please load the 'igb_uio' kernel module before querying or "
|
||||
echo "# adjusting NIC device bindings"
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# Uses pci_unbind.py to move devices to work with kernel drivers again
|
||||
#
|
||||
unbind_nics()
|
||||
{
|
||||
${RTE_SDK}/tools/pci_unbind.py --status
|
||||
echo ""
|
||||
echo -n "Enter PCI address of device to bind to IGB UIO driver: "
|
||||
read PCI_PATH
|
||||
echo ""
|
||||
echo -n "Enter name of kernel driver to bind the device to: "
|
||||
read DRV
|
||||
sudo ${RTE_SDK}/tools/pci_unbind.py -b $DRV $PCI_PATH && echo "OK"
|
||||
}
|
||||
|
||||
#
|
||||
@ -368,6 +406,12 @@ step2_func()
|
||||
|
||||
TEXT[4]="Setup hugepage mappings for NUMA systems"
|
||||
FUNC[4]="set_numa_pages"
|
||||
|
||||
TEXT[5]="Display current Ethernet device settings"
|
||||
FUNC[5]="show_nics"
|
||||
|
||||
TEXT[6]="Bind Ethernet device to IGB UIO module"
|
||||
FUNC[6]="bind_nics"
|
||||
}
|
||||
|
||||
#
|
||||
@ -394,8 +438,6 @@ step4_func()
|
||||
TEXT[1]="List hugepage info from /proc/meminfo"
|
||||
FUNC[1]="grep_meminfo"
|
||||
|
||||
TEXT[2]="List hugepage files in /mnt/huge"
|
||||
FUNC[2]="ls_mnt_huge"
|
||||
}
|
||||
|
||||
#
|
||||
@ -408,14 +450,17 @@ step5_func()
|
||||
TEXT[1]="Uninstall all targets"
|
||||
FUNC[1]="uninstall_targets"
|
||||
|
||||
TEXT[2]="Remove IGB UIO module"
|
||||
FUNC[2]="remove_igb_uio_module"
|
||||
TEXT[2]="Unbind NICs from IGB UIO driver"
|
||||
FUNC[2]="unbind_nics"
|
||||
|
||||
TEXT[3]="Remove KNI module"
|
||||
FUNC[3]="remove_kni_module"
|
||||
TEXT[3]="Remove IGB UIO module"
|
||||
FUNC[3]="remove_igb_uio_module"
|
||||
|
||||
TEXT[4]="Remove hugepage mappings"
|
||||
FUNC[4]="clear_huge_pages"
|
||||
TEXT[4]="Remove KNI module"
|
||||
FUNC[4]="remove_kni_module"
|
||||
|
||||
TEXT[5]="Remove hugepage mappings"
|
||||
FUNC[5]="clear_huge_pages"
|
||||
}
|
||||
|
||||
STEPS[1]="step1_func"
|
||||
|
Loading…
x
Reference in New Issue
Block a user