[dpdk-dev] devargs: add blacklisting by linux interface name

Message ID 1443798007-20122-1-git-send-email-3chas3@gmail.com (mailing list archive)
State Superseded, archived
Headers

Commit Message

Chas Williams Oct. 2, 2015, 3 p.m. UTC
  If a system is using deterministic interface names, it may be easier in
some cases to use the interface name to blacklist an interface.

Signed-off-by: Chas Williams <3chas3@gmail.com>
---
 app/test/test_devargs.c                     |  2 ++
 lib/librte_eal/common/eal_common_devargs.c  |  8 ++++++++
 lib/librte_eal/common/eal_common_options.c  | 10 ++++++++++
 lib/librte_eal/common/eal_common_pci.c      | 17 +++++++++++------
 lib/librte_eal/common/eal_options.h         |  2 ++
 lib/librte_eal/common/include/rte_devargs.h |  5 +++++
 lib/librte_eal/common/include/rte_pci.h     |  1 +
 lib/librte_eal/linuxapp/eal/eal_pci.c       | 15 +++++++++++++++
 8 files changed, 54 insertions(+), 6 deletions(-)
  

Comments

Bruce Richardson Oct. 2, 2015, 3:18 p.m. UTC | #1
On Fri, Oct 02, 2015 at 11:00:07AM -0400, Chas Williams wrote:
> If a system is using deterministic interface names, it may be easier in
> some cases to use the interface name to blacklist an interface.
>

Is it possible to do this using the existing arguments, i.e. have the -b flag
detect if it's a pci address or name automatically, rather than having to use
a separate command-line arg for it?

/Bruce
  
Chas Williams Oct. 2, 2015, 4:38 p.m. UTC | #2
On Fri, 2015-10-02 at 16:18 +0100, Bruce Richardson wrote:
> On Fri, Oct 02, 2015 at 11:00:07AM -0400, Chas Williams wrote:
> > If a system is using deterministic interface names, it may be easier in
> > some cases to use the interface name to blacklist an interface.
> >
> 
> Is it possible to do this using the existing arguments, i.e. have the -b flag
> detect if it's a pci address or name automatically, rather than having to use
> a separate command-line arg for it?

You might be able to distinguish names by context.  I doubt interface
names ever look like PCI addresses.  But that's going to be a bigger
change since -b will need to be updated to 'blacklist' intead of
'pci-blacklist' to prevent confusion.  Or do you just want to overload
'-b' and keep both long options?
  
Bruce Richardson Oct. 2, 2015, 4:44 p.m. UTC | #3
> -----Original Message-----

> From: Charles (Chas) Williams [mailto:3chas3@gmail.com]

> 

> On Fri, 2015-10-02 at 16:18 +0100, Bruce Richardson wrote:

> > On Fri, Oct 02, 2015 at 11:00:07AM -0400, Chas Williams wrote:

> > > If a system is using deterministic interface names, it may be easier

> > > in some cases to use the interface name to blacklist an interface.

> > >

> >

> > Is it possible to do this using the existing arguments, i.e. have the

> > -b flag detect if it's a pci address or name automatically, rather

> > than having to use a separate command-line arg for it?

> 

> You might be able to distinguish names by context.  I doubt interface

> names ever look like PCI addresses.  But that's going to be a bigger

> change since -b will need to be updated to 'blacklist' intead of 'pci-

> blacklist' to prevent confusion.  Or do you just want to overload '-b' and

> keep both long options?

>

I'm not sure about that, to be honest. However, I'd rather not have
too many cmd line options to be maintained in the code. 

Does you proposed blacklisting patch work with non-pci devices as well
as with PCI ones as now?

/Bruce
  
Chas Williams Oct. 2, 2015, 6:29 p.m. UTC | #4
On Fri, 2015-10-02 at 16:44 +0000, Richardson, Bruce wrote:
> > -----Original Message-----
> > From: Charles (Chas) Williams [mailto:3chas3@gmail.com]
> > 
> > On Fri, 2015-10-02 at 16:18 +0100, Bruce Richardson wrote:
> > > On Fri, Oct 02, 2015 at 11:00:07AM -0400, Chas Williams wrote:
> > > > If a system is using deterministic interface names, it may be easier
> > > > in some cases to use the interface name to blacklist an interface.
> > > >
> > >
> > > Is it possible to do this using the existing arguments, i.e. have the
> > > -b flag detect if it's a pci address or name automatically, rather
> > > than having to use a separate command-line arg for it?
> > 
> > You might be able to distinguish names by context.  I doubt interface
> > names ever look like PCI addresses.  But that's going to be a bigger
> > change since -b will need to be updated to 'blacklist' intead of 'pci-
> > blacklist' to prevent confusion.  Or do you just want to overload '-b' and
> > keep both long options?
> >
> I'm not sure about that, to be honest. However, I'd rather not have
> too many cmd line options to be maintained in the code. 
> 
> Does you proposed blacklisting patch work with non-pci devices as well
> as with PCI ones as now?

