devargs: allow to provide arguments per pci device

Some PCI drivers may require some specific initialization arguments at
start-up.

Even if unused today, adding this feature seems coherent with virtual
devices in order to provide a full-featured rte_devargs framework. In
the future, it could be added in pmd_ixgbe or pmd_igb for instance to
enable debug of drivers or setting a specific operating mode at
start-up.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
Acked-by: Thomas Monjalon <thomas.monjalon@6wind.com>
This commit is contained in:
Olivier Matz 2014-03-01 13:14:54 +01:00 committed by Thomas Monjalon
parent cac6d08c8b
commit 8e245de6ca
3 changed files with 26 additions and 28 deletions

View File

@ -32,7 +32,7 @@
*/
/* BSD LICENSE
*
* Copyright(c) 2013 6WIND.
* Copyright 2013-2014 6WIND S.A.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -85,17 +85,18 @@
struct pci_driver_list pci_driver_list;
struct pci_device_list pci_device_list;
static int is_blacklisted(struct rte_pci_device *dev)
static struct rte_devargs *pci_devargs_lookup(struct rte_pci_device *dev)
{
struct rte_devargs *devargs;
TAILQ_FOREACH(devargs, &devargs_list, next) {
if (devargs->type != RTE_DEVTYPE_BLACKLISTED_PCI)
if (devargs->type != RTE_DEVTYPE_BLACKLISTED_PCI &&
devargs->type != RTE_DEVTYPE_WHITELISTED_PCI)
continue;
if (!memcmp(&dev->addr, &devargs->pci.addr, sizeof(dev->addr)))
return 1;
return devargs;
}
return 0; /* not in blacklist */
return NULL;
}
/*
@ -113,7 +114,6 @@ pci_probe_all_drivers(struct rte_pci_device *dev)
struct rte_pci_driver *dr = NULL;
int rc;
dev->blacklisted = !!is_blacklisted(dev);
TAILQ_FOREACH(dr, &pci_driver_list, next) {
rc = rte_eal_pci_probe_one_driver(dr, dev);
if (rc < 0)
@ -124,7 +124,8 @@ pci_probe_all_drivers(struct rte_pci_device *dev)
continue;
/* initialize subsequent driver instances for this device */
if ((dr->drv_flags & RTE_PCI_DRV_MULTIPLE) &&
(!dev->blacklisted))
(dev->devargs == NULL ||
dev->devargs->type != RTE_DEVTYPE_BLACKLISTED_PCI))
while (rte_eal_pci_probe_one_driver(dr, dev) == 0)
;
return 0;
@ -132,23 +133,6 @@ pci_probe_all_drivers(struct rte_pci_device *dev)
return -1;
}
/*
* Check if a device is ok to use according to whitelist rules.
*/
static int
pcidev_is_whitelisted(struct rte_pci_device *dev)
{
struct rte_devargs *devargs;
TAILQ_FOREACH(devargs, &devargs_list, next) {
if (devargs->type != RTE_DEVTYPE_WHITELISTED_PCI)
continue;
if (!memcmp(&dev->addr, &devargs->pci.addr, sizeof(dev->addr)))
return 1;
}
return 0;
}
/*
* Scan the content of the PCI bus, and call the devinit() function for
* all registered drivers that have a matching entry in its id_table
@ -158,15 +142,25 @@ int
rte_eal_pci_probe(void)
{
struct rte_pci_device *dev = NULL;
struct rte_devargs *devargs;
int probe_all = 0;
if (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_PCI) == 0)
probe_all = 1;
TAILQ_FOREACH(dev, &pci_device_list, next) {
/* set devargs in PCI structure */
devargs = pci_devargs_lookup(dev);
if (devargs != NULL)
dev->devargs = devargs;
/* probe all or only whitelisted devices */
if (probe_all)
pci_probe_all_drivers(dev);
else if (pcidev_is_whitelisted(dev) && pci_probe_all_drivers(dev) < 0)
else if (devargs != NULL &&
devargs->type == RTE_DEVTYPE_WHITELISTED_PCI &&
pci_probe_all_drivers(dev) < 0)
rte_exit(EXIT_FAILURE, "Requested device " PCI_PRI_FMT
" cannot be used\n", dev->addr.domain, dev->addr.bus,
dev->addr.devid, dev->addr.function);

View File

@ -32,7 +32,7 @@
*/
/* BSD LICENSE
*
* Copyright(c) 2013 6WIND.
* Copyright 2013-2014 6WIND S.A.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@ -136,6 +136,8 @@ struct rte_pci_addr {
uint8_t function; /**< Device function. */
};
struct rte_devargs;
/**
* A structure describing a PCI device.
*/
@ -148,7 +150,7 @@ struct rte_pci_device {
const struct rte_pci_driver *driver; /**< Associated driver */
uint16_t max_vfs; /**< sriov enable if not zero */
int numa_node; /**< NUMA node connection */
unsigned int blacklisted:1; /**< Device is blacklisted */
struct rte_devargs *devargs; /**< Device user arguments */
};
/** Any PCI device identifier (vendor, device, ...) */

View File

@ -64,6 +64,7 @@
#include <rte_malloc.h>
#include <rte_string_fns.h>
#include <rte_debug.h>
#include <rte_devargs.h>
#include "rte_pci_dev_ids.h"
#include "eal_filesystem.h"
@ -1031,7 +1032,8 @@ rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr, struct rte_pci_device *d
dev->id.device_id, dr->name);
/* no initialization when blacklisted, return without error */
if (dev->blacklisted) {
if (dev->devargs != NULL &&
dev->devargs->type == RTE_DEVTYPE_BLACKLISTED_PCI) {
RTE_LOG(DEBUG, EAL, " Device is blacklisted, not initializing\n");
return 0;
}