Unfortunately, the devargs API is rather PCI specific -- it takes a PCI
device.  Nothing prevents you from writing a device specific version of
the devargs API though for your device class since the devargs list isn't
static but checking for certain devargs wouldn't make sense in some cases.
Checking to see if a USB device matched a blacklisted PCI device would
be pointless.

Other devices (like Xen or hyperv) have a net/ directory/link in their /sys
entry that lets you determine an interface name.  I think it's the same
for USB ethernet devices -- I don't happen to have one to check.
  
Chas Williams Oct. 5, 2015, 3:59 p.m. UTC | #5
On Fri, 2015-10-02 at 16:44 +0000, Richardson, Bruce wrote:
> I'm not sure about that, to be honest. However, I'd rather not have
> too many cmd line options to be maintained in the code. 
> 
> Does you proposed blacklisting patch work with non-pci devices as well
> as with PCI ones as now?

I refactored this a bit to fit it into the existing pci blacklisting.
Better?
  

Patch

diff --git a/app/test/test_devargs.c b/app/test/test_devargs.c
index f7fc59c..c204c49 100644
--- a/app/test/test_devargs.c
+++ b/app/test/test_devargs.c
@@ -85,6 +85,8 @@  test_devargs(void)
 		goto fail;
 	if (rte_eal_devargs_type_count(RTE_DEVTYPE_VIRTUAL) != 2)
 		goto fail;
+	if (rte_eal_devargs_add(RTE_DEVTYPE_BLACKLISTED_NAME, "eth0") < 0)
+		goto fail;
 	free_devargs_list();
 
 	/* check virtual device with argument parsing */
diff --git a/lib/librte_eal/common/eal_common_devargs.c b/lib/librte_eal/common/eal_common_devargs.c
index ec56165..cac651b 100644
--- a/lib/librte_eal/common/eal_common_devargs.c
+++ b/lib/librte_eal/common/eal_common_devargs.c
@@ -113,6 +113,14 @@  rte_eal_devargs_add(enum rte_devtype devtype, const char *devargs_str)
 			goto fail;
 
 		break;
+	case RTE_DEVTYPE_BLACKLISTED_NAME:
+		/* save interface name */
+		ret = snprintf(devargs->name.name,
+			       sizeof(devargs->name.name), "%s", buf);
+		if (ret < 0 || ret >= (int)sizeof(devargs->name.name))
+			goto fail;
+
+		break;
 	}
 
 	free(buf);
diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
index 1f459ac..c08126d 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -90,6 +90,7 @@  eal_long_options[] = {
 	{OPT_VFIO_INTR,         1, NULL, OPT_VFIO_INTR_NUM        },
 	{OPT_VMWARE_TSC_MAP,    0, NULL, OPT_VMWARE_TSC_MAP_NUM   },
 	{OPT_XEN_DOM0,          0, NULL, OPT_XEN_DOM0_NUM         },
+	{OPT_BLACKLISTED_NAME,  1, NULL, OPT_BLACKLISTED_NAME_NUM },
 	{0,                     0, NULL, 0                        }
 };
 
@@ -785,6 +786,13 @@  eal_parse_common_option(int opt, const char *optarg,
 		}
 		break;
 
+	case OPT_BLACKLISTED_NAME_NUM:
+		if (rte_eal_devargs_add(RTE_DEVTYPE_BLACKLISTED_NAME,
+				optarg) < 0) {
+			return -1;
+		}
+		break;
+
 	/* don't know what to do, leave this to caller */
 	default:
 		return 1;
@@ -898,6 +906,8 @@  eal_common_usage(void)
 	       "  --"OPT_VDEV"              Add a virtual device.\n"
 	       "                      The argument format is <driver><id>[,key=val,...]\n"
 	       "                      (ex: --vdev=eth_pcap0,iface=eth2).\n"
+	       "  --"OPT_BLACKLISTED_NAME" Add a device name to the black list.\n"
+	       "                      Prevent EAL from using this named interface.\n"
 	       "  --"OPT_VMWARE_TSC_MAP"    Use VMware TSC map instead of native RDTSC\n"
 	       "  --"OPT_PROC_TYPE"         Type of this process (primary|secondary|auto)\n"
 	       "  --"OPT_SYSLOG"            Set syslog facility\n"
diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c
index dcfe947..41a7690 100644
--- a/lib/librte_eal/common/eal_common_pci.c
+++ b/lib/librte_eal/common/eal_common_pci.c
@@ -90,11 +90,15 @@  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 &&
-			devargs->type != RTE_DEVTYPE_WHITELISTED_PCI)
-			continue;
-		if (!rte_eal_compare_pci_addr(&dev->addr, &devargs->pci.addr))
-			return devargs;
+		if (devargs->type == RTE_DEVTYPE_BLACKLISTED_PCI ||
+			devargs->type == RTE_DEVTYPE_WHITELISTED_PCI) {
+			if (!rte_eal_compare_pci_addr(&dev->addr, &devargs->pci.addr))
+				return devargs;
+		}
+		if (devargs->type == RTE_DEVTYPE_BLACKLISTED_NAME) {
+			if (strcmp(dev->name, devargs->name.name) == 0)
+				return devargs;
+		}
 	}
 	return NULL;
 }
@@ -174,7 +178,8 @@  rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr, struct rte_pci_device *d
 
 		/* no initialization when blacklisted, return without error */
 		if (dev->devargs != NULL &&
-			dev->devargs->type == RTE_DEVTYPE_BLACKLISTED_PCI) {
+			(dev->devargs->type == RTE_DEVTYPE_BLACKLISTED_PCI ||
+			 dev->devargs->type == RTE_DEVTYPE_BLACKLISTED_NAME)) {
 			RTE_LOG(DEBUG, EAL, "  Device is blacklisted, not initializing\n");
 			return 1;
 		}
diff --git a/lib/librte_eal/common/eal_options.h b/lib/librte_eal/common/eal_options.h
index f6714d9..2aea553 100644
--- a/lib/librte_eal/common/eal_options.h
+++ b/lib/librte_eal/common/eal_options.h
@@ -45,6 +45,8 @@  enum {
 	/* first long only option value must be >= 256, so that we won't
 	 * conflict with short options */
 	OPT_LONG_MIN_NUM = 256,
+#define OPT_BLACKLISTED_NAME  "blacklisted-name"
+	OPT_BLACKLISTED_NAME_NUM,
 #define OPT_BASE_VIRTADDR     "base-virtaddr"
 	OPT_BASE_VIRTADDR_NUM,
 #define OPT_CREATE_UIO_DEV    "create-uio-dev"
diff --git a/lib/librte_eal/common/include/rte_devargs.h b/lib/librte_eal/common/include/rte_devargs.h
index 7084ae2..8531405 100644
--- a/lib/librte_eal/common/include/rte_devargs.h
+++ b/lib/librte_eal/common/include/rte_devargs.h
@@ -59,6 +59,7 @@  enum rte_devtype {
 	RTE_DEVTYPE_WHITELISTED_PCI,
 	RTE_DEVTYPE_BLACKLISTED_PCI,
 	RTE_DEVTYPE_VIRTUAL,
+	RTE_DEVTYPE_BLACKLISTED_NAME,
 };
 
 /**
@@ -87,6 +88,10 @@  struct rte_devargs {
 			/** Driver name. */
 			char drv_name[32];
 		} virtual;
+		struct {
+			/** Interface name. */
+			char name[32];
+		} name;
 	};
 	/** Arguments string as given by user or "" for no argument. */
 	char *args;
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
index 83e3c28..852c149 100644
--- a/lib/librte_eal/common/include/rte_pci.h
+++ b/lib/librte_eal/common/include/rte_pci.h
@@ -161,6 +161,7 @@  struct rte_pci_device {
 	struct rte_pci_resource mem_resource[PCI_MAX_RESOURCE];   /**< PCI Memory Resource */
 	struct rte_intr_handle intr_handle;     /**< Interrupt handle */
 	struct rte_pci_driver *driver;          /**< Associated driver */
+	char name[32];				/**< Interface name (if any) */
 	uint16_t max_vfs;                       /**< sriov enable if not zero */
 	int numa_node;                          /**< NUMA node connection */
 	struct rte_devargs *devargs;            /**< Device user arguments */
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
index bc5b5be..c417d01 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
@@ -260,6 +260,8 @@  pci_scan_one(const char *dirname, uint16_t domain, uint8_t bus,
 	unsigned long tmp;
 	struct rte_pci_device *dev;
 	char driver[PATH_MAX];
+	struct dirent *e;
+	DIR *dir;
 	int ret;
 
 	dev = malloc(sizeof(*dev));
@@ -352,6 +354,19 @@  pci_scan_one(const char *dirname, uint16_t domain, uint8_t bus,
 		return -1;
 	}
 
+	/* get network interface name */
+	snprintf(filename, sizeof(filename), "%s/net", dirname);
+	dir = opendir(filename);
+	if (dir) {
+		while ((e = readdir(dir)) != NULL) {
+			if (e->d_name[0] == '.')
+				continue;
+
+			strcpy(dev->name, e->d_name);
+		}
+		closedir(dir);
+	}
+
 	if (!ret) {
 		if (!strcmp(driver, "vfio-pci"))
 			dev->kdrv = RTE_KDRV_VFIO;