DPDK patches and discussions
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH 00/11] eal: allow virtual pmd drivers as shared lib
@ 2014-02-28 17:25 Olivier Matz
  2014-02-28 17:25 ` [dpdk-dev] [PATCH 01/11] mk: use whole-archive option when creating dpdk binaries Olivier Matz
                   ` (10 more replies)
  0 siblings, 11 replies; 57+ messages in thread
From: Olivier Matz @ 2014-02-28 17:25 UTC (permalink / raw)
  To: dev

The main goal of the following commits is to be able to load a PMD
virtual device driver as a shared library (DPDK extension). Today it is
already possible to load an external PMD PCI driver (ex: memnic,
virtio-net-pmd, ...), but the DPDK framework does not allow to load a
virtual device driver in this way. For instance, adding the support of
host-side in memnic would require these patches.

How it worked before the patch
------------------------------

Example of what occurs when we started testpmd:

  testpmd -c 0x15 -n 3 \
    --proc-type=primary --huge-dir=/mnt/huge --use-device=eth_ring0 \
    --use-device=eth_ring1 \
    --use-device=02:00.0 \
    -- -i --port-topology=chained

For each "--use-device" option, we call eal_dev_whitelist_add_entry():

  main()
    rte_eal_init()
      eal_parse_args()
        eal_dev_whitelist_add_entry()

Each device is appended in a global string. After parsing all the
"--use-device" argumentss, we have dev_list_str="eth_ring0,eth_ring1,".

Then, after all eal arguments are parsed, eal_dev_whitelist_parse() is
called:

  main()
    rte_eal_init()
      eal_parse_args()
        eal_dev_whitelist_parse()
          is_valid_wl_entry()

It removes the extra ',' at the end of dev_list_str. Then, it splits
each device name and its argument (separated by ';'). Each device is
checked by is_valid_wl_entry(). It checks that the PCI identifier is
correct or that the name of the device starts with a known prefix
("eth_ring", "eth_pcap" or "eth_xenvirt", defined statically in eal code).

Then, rte_eal_pci_init() is called, it scans the PCI bus:

  main()
    rte_eal_init()
      rte_eal_pci_init()

After that, rte_eal_non_pci_ethdev_init() tries all combination:
"eth_ring0", "eth_ring1", ..., "eth_ring31", "eth_pcap0", ...,
"eth_pcap31", ..., "-nodev-0", ..., "-nodev-31". For each, test if it
is in whitelist or not:

  main()
    rte_eal_init()
      rte_eal_non_pci_ethdev_init()
        eal_dev_is_whitelisted(name, &params) # fills params
        dev_types[i].init_fn(name, params) [ex: rte_pmd_ring_init()]
          ...
            rte_eth_dev_allocate()

To check that, eal_dev_is_whitelisted() browse the list of devices in
the whitelist. Then, the init function of the device allocates the
ethernet device structure (attributing a port_id).

The main application then calls rte_pmd_init_all(). It initializes all
poll-mode drivers. Each driver calls rte_eth_driver_register(), like in
this example:

  main()
    rte_pmd_init_all()
      rte_igb_pmd_init()
        rte_eth_driver_register()

The probing of the PCI bus is done using rte_eal_pci_probe(), which
calls pci_probe_all_drivers(dev) for each PCI device:

  main()
    rte_eal_pci_probe()
      pcidev_is_whitelisted(dev)
      pci_probe_all_drivers(dev)
        rte_eal_pci_probe_one_driver(dev, driver)
          driver->devinit(driver, dev) [rte_eth_dev_init()]
            rte_eth_dev_allocate()
            eth_drv->eth_dev_init(eth_drv, eth_dev) [ex: eth_em_dev_init()]

List of problems
----------------

- pmd_ring, pmd_pcap and pmd_xenvirt are referenced in eal code:
  - it's not possible to add a new virtual pmd dynamically
  - eal compilation depends on these pmd... but the pmd depends on eal.
  - it's referenced twice with duplicated values: eal_common_nonpci_devs.c
    and eal_common_whitelist.c

- the parsing of virtual devices arguments is complex:
  - they are all appended in a global string then split again

- there are 2 ways to do the same thing, like in the following example:
  - --use-device="eth_ring0,eth_pcap0;iface=ixgbe0"
  - --use-device="eth_ring0" --use-device="eth_pcap0;iface=ixgbe0"

- the same --use-device option is used for both pci whitelist and
  virtual devices

- files and functions related to virtual devices are called 'non_pci',
  'vdev' would be clearer (all non_pci devices aren't virtual devices).

- using ";" to separate a device and its argument is not a good idea in
  a command line argument as it can be used in shell to separate
  commands.

- it is not possible to use the blacklist mode (bind all devices) while
  we add virtual devices.

Summary of the changes introduced by the patchset
-------------------------------------------------

- allow to register a virtual device driver from a dpdk extension
  provided as a shared library

- embed all library symbols in dpdk library.

- remove references to rte_pmd_ring, rte_pmd_pcap and rte_pmd_xenvirt in
  eal code

- add a new rte_devargs file in eal that unifies the code storing the
  user arguments pci-blacklist, pci-whitelist, and virtual devices
  arguments in one file

- rework eal user arguments
  - "--use-device" becomes "--pci-whitelist" and "--vdev"
  - replace ";" by "," when parsing device args

- support start-up arguments for PCI devices


Olivier Matz (11):
  mk: use whole-archive option when creating dpdk binaries
  devices-args: introduce rte_devargs in eal
  devices-args: use rte_devargs and remove old whitelist code
  devices-args: add a dump_devargs command in basic test application
  pci: rename device_list as pci_device_list
  vdev: rename eal_common_nonpci_devs.c as eal_common_vdev.c
  vdev: allow external registration of virtual device drivers
  device-args: use a comma instead of semicolon to separate key/values
  device-args: replace use-device eal option by pci-whitelist and vdev
  device-args: allow to provide per pci device command line arguments
  testpmd: add several dump commands, useful for debug

 app/test-pmd/cmdline.c                         | 114 +++++++++++++
 app/test/Makefile                              |   1 +
 app/test/commands.c                            |   9 +-
 app/test/test.h                                |   1 +
 app/test/test_devargs.c                        | 132 ++++++++++++++
 app/test/test_eal_flags.c                      |  70 ++------
 app/test/test_kvargs.c                         |  14 +-
 app/test/test_pci.c                            |  55 +++---
 app/test/test_pmd_ring.c                       |   6 +-
 lib/librte_eal/common/Makefile                 |   2 +-
 lib/librte_eal/common/eal_common_devargs.c     | 153 +++++++++++++++++
 lib/librte_eal/common/eal_common_nonpci_devs.c |  93 ----------
 lib/librte_eal/common/eal_common_pci.c         |  98 +++++------
 lib/librte_eal/common/eal_common_vdev.c        | 107 ++++++++++++
 lib/librte_eal/common/eal_common_whitelist.c   | 227 -------------------------
 lib/librte_eal/common/include/eal_private.h    |  42 +----
 lib/librte_eal/common/include/rte_devargs.h    | 140 +++++++++++++++
 lib/librte_eal/common/include/rte_pci.h        |  20 +--
 lib/librte_eal/common/include/rte_vdev.h       |  90 ++++++++++
 lib/librte_eal/linuxapp/eal/Makefile           |   4 +-
 lib/librte_eal/linuxapp/eal/eal.c              | 114 +++++++------
 lib/librte_eal/linuxapp/eal/eal_ivshmem.c      |   2 +-
 lib/librte_eal/linuxapp/eal/eal_pci.c          |  16 +-
 lib/librte_kvargs/rte_kvargs.h                 |   6 +-
 lib/librte_pmd_pcap/rte_eth_pcap.c             |  16 +-
 lib/librte_pmd_pcap/rte_eth_pcap.h             |   8 -
 lib/librte_pmd_ring/rte_eth_ring.c             |  17 +-
 lib/librte_pmd_ring/rte_eth_ring.h             |   6 +-
 lib/librte_pmd_xenvirt/rte_eth_xenvirt.c       |  14 +-
 lib/librte_pmd_xenvirt/rte_eth_xenvirt.h       |   4 +-
 mk/rte.app.mk                                  |   5 +
 31 files changed, 987 insertions(+), 599 deletions(-)
 create mode 100644 app/test/test_devargs.c
 create mode 100644 lib/librte_eal/common/eal_common_devargs.c
 delete mode 100644 lib/librte_eal/common/eal_common_nonpci_devs.c
 create mode 100644 lib/librte_eal/common/eal_common_vdev.c
 delete mode 100644 lib/librte_eal/common/eal_common_whitelist.c
 create mode 100644 lib/librte_eal/common/include/rte_devargs.h
 create mode 100644 lib/librte_eal/common/include/rte_vdev.h

-- 
1.8.5.3

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [dpdk-dev] [PATCH 01/11] mk: use whole-archive option when creating dpdk binaries
  2014-02-28 17:25 [dpdk-dev] [PATCH 00/11] eal: allow virtual pmd drivers as shared lib Olivier Matz
@ 2014-02-28 17:25 ` Olivier Matz
  2014-04-10 13:58   ` Thomas Monjalon
  2014-02-28 17:25 ` [dpdk-dev] [PATCH 02/11] devices-args: introduce rte_devargs in eal Olivier Matz
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 57+ messages in thread
From: Olivier Matz @ 2014-02-28 17:25 UTC (permalink / raw)
  To: dev

To fully support dpdk extensions (loading of .so), all symbols provided
by dpdk libraries must be available in the binaries: before this patch,
unused functions/variables from dpdk static libraries could be stripped
by the linker because they are not used. These symbols can be used by a
dpdk extension that is loaded at runtime with the -d option.

Adding --whole-archive when generating a binary solves this issue.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 mk/rte.app.mk | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index d90a0b0..6f21e16 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -1,6 +1,7 @@
 #   BSD LICENSE
 # 
 #   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+#   Copyright(c) 2014 6WIND S.A.
 #   All rights reserved.
 # 
 #   Redistribution and use in source and binary forms, with or without
@@ -58,6 +59,8 @@ LDLIBS += -L$(RTE_SDK_BIN)/lib
 #
 ifeq ($(NO_AUTOLIBS),)
 
+LDLIBS += --whole-archive
+
 ifeq ($(CONFIG_RTE_LIBRTE_KNI),y)
 ifeq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
 LDLIBS += -lrte_kni
@@ -180,6 +183,8 @@ LDLIBS += $(EXECENV_LDLIBS)
 
 LDLIBS += --end-group
 
+LDLIBS += --no-whole-archive
+
 endif # ifeq ($(NO_AUTOLIBS),)
 
 LDLIBS += $(CPU_LDLIBS)
-- 
1.8.5.3

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [dpdk-dev] [PATCH 02/11] devices-args: introduce rte_devargs in eal
  2014-02-28 17:25 [dpdk-dev] [PATCH 00/11] eal: allow virtual pmd drivers as shared lib Olivier Matz
  2014-02-28 17:25 ` [dpdk-dev] [PATCH 01/11] mk: use whole-archive option when creating dpdk binaries Olivier Matz
@ 2014-02-28 17:25 ` Olivier Matz
  2014-02-28 21:39   ` Stephen Hemminger
  2014-02-28 17:25 ` [dpdk-dev] [PATCH 03/11] devices-args: use rte_devargs and remove old whitelist code Olivier Matz
                   ` (8 subsequent siblings)
  10 siblings, 1 reply; 57+ messages in thread
From: Olivier Matz @ 2014-02-28 17:25 UTC (permalink / raw)
  To: dev

This commit introduces a new API for storing device arguments given by
the user. It only adds the framework and the test. The modification of
EAL to use this new module is done in next commit.

The final goals:

- unify pci-blacklist, pci-whitelist, and virtual devices arguments
  in one file
- allow to register a virtual device driver from a dpdk extension
  provided as a shared library. For that we will require to remove
  references to rte_pmd_ring and rte_pmd_pcap in argument parsing code
- clarify the API of eal_common_whitelist.c, and rework its code that is
  often complex for no reason.
- support arguments for PCI devices and possibly future non-PCI devices
  (other than virtual devices) without effort.

Test result:

echo 100 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages
echo 100 > /sys/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages
./app/test -c 0x15 -n 3 -m 64
RTE>>eal_flags_autotest
[...]
Test OK

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 app/test/Makefile                           |   1 +
 app/test/commands.c                         |   3 +
 app/test/test.h                             |   1 +
 app/test/test_devargs.c                     | 132 ++++++++++++++++++++++++
 lib/librte_eal/common/Makefile              |   2 +-
 lib/librte_eal/common/eal_common_devargs.c  | 153 ++++++++++++++++++++++++++++
 lib/librte_eal/common/include/rte_devargs.h | 140 +++++++++++++++++++++++++
 lib/librte_eal/linuxapp/eal/Makefile        |   1 +
 8 files changed, 432 insertions(+), 1 deletion(-)
 create mode 100644 app/test/test_devargs.c
 create mode 100644 lib/librte_eal/common/eal_common_devargs.c
 create mode 100644 lib/librte_eal/common/include/rte_devargs.h

diff --git a/app/test/Makefile b/app/test/Makefile
index 28f1f62..b49785e 100644
--- a/app/test/Makefile
+++ b/app/test/Makefile
@@ -93,6 +93,7 @@ SRCS-$(CONFIG_RTE_APP_TEST) += test_power.c
 SRCS-$(CONFIG_RTE_APP_TEST) += test_common.c
 SRCS-$(CONFIG_RTE_APP_TEST) += test_timer_perf.c
 SRCS-$(CONFIG_RTE_APP_TEST) += test_ivshmem.c
+SRCS-$(CONFIG_RTE_APP_TEST) += test_devargs.c
 
 ifeq ($(CONFIG_RTE_APP_TEST),y)
 SRCS-$(CONFIG_RTE_LIBRTE_ACL) += test_acl.c
diff --git a/app/test/commands.c b/app/test/commands.c
index a153026..7595b4c 100644
--- a/app/test/commands.c
+++ b/app/test/commands.c
@@ -178,6 +178,8 @@ static void cmd_autotest_parsed(void *parsed_result,
 		ret = test_common();
 	if (!strcmp(res->autotest, "ivshmem_autotest"))
 		ret = test_ivshmem();
+	if (!strcmp(res->autotest, "devargs_autotest"))
+		ret = test_devargs();
 #ifdef RTE_LIBRTE_PMD_RING
 	if (!strcmp(res->autotest, "ring_pmd_autotest"))
 		ret = test_pmd_ring();
@@ -223,6 +225,7 @@ cmdline_parse_token_string_t cmd_autotest_autotest =
 			"red_autotest#meter_autotest#sched_autotest#"
 			"memcpy_perf_autotest#kni_autotest#"
 			"pm_autotest#ivshmem_autotest#"
+			"devargs_autotest#"
 #ifdef RTE_LIBRTE_ACL
 			"acl_autotest#"
 #endif
diff --git a/app/test/test.h b/app/test/test.h
index bc001b9..1945d29 100644
--- a/app/test/test.h
+++ b/app/test/test.h
@@ -93,6 +93,7 @@ int test_common(void);
 int test_pmd_ring(void);
 int test_ivshmem(void);
 int test_kvargs(void);
+int test_devargs(void);
 
 int test_pci_run;
 
diff --git a/app/test/test_devargs.c b/app/test/test_devargs.c
new file mode 100644
index 0000000..4d45d53
--- /dev/null
+++ b/app/test/test_devargs.c
@@ -0,0 +1,132 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2014 6WIND S.A.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of 6WIND S.A nor the names of its contributors
+ *       may be used to endorse or promote products derived from this
+ *       software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/queue.h>
+
+#include <rte_debug.h>
+#include <rte_devargs.h>
+
+#include "test.h"
+
+/* clear devargs list that was modified by the test */
+static void free_devargs_list(void)
+{
+	struct rte_devargs *devargs;
+
+	while (!TAILQ_EMPTY(&devargs_list)) {
+		devargs = TAILQ_FIRST(&devargs_list);
+		TAILQ_REMOVE(&devargs_list, devargs, next);
+		free(devargs);
+	}
+}
+
+int
+test_devargs(void)
+{
+	struct rte_devargs_list save_devargs_list;
+	struct rte_devargs *devargs;
+
+	/* save the real devargs_list, it is restored at the end of the test */
+	save_devargs_list = devargs_list;
+	TAILQ_INIT(&devargs_list);
+
+	/* test valid cases */
+	if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, "08:00.1") < 0)
+		goto fail;
+	if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, "0000:5:00.0") < 0)
+		goto fail;
+	if (rte_eal_devargs_add(RTE_DEVTYPE_BLACKLISTED_PCI, "04:00.0;arg=val") < 0)
+		goto fail;
+	if (rte_eal_devargs_add(RTE_DEVTYPE_BLACKLISTED_PCI, "0000:01:00.1") < 0)
+		goto fail;
+	if (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_PCI) != 2)
+		goto fail;
+	if (rte_eal_devargs_type_count(RTE_DEVTYPE_BLACKLISTED_PCI) != 2)
+		goto fail;
+	if (rte_eal_devargs_type_count(RTE_DEVTYPE_VIRTUAL) != 0)
+		goto fail;
+	if (rte_eal_devargs_add(RTE_DEVTYPE_VIRTUAL, "eth_ring0") < 0)
+		goto fail;
+	if (rte_eal_devargs_add(RTE_DEVTYPE_VIRTUAL, "eth_ring1;key=val;k2=val2") < 0)
+		goto fail;
+	if (rte_eal_devargs_type_count(RTE_DEVTYPE_VIRTUAL) != 2)
+		goto fail;
+	free_devargs_list();
+
+	/* check virtual device with argument parsing */
+	if (rte_eal_devargs_add(RTE_DEVTYPE_VIRTUAL, "eth_ring1;k1=val;k2=val2") < 0)
+		goto fail;
+	devargs = TAILQ_FIRST(&devargs_list);
+	if (strncmp(devargs->virtual.drv_name, "eth_ring1",
+			sizeof(devargs->virtual.drv_name) != 0))
+		goto fail;
+	if (strncmp(devargs->args, "k1=val;k2=val2", sizeof(devargs->args) != 0))
+		goto fail;
+	free_devargs_list();
+
+	/* check PCI device with empty argument parsing */
+	if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, "04:00.1") < 0)
+		goto fail;
+	devargs = TAILQ_FIRST(&devargs_list);
+	if (devargs->pci.addr.domain != 0 ||
+		devargs->pci.addr.bus != 4 ||
+		devargs->pci.addr.devid != 0 ||
+		devargs->pci.addr.function != 1)
+		goto fail;
+	if (strncmp(devargs->args, "", sizeof(devargs->args) != 0))
+		goto fail;
+	free_devargs_list();
+
+	/* test error case: bad PCI address */
+	if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, "08:1") == 0)
+		goto fail;
+	if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, "00.1") == 0)
+		goto fail;
+	if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, "foo") == 0)
+		goto fail;
+	if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, ";") == 0)
+		goto fail;
+	if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, "000f:0:0") == 0)
+		goto fail;
+
+	devargs_list = save_devargs_list;
+	return 0;
+
+ fail:
+	free_devargs_list();
+	devargs_list = save_devargs_list;
+	return -1;
+}
diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index f7b581e..b9f3b88 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -38,7 +38,7 @@ INC += rte_pci_dev_ids.h rte_per_lcore.h rte_prefetch.h rte_random.h
 INC += rte_rwlock.h rte_spinlock.h rte_tailq.h rte_interrupts.h rte_alarm.h
 INC += rte_string_fns.h rte_cpuflags.h rte_version.h rte_tailq_elem.h
 INC += rte_eal_memconfig.h rte_malloc_heap.h
-INC += rte_hexdump.h
+INC += rte_hexdump.h rte_devargs.h
 
 ifeq ($(CONFIG_RTE_INSECURE_FUNCTION_WARNING),y)
 INC += rte_warnings.h
diff --git a/lib/librte_eal/common/eal_common_devargs.c b/lib/librte_eal/common/eal_common_devargs.c
new file mode 100644
index 0000000..de4ac6c
--- /dev/null
+++ b/lib/librte_eal/common/eal_common_devargs.c
@@ -0,0 +1,153 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2014 6WIND S.A.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of 6WIND S.A nor the names of its contributors
+ *       may be used to endorse or promote products derived from this
+ *       software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* This file manages the list of devices and their arguments, as given
+ * by the user at startup */
+
+#include <string.h>
+
+#include <rte_log.h>
+#include <rte_pci.h>
+#include <rte_devargs.h>
+#include "eal_private.h"
+
+/** Global list of user devices */
+struct rte_devargs_list devargs_list =
+	TAILQ_HEAD_INITIALIZER(devargs_list);
+
+/* store a whitelist parameter for later parsing */
+int
+rte_eal_devargs_add(enum rte_devtype devtype, const char *devargs_str)
+{
+	struct rte_devargs *devargs;
+	char buf[RTE_DEVARGS_LEN];
+	char *sep;
+	int ret;
+
+	ret = snprintf(buf, sizeof(buf), "%s", devargs_str);
+	if (ret < 0 || ret >= (int)sizeof(buf)) {
+		RTE_LOG(ERR, EAL, "user device args too large: <%s>\n",
+			devargs_str);
+		return -1;
+	}
+
+	/* use malloc instead of rte_malloc as it's called early at init */
+	devargs = malloc(sizeof(*devargs));
+	if (devargs == NULL) {
+		RTE_LOG(ERR, EAL, "cannot allocate devargs\n");
+		return -1;
+	}
+	memset(devargs, 0, sizeof(*devargs));
+	devargs->type = devtype;
+
+	/* set the first ';' to '\0' to split name and arguments */
+	sep = strchr(buf, ';');
+	if (sep != NULL) {
+		sep[0] = '\0';
+		snprintf(devargs->args, sizeof(devargs->args), "%s", sep + 1);
+	}
+
+	switch (devargs->type) {
+		case RTE_DEVTYPE_WHITELISTED_PCI:
+		case RTE_DEVTYPE_BLACKLISTED_PCI:
+			/* try to parse pci identifier */
+			if (eal_parse_pci_BDF(buf, &devargs->pci.addr) != 0 &&
+				eal_parse_pci_DomBDF(buf, &devargs->pci.addr) != 0) {
+				RTE_LOG(ERR, EAL,
+					"invalid PCI identifier <%s>\n", buf);
+				free(devargs);
+				return -1;
+			}
+			break;
+		case RTE_DEVTYPE_VIRTUAL:
+			/* save driver name */
+			ret = snprintf(devargs->virtual.drv_name,
+				sizeof(devargs->virtual.drv_name), "%s", buf);
+			if (ret < 0 || ret >= (int)sizeof(devargs->virtual.drv_name)) {
+				RTE_LOG(ERR, EAL,
+					"driver name too large: <%s>\n", buf);
+				free(devargs);
+				return -1;
+			}
+			break;
+	}
+
+	TAILQ_INSERT_TAIL(&devargs_list, devargs, next);
+	return 0;
+}
+
+/* count the number of devices of a specified type */
+unsigned int
+rte_eal_devargs_type_count(enum rte_devtype devtype)
+{
+	struct rte_devargs *devargs;
+	unsigned int count = 0;
+
+	TAILQ_FOREACH(devargs, &devargs_list, next) {
+		if (devargs->type != devtype)
+			continue;
+		count++;
+	}
+	return count;
+}
+
+/* dump the user devices on the console */
+void
+rte_eal_devargs_dump(void)
+{
+	struct rte_devargs *devargs;
+
+	printf("User device white list:\n");
+	TAILQ_FOREACH(devargs, &devargs_list, next) {
+		if (devargs->type == RTE_DEVTYPE_WHITELISTED_PCI)
+			printf("  PCI whitelist " PCI_PRI_FMT " %s\n",
+			       devargs->pci.addr.domain,
+			       devargs->pci.addr.bus,
+			       devargs->pci.addr.devid,
+			       devargs->pci.addr.function,
+			       devargs->args);
+		else if (devargs->type == RTE_DEVTYPE_BLACKLISTED_PCI)
+			printf("  PCI blacklist " PCI_PRI_FMT " %s\n",
+			       devargs->pci.addr.domain,
+			       devargs->pci.addr.bus,
+			       devargs->pci.addr.devid,
+			       devargs->pci.addr.function,
+			       devargs->args);
+		else if (devargs->type == RTE_DEVTYPE_VIRTUAL)
+			printf("  VIRTUAL %s %s\n",
+			       devargs->virtual.drv_name,
+			       devargs->args);
+		else
+			printf("  UNKNOWN %s\n", devargs->args);
+	}
+}
diff --git a/lib/librte_eal/common/include/rte_devargs.h b/lib/librte_eal/common/include/rte_devargs.h
new file mode 100644
index 0000000..fbfbe45
--- /dev/null
+++ b/lib/librte_eal/common/include/rte_devargs.h
@@ -0,0 +1,140 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2014 6WIND S.A.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of 6WIND S.A nor the names of its contributors
+ *       may be used to endorse or promote products derived from this
+ *       software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_DEVARGS_H_
+#define _RTE_DEVARGS_H_
+
+/**
+ * @file
+ *
+ * RTE devargs: list of devices and their user arguments
+ *
+ * This file stores a list of devices and their arguments given by
+ * the user when a DPDK application is started. These devices can be PCI
+ * devices or virtual devices. These devices are stored at startup in a
+ * list of rte_devargs structures.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/queue.h>
+#include <rte_pci.h>
+
+/**
+ * Type of generic device
+ */
+enum rte_devtype {
+	RTE_DEVTYPE_WHITELISTED_PCI,
+	RTE_DEVTYPE_BLACKLISTED_PCI,
+	RTE_DEVTYPE_VIRTUAL,
+};
+
+/**
+ * Structure that stores a device given by the user with its arguments
+ *
+ * A user device is a physical or a virtual device given by the user to
+ * the DPDK application at startup through command line arguments.
+ *
+ * The structure stores the configuration of the device, its PCI
+ * identifier if it's a PCI device or the driver name if it's a virtual
+ * device.
+ */
+struct rte_devargs {
+	TAILQ_ENTRY(rte_devargs) next;            /**< Next in list. */
+	enum rte_devtype type;                    /**< Type of device. */
+	union {
+		struct {
+			struct rte_pci_addr addr; /**< PCI location. */
+		} pci;              /**< Used if type is RTE_DEVTYPE_*_PCI. */
+		struct {
+			char drv_name[32];        /**< Driver name. */
+		} virtual;          /**< Used if type is RTE_DEVTYPE_VIRTUAL. */
+	};
+#define RTE_DEVARGS_LEN 256
+	char args[RTE_DEVARGS_LEN]; /**< Arguments string as given by user. */
+};
+
+/** user device double-linked queue type definition */
+TAILQ_HEAD(rte_devargs_list, rte_devargs);
+
+/** Global list of user devices */
+extern struct rte_devargs_list devargs_list;
+
+/**
+ * Add a device to the user device list
+ *
+ * For PCI devices, the format of arguments string is "PCI_ADDR" or
+ * "PCI_ADDR;key=val;key2=val2;...". Examples: "08:00.1", "0000:5:00.0",
+ * "04:00.0;arg=val".
+ *
+ * For virtual devices, the format of arguments string is "DRIVER_NAME*"
+ * or "DRIVER_NAME*;key=val;key2=val2;...". Examples: "eth_ring",
+ * "eth_ring0", "eth_pmdAnything;arg=0:arg2=1". The validity of the
+ * driver name is not checked by this function, it is done when probing
+ * the drivers.
+ *
+ * @param devtype
+ *   The type of the device.
+ * @param devargs_list
+ *   The arguments as given by the user.
+ *
+ * @return
+ *   - 0 on success
+ *   - A negative value on error
+ */
+int rte_eal_devargs_add(enum rte_devtype devtype, const char *devargs_str);
+
+/**
+ * Count the number of user devices of a specified type
+ *
+ * @param devtype
+ *   The type of the devices to counted.
+ *
+ * @return
+ *   The number of devices.
+ */
+unsigned int
+rte_eal_devargs_type_count(enum rte_devtype devtype);
+
+/**
+ * This function dumps the list of user device and their arguments.
+ */
+void rte_eal_devargs_dump(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_DEVARGS_H_ */
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index b525130..f57fda5 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -77,6 +77,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_errno.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_cpuflags.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_hexdump.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_whitelist.c
+SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_devargs.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_nonpci_devs.c
 
 CFLAGS_eal.o := -D_GNU_SOURCE
-- 
1.8.5.3

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [dpdk-dev] [PATCH 03/11] devices-args: use rte_devargs and remove old whitelist code
  2014-02-28 17:25 [dpdk-dev] [PATCH 00/11] eal: allow virtual pmd drivers as shared lib Olivier Matz
  2014-02-28 17:25 ` [dpdk-dev] [PATCH 01/11] mk: use whole-archive option when creating dpdk binaries Olivier Matz
  2014-02-28 17:25 ` [dpdk-dev] [PATCH 02/11] devices-args: introduce rte_devargs in eal Olivier Matz
@ 2014-02-28 17:25 ` Olivier Matz
  2014-03-01 12:14   ` [dpdk-dev] [PATCH v2 " Olivier Matz
  2014-02-28 17:25 ` [dpdk-dev] [PATCH 04/11] devices-args: add a dump_devargs command in basic test application Olivier Matz
                   ` (7 subsequent siblings)
  10 siblings, 1 reply; 57+ messages in thread
From: Olivier Matz @ 2014-02-28 17:25 UTC (permalink / raw)
  To: dev

Remove old whitelist code:
- remove references to rte_pmd_ring, rte_pmd_pcap and pmd_xenvirt in
  is_valid_wl_entry() as we want to be able to register external virtual
  drivers as a shared library. Moreover this code was duplicated with
  dev_types[] from eal_common_pci.c
- eal_common_whitelist.c was badly named: it was able to process PCI
  devices white list and the registration of virtual devices
- the parsing code was complex: all arguments were prepended in
  one string dev_list_str[4096], then split again

Use the newly introduced rte_devargs to get:
- the PCI white list
- the PCI black list
- the list of virtual devices

Rework the tests:
- a part of the whitelist test can be removed as it is now tested
  in app/test/test_devargs.c
- the other parts are just reworked to adapt them to the new API

This commit induce a small API modification: it is not possible to specify
several devices per "--use-device" option. This notation was anyway a bit
cryptic. Ex:
  --use-device="eth_ring0,eth_pcap0;iface=ixgbe0"
  now becomes:
  --use-device="eth_ring0" --use-device="eth_pcap0;iface=ixgbe0"

On the other hand, it is now possible to work in PCI blacklist mode and
instanciate virtual drivers, which was not possible before this patch.

Test result:

./app/test -c 0x15 -n 3 -m 64
RTE>>devargs_autotest
EAL: invalid PCI identifier <08:1>
EAL: invalid PCI identifier <00.1>
EAL: invalid PCI identifier <foo>
EAL: invalid PCI identifier <>
EAL: invalid PCI identifier <000f:0:0>
Test OK

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 app/test/test_eal_flags.c                      |  49 +-----
 app/test/test_pci.c                            |  51 +++---
 lib/librte_eal/common/eal_common_nonpci_devs.c |  36 +++-
 lib/librte_eal/common/eal_common_pci.c         |  60 +++----
 lib/librte_eal/common/eal_common_whitelist.c   | 227 -------------------------
 lib/librte_eal/common/include/eal_private.h    |  38 -----
 lib/librte_eal/common/include/rte_pci.h        |  10 --
 lib/librte_eal/linuxapp/eal/Makefile           |   1 -
 lib/librte_eal/linuxapp/eal/eal.c              |  80 +++++----
 lib/librte_pmd_ring/rte_eth_ring.c             |   2 +-
 10 files changed, 133 insertions(+), 421 deletions(-)
 delete mode 100644 lib/librte_eal/common/eal_common_whitelist.c

diff --git a/app/test/test_eal_flags.c b/app/test/test_eal_flags.c
index 964a3a9..9bab1a5 100644
--- a/app/test/test_eal_flags.c
+++ b/app/test/test_eal_flags.c
@@ -2,6 +2,7 @@
  *   BSD LICENSE
  * 
  *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2014 6WIND S.A.
  *   All rights reserved.
  * 
  *   Redistribution and use in source and binary forms, with or without
@@ -271,20 +272,6 @@ get_current_prefix(char * prefix, int size)
 	return prefix;
 }
 
-/* extra function prototypes for internal eal function to test in whitelist 
- * ICC 12 doesn't approve of this practice, so temporarily disable warnings for it */
-#ifdef __INTEL_COMPILER
-#pragma warning disable 1419
-#endif
-extern int eal_dev_whitelist_exists(void);
-extern int eal_dev_whitelist_add_entry(const char *);
-extern int eal_dev_whitelist_parse(void);
-extern int eal_dev_is_whitelisted(const char *, const char **);
-extern void eal_dev_whitelist_clear(void);
-#ifdef __INTEL_COMPILER
-#pragma warning enable 1419
-#endif
-
 /*
  * Test that the app doesn't run with invalid whitelist option.
  * Final tests ensures it does run with valid options as sanity check (one
@@ -319,17 +306,15 @@ test_whitelist_flag(void)
 				use_device, "error0:0:0.1", "", ""},
 		{prgname, prefix, mp_flag, "-n", "1", "-c", "1",
 				use_device, "0:0:0.1.2", "", ""},
-		{prgname, prefix, mp_flag, "-n", "1", "-c", "1",
-				use_device, "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x",
-				use_device, "y,z,1,2,3,4,5,6,7,8,9,0"},
 	};
 	/* Test with valid whitelist option */
 	const char *wlval1[] = {prgname, prefix, mp_flag, "-n", "1", "-c", "1",
 			use_device, "00FF:09:0B.3"};
 	const char *wlval2[] = {prgname, prefix, mp_flag, "-n", "1", "-c", "1",
-			use_device, "09:0B.3,0a:0b.1"};
+			use_device, "09:0B.3", use_device, "0a:0b.1"};
 	const char *wlval3[] = {prgname, prefix, mp_flag, "-n", "1", "-c", "1",
-			use_device, "09:0B.3;type=test,08:00.1;type=normal"};
+			use_device, "09:0B.3;type=test",
+			use_device, "08:00.1;type=normal"};
 
 	for (i = 0; i < sizeof(wlinval) / sizeof(wlinval[0]); i++) {
 		if (launch_proc(wlinval[i]) == 0) {
@@ -351,32 +336,6 @@ test_whitelist_flag(void)
 		return -1;
 	}
 
-	/* extra-sanity checks of whitelists - to be run only if no whitelist */
-	if (eal_dev_whitelist_exists())
-		return 0;
-
-	/* check that whitelist_parse returns error without whitelist */
-	if (eal_dev_whitelist_parse() != -1) {
-		printf("ERROR: calling whitelist parse without a whitelist doesn't "
-				"return an error\n");
-		return -1;
-	}
-	if (eal_dev_is_whitelisted("adevice", NULL)) {
-		printf("Whitelist lookup does not return false if no whitelist\n");
-		return -1;
-	}
-	eal_dev_whitelist_add_entry("0000:00:00.0");
-	eal_dev_whitelist_parse();
-	if (eal_dev_is_whitelisted("adevice", NULL)) {
-		printf("Whitelist lookup does not return false for unlisted dev\n");
-		return -1;
-	}
-	if (!eal_dev_is_whitelisted("0000:00:00.0", NULL)) {
-		printf("Whitelist lookup does not return true for whitelisted dev\n");
-		return -1;
-	}
-	eal_dev_whitelist_clear();
-
 	return 0;
 }
 
diff --git a/app/test/test_pci.c b/app/test/test_pci.c
index 64b13c1..223d76a 100644
--- a/app/test/test_pci.c
+++ b/app/test/test_pci.c
@@ -2,6 +2,7 @@
  *   BSD LICENSE
  * 
  *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2014 6WIND S.A.
  *   All rights reserved.
  * 
  *   Redistribution and use in source and binary forms, with or without
@@ -38,12 +39,11 @@
 
 #include <rte_interrupts.h>
 #include <rte_pci.h>
+#include <rte_devargs.h>
 
 #include "test.h"
 
 
-#define	TEST_BLACKLIST_NUM	0x100
-
 /*
  * PCI test
  * ========
@@ -58,7 +58,6 @@
 int test_pci_run = 0; /* value checked by the multiprocess test */
 static unsigned pci_dev_count;
 static unsigned driver_registered = 0;
-static struct rte_pci_addr blacklist[TEST_BLACKLIST_NUM];
 
 static int my_driver_init(struct rte_pci_driver *dr,
 			  struct rte_pci_device *dev);
@@ -116,37 +115,42 @@ my_driver_init(__attribute__((unused)) struct rte_pci_driver *dr,
 }
 
 static void
-blacklist_clear(void)
-{
-	rte_eal_pci_set_blacklist(NULL, 0);
-}
-
-
-
-static void
 blacklist_all_devices(void)
 {
 	struct rte_pci_device *dev = NULL;
-	unsigned idx = 0;
-
-	memset(blacklist, 0, sizeof (blacklist));
+	unsigned i = 0;
+	char pci_addr_str[16];
 
 	TAILQ_FOREACH(dev, &device_list, next) {
-		if (idx >= sizeof (blacklist) / sizeof (blacklist[0])) {
-			printf("Error: too many devices to blacklist");
+		snprintf(pci_addr_str, sizeof(pci_addr_str), PCI_PRI_FMT,
+			dev->addr.domain, dev->addr.bus, dev->addr.devid,
+			dev->addr.function);
+		if (rte_eal_devargs_add(RTE_DEVTYPE_BLACKLISTED_PCI,
+				pci_addr_str) < 0) {
+			printf("Error: cannot blacklist <%s>", pci_addr_str);
 			break;
 		}
-		blacklist[idx] = dev->addr;
-		++idx;
+		i++;
 	}
+	printf("%u devices blacklisted\n", i);
+}
+
+/* clear devargs list that was modified by the test */
+static void free_devargs_list(void)
+{
+	struct rte_devargs *devargs;
 
-	rte_eal_pci_set_blacklist(blacklist, idx);
-	printf("%u devices blacklisted\n", idx);
+	while (!TAILQ_EMPTY(&devargs_list)) {
+		devargs = TAILQ_FIRST(&devargs_list);
+		TAILQ_REMOVE(&devargs_list, devargs, next);
+		free(devargs);
+	}
 }
 
 int
 test_pci(void)
 {
+	struct rte_devargs_list save_devargs_list;
 
 	printf("Dump all devices\n");
 	rte_eal_pci_dump();
@@ -165,13 +169,18 @@ test_pci(void)
 		return -1;
 	}
 
+	/* save the real devargs_list */
+	save_devargs_list = devargs_list;
+	TAILQ_INIT(&devargs_list);
+
 	blacklist_all_devices();
 
 	pci_dev_count = 0;
 	printf("Scan bus with all devices blacklisted\n");
 	rte_eal_pci_probe();
 
-	blacklist_clear();
+	free_devargs_list();
+	devargs_list = save_devargs_list;
 
 	if (pci_dev_count != 0) {
 		printf("not all devices are blacklisted\n");
diff --git a/lib/librte_eal/common/eal_common_nonpci_devs.c b/lib/librte_eal/common/eal_common_nonpci_devs.c
index 1c9c88b..71cbb1e 100644
--- a/lib/librte_eal/common/eal_common_nonpci_devs.c
+++ b/lib/librte_eal/common/eal_common_nonpci_devs.c
@@ -2,6 +2,7 @@
  *   BSD LICENSE
  * 
  *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2014 6WIND S.A.
  *   All rights reserved.
  * 
  *   Redistribution and use in source and binary forms, with or without
@@ -31,6 +32,7 @@
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <string.h>
 #include <inttypes.h>
 #include <rte_string_fns.h>
 #ifdef RTE_LIBRTE_PMD_RING
@@ -42,6 +44,8 @@
 #ifdef RTE_LIBRTE_PMD_XENVIRT
 #include <rte_eth_xenvirt.h>
 #endif
+#include <rte_debug.h>
+#include <rte_devargs.h>
 #include "eal_private.h"
 
 struct device_init {
@@ -78,15 +82,29 @@ struct device_init dev_types[] = {
 int
 rte_eal_non_pci_ethdev_init(void)
 {
-	uint8_t i, j;
-	for (i = 0; i < NUM_DEV_TYPES; i++) {
-		for (j = 0; j < RTE_MAX_ETHPORTS; j++) {
-			const char *params;
-			char buf[16];
-			rte_snprintf(buf, sizeof(buf), "%s%"PRIu8,
-					dev_types[i].dev_prefix, j);
-			if (eal_dev_is_whitelisted(buf, &params))
-				dev_types[i].init_fn(buf, params);
+	struct rte_devargs *devargs;
+	uint8_t i;
+
+	/* call the init function for each virtual device */
+	TAILQ_FOREACH(devargs, &devargs_list, next) {
+
+		if (devargs->type != RTE_DEVTYPE_VIRTUAL)
+			continue;
+
+		for (i = 0; i < NUM_DEV_TYPES; i++) {
+			/* search a driver prefix in virtual device name */
+			if (!strncmp(dev_types[i].dev_prefix,
+				    devargs->virtual.drv_name,
+				     sizeof(dev_types[i].dev_prefix) - 1)) {
+				dev_types[i].init_fn(devargs->virtual.drv_name,
+						     devargs->args);
+				break;
+			}
+		}
+
+		if (i == NUM_DEV_TYPES) {
+			rte_panic("no driver found for %s\n",
+				  devargs->virtual.drv_name);
 		}
 	}
 	return 0;
diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c
index 9c9e842..972d844 100644
--- a/lib/librte_eal/common/eal_common_pci.c
+++ b/lib/librte_eal/common/eal_common_pci.c
@@ -61,6 +61,7 @@
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <string.h>
 #include <inttypes.h>
 #include <stdint.h>
 #include <stdlib.h>
@@ -77,29 +78,23 @@
 #include <rte_eal.h>
 #include <rte_string_fns.h>
 #include <rte_common.h>
+#include <rte_devargs.h>
 
 #include "eal_private.h"
 
 struct pci_driver_list driver_list;
 struct pci_device_list device_list;
 
-static struct rte_pci_addr *dev_blacklist = NULL;
-static unsigned dev_blacklist_size = 0;
-
 static int is_blacklisted(struct rte_pci_device *dev)
 {
-	struct rte_pci_addr *loc = &dev->addr;
-	unsigned i;
-
-	for (i = 0; i < dev_blacklist_size; i++) {
-		if ((loc->domain == dev_blacklist[i].domain) &&
-				(loc->bus == dev_blacklist[i].bus) &&
-				(loc->devid == dev_blacklist[i].devid) &&
-				(loc->function == dev_blacklist[i].function)) {
+	struct rte_devargs *devargs;
+
+	TAILQ_FOREACH(devargs, &devargs_list, next) {
+		if (devargs->type != RTE_DEVTYPE_BLACKLISTED_PCI)
+			continue;
+		if (!memcmp(&dev->addr, &devargs->pci.addr, sizeof(dev->addr)))
 			return 1;
-		}
 	}
-
 	return 0;           /* not in blacklist */
 }
 
@@ -143,16 +138,15 @@ pci_probe_all_drivers(struct rte_pci_device *dev)
 static int
 pcidev_is_whitelisted(struct rte_pci_device *dev)
 {
-	char buf[16];
-	if (dev->addr.domain == 0) {
-		rte_snprintf(buf, sizeof(buf), PCI_SHORT_PRI_FMT, dev->addr.bus,
-				dev->addr.devid, dev->addr.function);
-		if (eal_dev_is_whitelisted(buf, NULL))
+	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;
 	}
-	rte_snprintf(buf, sizeof(buf), PCI_PRI_FMT, dev->addr.domain,dev->addr.bus,
-			dev->addr.devid, dev->addr.function);
-	return eal_dev_is_whitelisted(buf, NULL);
+	return 0;
 }
 
 /*
@@ -164,14 +158,19 @@ int
 rte_eal_pci_probe(void)
 {
 	struct rte_pci_device *dev = NULL;
+	int probe_all = 0;
 
-	TAILQ_FOREACH(dev, &device_list, next)
-		if (!eal_dev_whitelist_exists())
+	if (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_PCI) == 0)
+		probe_all = 1;
+
+	TAILQ_FOREACH(dev, &device_list, next) {
+		if (probe_all)
 			pci_probe_all_drivers(dev);
-		else if (pcidev_is_whitelisted(dev) && 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);
+		else if (pcidev_is_whitelisted(dev) && 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);
+	}
 
 	return 0;
 }
@@ -220,10 +219,3 @@ 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)
-{
-	dev_blacklist = blacklist;
-	dev_blacklist_size = size;
-}
diff --git a/lib/librte_eal/common/eal_common_whitelist.c b/lib/librte_eal/common/eal_common_whitelist.c
deleted file mode 100644
index 9cc0446..0000000
--- a/lib/librte_eal/common/eal_common_whitelist.c
+++ /dev/null
@@ -1,227 +0,0 @@
-/*-
- *   BSD LICENSE
- * 
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- * 
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- * 
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- * 
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-/**
- * This file provides functions for managing a whitelist of devices. An EAL
- * command-line parameter should be used for specifying what devices to
- * whitelist, and the functions here should be called in handling that
- * parameter. Then when scanning the PCI bus, the is_whitelisted() function
- * can be used to query the previously set up whitelist.
- */
-#include <string.h>
-#include <rte_string_fns.h>
-#include <rte_log.h>
-#include <rte_debug.h>
-#include <rte_pci.h>
-#include <ctype.h>
-#ifdef RTE_LIBRTE_PMD_RING
-#include <rte_eth_ring.h>
-#endif
-#ifdef RTE_LIBRTE_PMD_PCAP
-#include <rte_eth_pcap.h>
-#endif
-#ifdef RTE_LIBRTE_PMD_XENVIRT
-#include <rte_eth_xenvirt.h>
-#endif
-#include "eal_private.h"
-
-static char dev_list_str[4096];
-static size_t dev_list_str_len = 0;
-
-/*
- * structure for storing a whitelist entry. Unlike for blacklists, we may
- * in future use this for dummy NICs not backed by a physical device, e.g.
- * backed by a file-system object instead, so we store the device path/addr
- * as a string, rather than as a PCI Bus-Device-Function.
- */
-static struct whitelist_entry {
-	const char *device_str;
-	const char *device_params;
-} whitelist[RTE_MAX_ETHPORTS] = { {NULL, NULL} };
-
-static unsigned num_wl_entries = 0;
-
-/* store a whitelist parameter for later parsing */
-int
-eal_dev_whitelist_add_entry(const char *entry)
-{
-	dev_list_str_len += rte_snprintf(&dev_list_str[dev_list_str_len],
-			sizeof(dev_list_str)-dev_list_str_len, "%s,", entry);
-	/* check for strings that won't fit (snprintf doesn't go beyond buffer) */
-	if (dev_list_str_len >= sizeof(dev_list_str)) {
-		dev_list_str_len = sizeof(dev_list_str) - 1;
-		return -1;
-	}
-
-	return 0;
-}
-
-/* check if a whitelist has been set up */
-int
-eal_dev_whitelist_exists(void)
-{
-	return !!dev_list_str_len;
-}
-
-/* sanity checks a whitelist entry to ensure device is correct */
-static int
-is_valid_wl_entry(const char *device_str, size_t dev_buf_len)
-{
-#define NUM_PREFIXES (sizeof(non_pci_prefixes)/sizeof(non_pci_prefixes[0]))
-	static const char *non_pci_prefixes[] = {
-#ifdef  RTE_LIBRTE_PMD_RING
-			RTE_ETH_RING_PARAM_NAME,
-#endif
-#ifdef RTE_LIBRTE_PMD_PCAP
-			RTE_ETH_PCAP_PARAM_NAME,
-#endif
-#ifdef RTE_LIBRTE_PMD_XENVIRT
-			RTE_ETH_XENVIRT_PARAM_NAME,
-#endif
-			"-nodev-" /* dummy value to prevent compiler warnings */
-	};
-	static uint8_t prefix_counts[NUM_PREFIXES] = {0};
-	char buf[16];
-	unsigned i;
-	struct rte_pci_addr pci_addr = { .domain = 0 };
-
-	if (eal_parse_pci_BDF(device_str, &pci_addr) == 0) {
-		size_t n = rte_snprintf(buf, sizeof(buf), PCI_SHORT_PRI_FMT,
-				pci_addr.bus, pci_addr.devid, pci_addr.function);
-		return (n == dev_buf_len) && (!strncmp(buf, device_str, dev_buf_len));
-	}
-	if (eal_parse_pci_DomBDF(device_str, &pci_addr) == 0) {
-		size_t n = rte_snprintf(buf, sizeof(buf), PCI_PRI_FMT, pci_addr.domain,
-				pci_addr.bus, pci_addr.devid, pci_addr.function);
-		return (n == dev_buf_len) && (!strncmp(buf, device_str, dev_buf_len));
-	}
-	for (i = 0; i < NUM_PREFIXES; i++) {
-		size_t n = rte_snprintf(buf, sizeof(buf), "%s%u",
-				non_pci_prefixes[i], prefix_counts[i]);
-		if ((n == dev_buf_len) && (!strncmp(buf, device_str, dev_buf_len))) {
-			prefix_counts[i]++;
-			return 1;
-		}
-	}
-	return 0;
-}
-
-/*
- * parse a whitelist string into a set of valid devices. To be called once
- * all parameters have been added to the whitelist string.
- */
-int
-eal_dev_whitelist_parse(void)
-{
-	char *devs[RTE_MAX_ETHPORTS + 1] = { NULL };
-	int i, num_devs;
-	unsigned dev_name_len, j;
-
-	if (!eal_dev_whitelist_exists())
-		return -1;
-
-	/* strip off any extra commas */
-	if (dev_list_str[dev_list_str_len - 1] == ',')
-		dev_list_str[--dev_list_str_len] = '\0';
-
-	/* split on commas into separate device entries */
-	num_devs = rte_strsplit(dev_list_str, sizeof(dev_list_str), devs,
-			RTE_MAX_ETHPORTS+1, ',');
-	if (num_devs > RTE_MAX_ETHPORTS) {
-		RTE_LOG(ERR, EAL, "Error, too many devices specified. "
-				"[RTE_MAX_ETHPORTS = %u]\n", (unsigned)RTE_MAX_ETHPORTS);
-		return -1;
-	}
-
-	size_t buf_len_rem = sizeof(dev_list_str); /* for tracking buffer length */
-	for (i = 0; i < num_devs; i++) {
-		char *dev_n_params[2]; /* possibly split device name from params*/
-
-		size_t curr_len = strnlen(devs[i], buf_len_rem);
-		buf_len_rem-= (curr_len + 1);
-
-		int split_res = rte_strsplit(devs[i], curr_len, dev_n_params, 2, ';');
-
-		/* device names go lower case, i.e. '00:0A.0' wouldn't work
-		 * while '00:0a.0' would. */
-		dev_name_len = strnlen(dev_n_params[0], curr_len);
-		for (j = 0; j < dev_name_len; j++)
-			dev_n_params[0][j] = (char)tolower((int)dev_n_params[0][j]);
-
-		switch (split_res) {
-		case 2:
-			whitelist[i].device_params = dev_n_params[1]; /* fallthrough */
-		case 1:
-			whitelist[i].device_str = dev_n_params[0];
-			break;
-		default: /* should never ever occur */
-			rte_panic("Fatal error parsing whitelist [--use-device] options\n");
-		}
-
-		if (!is_valid_wl_entry(whitelist[i].device_str,
-				strnlen(whitelist[i].device_str, curr_len))) {
-			RTE_LOG(ERR, EAL, "Error parsing device identifier: '%s'\n",
-					whitelist[i].device_str);
-			return -1;
-		}
-	}
-	num_wl_entries = num_devs;
-	return 0;
-}
-
-/* check if a device is on the whitelist */
-int
-eal_dev_is_whitelisted(const char *device_str, const char **params)
-{
-	unsigned i;
-	if (!eal_dev_whitelist_exists())
-		return 0; /* return false if no whitelist set up */
-
-	for (i = 0; i < num_wl_entries; i++)
-		if (strncmp(device_str, whitelist[i].device_str, 32) == 0) {
-			if (params != NULL)
-				*params = whitelist[i].device_params;
-			return 1;
-		}
-
-	return 0;
-}
-
-/* clear the whole whitelist */
-void
-eal_dev_whitelist_clear(void)
-{
-	dev_list_str[0] = '\0';
-	dev_list_str_len = num_wl_entries = 0;
-}
diff --git a/lib/librte_eal/common/include/eal_private.h b/lib/librte_eal/common/include/eal_private.h
index 251f15e..f9a019b 100644
--- a/lib/librte_eal/common/include/eal_private.h
+++ b/lib/librte_eal/common/include/eal_private.h
@@ -197,44 +197,6 @@ int rte_eal_intr_init(void);
 int rte_eal_alarm_init(void);
 
 /**
- * When parsing command-line args add a new entry to the whitelist string
- * to be parsed, i.e. this is used to join multiple --use-device flags together
- *
- * This function is private to EAL
- */
-int eal_dev_whitelist_add_entry(const char *entry);
-
-/**
- * Returns true if whitelist parameters are available for parsing,
- * false otherwise.
- *
- * This function is private to EAL
- */
-int eal_dev_whitelist_exists(void);
-
-/**
- * Parse the combined whitelist options into a single white-list for later use.
- *
- * This function is private to EAL
- */
-int eal_dev_whitelist_parse(void);
-
-/**
- * Check if a particular device is whitelisted or not. Returns true if the
- * device is in the whitelist.
- *
- * This function is private to EAL
- */
-int eal_dev_is_whitelisted(const char *device_str, const char **params);
-
-/**
- * This function clears the whitelist settings.
- *
- * This function is private to the EAL.
- */
-void eal_dev_whitelist_clear(void);
-
-/**
  * This function initialises any non-PCI i.e. dummy ethernet devices
  *
  * This function is private to the EAL.
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
index 9d4f94f..0aee5ff 100644
--- a/lib/librte_eal/common/include/rte_pci.h
+++ b/lib/librte_eal/common/include/rte_pci.h
@@ -290,16 +290,6 @@ void rte_eal_pci_register(struct rte_pci_driver *driver);
  */
 void rte_eal_pci_unregister(struct rte_pci_driver *driver);
 
-/**
- * Register a list of PCI locations that will be blacklisted (not used by DPDK).
- *
- * @param blacklist
- *   List of PCI device addresses that will not be used by DPDK.
- * @param size
- *   Number of items in the list.
- */
-void rte_eal_pci_set_blacklist(struct rte_pci_addr *blacklist, unsigned size);
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index f57fda5..bdd940d 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -76,7 +76,6 @@ SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_tailqs.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_errno.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_cpuflags.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_hexdump.c
-SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_whitelist.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_devargs.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_nonpci_devs.c
 
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index db0e15c..4c23614 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -2,7 +2,7 @@
  *   BSD LICENSE
  * 
  *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   Copyright(c) 2012-2013 6WIND S.A.
+ *   Copyright(c) 2012-2014 6WIND S.A.
  *   All rights reserved.
  * 
  *   Redistribution and use in source and binary forms, with or without
@@ -69,6 +69,7 @@
 #include <rte_cpuflags.h>
 #include <rte_interrupts.h>
 #include <rte_pci.h>
+#include <rte_devargs.h>
 #include <rte_common.h>
 #include <rte_version.h>
 #include <rte_atomic.h>
@@ -142,8 +143,6 @@ static struct rte_config rte_config = {
 		.mem_config = &early_mem_config,
 };
 
-static struct rte_pci_addr eal_dev_blacklist[RTE_EAL_BLACKLIST_SIZE];
-
 /* internal configuration (per-core) */
 struct lcore_config lcore_config[RTE_MAX_LCORE];
 
@@ -350,9 +349,11 @@ eal_usage(const char *prgname)
 	       "  --"OPT_HUGE_DIR"   : directory where hugetlbfs is mounted\n"
 	       "  --"OPT_PROC_TYPE"  : type of this process\n"
 	       "  --"OPT_FILE_PREFIX": prefix for hugepage filenames\n"
-	       "  --"OPT_USE_DEVICE": use the specified ethernet device(s) only. "
-	    		   "Use comma-separate <[domain:]bus:devid.func> values.\n"
-	       "               [NOTE: Cannot be used with -b option]\n"
+	       "  --"OPT_USE_DEVICE": use the specified ethernet device(s) only.\n"
+	       "               The argument format is <[domain:]bus:devid.func> to add\n"
+	       "               a PCI device to the white list or <driver><id>[;key=val;...]\n"
+	       "               to add a virtual device.\n"
+	       "               [NOTE: PCI whitelist cannot be used with -b option]\n"
 	       "  --"OPT_VMWARE_TSC_MAP": use VMware TSC map instead of "
 	    		   "native RDTSC\n"
 	       "  --"OPT_BASE_VIRTADDR": specify base virtual address\n"
@@ -600,20 +601,32 @@ eal_parse_proc_type(const char *arg)
 	return RTE_PROC_INVALID;
 }
 
-static ssize_t
-eal_parse_blacklist_opt(const char *optarg, size_t idx)
+static int
+eal_parse_use_device(const char *optarg)
 {
-	if (idx >= sizeof (eal_dev_blacklist) / sizeof (eal_dev_blacklist[0])) {
-		RTE_LOG(ERR, EAL, "%s - too many devices to blacklist...\n", optarg);
-		return (-EINVAL);
-	} else if (eal_parse_pci_DomBDF(optarg, eal_dev_blacklist + idx) < 0 &&
-			eal_parse_pci_BDF(optarg, eal_dev_blacklist + idx) < 0) {
-		RTE_LOG(ERR, EAL, "%s - invalid device to blacklist...\n", optarg);
-		return (-EINVAL);
+	struct rte_pci_addr addr;
+	char *dup, *sep;
+
+	dup = strdup(optarg);
+	if (dup == NULL)
+		return -1;
+
+	/* remove arguments in 'dup' string */
+	sep = strchr(dup, ';');
+	if (sep != NULL)
+		*sep = '\0';
+
+	/* if argument is a PCI address, it's a whitelisted device */
+	if (eal_parse_pci_DomBDF(dup, &addr) == 0 ||
+		eal_parse_pci_BDF(dup, &addr) == 0) {
+		rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, optarg);
+	}
+	else {
+		rte_eal_devargs_add(RTE_DEVTYPE_VIRTUAL, optarg);
 	}
 
-	idx += 1;
-	return (idx);
+	free(dup);
+	return 0;
 }
 
 /* Parse the argument given in the command line of the application */
@@ -624,7 +637,6 @@ eal_parse_args(int argc, char **argv)
 	char **argvopt;
 	int option_index;
 	int coremask_ok = 0;
-	ssize_t blacklist_index = 0;
 	char *prgname = argv[0];
 	static struct option lgopts[] = {
 		{OPT_NO_HUGE, 0, 0, 0},
@@ -677,8 +689,8 @@ eal_parse_args(int argc, char **argv)
 		switch (opt) {
 		/* blacklist */
 		case 'b':
-			if ((blacklist_index = eal_parse_blacklist_opt(optarg,
-			    blacklist_index)) < 0) {
+			if (rte_eal_devargs_add(RTE_DEVTYPE_BLACKLISTED_PCI,
+					optarg) < 0) {
 				eal_usage(prgname);
 				return (-1);
 			}
@@ -782,7 +794,12 @@ eal_parse_args(int argc, char **argv)
 				}
 			}
 			else if (!strcmp(lgopts[option_index].name, OPT_USE_DEVICE)) {
-				eal_dev_whitelist_add_entry(optarg);
+				if (eal_parse_use_device(optarg) < 0) {
+					RTE_LOG(ERR, EAL, "invalid parameters for --"
+							OPT_USE_DEVICE "\n");
+					eal_usage(prgname);
+					return -1;
+				}
 			}
 			else if (!strcmp(lgopts[option_index].name, OPT_SYSLOG)) {
 				if (eal_parse_syslog(optarg) < 0) {
@@ -858,20 +875,13 @@ eal_parse_args(int argc, char **argv)
 		eal_usage(prgname);
 		return -1;
 	}
-	/* if no blacklist, parse a whitelist */
-	if (blacklist_index > 0) {
-		if (eal_dev_whitelist_exists()) {
-			RTE_LOG(ERR, EAL, "Error: blacklist [-b] and whitelist "
-					"[--use-device] options cannot be used at the same time\n");
-			eal_usage(prgname);
-			return -1;
-		}
-		rte_eal_pci_set_blacklist(eal_dev_blacklist, blacklist_index);
-	} else {
-		if (eal_dev_whitelist_exists() && eal_dev_whitelist_parse() < 0) {
-			RTE_LOG(ERR,EAL, "Error parsing whitelist[--use-device] options\n");
-			return -1;
-		}
+
+	if (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_PCI) != 0 &&
+		rte_eal_devargs_type_count(RTE_DEVTYPE_BLACKLISTED_PCI) != 0) {
+		RTE_LOG(ERR, EAL, "Error: blacklist [-b] and whitelist "
+			"[--use-device] options cannot be used at the same time\n");
+		eal_usage(prgname);
+		return -1;
 	}
 
 	if (optind >= 0)
diff --git a/lib/librte_pmd_ring/rte_eth_ring.c b/lib/librte_pmd_ring/rte_eth_ring.c
index 1fed8d3..24635f3 100644
--- a/lib/librte_pmd_ring/rte_eth_ring.c
+++ b/lib/librte_pmd_ring/rte_eth_ring.c
@@ -386,7 +386,7 @@ rte_pmd_ring_init(const char *name, const char *params)
 {
 	RTE_LOG(INFO, PMD, "Initializing pmd_ring for %s\n", name);
 
-	if (params == NULL)
+	if (params == NULL || params[0] == '\0')
 		eth_dev_ring_create(name, rte_socket_id(), DEV_CREATE);
 	else {
 		RTE_LOG(INFO, PMD, "Ignoring unsupported parameters when creating"
-- 
1.8.5.3

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [dpdk-dev] [PATCH 04/11] devices-args: add a dump_devargs command in basic test application
  2014-02-28 17:25 [dpdk-dev] [PATCH 00/11] eal: allow virtual pmd drivers as shared lib Olivier Matz
                   ` (2 preceding siblings ...)
  2014-02-28 17:25 ` [dpdk-dev] [PATCH 03/11] devices-args: use rte_devargs and remove old whitelist code Olivier Matz
@ 2014-02-28 17:25 ` Olivier Matz
  2014-04-10 14:02   ` Thomas Monjalon
  2014-02-28 17:25 ` [dpdk-dev] [PATCH 05/11] pci: rename device_list as pci_device_list Olivier Matz
                   ` (6 subsequent siblings)
  10 siblings, 1 reply; 57+ messages in thread
From: Olivier Matz @ 2014-02-28 17:25 UTC (permalink / raw)
  To: dev

This is useful for debug purposes. Example:

echo 100 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages
echo 100 > /sys/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages
./app/test -c 0x15 -n 3 -m 64 \
  --use-dev="eth_ring0" --use-device="eth_ring1" --use-device="02:00.0"
RTE>>dump_devargs
User device white list:
  VIRTUAL eth_ring0
  VIRTUAL eth_ring1
  PCI whitelist 0000:02:00.0

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 app/test/commands.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/app/test/commands.c b/app/test/commands.c
index 7595b4c..b145036 100644
--- a/app/test/commands.c
+++ b/app/test/commands.c
@@ -65,6 +65,7 @@
 #include <rte_ring.h>
 #include <rte_mempool.h>
 #include <rte_mbuf.h>
+#include <rte_devargs.h>
 
 #include <cmdline_rdline.h>
 #include <cmdline_parse.h>
@@ -285,12 +286,15 @@ static void cmd_dump_parsed(void *parsed_result,
 		rte_ring_list_dump();
 	else if (!strcmp(res->dump, "dump_mempool"))
 		rte_mempool_list_dump();
+	else if (!strcmp(res->dump, "dump_devargs"))
+		rte_eal_devargs_dump();
 }
 
 cmdline_parse_token_string_t cmd_dump_dump =
 	TOKEN_STRING_INITIALIZER(struct cmd_dump_result, dump,
 				 "dump_physmem#dump_memzone#dump_log_history#"
-				 "dump_struct_sizes#dump_ring#dump_mempool");
+				 "dump_struct_sizes#dump_ring#dump_mempool#"
+				 "dump_devargs");
 
 cmdline_parse_inst_t cmd_dump = {
 	.f = cmd_dump_parsed,  /* function to call */
-- 
1.8.5.3

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [dpdk-dev] [PATCH 05/11] pci: rename device_list as pci_device_list
  2014-02-28 17:25 [dpdk-dev] [PATCH 00/11] eal: allow virtual pmd drivers as shared lib Olivier Matz
                   ` (3 preceding siblings ...)
  2014-02-28 17:25 ` [dpdk-dev] [PATCH 04/11] devices-args: add a dump_devargs command in basic test application Olivier Matz
@ 2014-02-28 17:25 ` Olivier Matz
  2014-04-10 14:03   ` Thomas Monjalon
  2014-02-28 17:25 ` [dpdk-dev] [PATCH 06/11] vdev: rename eal_common_nonpci_devs.c as eal_common_vdev.c Olivier Matz
                   ` (5 subsequent siblings)
  10 siblings, 1 reply; 57+ messages in thread
From: Olivier Matz @ 2014-02-28 17:25 UTC (permalink / raw)
  To: dev

To avoid confusion with virtual devices, rename device_list as
pci_device_list and driver_list as pci_driver_list.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 app/test/test_pci.c                       |  2 +-
 lib/librte_eal/common/eal_common_pci.c    | 14 +++++++-------
 lib/librte_eal/common/include/rte_pci.h   |  4 ++--
 lib/librte_eal/linuxapp/eal/eal_ivshmem.c |  2 +-
 lib/librte_eal/linuxapp/eal/eal_pci.c     | 12 ++++++------
 5 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/app/test/test_pci.c b/app/test/test_pci.c
index 223d76a..445cf57 100644
--- a/app/test/test_pci.c
+++ b/app/test/test_pci.c
@@ -121,7 +121,7 @@ blacklist_all_devices(void)
 	unsigned i = 0;
 	char pci_addr_str[16];
 
-	TAILQ_FOREACH(dev, &device_list, next) {
+	TAILQ_FOREACH(dev, &pci_device_list, next) {
 		snprintf(pci_addr_str, sizeof(pci_addr_str), PCI_PRI_FMT,
 			dev->addr.domain, dev->addr.bus, dev->addr.devid,
 			dev->addr.function);
diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c
index 972d844..03e1378 100644
--- a/lib/librte_eal/common/eal_common_pci.c
+++ b/lib/librte_eal/common/eal_common_pci.c
@@ -82,8 +82,8 @@
 
 #include "eal_private.h"
 
-struct pci_driver_list driver_list;
-struct pci_device_list device_list;
+struct pci_driver_list pci_driver_list;
+struct pci_device_list pci_device_list;
 
 static int is_blacklisted(struct rte_pci_device *dev)
 {
@@ -114,7 +114,7 @@ pci_probe_all_drivers(struct rte_pci_device *dev)
 	int rc;
 
 	dev->blacklisted = !!is_blacklisted(dev);
-	TAILQ_FOREACH(dr, &driver_list, next) {
+	TAILQ_FOREACH(dr, &pci_driver_list, next) {
 		rc = rte_eal_pci_probe_one_driver(dr, dev);
 		if (rc < 0)
 			/* negative value is an error */
@@ -163,7 +163,7 @@ rte_eal_pci_probe(void)
 	if (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_PCI) == 0)
 		probe_all = 1;
 
-	TAILQ_FOREACH(dev, &device_list, next) {
+	TAILQ_FOREACH(dev, &pci_device_list, next) {
 		if (probe_all)
 			pci_probe_all_drivers(dev);
 		else if (pcidev_is_whitelisted(dev) && pci_probe_all_drivers(dev) < 0)
@@ -201,7 +201,7 @@ rte_eal_pci_dump(void)
 {
 	struct rte_pci_device *dev = NULL;
 
-	TAILQ_FOREACH(dev, &device_list, next) {
+	TAILQ_FOREACH(dev, &pci_device_list, next) {
 		pci_dump_one_device(dev);
 	}
 }
@@ -210,12 +210,12 @@ rte_eal_pci_dump(void)
 void
 rte_eal_pci_register(struct rte_pci_driver *driver)
 {
-	TAILQ_INSERT_TAIL(&driver_list, driver, next);
+	TAILQ_INSERT_TAIL(&pci_driver_list, driver, next);
 }
 
 /* unregister a driver */
 void
 rte_eal_pci_unregister(struct rte_pci_driver *driver)
 {
-	TAILQ_REMOVE(&driver_list, driver, next);
+	TAILQ_REMOVE(&pci_driver_list, driver, next);
 }
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
index 0aee5ff..6dd962a 100644
--- a/lib/librte_eal/common/include/rte_pci.h
+++ b/lib/librte_eal/common/include/rte_pci.h
@@ -85,8 +85,8 @@ extern "C" {
 TAILQ_HEAD(pci_device_list, rte_pci_device); /**< PCI devices in D-linked Q. */
 TAILQ_HEAD(pci_driver_list, rte_pci_driver); /**< PCI drivers in D-linked Q. */
 
-extern struct pci_driver_list driver_list; /**< Global list of PCI drivers. */
-extern struct pci_device_list device_list; /**< Global list of PCI devices. */
+extern struct pci_driver_list pci_driver_list; /**< Global list of PCI drivers. */
+extern struct pci_device_list pci_device_list; /**< Global list of PCI devices. */
 
 /** Pathname of PCI devices directory. */
 #define SYSFS_PCI_DEVICES "/sys/bus/pci/devices"
diff --git a/lib/librte_eal/linuxapp/eal/eal_ivshmem.c b/lib/librte_eal/linuxapp/eal/eal_ivshmem.c
index 6191fef..87e88c3 100644
--- a/lib/librte_eal/linuxapp/eal/eal_ivshmem.c
+++ b/lib/librte_eal/linuxapp/eal/eal_ivshmem.c
@@ -854,7 +854,7 @@ int rte_eal_ivshmem_init(void)
 	}
 	else {
 
-		TAILQ_FOREACH(dev, &device_list, next) {
+		TAILQ_FOREACH(dev, &pci_device_list, next) {
 
 			if (is_ivshmem_device(dev)) {
 
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
index 5fa466e..f4ac8f4 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
@@ -888,13 +888,13 @@ pci_scan_one(const char *dirname, uint16_t domain, uint8_t bus,
 	}
 
 	/* device is valid, add in list (sorted) */
-	if (TAILQ_EMPTY(&device_list)) {
-		TAILQ_INSERT_TAIL(&device_list, dev, next);
+	if (TAILQ_EMPTY(&pci_device_list)) {
+		TAILQ_INSERT_TAIL(&pci_device_list, dev, next);
 	}	
 	else {
 		struct rte_pci_device *dev2 = NULL;
 
-		TAILQ_FOREACH(dev2, &device_list, next) {
+		TAILQ_FOREACH(dev2, &pci_device_list, next) {
 			if (pci_addr_comparison(&dev->addr, &dev2->addr))
 				continue;
 			else {
@@ -902,7 +902,7 @@ pci_scan_one(const char *dirname, uint16_t domain, uint8_t bus,
 				return 0;
 			}
 		}
-		TAILQ_INSERT_TAIL(&device_list, dev, next);
+		TAILQ_INSERT_TAIL(&pci_device_list, dev, next);
 	}
 				
 	return 0;
@@ -1068,8 +1068,8 @@ rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr, struct rte_pci_device *d
 int
 rte_eal_pci_init(void)
 {
-	TAILQ_INIT(&driver_list);
-	TAILQ_INIT(&device_list);
+	TAILQ_INIT(&pci_driver_list);
+	TAILQ_INIT(&pci_device_list);
 	uio_res_list = RTE_TAILQ_RESERVE_BY_IDX(RTE_TAILQ_PCI, uio_res_list);
 
 	/* for debug purposes, PCI can be disabled */
-- 
1.8.5.3

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [dpdk-dev] [PATCH 06/11] vdev: rename eal_common_nonpci_devs.c as eal_common_vdev.c
  2014-02-28 17:25 [dpdk-dev] [PATCH 00/11] eal: allow virtual pmd drivers as shared lib Olivier Matz
                   ` (4 preceding siblings ...)
  2014-02-28 17:25 ` [dpdk-dev] [PATCH 05/11] pci: rename device_list as pci_device_list Olivier Matz
@ 2014-02-28 17:25 ` Olivier Matz
  2014-04-10 14:39   ` Thomas Monjalon
  2014-02-28 17:25 ` [dpdk-dev] [PATCH 07/11] vdev: allow external registration of virtual device drivers Olivier Matz
                   ` (4 subsequent siblings)
  10 siblings, 1 reply; 57+ messages in thread
From: Olivier Matz @ 2014-02-28 17:25 UTC (permalink / raw)
  To: dev

The name "nonpci" for virtual devices is ambiguous. A physical device
can be non-PCI (ex: usb, sata, ...). This file only deal with virtual
devices so rename it to avoid confusion.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 lib/librte_eal/common/Makefile                 |   2 +-
 lib/librte_eal/common/eal_common_nonpci_devs.c | 111 -------------------------
 lib/librte_eal/common/eal_common_vdev.c        | 111 +++++++++++++++++++++++++
 lib/librte_eal/common/include/eal_private.h    |   4 +-
 lib/librte_eal/common/include/rte_vdev.h       |  90 ++++++++++++++++++++
 lib/librte_eal/linuxapp/eal/Makefile           |   2 +-
 lib/librte_eal/linuxapp/eal/eal.c              |   4 +-
 7 files changed, 207 insertions(+), 117 deletions(-)
 delete mode 100644 lib/librte_eal/common/eal_common_nonpci_devs.c
 create mode 100644 lib/librte_eal/common/eal_common_vdev.c
 create mode 100644 lib/librte_eal/common/include/rte_vdev.h

diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index b9f3b88..2f99bf4 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -38,7 +38,7 @@ INC += rte_pci_dev_ids.h rte_per_lcore.h rte_prefetch.h rte_random.h
 INC += rte_rwlock.h rte_spinlock.h rte_tailq.h rte_interrupts.h rte_alarm.h
 INC += rte_string_fns.h rte_cpuflags.h rte_version.h rte_tailq_elem.h
 INC += rte_eal_memconfig.h rte_malloc_heap.h
-INC += rte_hexdump.h rte_devargs.h
+INC += rte_hexdump.h rte_devargs.h rte_vdev.h
 
 ifeq ($(CONFIG_RTE_INSECURE_FUNCTION_WARNING),y)
 INC += rte_warnings.h
diff --git a/lib/librte_eal/common/eal_common_nonpci_devs.c b/lib/librte_eal/common/eal_common_nonpci_devs.c
deleted file mode 100644
index 71cbb1e..0000000
--- a/lib/librte_eal/common/eal_common_nonpci_devs.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/*-
- *   BSD LICENSE
- * 
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   Copyright(c) 2014 6WIND S.A.
- *   All rights reserved.
- * 
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- * 
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- * 
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <inttypes.h>
-#include <rte_string_fns.h>
-#ifdef RTE_LIBRTE_PMD_RING
-#include <rte_eth_ring.h>
-#endif
-#ifdef RTE_LIBRTE_PMD_PCAP
-#include <rte_eth_pcap.h>
-#endif
-#ifdef RTE_LIBRTE_PMD_XENVIRT
-#include <rte_eth_xenvirt.h>
-#endif
-#include <rte_debug.h>
-#include <rte_devargs.h>
-#include "eal_private.h"
-
-struct device_init {
-	const char *dev_prefix;
-	int (*init_fn)(const char*, const char *);
-};
-
-#define NUM_DEV_TYPES (sizeof(dev_types)/sizeof(dev_types[0]))
-struct device_init dev_types[] = {
-#ifdef RTE_LIBRTE_PMD_RING
-		{
-			.dev_prefix = RTE_ETH_RING_PARAM_NAME,
-			.init_fn = rte_pmd_ring_init
-		},
-#endif
-#ifdef RTE_LIBRTE_PMD_PCAP
-		{
-			.dev_prefix = RTE_ETH_PCAP_PARAM_NAME,
-			.init_fn = rte_pmd_pcap_init
-		},
-#endif
-#ifdef RTE_LIBRTE_PMD_XENVIRT
-		{
-			.dev_prefix = RTE_ETH_XENVIRT_PARAM_NAME,
-			.init_fn = rte_pmd_xenvirt_init
-		},
-#endif
-		{
-			.dev_prefix = "-nodev-",
-			.init_fn = NULL
-		}
-};
-
-int
-rte_eal_non_pci_ethdev_init(void)
-{
-	struct rte_devargs *devargs;
-	uint8_t i;
-
-	/* call the init function for each virtual device */
-	TAILQ_FOREACH(devargs, &devargs_list, next) {
-
-		if (devargs->type != RTE_DEVTYPE_VIRTUAL)
-			continue;
-
-		for (i = 0; i < NUM_DEV_TYPES; i++) {
-			/* search a driver prefix in virtual device name */
-			if (!strncmp(dev_types[i].dev_prefix,
-				    devargs->virtual.drv_name,
-				     sizeof(dev_types[i].dev_prefix) - 1)) {
-				dev_types[i].init_fn(devargs->virtual.drv_name,
-						     devargs->args);
-				break;
-			}
-		}
-
-		if (i == NUM_DEV_TYPES) {
-			rte_panic("no driver found for %s\n",
-				  devargs->virtual.drv_name);
-		}
-	}
-	return 0;
-}
diff --git a/lib/librte_eal/common/eal_common_vdev.c b/lib/librte_eal/common/eal_common_vdev.c
new file mode 100644
index 0000000..02d3fd6
--- /dev/null
+++ b/lib/librte_eal/common/eal_common_vdev.c
@@ -0,0 +1,111 @@
+/*-
+ *   BSD LICENSE
+ * 
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2014 6WIND S.A.
+ *   All rights reserved.
+ * 
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ * 
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ * 
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <inttypes.h>
+#include <rte_string_fns.h>
+#ifdef RTE_LIBRTE_PMD_RING
+#include <rte_eth_ring.h>
+#endif
+#ifdef RTE_LIBRTE_PMD_PCAP
+#include <rte_eth_pcap.h>
+#endif
+#ifdef RTE_LIBRTE_PMD_XENVIRT
+#include <rte_eth_xenvirt.h>
+#endif
+#include <rte_debug.h>
+#include <rte_devargs.h>
+#include "eal_private.h"
+
+struct device_init {
+	const char *dev_prefix;
+	int (*init_fn)(const char*, const char *);
+};
+
+#define NUM_DEV_TYPES (sizeof(dev_types)/sizeof(dev_types[0]))
+struct device_init dev_types[] = {
+#ifdef RTE_LIBRTE_PMD_RING
+		{
+			.dev_prefix = RTE_ETH_RING_PARAM_NAME,
+			.init_fn = rte_pmd_ring_init
+		},
+#endif
+#ifdef RTE_LIBRTE_PMD_PCAP
+		{
+			.dev_prefix = RTE_ETH_PCAP_PARAM_NAME,
+			.init_fn = rte_pmd_pcap_init
+		},
+#endif
+#ifdef RTE_LIBRTE_PMD_XENVIRT
+		{
+			.dev_prefix = RTE_ETH_XENVIRT_PARAM_NAME,
+			.init_fn = rte_pmd_xenvirt_init
+		},
+#endif
+		{
+			.dev_prefix = "-nodev-",
+			.init_fn = NULL
+		}
+};
+
+int
+rte_eal_vdev_init(void)
+{
+	struct rte_devargs *devargs;
+	uint8_t i;
+
+	/* call the init function for each virtual device */
+	TAILQ_FOREACH(devargs, &devargs_list, next) {
+
+		if (devargs->type != RTE_DEVTYPE_VIRTUAL)
+			continue;
+
+		for (i = 0; i < NUM_DEV_TYPES; i++) {
+			/* search a driver prefix in virtual device name */
+			if (!strncmp(dev_types[i].dev_prefix,
+				    devargs->virtual.drv_name,
+				     sizeof(dev_types[i].dev_prefix) - 1)) {
+				dev_types[i].init_fn(devargs->virtual.drv_name,
+						     devargs->args);
+				break;
+			}
+		}
+
+		if (i == NUM_DEV_TYPES) {
+			rte_panic("no driver found for %s\n",
+				  devargs->virtual.drv_name);
+		}
+	}
+	return 0;
+}
diff --git a/lib/librte_eal/common/include/eal_private.h b/lib/librte_eal/common/include/eal_private.h
index f9a019b..22d8b08 100644
--- a/lib/librte_eal/common/include/eal_private.h
+++ b/lib/librte_eal/common/include/eal_private.h
@@ -197,10 +197,10 @@ int rte_eal_intr_init(void);
 int rte_eal_alarm_init(void);
 
 /**
- * This function initialises any non-PCI i.e. dummy ethernet devices
+ * This function initialises any virtual devices
  *
  * This function is private to the EAL.
  */
-int rte_eal_non_pci_ethdev_init(void);
+int rte_eal_vdev_init(void);
 
 #endif /* _EAL_PRIVATE_H_ */
diff --git a/lib/librte_eal/common/include/rte_vdev.h b/lib/librte_eal/common/include/rte_vdev.h
new file mode 100644
index 0000000..48f71b7
--- /dev/null
+++ b/lib/librte_eal/common/include/rte_vdev.h
@@ -0,0 +1,90 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2014 6WIND S.A.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of 6WIND S.A. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_VDEV_H_
+#define _RTE_VDEV_H_
+
+/**
+ * @file
+ *
+ * RTE Virtual Devices Interface
+ *
+ * This file manages the list of the virtual device drivers.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/queue.h>
+
+/** Double linked list of virtual device drivers. */
+TAILQ_HEAD(rte_vdev_driver_list, rte_vdev_driver);
+
+/**
+ * Initialization function called for each virtual device probing.
+ */
+typedef int (rte_vdev_init_t)(const char *name, const char *args);
+
+/**
+ * A structure describing a virtual device driver.
+ */
+struct rte_vdev_driver {
+	TAILQ_ENTRY(rte_vdev_driver) next;  /**< Next in list. */
+	const char *name;                   /**< Driver name. */
+	rte_vdev_init_t *init;              /**< Device init. function. */
+};
+
+/**
+ * Register a virtual device driver.
+ *
+ * @param driver
+ *   A pointer to a rte_vdev structure describing the driver
+ *   to be registered.
+ */
+void rte_eal_vdev_driver_register(struct rte_vdev_driver *driver);
+
+/**
+ * Unregister a virtual device driver.
+ *
+ * @param driver
+ *   A pointer to a rte_vdev structure describing the driver
+ *   to be unregistered.
+ */
+void rte_eal_vdev_driver_unregister(struct rte_vdev_driver *driver);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_VDEV_H_ */
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index bdd940d..00f7367 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -77,7 +77,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_errno.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_cpuflags.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_hexdump.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_devargs.c
-SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_nonpci_devs.c
+SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_vdev.c
 
 CFLAGS_eal.o := -D_GNU_SOURCE
 CFLAGS_eal_thread.o := -D_GNU_SOURCE
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 4c23614..2f3222d 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -1039,8 +1039,8 @@ rte_eal_init(int argc, char **argv)
 
 	rte_eal_mcfg_complete();
 
-	if (rte_eal_non_pci_ethdev_init() < 0)
-		rte_panic("Cannot init non-PCI eth_devs\n");
+	if (rte_eal_vdev_init() < 0)
+		rte_panic("Cannot init virtual devices\n");
 
 	TAILQ_FOREACH(solib, &solib_list, next) {
 		solib->lib_handle = dlopen(solib->name, RTLD_NOW);
-- 
1.8.5.3

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [dpdk-dev] [PATCH 07/11] vdev: allow external registration of virtual device drivers
  2014-02-28 17:25 [dpdk-dev] [PATCH 00/11] eal: allow virtual pmd drivers as shared lib Olivier Matz
                   ` (5 preceding siblings ...)
  2014-02-28 17:25 ` [dpdk-dev] [PATCH 06/11] vdev: rename eal_common_nonpci_devs.c as eal_common_vdev.c Olivier Matz
@ 2014-02-28 17:25 ` Olivier Matz
  2014-04-10 14:55   ` Thomas Monjalon
  2014-02-28 17:25 ` [dpdk-dev] [PATCH 08/11] device-args: use a comma instead of semicolon to separate key/values Olivier Matz
                   ` (3 subsequent siblings)
  10 siblings, 1 reply; 57+ messages in thread
From: Olivier Matz @ 2014-02-28 17:25 UTC (permalink / raw)
  To: dev

Instead of having a list of virtual device drivers in EAL code, add an
API to register drivers. Thanks to this change:
- we don't need to reference pmd_ring, pmd_pcap and pmd_xenvirt in EAL code
- it is now possible to provide a virtual device driver as a shared
  library.

The registration is done in an init function flaged with
__attribute__((constructor)). The new convention is to name this
function rte_pmd_xyz_init(). The per-device init function is renamed
rte_pmd_xyz_devinit().

By the way the internal PMDs are now also .so/standalone ready. Let's do
it later on. It will be required to ease maintenance.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 app/test/test_pmd_ring.c                 |  6 +--
 lib/librte_eal/common/eal_common_vdev.c  | 72 +++++++++++++++-----------------
 lib/librte_eal/linuxapp/eal/eal.c        |  7 ++--
 lib/librte_pmd_pcap/rte_eth_pcap.c       | 16 ++++++-
 lib/librte_pmd_pcap/rte_eth_pcap.h       |  8 ----
 lib/librte_pmd_ring/rte_eth_ring.c       | 15 ++++++-
 lib/librte_pmd_ring/rte_eth_ring.h       |  6 +--
 lib/librte_pmd_xenvirt/rte_eth_xenvirt.c | 14 ++++++-
 lib/librte_pmd_xenvirt/rte_eth_xenvirt.h |  4 +-
 9 files changed, 85 insertions(+), 63 deletions(-)

diff --git a/app/test/test_pmd_ring.c b/app/test/test_pmd_ring.c
index c8242b3..4d9c2ba 100644
--- a/app/test/test_pmd_ring.c
+++ b/app/test/test_pmd_ring.c
@@ -315,12 +315,12 @@ test_pmd_ring_init(void)
 
 	printf("Testing ring pmd init\n");
 
-	if (rte_pmd_ring_init(name1, params_null) < 0) {
+	if (rte_pmd_ring_devinit(name1, params_null) < 0) {
 		printf("Testing ring pmd init fail\n");
 		return -1;
 	}
 
-	if (rte_pmd_ring_init(name2, params) < 0) {
+	if (rte_pmd_ring_devinit(name2, params) < 0) {
 		printf("Testing ring pmd init fail\n");
 		return -1;
 	}
@@ -372,7 +372,7 @@ test_pmd_ring_init(void)
 	rte_eth_dev_stop(RXTX_PORT2);
 
 	/* Test init same name pmd ring */
-	rte_pmd_ring_init(name1, params_null);
+	rte_pmd_ring_devinit(name1, params_null);
 	return 0;
 }
 
diff --git a/lib/librte_eal/common/eal_common_vdev.c b/lib/librte_eal/common/eal_common_vdev.c
index 02d3fd6..84547c7 100644
--- a/lib/librte_eal/common/eal_common_vdev.c
+++ b/lib/librte_eal/common/eal_common_vdev.c
@@ -34,7 +34,11 @@
 
 #include <string.h>
 #include <inttypes.h>
-#include <rte_string_fns.h>
+#include <sys/queue.h>
+
+#include <rte_vdev.h>
+#include <rte_devargs.h>
+#include <rte_debug.h>
 #ifdef RTE_LIBRTE_PMD_RING
 #include <rte_eth_ring.h>
 #endif
@@ -46,44 +50,37 @@
 #endif
 #include <rte_debug.h>
 #include <rte_devargs.h>
+
 #include "eal_private.h"
 
-struct device_init {
-	const char *dev_prefix;
-	int (*init_fn)(const char*, const char *);
-};
+/** Global list of virtual device drivers. */
+static struct rte_vdev_driver_list vdev_driver_list =
+	TAILQ_HEAD_INITIALIZER(vdev_driver_list);
 
-#define NUM_DEV_TYPES (sizeof(dev_types)/sizeof(dev_types[0]))
-struct device_init dev_types[] = {
-#ifdef RTE_LIBRTE_PMD_RING
-		{
-			.dev_prefix = RTE_ETH_RING_PARAM_NAME,
-			.init_fn = rte_pmd_ring_init
-		},
-#endif
-#ifdef RTE_LIBRTE_PMD_PCAP
-		{
-			.dev_prefix = RTE_ETH_PCAP_PARAM_NAME,
-			.init_fn = rte_pmd_pcap_init
-		},
-#endif
-#ifdef RTE_LIBRTE_PMD_XENVIRT
-		{
-			.dev_prefix = RTE_ETH_XENVIRT_PARAM_NAME,
-			.init_fn = rte_pmd_xenvirt_init
-		},
-#endif
-		{
-			.dev_prefix = "-nodev-",
-			.init_fn = NULL
-		}
-};
+/* register a driver */
+void
+rte_eal_vdev_driver_register(struct rte_vdev_driver *driver)
+{
+	TAILQ_INSERT_TAIL(&vdev_driver_list, driver, next);
+}
+
+/* unregister a driver */
+void
+rte_eal_vdev_driver_unregister(struct rte_vdev_driver *driver)
+{
+	TAILQ_REMOVE(&vdev_driver_list, driver, next);
+}
 
 int
 rte_eal_vdev_init(void)
 {
 	struct rte_devargs *devargs;
-	uint8_t i;
+	struct rte_vdev_driver *driver;
+
+	/* No need to register drivers that are embeded in DPDK
+	 * (pmd_pcap, pmd_ring, ...). The initialization function have
+	 * the ((constructor)) attribute so they will register at
+	 * startup. */
 
 	/* call the init function for each virtual device */
 	TAILQ_FOREACH(devargs, &devargs_list, next) {
@@ -91,18 +88,17 @@ rte_eal_vdev_init(void)
 		if (devargs->type != RTE_DEVTYPE_VIRTUAL)
 			continue;
 
-		for (i = 0; i < NUM_DEV_TYPES; i++) {
+		TAILQ_FOREACH(driver, &vdev_driver_list, next) {
 			/* search a driver prefix in virtual device name */
-			if (!strncmp(dev_types[i].dev_prefix,
-				    devargs->virtual.drv_name,
-				     sizeof(dev_types[i].dev_prefix) - 1)) {
-				dev_types[i].init_fn(devargs->virtual.drv_name,
-						     devargs->args);
+			if (!strncmp(driver->name, devargs->virtual.drv_name,
+					strlen(driver->name))) {
+				driver->init(devargs->virtual.drv_name,
+					devargs->args);
 				break;
 			}
 		}
 
-		if (i == NUM_DEV_TYPES) {
+		if (driver == NULL) {
 			rte_panic("no driver found for %s\n",
 				  devargs->virtual.drv_name);
 		}
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 2f3222d..6502755 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -1039,10 +1039,8 @@ rte_eal_init(int argc, char **argv)
 
 	rte_eal_mcfg_complete();
 
-	if (rte_eal_vdev_init() < 0)
-		rte_panic("Cannot init virtual devices\n");
-
 	TAILQ_FOREACH(solib, &solib_list, next) {
+		RTE_LOG(INFO, EAL, "open shared lib %s\n", solib->name);
 		solib->lib_handle = dlopen(solib->name, RTLD_NOW);
 		if ((solib->lib_handle == NULL) && (solib->name[0] != '/')) {
 			/* relative path: try again with "./" prefix */
@@ -1054,6 +1052,9 @@ rte_eal_init(int argc, char **argv)
 			RTE_LOG(WARNING, EAL, "%s\n", dlerror());
 	}
 
+	if (rte_eal_vdev_init() < 0)
+		rte_panic("Cannot init virtual devices\n");
+
 	RTE_LOG(DEBUG, EAL, "Master core %u is ready (tid=%x)\n",
 		rte_config.master_lcore, (int)thread_id);
 
diff --git a/lib/librte_pmd_pcap/rte_eth_pcap.c b/lib/librte_pmd_pcap/rte_eth_pcap.c
index 03e6e6c..15f7469 100644
--- a/lib/librte_pmd_pcap/rte_eth_pcap.c
+++ b/lib/librte_pmd_pcap/rte_eth_pcap.c
@@ -40,6 +40,7 @@
 #include <rte_string_fns.h>
 #include <rte_cycles.h>
 #include <rte_kvargs.h>
+#include <rte_vdev.h>
 
 #include <net/if.h>
 
@@ -697,8 +698,8 @@ rte_eth_from_pcaps(pcap_t * const rx_queues[],
 }
 
 
-int
-rte_pmd_pcap_init(const char *name, const char *params)
+static int
+rte_pmd_pcap_devinit(const char *name, const char *params)
 {
 	unsigned numa_node, using_dumpers = 0;
 	int ret;
@@ -777,3 +778,14 @@ rte_pmd_pcap_init(const char *name, const char *params)
 
 }
 
+static struct rte_vdev_driver pmd_pcap_drv = {
+	.name = "eth_pcap",
+	.init = rte_pmd_pcap_devinit,
+};
+
+__attribute__((constructor))
+static void
+rte_pmd_pcap_init(void)
+{
+	rte_eal_vdev_driver_register(&pmd_pcap_drv);
+}
diff --git a/lib/librte_pmd_pcap/rte_eth_pcap.h b/lib/librte_pmd_pcap/rte_eth_pcap.h
index c0bc5d8..473b6cb 100644
--- a/lib/librte_pmd_pcap/rte_eth_pcap.h
+++ b/lib/librte_pmd_pcap/rte_eth_pcap.h
@@ -45,8 +45,6 @@ extern "C" {
 #undef PCAP_CAN_SEND
 #endif
 
-#define RTE_ETH_PCAP_PARAM_NAME "eth_pcap"
-
 /* struct args_dict is declared in rte_eth_pcap_args_parser.h */
 struct args_dict;
 
@@ -64,12 +62,6 @@ int rte_eth_from_pcaps_n_dumpers(pcap_t * const rx_queues[],
 		const unsigned numa_node,
 		struct args_dict *dict);
 
-/**
- * For use by the EAL only. Called as part of EAL init to set up any dummy NICs
- * configured on command line.
- */
-int rte_pmd_pcap_init(const char *name, const char *params);
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_pmd_ring/rte_eth_ring.c b/lib/librte_pmd_ring/rte_eth_ring.c
index 24635f3..cee3fff 100644
--- a/lib/librte_pmd_ring/rte_eth_ring.c
+++ b/lib/librte_pmd_ring/rte_eth_ring.c
@@ -37,6 +37,7 @@
 #include <rte_malloc.h>
 #include <rte_memcpy.h>
 #include <rte_string_fns.h>
+#include <rte_vdev.h>
 
 struct ring_queue {
 	struct rte_ring *rng;
@@ -382,7 +383,7 @@ rte_eth_ring_pair_attach(const char *name, const unsigned numa_node)
 }
 
 int
-rte_pmd_ring_init(const char *name, const char *params)
+rte_pmd_ring_devinit(const char *name, const char *params)
 {
 	RTE_LOG(INFO, PMD, "Initializing pmd_ring for %s\n", name);
 
@@ -395,3 +396,15 @@ rte_pmd_ring_init(const char *name, const char *params)
 	}
 	return 0;
 }
+
+static struct rte_vdev_driver pmd_ring_drv = {
+	.name = "eth_ring",
+	.init = rte_pmd_ring_devinit,
+};
+
+__attribute__((constructor))
+static void
+rte_pmd_ring_init(void)
+{
+	rte_eal_vdev_driver_register(&pmd_ring_drv);
+}
diff --git a/lib/librte_pmd_ring/rte_eth_ring.h b/lib/librte_pmd_ring/rte_eth_ring.h
index a222ecb..b84a29e 100644
--- a/lib/librte_pmd_ring/rte_eth_ring.h
+++ b/lib/librte_pmd_ring/rte_eth_ring.h
@@ -40,8 +40,6 @@ extern "C" {
 
 #include <rte_ring.h>
 
-#define RTE_ETH_RING_PARAM_NAME "eth_ring"
-
 int rte_eth_from_rings(struct rte_ring * const rx_queues[],
 		const unsigned nb_rx_queues,
 		struct rte_ring *const tx_queues[],
@@ -52,10 +50,10 @@ int rte_eth_ring_pair_create(const char *name, const unsigned numa_node);
 int rte_eth_ring_pair_attach(const char *name, const unsigned numa_node);
 
 /**
- * For use by the EAL only. Called as part of EAL init to set up any dummy NICs
+ * For use by test apps only. Called as part of EAL init to set up any dummy NICs
  * configured on command line.
  */
-int rte_pmd_ring_init(const char *name, const char *params);
+int rte_pmd_ring_devinit(const char *name, const char *params);
 
 #ifdef __cplusplus
 }
diff --git a/lib/librte_pmd_xenvirt/rte_eth_xenvirt.c b/lib/librte_pmd_xenvirt/rte_eth_xenvirt.c
index bad8dd4..d142973 100644
--- a/lib/librte_pmd_xenvirt/rte_eth_xenvirt.c
+++ b/lib/librte_pmd_xenvirt/rte_eth_xenvirt.c
@@ -689,7 +689,7 @@ err:
 
 /*TODO: Support multiple process model */
 int
-rte_pmd_xenvirt_init(const char *name, const char *params)
+rte_pmd_xenvirt_devinit(const char *name, const char *params)
 {
 	if (virtio_idx == 0) {
 		if (xenstore_init() != 0) {
@@ -704,3 +704,15 @@ rte_pmd_xenvirt_init(const char *name, const char *params)
 	eth_dev_xenvirt_create(name, params, rte_socket_id(), DEV_CREATE);
 	return 0;
 }
+
+static struct rte_vdev_driver pmd_xenvirt_drv = {
+	.name = "eth_xenvirt",
+	.init = rte_pmd_xenvirt_devinit,
+};
+
+__attribute__((constructor))
+static void
+rte_pmd_xenvirt_init(void)
+{
+	rte_eal_vdev_driver_register(&pmd_xenvirt_drv);
+}
diff --git a/lib/librte_pmd_xenvirt/rte_eth_xenvirt.h b/lib/librte_pmd_xenvirt/rte_eth_xenvirt.h
index cb1924a..f3f3220 100644
--- a/lib/librte_pmd_xenvirt/rte_eth_xenvirt.h
+++ b/lib/librte_pmd_xenvirt/rte_eth_xenvirt.h
@@ -41,13 +41,11 @@ extern "C" {
 #include <rte_mempool.h>
 #include <rte_ring.h>
 
-#define RTE_ETH_XENVIRT_PARAM_NAME "eth_xenvirt"
-
 /**
  * For use by the EAL only. Called as part of EAL init to set up any dummy NICs
  * configured on command line.
  */
-int rte_pmd_xenvirt_init(const char *name, const char *params);
+int rte_pmd_xenvirt_devinit(const char *name, const char *params);
 
 /**
  * Creates mempool for xen virtio PMD.
-- 
1.8.5.3

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [dpdk-dev] [PATCH 08/11] device-args: use a comma instead of semicolon to separate key/values
  2014-02-28 17:25 [dpdk-dev] [PATCH 00/11] eal: allow virtual pmd drivers as shared lib Olivier Matz
                   ` (6 preceding siblings ...)
  2014-02-28 17:25 ` [dpdk-dev] [PATCH 07/11] vdev: allow external registration of virtual device drivers Olivier Matz
@ 2014-02-28 17:25 ` Olivier Matz
  2014-04-10 14:05   ` Thomas Monjalon
  2014-02-28 17:25 ` [dpdk-dev] [PATCH 09/11] device-args: replace use-device eal option by pci-whitelist and vdev Olivier Matz
                   ` (2 subsequent siblings)
  10 siblings, 1 reply; 57+ messages in thread
From: Olivier Matz @ 2014-02-28 17:25 UTC (permalink / raw)
  To: dev

This commit changes the API of --use-device. It changes the separator
used between each key/value pairs from ';' to ','. Indeed, ';' was not
the best choice as this character is also used to separate shell
commands, forcing the user to surround arguments with quotes.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 app/test/test_devargs.c                     | 10 +++++-----
 app/test/test_eal_flags.c                   |  4 ++--
 app/test/test_kvargs.c                      | 14 +++++++-------
 lib/librte_eal/common/eal_common_devargs.c  |  4 ++--
 lib/librte_eal/common/include/rte_devargs.h |  8 ++++----
 lib/librte_eal/linuxapp/eal/eal.c           |  2 +-
 lib/librte_kvargs/rte_kvargs.h              |  6 +++---
 7 files changed, 24 insertions(+), 24 deletions(-)

diff --git a/app/test/test_devargs.c b/app/test/test_devargs.c
index 4d45d53..f5451b2 100644
--- a/app/test/test_devargs.c
+++ b/app/test/test_devargs.c
@@ -68,7 +68,7 @@ test_devargs(void)
 		goto fail;
 	if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, "0000:5:00.0") < 0)
 		goto fail;
-	if (rte_eal_devargs_add(RTE_DEVTYPE_BLACKLISTED_PCI, "04:00.0;arg=val") < 0)
+	if (rte_eal_devargs_add(RTE_DEVTYPE_BLACKLISTED_PCI, "04:00.0,arg=val") < 0)
 		goto fail;
 	if (rte_eal_devargs_add(RTE_DEVTYPE_BLACKLISTED_PCI, "0000:01:00.1") < 0)
 		goto fail;
@@ -80,20 +80,20 @@ test_devargs(void)
 		goto fail;
 	if (rte_eal_devargs_add(RTE_DEVTYPE_VIRTUAL, "eth_ring0") < 0)
 		goto fail;
-	if (rte_eal_devargs_add(RTE_DEVTYPE_VIRTUAL, "eth_ring1;key=val;k2=val2") < 0)
+	if (rte_eal_devargs_add(RTE_DEVTYPE_VIRTUAL, "eth_ring1,key=val,k2=val2") < 0)
 		goto fail;
 	if (rte_eal_devargs_type_count(RTE_DEVTYPE_VIRTUAL) != 2)
 		goto fail;
 	free_devargs_list();
 
 	/* check virtual device with argument parsing */
-	if (rte_eal_devargs_add(RTE_DEVTYPE_VIRTUAL, "eth_ring1;k1=val;k2=val2") < 0)
+	if (rte_eal_devargs_add(RTE_DEVTYPE_VIRTUAL, "eth_ring1,k1=val,k2=val2") < 0)
 		goto fail;
 	devargs = TAILQ_FIRST(&devargs_list);
 	if (strncmp(devargs->virtual.drv_name, "eth_ring1",
 			sizeof(devargs->virtual.drv_name) != 0))
 		goto fail;
-	if (strncmp(devargs->args, "k1=val;k2=val2", sizeof(devargs->args) != 0))
+	if (strncmp(devargs->args, "k1=val,k2=val2", sizeof(devargs->args) != 0))
 		goto fail;
 	free_devargs_list();
 
@@ -117,7 +117,7 @@ test_devargs(void)
 		goto fail;
 	if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, "foo") == 0)
 		goto fail;
-	if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, ";") == 0)
+	if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, ",") == 0)
 		goto fail;
 	if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, "000f:0:0") == 0)
 		goto fail;
diff --git a/app/test/test_eal_flags.c b/app/test/test_eal_flags.c
index 9bab1a5..45d3d02 100644
--- a/app/test/test_eal_flags.c
+++ b/app/test/test_eal_flags.c
@@ -313,8 +313,8 @@ test_whitelist_flag(void)
 	const char *wlval2[] = {prgname, prefix, mp_flag, "-n", "1", "-c", "1",
 			use_device, "09:0B.3", use_device, "0a:0b.1"};
 	const char *wlval3[] = {prgname, prefix, mp_flag, "-n", "1", "-c", "1",
-			use_device, "09:0B.3;type=test",
-			use_device, "08:00.1;type=normal"};
+			use_device, "09:0B.3,type=test",
+			use_device, "08:00.1,type=normal"};
 
 	for (i = 0; i < sizeof(wlinval) / sizeof(wlinval[0]); i++) {
 		if (launch_proc(wlinval[i]) == 0) {
diff --git a/app/test/test_kvargs.c b/app/test/test_kvargs.c
index 2db9d08..c417ba2 100644
--- a/app/test/test_kvargs.c
+++ b/app/test/test_kvargs.c
@@ -84,7 +84,7 @@ static int test_valid_kvargs(void)
 	rte_kvargs_free(kvlist);
 
 	/* first test without valid_keys */
-	args = "foo=1234;check=value0;check=value1";
+	args = "foo=1234,check=value0,check=value1";
 	valid_keys = NULL;
 	kvlist = rte_kvargs_parse(args, valid_keys);
 	if (kvlist == NULL) {
@@ -145,7 +145,7 @@ static int test_valid_kvargs(void)
 	rte_kvargs_free(kvlist);
 
 	/* second test using valid_keys */
-	args = "foo=droids;check=value0;check=value1;check=wrong_value";
+	args = "foo=droids,check=value0,check=value1,check=wrong_value";
 	valid_keys = valid_keys_list;
 	kvlist = rte_kvargs_parse(args, valid_keys);
 	if (kvlist == NULL) {
@@ -190,11 +190,11 @@ static int test_invalid_kvargs(void)
 	/* list of argument that should fail */
 	const char *args_list[] = {
 		"wrong-key=x",     /* key not in valid_keys_list */
-		"foo=1;foo=",      /* empty value */
-		"foo=1;;foo=2",    /* empty key/value */
-		"foo=1;foo",       /* no value */
-		"foo=1;=2",        /* no key */
-		";=",              /* also test with a smiley */
+		"foo=1,foo=",      /* empty value */
+		"foo=1,,foo=2",    /* empty key/value */
+		"foo=1,foo",       /* no value */
+		"foo=1,=2",        /* no key */
+		",=",              /* also test with a smiley */
 		NULL };
 	const char **args;
 	const char *valid_keys_list[] = { "foo", "check", NULL };
diff --git a/lib/librte_eal/common/eal_common_devargs.c b/lib/librte_eal/common/eal_common_devargs.c
index de4ac6c..3d6656a 100644
--- a/lib/librte_eal/common/eal_common_devargs.c
+++ b/lib/librte_eal/common/eal_common_devargs.c
@@ -70,8 +70,8 @@ rte_eal_devargs_add(enum rte_devtype devtype, const char *devargs_str)
 	memset(devargs, 0, sizeof(*devargs));
 	devargs->type = devtype;
 
-	/* set the first ';' to '\0' to split name and arguments */
-	sep = strchr(buf, ';');
+	/* set the first ',' to '\0' to split name and arguments */
+	sep = strchr(buf, ',');
 	if (sep != NULL) {
 		sep[0] = '\0';
 		snprintf(devargs->args, sizeof(devargs->args), "%s", sep + 1);
diff --git a/lib/librte_eal/common/include/rte_devargs.h b/lib/librte_eal/common/include/rte_devargs.h
index fbfbe45..6dd901a 100644
--- a/lib/librte_eal/common/include/rte_devargs.h
+++ b/lib/librte_eal/common/include/rte_devargs.h
@@ -96,12 +96,12 @@ extern struct rte_devargs_list devargs_list;
  * Add a device to the user device list
  *
  * For PCI devices, the format of arguments string is "PCI_ADDR" or
- * "PCI_ADDR;key=val;key2=val2;...". Examples: "08:00.1", "0000:5:00.0",
- * "04:00.0;arg=val".
+ * "PCI_ADDR,key=val,key2=val2,...". Examples: "08:00.1", "0000:5:00.0",
+ * "04:00.0,arg=val".
  *
  * For virtual devices, the format of arguments string is "DRIVER_NAME*"
- * or "DRIVER_NAME*;key=val;key2=val2;...". Examples: "eth_ring",
- * "eth_ring0", "eth_pmdAnything;arg=0:arg2=1". The validity of the
+ * or "DRIVER_NAME*,key=val,key2=val2,...". Examples: "eth_ring",
+ * "eth_ring0", "eth_pmdAnything,arg=0:arg2=1". The validity of the
  * driver name is not checked by this function, it is done when probing
  * the drivers.
  *
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 6502755..67b2097 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -612,7 +612,7 @@ eal_parse_use_device(const char *optarg)
 		return -1;
 
 	/* remove arguments in 'dup' string */
-	sep = strchr(dup, ';');
+	sep = strchr(dup, ',');
 	if (sep != NULL)
 		*sep = '\0';
 
diff --git a/lib/librte_kvargs/rte_kvargs.h b/lib/librte_kvargs/rte_kvargs.h
index 71c9630..ef4efab 100644
--- a/lib/librte_kvargs/rte_kvargs.h
+++ b/lib/librte_kvargs/rte_kvargs.h
@@ -40,7 +40,7 @@
  * RTE Argument parsing
  *
  * This module can be used to parse arguments whose format is
- * key1=value1;key2=value2;key3=value3;...
+ * key1=value1,key2=value2,key3=value3,...
  *
  * The same key can appear several times with the same or a different
  * value. Indeed, the arguments are stored as a list of key/values
@@ -58,7 +58,7 @@ extern "C" {
 #define RTE_KVARGS_MAX 32
 
 /** separator character used between each pair */
-#define RTE_KVARGS_PAIRS_DELIM	";"
+#define RTE_KVARGS_PAIRS_DELIM	","
 
 /** separator character used between key and value */
 #define RTE_KVARGS_KV_DELIM	"="
@@ -83,7 +83,7 @@ struct rte_kvargs {
  * Allocate a rte_kvargs and store key/value associations from a string
  *
  * The function allocates and fills a rte_kvargs structure from a given
- * string whose format is key1=value1;key2=value2;...
+ * string whose format is key1=value1,key2=value2,...
  *
  * The structure can be freed with rte_kvargs_free().
  *
-- 
1.8.5.3

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [dpdk-dev] [PATCH 09/11] device-args: replace use-device eal option by pci-whitelist and vdev
  2014-02-28 17:25 [dpdk-dev] [PATCH 00/11] eal: allow virtual pmd drivers as shared lib Olivier Matz
                   ` (7 preceding siblings ...)
  2014-02-28 17:25 ` [dpdk-dev] [PATCH 08/11] device-args: use a comma instead of semicolon to separate key/values Olivier Matz
@ 2014-02-28 17:25 ` Olivier Matz
  2014-03-01 12:14   ` [dpdk-dev] [PATCH v2 " Olivier Matz
  2014-03-03 17:14   ` [dpdk-dev] [PATCH " Richardson, Bruce
  2014-02-28 17:25 ` [dpdk-dev] [PATCH 10/11] device-args: allow to provide per pci device command line arguments Olivier Matz
  2014-02-28 17:25 ` [dpdk-dev] [PATCH 11/11] testpmd: add several dump commands, useful for debug Olivier Matz
  10 siblings, 2 replies; 57+ messages in thread
From: Olivier Matz @ 2014-02-28 17:25 UTC (permalink / raw)
  To: dev

This commit splits the "--use-device" option in two new options:

- "--pci-whitelist or -w": add a PCI device in the white list
- "--vdev": instanciate a new virtual device

Before the patch, the same option "--use-device" was used for these 2
use-cases.

By the way, we also add "--pci-blacklist" in addition to the existing
"-b" for coherency with the whitelist parameter.

Test result:

echo 100 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages
echo 100 > /sys/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages
./app/test -c 0x15 -n 3 -m 64
RTE>>eal_flags_autotest
[...]
Test OK

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 app/test/test_eal_flags.c         | 27 +++++++-----
 lib/librte_eal/linuxapp/eal/eal.c | 89 +++++++++++++++++++++------------------
 2 files changed, 64 insertions(+), 52 deletions(-)

diff --git a/app/test/test_eal_flags.c b/app/test/test_eal_flags.c
index 45d3d02..195a1f5 100644
--- a/app/test/test_eal_flags.c
+++ b/app/test/test_eal_flags.c
@@ -57,7 +57,8 @@
 #define no_hpet "--no-hpet"
 #define no_huge "--no-huge"
 #define no_shconf "--no-shconf"
-#define use_device "--use-device"
+#define pci_whitelist "--pci-whitelist"
+#define vdev "--vdev"
 #define memtest "memtest"
 #define memtest1 "memtest1"
 #define memtest2 "memtest2"
@@ -295,26 +296,30 @@ test_whitelist_flag(void)
 
 	const char *wlinval[][11] = {
 		{prgname, prefix, mp_flag, "-n", "1", "-c", "1",
-				use_device, "error", "", ""},
+				pci_whitelist, "error", "", ""},
 		{prgname, prefix, mp_flag, "-n", "1", "-c", "1",
-				use_device, "0:0:0", "", ""},
+				pci_whitelist, "0:0:0", "", ""},
 		{prgname, prefix, mp_flag, "-n", "1", "-c", "1",
-				use_device, "0:error:0.1", "", ""},
+				pci_whitelist, "0:error:0.1", "", ""},
 		{prgname, prefix, mp_flag, "-n", "1", "-c", "1",
-				use_device, "0:0:0.1error", "", ""},
+				pci_whitelist, "0:0:0.1error", "", ""},
 		{prgname, prefix, mp_flag, "-n", "1", "-c", "1",
-				use_device, "error0:0:0.1", "", ""},
+				pci_whitelist, "error0:0:0.1", "", ""},
 		{prgname, prefix, mp_flag, "-n", "1", "-c", "1",
-				use_device, "0:0:0.1.2", "", ""},
+				pci_whitelist, "0:0:0.1.2", "", ""},
 	};
 	/* Test with valid whitelist option */
 	const char *wlval1[] = {prgname, prefix, mp_flag, "-n", "1", "-c", "1",
-			use_device, "00FF:09:0B.3"};
+			pci_whitelist, "00FF:09:0B.3"};
 	const char *wlval2[] = {prgname, prefix, mp_flag, "-n", "1", "-c", "1",
-			use_device, "09:0B.3", use_device, "0a:0b.1"};
+			pci_whitelist, "09:0B.3", pci_whitelist, "0a:0b.1"};
 	const char *wlval3[] = {prgname, prefix, mp_flag, "-n", "1", "-c", "1",
-			use_device, "09:0B.3,type=test",
-			use_device, "08:00.1,type=normal"};
+			pci_whitelist, "09:0B.3,type=test",
+			pci_whitelist, "08:00.1,type=normal",
+#ifdef CONFIG_RTE_LIBRTE_PMD_RING
+			vdev, "eth_ring,arg=test",
+#endif
+	};
 
 	for (i = 0; i < sizeof(wlinval) / sizeof(wlinval[0]); i++) {
 		if (launch_proc(wlinval[i]) == 0) {
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 67b2097..16ebec0 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -92,6 +92,9 @@
 #define OPT_FILE_PREFIX "file-prefix"
 #define OPT_SOCKET_MEM  "socket-mem"
 #define OPT_USE_DEVICE  "use-device"
+#define OPT_PCI_WHITELIST "pci-whitelist"
+#define OPT_PCI_BLACKLIST "pci-blacklist"
+#define OPT_VDEV        "vdev"
 #define OPT_SYSLOG      "syslog"
 #define OPT_BASE_VIRTADDR   "base-virtaddr"
 #define OPT_XEN_DOM0    "xen-dom0"
@@ -336,9 +339,6 @@ eal_usage(const char *prgname)
 	       "  -n NUM       : Number of memory channels\n"
 		   "  -v           : Display version information on startup\n"
 	       "  -d LIB.so    : add driver (can be used multiple times)\n"
-	       "  -b <domain:bus:devid.func>: to prevent EAL from using specified "
-           "PCI device\n"
-	       "                 (multiple -b options are allowed)\n"
 	       "  -m MB        : memory to allocate (see also --"OPT_SOCKET_MEM")\n"
 	       "  -r NUM       : force number of memory ranks (don't detect)\n"
 	       "  --"OPT_XEN_DOM0" : support application running on Xen Domain0 "
@@ -349,11 +349,17 @@ eal_usage(const char *prgname)
 	       "  --"OPT_HUGE_DIR"   : directory where hugetlbfs is mounted\n"
 	       "  --"OPT_PROC_TYPE"  : type of this process\n"
 	       "  --"OPT_FILE_PREFIX": prefix for hugepage filenames\n"
-	       "  --"OPT_USE_DEVICE": use the specified ethernet device(s) only.\n"
-	       "               The argument format is <[domain:]bus:devid.func> to add\n"
-	       "               a PCI device to the white list or <driver><id>[;key=val;...]\n"
-	       "               to add a virtual device.\n"
+	       "  --"OPT_PCI_BLACKLIST", -b: add a PCI device in black list.\n"
+	       "               Prevent EAL from using this PCI device. The argument\n"
+	       "               format is <domain:bus:devid.func>.\n"
+	       "  --"OPT_PCI_WHITELIST", -w: add a PCI device in white list.\n"
+	       "               Only use the specified PCI devices. The argument format\n"
+	       "               is <[domain:]bus:devid.func>. This option can be present\n"
+	       "               several times (once per device).\n"
 	       "               [NOTE: PCI whitelist cannot be used with -b option]\n"
+	       "  --"OPT_VDEV": add a virtual device.\n"
+	       "               The argument format is <driver><id>[,key=val,...]\n"
+	       "               (ex: --vdev=eth_pcap0,iface=eth2).\n"
 	       "  --"OPT_VMWARE_TSC_MAP": use VMware TSC map instead of "
 	    		   "native RDTSC\n"
 	       "  --"OPT_BASE_VIRTADDR": specify base virtual address\n"
@@ -601,34 +607,6 @@ eal_parse_proc_type(const char *arg)
 	return RTE_PROC_INVALID;
 }
 
-static int
-eal_parse_use_device(const char *optarg)
-{
-	struct rte_pci_addr addr;
-	char *dup, *sep;
-
-	dup = strdup(optarg);
-	if (dup == NULL)
-		return -1;
-
-	/* remove arguments in 'dup' string */
-	sep = strchr(dup, ',');
-	if (sep != NULL)
-		*sep = '\0';
-
-	/* if argument is a PCI address, it's a whitelisted device */
-	if (eal_parse_pci_DomBDF(dup, &addr) == 0 ||
-		eal_parse_pci_BDF(dup, &addr) == 0) {
-		rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, optarg);
-	}
-	else {
-		rte_eal_devargs_add(RTE_DEVTYPE_VIRTUAL, optarg);
-	}
-
-	free(dup);
-	return 0;
-}
-
 /* Parse the argument given in the command line of the application */
 static int
 eal_parse_args(int argc, char **argv)
@@ -648,7 +626,9 @@ eal_parse_args(int argc, char **argv)
 		{OPT_PROC_TYPE, 1, 0, 0},
 		{OPT_FILE_PREFIX, 1, 0, 0},
 		{OPT_SOCKET_MEM, 1, 0, 0},
-		{OPT_USE_DEVICE, 1, 0, 0},
+		{OPT_PCI_WHITELIST, 1, 0, 0},
+		{OPT_PCI_BLACKLIST, 1, 0, 0},
+		{OPT_VDEV, 1, 0, 0},
 		{OPT_SYSLOG, 1, NULL, 0},
 		{OPT_BASE_VIRTADDR, 1, 0, 0},
 		{OPT_XEN_DOM0, 0, 0, 0},
@@ -683,7 +663,7 @@ eal_parse_args(int argc, char **argv)
 	internal_config.vmware_tsc_map = 0;
 	internal_config.base_virtaddr = 0;
 
-	while ((opt = getopt_long(argc, argvopt, "b:c:d:m:n:r:v",
+	while ((opt = getopt_long(argc, argvopt, "b:w:c:d:m:n:r:v",
 				  lgopts, &option_index)) != EOF) {
 
 		switch (opt) {
@@ -695,6 +675,14 @@ eal_parse_args(int argc, char **argv)
 				return (-1);
 			}
 			break;
+		/* whitelist */
+		case 'w':
+			if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI,
+					optarg) < 0) {
+				eal_usage(prgname);
+				return -1;
+			}
+			break;
 		/* coremask */
 		case 'c':
 			if (eal_parse_coremask(optarg) < 0) {
@@ -794,9 +782,28 @@ eal_parse_args(int argc, char **argv)
 				}
 			}
 			else if (!strcmp(lgopts[option_index].name, OPT_USE_DEVICE)) {
-				if (eal_parse_use_device(optarg) < 0) {
-					RTE_LOG(ERR, EAL, "invalid parameters for --"
-							OPT_USE_DEVICE "\n");
+				printf("The --use-device option is deprecated, please use\n"
+					"--whitelist or --vdev instead.\n");
+				eal_usage(prgname);
+				return -1;
+			}
+			else if (!strcmp(lgopts[option_index].name, OPT_PCI_BLACKLIST)) {
+				if (rte_eal_devargs_add(RTE_DEVTYPE_BLACKLISTED_PCI,
+						optarg) < 0) {
+					eal_usage(prgname);
+					return -1;
+				}
+			}
+			else if (!strcmp(lgopts[option_index].name, OPT_PCI_WHITELIST)) {
+				if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI,
+						optarg) < 0) {
+					eal_usage(prgname);
+					return -1;
+				}
+			}
+			else if (!strcmp(lgopts[option_index].name, OPT_VDEV)) {
+				if (rte_eal_devargs_add(RTE_DEVTYPE_VIRTUAL,
+						optarg) < 0) {
 					eal_usage(prgname);
 					return -1;
 				}
@@ -879,7 +886,7 @@ eal_parse_args(int argc, char **argv)
 	if (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_PCI) != 0 &&
 		rte_eal_devargs_type_count(RTE_DEVTYPE_BLACKLISTED_PCI) != 0) {
 		RTE_LOG(ERR, EAL, "Error: blacklist [-b] and whitelist "
-			"[--use-device] options cannot be used at the same time\n");
+			"[-w] options cannot be used at the same time\n");
 		eal_usage(prgname);
 		return -1;
 	}
-- 
1.8.5.3

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [dpdk-dev] [PATCH 10/11] device-args: allow to provide per pci device command line arguments
  2014-02-28 17:25 [dpdk-dev] [PATCH 00/11] eal: allow virtual pmd drivers as shared lib Olivier Matz
                   ` (8 preceding siblings ...)
  2014-02-28 17:25 ` [dpdk-dev] [PATCH 09/11] device-args: replace use-device eal option by pci-whitelist and vdev Olivier Matz
@ 2014-02-28 17:25 ` Olivier Matz
  2014-03-01 12:14   ` [dpdk-dev] [PATCH v2 " Olivier Matz
  2014-02-28 17:25 ` [dpdk-dev] [PATCH 11/11] testpmd: add several dump commands, useful for debug Olivier Matz
  10 siblings, 1 reply; 57+ messages in thread
From: Olivier Matz @ 2014-02-28 17:25 UTC (permalink / raw)
  To: dev

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>
---
 lib/librte_eal/common/eal_common_pci.c  | 44 ++++++++++++++-------------------
 lib/librte_eal/common/include/rte_pci.h |  6 +++--
 lib/librte_eal/linuxapp/eal/eal_pci.c   |  4 ++-
 3 files changed, 26 insertions(+), 28 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c
index 03e1378..9eb9d5c 100644
--- a/lib/librte_eal/common/eal_common_pci.c
+++ b/lib/librte_eal/common/eal_common_pci.c
@@ -32,7 +32,7 @@
  */
 /*   BSD LICENSE
  *
- *   Copyright(c) 2013 6WIND.
+ *   Copyright(c) 2013-2014 6WIND.
  *
  *   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;
@@ -133,23 +134,6 @@ pci_probe_all_drivers(struct rte_pci_device *dev)
 }
 
 /*
- * 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
  * for discovered devices.
@@ -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);
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
index 6dd962a..3aa7d56 100644
--- a/lib/librte_eal/common/include/rte_pci.h
+++ b/lib/librte_eal/common/include/rte_pci.h
@@ -32,7 +32,7 @@
  */
 /*   BSD LICENSE
  *
- *   Copyright(c) 2013 6WIND.
+ *   Copyright(c) 2013-2014 6WIND.
  *
  *   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, ...) */
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
index f4ac8f4..9538efe 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
@@ -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;
 		}
-- 
1.8.5.3

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [dpdk-dev] [PATCH 11/11] testpmd: add several dump commands, useful for debug
  2014-02-28 17:25 [dpdk-dev] [PATCH 00/11] eal: allow virtual pmd drivers as shared lib Olivier Matz
                   ` (9 preceding siblings ...)
  2014-02-28 17:25 ` [dpdk-dev] [PATCH 10/11] device-args: allow to provide per pci device command line arguments Olivier Matz
@ 2014-02-28 17:25 ` Olivier Matz
  2014-03-01 12:15   ` [dpdk-dev] [PATCH v2 " Olivier Matz
  10 siblings, 1 reply; 57+ messages in thread
From: Olivier Matz @ 2014-02-28 17:25 UTC (permalink / raw)
  To: dev

Copy all the dump commands provided in app/test into app/testpmd. These
commands are useful to debug a problem when using testpmd.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 app/test-pmd/cmdline.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 114 insertions(+)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 37aa3d2..00f88f9 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -2,6 +2,7 @@
  *   BSD LICENSE
  * 
  *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2014 6WIND S.A.
  *   All rights reserved.
  * 
  *   Redistribution and use in source and binary forms, with or without
@@ -72,6 +73,7 @@
 #include <rte_ether.h>
 #include <rte_ethdev.h>
 #include <rte_string_fns.h>
+#include <rte_devargs.h>
 
 #include <cmdline_rdline.h>
 #include <cmdline_parse.h>
@@ -4998,6 +5000,116 @@ cmdline_parse_inst_t cmd_reset_mirror_rule = {
 
 /* ******************************************************************************** */
 
+struct cmd_dump_result {
+	cmdline_fixed_string_t dump;
+};
+
+static void
+dump_struct_sizes(void)
+{
+#define DUMP_SIZE(t) printf("sizeof(" #t ") = %u\n", (unsigned)sizeof(t));
+	DUMP_SIZE(struct rte_mbuf);
+	DUMP_SIZE(struct rte_pktmbuf);
+	DUMP_SIZE(struct rte_ctrlmbuf);
+	DUMP_SIZE(struct rte_mempool);
+	DUMP_SIZE(struct rte_ring);
+#undef DUMP_SIZE
+}
+
+static void cmd_dump_parsed(void *parsed_result,
+			    __attribute__((unused)) struct cmdline *cl,
+			    __attribute__((unused)) void *data)
+{
+	struct cmd_dump_result *res = parsed_result;
+
+	if (!strcmp(res->dump, "dump_physmem"))
+		rte_dump_physmem_layout();
+	else if (!strcmp(res->dump, "dump_memzone"))
+		rte_memzone_dump();
+	else if (!strcmp(res->dump, "dump_log_history"))
+		rte_log_dump_history();
+	else if (!strcmp(res->dump, "dump_struct_sizes"))
+		dump_struct_sizes();
+	else if (!strcmp(res->dump, "dump_ring"))
+		rte_ring_list_dump();
+	else if (!strcmp(res->dump, "dump_mempool"))
+		rte_mempool_list_dump();
+	else if (!strcmp(res->dump, "dump_devargs"))
+		rte_eal_devargs_dump();
+}
+
+cmdline_parse_token_string_t cmd_dump_dump =
+	TOKEN_STRING_INITIALIZER(struct cmd_dump_result, dump,
+		"dump_physmem#"
+		"dump_memzone#"
+		"dump_log_history#"
+		"dump_struct_sizes#"
+		"dump_ring#"
+		"dump_mempool#"
+		"dump_devargs");
+
+cmdline_parse_inst_t cmd_dump = {
+	.f = cmd_dump_parsed,  /* function to call */
+	.data = NULL,      /* 2nd arg of func */
+	.help_str = "dump status",
+	.tokens = {        /* token list, NULL terminated */
+		(void *)&cmd_dump_dump,
+		NULL,
+	},
+};
+
+/* ******************************************************************************** */
+
+struct cmd_dump_one_result {
+	cmdline_fixed_string_t dump;
+	cmdline_fixed_string_t name;
+};
+
+static void cmd_dump_one_parsed(void *parsed_result, struct cmdline *cl,
+				__attribute__((unused)) void *data)
+{
+	struct cmd_dump_one_result *res = parsed_result;
+
+	if (!strcmp(res->dump, "dump_ring")) {
+		struct rte_ring *r;
+		r = rte_ring_lookup(res->name);
+		if (r == NULL) {
+			cmdline_printf(cl, "Cannot find ring\n");
+			return;
+		}
+		rte_ring_dump(r);
+	}
+	else if (!strcmp(res->dump, "dump_mempool")) {
+		struct rte_mempool *mp;
+		mp = rte_mempool_lookup(res->name);
+		if (mp == NULL) {
+			cmdline_printf(cl, "Cannot find mempool\n");
+			return;
+		}
+		rte_mempool_dump(mp);
+	}
+}
+
+cmdline_parse_token_string_t cmd_dump_one_dump =
+	TOKEN_STRING_INITIALIZER(struct cmd_dump_one_result, dump,
+				 "dump_ring#dump_mempool");
+
+cmdline_parse_token_string_t cmd_dump_one_name =
+	TOKEN_STRING_INITIALIZER(struct cmd_dump_one_result, name, NULL);
+
+cmdline_parse_inst_t cmd_dump_one = {
+	.f = cmd_dump_one_parsed,  /* function to call */
+	.data = NULL,      /* 2nd arg of func */
+	.help_str = "dump one ring/mempool: dump_ring|dump_mempool <name>",
+	.tokens = {        /* token list, NULL terminated */
+		(void *)&cmd_dump_one_dump,
+		(void *)&cmd_dump_one_name,
+		NULL,
+	},
+};
+
+/* ******************************************************************************** */
+
 /* list of instructions */
 cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_help_brief,
@@ -5076,6 +5188,8 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_set_mirror_mask,
 	(cmdline_parse_inst_t *)&cmd_set_mirror_link,
 	(cmdline_parse_inst_t *)&cmd_reset_mirror_rule,
+	(cmdline_parse_inst_t *)&cmd_dump,
+	(cmdline_parse_inst_t *)&cmd_dump_one,
 	NULL,
 };
 
-- 
1.8.5.3

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [dpdk-dev] [PATCH 02/11] devices-args: introduce rte_devargs in eal
  2014-02-28 17:25 ` [dpdk-dev] [PATCH 02/11] devices-args: introduce rte_devargs in eal Olivier Matz
@ 2014-02-28 21:39   ` Stephen Hemminger
  2014-03-01 12:02     ` Olivier MATZ
  0 siblings, 1 reply; 57+ messages in thread
From: Stephen Hemminger @ 2014-02-28 21:39 UTC (permalink / raw)
  To: Olivier Matz; +Cc: dev

On Fri, 28 Feb 2014 18:25:41 +0100
Olivier Matz <olivier.matz@6wind.com> wrote:

> 	switch (devargs->type) {
> +		case RTE_DEVTYPE_WHITELISTED_PCI:
> +		case RTE_DEVTYPE_BLACKLISTED_PCI:
> +			/* try to parse pci identifier */
> +			if (eal_parse_pci_BDF(buf, &devargs->pci.addr) != 0 &&
> +				eal_parse_pci_DomBDF(buf, &devargs->pci.addr) != 0) {
> +				RTE_LOG(ERR, EAL,
> +					"invalid PCI identifier <%s>\n", buf);
> +				free(devargs);
> +				return -1;
> +			}
> +			break;

Minor nit. please align case with switch().
The DPDK in general follows Linux coding style.
In fact, I have run the code through checkpatch to find style issues.

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [dpdk-dev] [PATCH 02/11] devices-args: introduce rte_devargs in eal
  2014-02-28 21:39   ` Stephen Hemminger
@ 2014-03-01 12:02     ` Olivier MATZ
  2014-03-01 12:14       ` [dpdk-dev] [PATCH v2 " Olivier Matz
  0 siblings, 1 reply; 57+ messages in thread
From: Olivier MATZ @ 2014-03-01 12:02 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: dev

Hi Stephen,

On 02/28/2014 10:39 PM, Stephen Hemminger wrote:
> Minor nit. please align case with switch().
> The DPDK in general follows Linux coding style.
> In fact, I have run the code through checkpatch to find style issues.

Thank you for reporting this. Following you comment, I launched
checkpatch.pl on the all my patches and found some (minor) issues.
I will submit new versions for them.

Regards,
Olivier

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [dpdk-dev] [PATCH v2 02/11] devices-args: introduce rte_devargs in eal
  2014-03-01 12:02     ` Olivier MATZ
@ 2014-03-01 12:14       ` Olivier Matz
  2014-04-10 13:59         ` Thomas Monjalon
  0 siblings, 1 reply; 57+ messages in thread
From: Olivier Matz @ 2014-03-01 12:14 UTC (permalink / raw)
  To: dev

This commit introduces a new API for storing device arguments given by
the user. It only adds the framework and the test. The modification of
EAL to use this new module is done in next commit.

The final goals:

- unify pci-blacklist, pci-whitelist, and virtual devices arguments
  in one file
- allow to register a virtual device driver from a dpdk extension
  provided as a shared library. For that we will require to remove
  references to rte_pmd_ring and rte_pmd_pcap in argument parsing code
- clarify the API of eal_common_whitelist.c, and rework its code that is
  often complex for no reason.
- support arguments for PCI devices and possibly future non-PCI devices
  (other than virtual devices) without effort.

Test result:

echo 100 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages
echo 100 > /sys/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages
./app/test -c 0x15 -n 3 -m 64
RTE>>eal_flags_autotest
[...]
Test OK

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 app/test/Makefile                           |   1 +
 app/test/commands.c                         |   3 +
 app/test/test.h                             |   1 +
 app/test/test_devargs.c                     | 132 ++++++++++++++++++++++++
 lib/librte_eal/common/Makefile              |   2 +-
 lib/librte_eal/common/eal_common_devargs.c  | 153 ++++++++++++++++++++++++++++
 lib/librte_eal/common/include/rte_devargs.h | 140 +++++++++++++++++++++++++
 lib/librte_eal/linuxapp/eal/Makefile        |   1 +
 8 files changed, 432 insertions(+), 1 deletion(-)
 create mode 100644 app/test/test_devargs.c
 create mode 100644 lib/librte_eal/common/eal_common_devargs.c
 create mode 100644 lib/librte_eal/common/include/rte_devargs.h

v2 changes:
* passed checkpatch.pl

diff --git a/app/test/Makefile b/app/test/Makefile
index 28f1f62..b49785e 100644
--- a/app/test/Makefile
+++ b/app/test/Makefile
@@ -93,6 +93,7 @@ SRCS-$(CONFIG_RTE_APP_TEST) += test_power.c
 SRCS-$(CONFIG_RTE_APP_TEST) += test_common.c
 SRCS-$(CONFIG_RTE_APP_TEST) += test_timer_perf.c
 SRCS-$(CONFIG_RTE_APP_TEST) += test_ivshmem.c
+SRCS-$(CONFIG_RTE_APP_TEST) += test_devargs.c
 
 ifeq ($(CONFIG_RTE_APP_TEST),y)
 SRCS-$(CONFIG_RTE_LIBRTE_ACL) += test_acl.c
diff --git a/app/test/commands.c b/app/test/commands.c
index a153026..7595b4c 100644
--- a/app/test/commands.c
+++ b/app/test/commands.c
@@ -178,6 +178,8 @@ static void cmd_autotest_parsed(void *parsed_result,
 		ret = test_common();
 	if (!strcmp(res->autotest, "ivshmem_autotest"))
 		ret = test_ivshmem();
+	if (!strcmp(res->autotest, "devargs_autotest"))
+		ret = test_devargs();
 #ifdef RTE_LIBRTE_PMD_RING
 	if (!strcmp(res->autotest, "ring_pmd_autotest"))
 		ret = test_pmd_ring();
@@ -223,6 +225,7 @@ cmdline_parse_token_string_t cmd_autotest_autotest =
 			"red_autotest#meter_autotest#sched_autotest#"
 			"memcpy_perf_autotest#kni_autotest#"
 			"pm_autotest#ivshmem_autotest#"
+			"devargs_autotest#"
 #ifdef RTE_LIBRTE_ACL
 			"acl_autotest#"
 #endif
diff --git a/app/test/test.h b/app/test/test.h
index bc001b9..1945d29 100644
--- a/app/test/test.h
+++ b/app/test/test.h
@@ -93,6 +93,7 @@ int test_common(void);
 int test_pmd_ring(void);
 int test_ivshmem(void);
 int test_kvargs(void);
+int test_devargs(void);
 
 int test_pci_run;
 
diff --git a/app/test/test_devargs.c b/app/test/test_devargs.c
new file mode 100644
index 0000000..4d45d53
--- /dev/null
+++ b/app/test/test_devargs.c
@@ -0,0 +1,132 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2014 6WIND S.A.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of 6WIND S.A nor the names of its contributors
+ *       may be used to endorse or promote products derived from this
+ *       software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/queue.h>
+
+#include <rte_debug.h>
+#include <rte_devargs.h>
+
+#include "test.h"
+
+/* clear devargs list that was modified by the test */
+static void free_devargs_list(void)
+{
+	struct rte_devargs *devargs;
+
+	while (!TAILQ_EMPTY(&devargs_list)) {
+		devargs = TAILQ_FIRST(&devargs_list);
+		TAILQ_REMOVE(&devargs_list, devargs, next);
+		free(devargs);
+	}
+}
+
+int
+test_devargs(void)
+{
+	struct rte_devargs_list save_devargs_list;
+	struct rte_devargs *devargs;
+
+	/* save the real devargs_list, it is restored at the end of the test */
+	save_devargs_list = devargs_list;
+	TAILQ_INIT(&devargs_list);
+
+	/* test valid cases */
+	if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, "08:00.1") < 0)
+		goto fail;
+	if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, "0000:5:00.0") < 0)
+		goto fail;
+	if (rte_eal_devargs_add(RTE_DEVTYPE_BLACKLISTED_PCI, "04:00.0;arg=val") < 0)
+		goto fail;
+	if (rte_eal_devargs_add(RTE_DEVTYPE_BLACKLISTED_PCI, "0000:01:00.1") < 0)
+		goto fail;
+	if (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_PCI) != 2)
+		goto fail;
+	if (rte_eal_devargs_type_count(RTE_DEVTYPE_BLACKLISTED_PCI) != 2)
+		goto fail;
+	if (rte_eal_devargs_type_count(RTE_DEVTYPE_VIRTUAL) != 0)
+		goto fail;
+	if (rte_eal_devargs_add(RTE_DEVTYPE_VIRTUAL, "eth_ring0") < 0)
+		goto fail;
+	if (rte_eal_devargs_add(RTE_DEVTYPE_VIRTUAL, "eth_ring1;key=val;k2=val2") < 0)
+		goto fail;
+	if (rte_eal_devargs_type_count(RTE_DEVTYPE_VIRTUAL) != 2)
+		goto fail;
+	free_devargs_list();
+
+	/* check virtual device with argument parsing */
+	if (rte_eal_devargs_add(RTE_DEVTYPE_VIRTUAL, "eth_ring1;k1=val;k2=val2") < 0)
+		goto fail;
+	devargs = TAILQ_FIRST(&devargs_list);
+	if (strncmp(devargs->virtual.drv_name, "eth_ring1",
+			sizeof(devargs->virtual.drv_name) != 0))
+		goto fail;
+	if (strncmp(devargs->args, "k1=val;k2=val2", sizeof(devargs->args) != 0))
+		goto fail;
+	free_devargs_list();
+
+	/* check PCI device with empty argument parsing */
+	if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, "04:00.1") < 0)
+		goto fail;
+	devargs = TAILQ_FIRST(&devargs_list);
+	if (devargs->pci.addr.domain != 0 ||
+		devargs->pci.addr.bus != 4 ||
+		devargs->pci.addr.devid != 0 ||
+		devargs->pci.addr.function != 1)
+		goto fail;
+	if (strncmp(devargs->args, "", sizeof(devargs->args) != 0))
+		goto fail;
+	free_devargs_list();
+
+	/* test error case: bad PCI address */
+	if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, "08:1") == 0)
+		goto fail;
+	if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, "00.1") == 0)
+		goto fail;
+	if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, "foo") == 0)
+		goto fail;
+	if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, ";") == 0)
+		goto fail;
+	if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, "000f:0:0") == 0)
+		goto fail;
+
+	devargs_list = save_devargs_list;
+	return 0;
+
+ fail:
+	free_devargs_list();
+	devargs_list = save_devargs_list;
+	return -1;
+}
diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index f7b581e..b9f3b88 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -38,7 +38,7 @@ INC += rte_pci_dev_ids.h rte_per_lcore.h rte_prefetch.h rte_random.h
 INC += rte_rwlock.h rte_spinlock.h rte_tailq.h rte_interrupts.h rte_alarm.h
 INC += rte_string_fns.h rte_cpuflags.h rte_version.h rte_tailq_elem.h
 INC += rte_eal_memconfig.h rte_malloc_heap.h
-INC += rte_hexdump.h
+INC += rte_hexdump.h rte_devargs.h
 
 ifeq ($(CONFIG_RTE_INSECURE_FUNCTION_WARNING),y)
 INC += rte_warnings.h
diff --git a/lib/librte_eal/common/eal_common_devargs.c b/lib/librte_eal/common/eal_common_devargs.c
new file mode 100644
index 0000000..9d553fc
--- /dev/null
+++ b/lib/librte_eal/common/eal_common_devargs.c
@@ -0,0 +1,153 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2014 6WIND S.A.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of 6WIND S.A nor the names of its contributors
+ *       may be used to endorse or promote products derived from this
+ *       software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* This file manages the list of devices and their arguments, as given
+ * by the user at startup */
+
+#include <string.h>
+
+#include <rte_log.h>
+#include <rte_pci.h>
+#include <rte_devargs.h>
+#include "eal_private.h"
+
+/** Global list of user devices */
+struct rte_devargs_list devargs_list =
+	TAILQ_HEAD_INITIALIZER(devargs_list);
+
+/* store a whitelist parameter for later parsing */
+int
+rte_eal_devargs_add(enum rte_devtype devtype, const char *devargs_str)
+{
+	struct rte_devargs *devargs;
+	char buf[RTE_DEVARGS_LEN];
+	char *sep;
+	int ret;
+
+	ret = snprintf(buf, sizeof(buf), "%s", devargs_str);
+	if (ret < 0 || ret >= (int)sizeof(buf)) {
+		RTE_LOG(ERR, EAL, "user device args too large: <%s>\n",
+			devargs_str);
+		return -1;
+	}
+
+	/* use malloc instead of rte_malloc as it's called early at init */
+	devargs = malloc(sizeof(*devargs));
+	if (devargs == NULL) {
+		RTE_LOG(ERR, EAL, "cannot allocate devargs\n");
+		return -1;
+	}
+	memset(devargs, 0, sizeof(*devargs));
+	devargs->type = devtype;
+
+	/* set the first ';' to '\0' to split name and arguments */
+	sep = strchr(buf, ';');
+	if (sep != NULL) {
+		sep[0] = '\0';
+		snprintf(devargs->args, sizeof(devargs->args), "%s", sep + 1);
+	}
+
+	switch (devargs->type) {
+	case RTE_DEVTYPE_WHITELISTED_PCI:
+	case RTE_DEVTYPE_BLACKLISTED_PCI:
+		/* try to parse pci identifier */
+		if (eal_parse_pci_BDF(buf, &devargs->pci.addr) != 0 &&
+			eal_parse_pci_DomBDF(buf, &devargs->pci.addr) != 0) {
+			RTE_LOG(ERR, EAL,
+				"invalid PCI identifier <%s>\n", buf);
+			free(devargs);
+			return -1;
+		}
+		break;
+	case RTE_DEVTYPE_VIRTUAL:
+		/* save driver name */
+		ret = snprintf(devargs->virtual.drv_name,
+			sizeof(devargs->virtual.drv_name), "%s", buf);
+		if (ret < 0 || ret >= (int)sizeof(devargs->virtual.drv_name)) {
+			RTE_LOG(ERR, EAL,
+				"driver name too large: <%s>\n", buf);
+			free(devargs);
+			return -1;
+		}
+		break;
+	}
+
+	TAILQ_INSERT_TAIL(&devargs_list, devargs, next);
+	return 0;
+}
+
+/* count the number of devices of a specified type */
+unsigned int
+rte_eal_devargs_type_count(enum rte_devtype devtype)
+{
+	struct rte_devargs *devargs;
+	unsigned int count = 0;
+
+	TAILQ_FOREACH(devargs, &devargs_list, next) {
+		if (devargs->type != devtype)
+			continue;
+		count++;
+	}
+	return count;
+}
+
+/* dump the user devices on the console */
+void
+rte_eal_devargs_dump(void)
+{
+	struct rte_devargs *devargs;
+
+	printf("User device white list:\n");
+	TAILQ_FOREACH(devargs, &devargs_list, next) {
+		if (devargs->type == RTE_DEVTYPE_WHITELISTED_PCI)
+			printf("  PCI whitelist " PCI_PRI_FMT " %s\n",
+			       devargs->pci.addr.domain,
+			       devargs->pci.addr.bus,
+			       devargs->pci.addr.devid,
+			       devargs->pci.addr.function,
+			       devargs->args);
+		else if (devargs->type == RTE_DEVTYPE_BLACKLISTED_PCI)
+			printf("  PCI blacklist " PCI_PRI_FMT " %s\n",
+			       devargs->pci.addr.domain,
+			       devargs->pci.addr.bus,
+			       devargs->pci.addr.devid,
+			       devargs->pci.addr.function,
+			       devargs->args);
+		else if (devargs->type == RTE_DEVTYPE_VIRTUAL)
+			printf("  VIRTUAL %s %s\n",
+			       devargs->virtual.drv_name,
+			       devargs->args);
+		else
+			printf("  UNKNOWN %s\n", devargs->args);
+	}
+}
diff --git a/lib/librte_eal/common/include/rte_devargs.h b/lib/librte_eal/common/include/rte_devargs.h
new file mode 100644
index 0000000..fbfbe45
--- /dev/null
+++ b/lib/librte_eal/common/include/rte_devargs.h
@@ -0,0 +1,140 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2014 6WIND S.A.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of 6WIND S.A nor the names of its contributors
+ *       may be used to endorse or promote products derived from this
+ *       software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_DEVARGS_H_
+#define _RTE_DEVARGS_H_
+
+/**
+ * @file
+ *
+ * RTE devargs: list of devices and their user arguments
+ *
+ * This file stores a list of devices and their arguments given by
+ * the user when a DPDK application is started. These devices can be PCI
+ * devices or virtual devices. These devices are stored at startup in a
+ * list of rte_devargs structures.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/queue.h>
+#include <rte_pci.h>
+
+/**
+ * Type of generic device
+ */
+enum rte_devtype {
+	RTE_DEVTYPE_WHITELISTED_PCI,
+	RTE_DEVTYPE_BLACKLISTED_PCI,
+	RTE_DEVTYPE_VIRTUAL,
+};
+
+/**
+ * Structure that stores a device given by the user with its arguments
+ *
+ * A user device is a physical or a virtual device given by the user to
+ * the DPDK application at startup through command line arguments.
+ *
+ * The structure stores the configuration of the device, its PCI
+ * identifier if it's a PCI device or the driver name if it's a virtual
+ * device.
+ */
+struct rte_devargs {
+	TAILQ_ENTRY(rte_devargs) next;            /**< Next in list. */
+	enum rte_devtype type;                    /**< Type of device. */
+	union {
+		struct {
+			struct rte_pci_addr addr; /**< PCI location. */
+		} pci;              /**< Used if type is RTE_DEVTYPE_*_PCI. */
+		struct {
+			char drv_name[32];        /**< Driver name. */
+		} virtual;          /**< Used if type is RTE_DEVTYPE_VIRTUAL. */
+	};
+#define RTE_DEVARGS_LEN 256
+	char args[RTE_DEVARGS_LEN]; /**< Arguments string as given by user. */
+};
+
+/** user device double-linked queue type definition */
+TAILQ_HEAD(rte_devargs_list, rte_devargs);
+
+/** Global list of user devices */
+extern struct rte_devargs_list devargs_list;
+
+/**
+ * Add a device to the user device list
+ *
+ * For PCI devices, the format of arguments string is "PCI_ADDR" or
+ * "PCI_ADDR;key=val;key2=val2;...". Examples: "08:00.1", "0000:5:00.0",
+ * "04:00.0;arg=val".
+ *
+ * For virtual devices, the format of arguments string is "DRIVER_NAME*"
+ * or "DRIVER_NAME*;key=val;key2=val2;...". Examples: "eth_ring",
+ * "eth_ring0", "eth_pmdAnything;arg=0:arg2=1". The validity of the
+ * driver name is not checked by this function, it is done when probing
+ * the drivers.
+ *
+ * @param devtype
+ *   The type of the device.
+ * @param devargs_list
+ *   The arguments as given by the user.
+ *
+ * @return
+ *   - 0 on success
+ *   - A negative value on error
+ */
+int rte_eal_devargs_add(enum rte_devtype devtype, const char *devargs_str);
+
+/**
+ * Count the number of user devices of a specified type
+ *
+ * @param devtype
+ *   The type of the devices to counted.
+ *
+ * @return
+ *   The number of devices.
+ */
+unsigned int
+rte_eal_devargs_type_count(enum rte_devtype devtype);
+
+/**
+ * This function dumps the list of user device and their arguments.
+ */
+void rte_eal_devargs_dump(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_DEVARGS_H_ */
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index b525130..f57fda5 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -77,6 +77,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_errno.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_cpuflags.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_hexdump.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_whitelist.c
+SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_devargs.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_nonpci_devs.c
 
 CFLAGS_eal.o := -D_GNU_SOURCE
-- 
1.8.5.3

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [dpdk-dev] [PATCH v2 03/11] devices-args: use rte_devargs and remove old whitelist code
  2014-02-28 17:25 ` [dpdk-dev] [PATCH 03/11] devices-args: use rte_devargs and remove old whitelist code Olivier Matz
@ 2014-03-01 12:14   ` Olivier Matz
  2014-04-10 14:01     ` Thomas Monjalon
  0 siblings, 1 reply; 57+ messages in thread
From: Olivier Matz @ 2014-03-01 12:14 UTC (permalink / raw)
  To: dev

Remove old whitelist code:
- remove references to rte_pmd_ring, rte_pmd_pcap and pmd_xenvirt in
  is_valid_wl_entry() as we want to be able to register external virtual
  drivers as a shared library. Moreover this code was duplicated with
  dev_types[] from eal_common_pci.c
- eal_common_whitelist.c was badly named: it was able to process PCI
  devices white list and the registration of virtual devices
- the parsing code was complex: all arguments were prepended in
  one string dev_list_str[4096], then split again

Use the newly introduced rte_devargs to get:
- the PCI white list
- the PCI black list
- the list of virtual devices

Rework the tests:
- a part of the whitelist test can be removed as it is now tested
  in app/test/test_devargs.c
- the other parts are just reworked to adapt them to the new API

This commit induce a small API modification: it is not possible to specify
several devices per "--use-device" option. This notation was anyway a bit
cryptic. Ex:
  --use-device="eth_ring0,eth_pcap0;iface=ixgbe0"
  now becomes:
  --use-device="eth_ring0" --use-device="eth_pcap0;iface=ixgbe0"

On the other hand, it is now possible to work in PCI blacklist mode and
instanciate virtual drivers, which was not possible before this patch.

Test result:

./app/test -c 0x15 -n 3 -m 64
RTE>>devargs_autotest
EAL: invalid PCI identifier <08:1>
EAL: invalid PCI identifier <00.1>
EAL: invalid PCI identifier <foo>
EAL: invalid PCI identifier <>
EAL: invalid PCI identifier <000f:0:0>
Test OK

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 app/test/test_eal_flags.c                      |  49 +-----
 app/test/test_pci.c                            |  51 +++---
 lib/librte_eal/common/eal_common_nonpci_devs.c |  36 +++-
 lib/librte_eal/common/eal_common_pci.c         |  60 +++----
 lib/librte_eal/common/eal_common_whitelist.c   | 227 -------------------------
 lib/librte_eal/common/include/eal_private.h    |  38 -----
 lib/librte_eal/common/include/rte_pci.h        |  10 --
 lib/librte_eal/linuxapp/eal/Makefile           |   1 -
 lib/librte_eal/linuxapp/eal/eal.c              |  79 +++++----
 lib/librte_pmd_ring/rte_eth_ring.c             |   2 +-
 10 files changed, 132 insertions(+), 421 deletions(-)
 delete mode 100644 lib/librte_eal/common/eal_common_whitelist.c

v2 changes:
* passed checkpatch.pl

diff --git a/app/test/test_eal_flags.c b/app/test/test_eal_flags.c
index 964a3a9..9bab1a5 100644
--- a/app/test/test_eal_flags.c
+++ b/app/test/test_eal_flags.c
@@ -2,6 +2,7 @@
  *   BSD LICENSE
  * 
  *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2014 6WIND S.A.
  *   All rights reserved.
  * 
  *   Redistribution and use in source and binary forms, with or without
@@ -271,20 +272,6 @@ get_current_prefix(char * prefix, int size)
 	return prefix;
 }
 
-/* extra function prototypes for internal eal function to test in whitelist 
- * ICC 12 doesn't approve of this practice, so temporarily disable warnings for it */
-#ifdef __INTEL_COMPILER
-#pragma warning disable 1419
-#endif
-extern int eal_dev_whitelist_exists(void);
-extern int eal_dev_whitelist_add_entry(const char *);
-extern int eal_dev_whitelist_parse(void);
-extern int eal_dev_is_whitelisted(const char *, const char **);
-extern void eal_dev_whitelist_clear(void);
-#ifdef __INTEL_COMPILER
-#pragma warning enable 1419
-#endif
-
 /*
  * Test that the app doesn't run with invalid whitelist option.
  * Final tests ensures it does run with valid options as sanity check (one
@@ -319,17 +306,15 @@ test_whitelist_flag(void)
 				use_device, "error0:0:0.1", "", ""},
 		{prgname, prefix, mp_flag, "-n", "1", "-c", "1",
 				use_device, "0:0:0.1.2", "", ""},
-		{prgname, prefix, mp_flag, "-n", "1", "-c", "1",
-				use_device, "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x",
-				use_device, "y,z,1,2,3,4,5,6,7,8,9,0"},
 	};
 	/* Test with valid whitelist option */
 	const char *wlval1[] = {prgname, prefix, mp_flag, "-n", "1", "-c", "1",
 			use_device, "00FF:09:0B.3"};
 	const char *wlval2[] = {prgname, prefix, mp_flag, "-n", "1", "-c", "1",
-			use_device, "09:0B.3,0a:0b.1"};
+			use_device, "09:0B.3", use_device, "0a:0b.1"};
 	const char *wlval3[] = {prgname, prefix, mp_flag, "-n", "1", "-c", "1",
-			use_device, "09:0B.3;type=test,08:00.1;type=normal"};
+			use_device, "09:0B.3;type=test",
+			use_device, "08:00.1;type=normal"};
 
 	for (i = 0; i < sizeof(wlinval) / sizeof(wlinval[0]); i++) {
 		if (launch_proc(wlinval[i]) == 0) {
@@ -351,32 +336,6 @@ test_whitelist_flag(void)
 		return -1;
 	}
 
-	/* extra-sanity checks of whitelists - to be run only if no whitelist */
-	if (eal_dev_whitelist_exists())
-		return 0;
-
-	/* check that whitelist_parse returns error without whitelist */
-	if (eal_dev_whitelist_parse() != -1) {
-		printf("ERROR: calling whitelist parse without a whitelist doesn't "
-				"return an error\n");
-		return -1;
-	}
-	if (eal_dev_is_whitelisted("adevice", NULL)) {
-		printf("Whitelist lookup does not return false if no whitelist\n");
-		return -1;
-	}
-	eal_dev_whitelist_add_entry("0000:00:00.0");
-	eal_dev_whitelist_parse();
-	if (eal_dev_is_whitelisted("adevice", NULL)) {
-		printf("Whitelist lookup does not return false for unlisted dev\n");
-		return -1;
-	}
-	if (!eal_dev_is_whitelisted("0000:00:00.0", NULL)) {
-		printf("Whitelist lookup does not return true for whitelisted dev\n");
-		return -1;
-	}
-	eal_dev_whitelist_clear();
-
 	return 0;
 }
 
diff --git a/app/test/test_pci.c b/app/test/test_pci.c
index 64b13c1..223d76a 100644
--- a/app/test/test_pci.c
+++ b/app/test/test_pci.c
@@ -2,6 +2,7 @@
  *   BSD LICENSE
  * 
  *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2014 6WIND S.A.
  *   All rights reserved.
  * 
  *   Redistribution and use in source and binary forms, with or without
@@ -38,12 +39,11 @@
 
 #include <rte_interrupts.h>
 #include <rte_pci.h>
+#include <rte_devargs.h>
 
 #include "test.h"
 
 
-#define	TEST_BLACKLIST_NUM	0x100
-
 /*
  * PCI test
  * ========
@@ -58,7 +58,6 @@
 int test_pci_run = 0; /* value checked by the multiprocess test */
 static unsigned pci_dev_count;
 static unsigned driver_registered = 0;
-static struct rte_pci_addr blacklist[TEST_BLACKLIST_NUM];
 
 static int my_driver_init(struct rte_pci_driver *dr,
 			  struct rte_pci_device *dev);
@@ -116,37 +115,42 @@ my_driver_init(__attribute__((unused)) struct rte_pci_driver *dr,
 }
 
 static void
-blacklist_clear(void)
-{
-	rte_eal_pci_set_blacklist(NULL, 0);
-}
-
-
-
-static void
 blacklist_all_devices(void)
 {
 	struct rte_pci_device *dev = NULL;
-	unsigned idx = 0;
-
-	memset(blacklist, 0, sizeof (blacklist));
+	unsigned i = 0;
+	char pci_addr_str[16];
 
 	TAILQ_FOREACH(dev, &device_list, next) {
-		if (idx >= sizeof (blacklist) / sizeof (blacklist[0])) {
-			printf("Error: too many devices to blacklist");
+		snprintf(pci_addr_str, sizeof(pci_addr_str), PCI_PRI_FMT,
+			dev->addr.domain, dev->addr.bus, dev->addr.devid,
+			dev->addr.function);
+		if (rte_eal_devargs_add(RTE_DEVTYPE_BLACKLISTED_PCI,
+				pci_addr_str) < 0) {
+			printf("Error: cannot blacklist <%s>", pci_addr_str);
 			break;
 		}
-		blacklist[idx] = dev->addr;
-		++idx;
+		i++;
 	}
+	printf("%u devices blacklisted\n", i);
+}
+
+/* clear devargs list that was modified by the test */
+static void free_devargs_list(void)
+{
+	struct rte_devargs *devargs;
 
-	rte_eal_pci_set_blacklist(blacklist, idx);
-	printf("%u devices blacklisted\n", idx);
+	while (!TAILQ_EMPTY(&devargs_list)) {
+		devargs = TAILQ_FIRST(&devargs_list);
+		TAILQ_REMOVE(&devargs_list, devargs, next);
+		free(devargs);
+	}
 }
 
 int
 test_pci(void)
 {
+	struct rte_devargs_list save_devargs_list;
 
 	printf("Dump all devices\n");
 	rte_eal_pci_dump();
@@ -165,13 +169,18 @@ test_pci(void)
 		return -1;
 	}
 
+	/* save the real devargs_list */
+	save_devargs_list = devargs_list;
+	TAILQ_INIT(&devargs_list);
+
 	blacklist_all_devices();
 
 	pci_dev_count = 0;
 	printf("Scan bus with all devices blacklisted\n");
 	rte_eal_pci_probe();
 
-	blacklist_clear();
+	free_devargs_list();
+	devargs_list = save_devargs_list;
 
 	if (pci_dev_count != 0) {
 		printf("not all devices are blacklisted\n");
diff --git a/lib/librte_eal/common/eal_common_nonpci_devs.c b/lib/librte_eal/common/eal_common_nonpci_devs.c
index 1c9c88b..71cbb1e 100644
--- a/lib/librte_eal/common/eal_common_nonpci_devs.c
+++ b/lib/librte_eal/common/eal_common_nonpci_devs.c
@@ -2,6 +2,7 @@
  *   BSD LICENSE
  * 
  *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2014 6WIND S.A.
  *   All rights reserved.
  * 
  *   Redistribution and use in source and binary forms, with or without
@@ -31,6 +32,7 @@
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <string.h>
 #include <inttypes.h>
 #include <rte_string_fns.h>
 #ifdef RTE_LIBRTE_PMD_RING
@@ -42,6 +44,8 @@
 #ifdef RTE_LIBRTE_PMD_XENVIRT
 #include <rte_eth_xenvirt.h>
 #endif
+#include <rte_debug.h>
+#include <rte_devargs.h>
 #include "eal_private.h"
 
 struct device_init {
@@ -78,15 +82,29 @@ struct device_init dev_types[] = {
 int
 rte_eal_non_pci_ethdev_init(void)
 {
-	uint8_t i, j;
-	for (i = 0; i < NUM_DEV_TYPES; i++) {
-		for (j = 0; j < RTE_MAX_ETHPORTS; j++) {
-			const char *params;
-			char buf[16];
-			rte_snprintf(buf, sizeof(buf), "%s%"PRIu8,
-					dev_types[i].dev_prefix, j);
-			if (eal_dev_is_whitelisted(buf, &params))
-				dev_types[i].init_fn(buf, params);
+	struct rte_devargs *devargs;
+	uint8_t i;
+
+	/* call the init function for each virtual device */
+	TAILQ_FOREACH(devargs, &devargs_list, next) {
+
+		if (devargs->type != RTE_DEVTYPE_VIRTUAL)
+			continue;
+
+		for (i = 0; i < NUM_DEV_TYPES; i++) {
+			/* search a driver prefix in virtual device name */
+			if (!strncmp(dev_types[i].dev_prefix,
+				    devargs->virtual.drv_name,
+				     sizeof(dev_types[i].dev_prefix) - 1)) {
+				dev_types[i].init_fn(devargs->virtual.drv_name,
+						     devargs->args);
+				break;
+			}
+		}
+
+		if (i == NUM_DEV_TYPES) {
+			rte_panic("no driver found for %s\n",
+				  devargs->virtual.drv_name);
 		}
 	}
 	return 0;
diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c
index 9c9e842..0ab7e9c 100644
--- a/lib/librte_eal/common/eal_common_pci.c
+++ b/lib/librte_eal/common/eal_common_pci.c
@@ -61,6 +61,7 @@
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <string.h>
 #include <inttypes.h>
 #include <stdint.h>
 #include <stdlib.h>
@@ -77,29 +78,23 @@
 #include <rte_eal.h>
 #include <rte_string_fns.h>
 #include <rte_common.h>
+#include <rte_devargs.h>
 
 #include "eal_private.h"
 
 struct pci_driver_list driver_list;
 struct pci_device_list device_list;
 
-static struct rte_pci_addr *dev_blacklist = NULL;
-static unsigned dev_blacklist_size = 0;
-
 static int is_blacklisted(struct rte_pci_device *dev)
 {
-	struct rte_pci_addr *loc = &dev->addr;
-	unsigned i;
-
-	for (i = 0; i < dev_blacklist_size; i++) {
-		if ((loc->domain == dev_blacklist[i].domain) &&
-				(loc->bus == dev_blacklist[i].bus) &&
-				(loc->devid == dev_blacklist[i].devid) &&
-				(loc->function == dev_blacklist[i].function)) {
+	struct rte_devargs *devargs;
+
+	TAILQ_FOREACH(devargs, &devargs_list, next) {
+		if (devargs->type != RTE_DEVTYPE_BLACKLISTED_PCI)
+			continue;
+		if (!memcmp(&dev->addr, &devargs->pci.addr, sizeof(dev->addr)))
 			return 1;
-		}
 	}
-
 	return 0;           /* not in blacklist */
 }
 
@@ -143,16 +138,15 @@ pci_probe_all_drivers(struct rte_pci_device *dev)
 static int
 pcidev_is_whitelisted(struct rte_pci_device *dev)
 {
-	char buf[16];
-	if (dev->addr.domain == 0) {
-		rte_snprintf(buf, sizeof(buf), PCI_SHORT_PRI_FMT, dev->addr.bus,
-				dev->addr.devid, dev->addr.function);
-		if (eal_dev_is_whitelisted(buf, NULL))
+	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;
 	}
-	rte_snprintf(buf, sizeof(buf), PCI_PRI_FMT, dev->addr.domain,dev->addr.bus,
-			dev->addr.devid, dev->addr.function);
-	return eal_dev_is_whitelisted(buf, NULL);
+	return 0;
 }
 
 /*
@@ -164,14 +158,19 @@ int
 rte_eal_pci_probe(void)
 {
 	struct rte_pci_device *dev = NULL;
+	int probe_all = 0;
 
-	TAILQ_FOREACH(dev, &device_list, next)
-		if (!eal_dev_whitelist_exists())
+	if (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_PCI) == 0)
+		probe_all = 1;
+
+	TAILQ_FOREACH(dev, &device_list, next) {
+		if (probe_all)
 			pci_probe_all_drivers(dev);
-		else if (pcidev_is_whitelisted(dev) && 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);
+		else if (pcidev_is_whitelisted(dev) && 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);
+	}
 
 	return 0;
 }
@@ -220,10 +219,3 @@ 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)
-{
-	dev_blacklist = blacklist;
-	dev_blacklist_size = size;
-}
diff --git a/lib/librte_eal/common/eal_common_whitelist.c b/lib/librte_eal/common/eal_common_whitelist.c
deleted file mode 100644
index 9cc0446..0000000
--- a/lib/librte_eal/common/eal_common_whitelist.c
+++ /dev/null
@@ -1,227 +0,0 @@
-/*-
- *   BSD LICENSE
- * 
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- * 
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- * 
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- * 
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-/**
- * This file provides functions for managing a whitelist of devices. An EAL
- * command-line parameter should be used for specifying what devices to
- * whitelist, and the functions here should be called in handling that
- * parameter. Then when scanning the PCI bus, the is_whitelisted() function
- * can be used to query the previously set up whitelist.
- */
-#include <string.h>
-#include <rte_string_fns.h>
-#include <rte_log.h>
-#include <rte_debug.h>
-#include <rte_pci.h>
-#include <ctype.h>
-#ifdef RTE_LIBRTE_PMD_RING
-#include <rte_eth_ring.h>
-#endif
-#ifdef RTE_LIBRTE_PMD_PCAP
-#include <rte_eth_pcap.h>
-#endif
-#ifdef RTE_LIBRTE_PMD_XENVIRT
-#include <rte_eth_xenvirt.h>
-#endif
-#include "eal_private.h"
-
-static char dev_list_str[4096];
-static size_t dev_list_str_len = 0;
-
-/*
- * structure for storing a whitelist entry. Unlike for blacklists, we may
- * in future use this for dummy NICs not backed by a physical device, e.g.
- * backed by a file-system object instead, so we store the device path/addr
- * as a string, rather than as a PCI Bus-Device-Function.
- */
-static struct whitelist_entry {
-	const char *device_str;
-	const char *device_params;
-} whitelist[RTE_MAX_ETHPORTS] = { {NULL, NULL} };
-
-static unsigned num_wl_entries = 0;
-
-/* store a whitelist parameter for later parsing */
-int
-eal_dev_whitelist_add_entry(const char *entry)
-{
-	dev_list_str_len += rte_snprintf(&dev_list_str[dev_list_str_len],
-			sizeof(dev_list_str)-dev_list_str_len, "%s,", entry);
-	/* check for strings that won't fit (snprintf doesn't go beyond buffer) */
-	if (dev_list_str_len >= sizeof(dev_list_str)) {
-		dev_list_str_len = sizeof(dev_list_str) - 1;
-		return -1;
-	}
-
-	return 0;
-}
-
-/* check if a whitelist has been set up */
-int
-eal_dev_whitelist_exists(void)
-{
-	return !!dev_list_str_len;
-}
-
-/* sanity checks a whitelist entry to ensure device is correct */
-static int
-is_valid_wl_entry(const char *device_str, size_t dev_buf_len)
-{
-#define NUM_PREFIXES (sizeof(non_pci_prefixes)/sizeof(non_pci_prefixes[0]))
-	static const char *non_pci_prefixes[] = {
-#ifdef  RTE_LIBRTE_PMD_RING
-			RTE_ETH_RING_PARAM_NAME,
-#endif
-#ifdef RTE_LIBRTE_PMD_PCAP
-			RTE_ETH_PCAP_PARAM_NAME,
-#endif
-#ifdef RTE_LIBRTE_PMD_XENVIRT
-			RTE_ETH_XENVIRT_PARAM_NAME,
-#endif
-			"-nodev-" /* dummy value to prevent compiler warnings */
-	};
-	static uint8_t prefix_counts[NUM_PREFIXES] = {0};
-	char buf[16];
-	unsigned i;
-	struct rte_pci_addr pci_addr = { .domain = 0 };
-
-	if (eal_parse_pci_BDF(device_str, &pci_addr) == 0) {
-		size_t n = rte_snprintf(buf, sizeof(buf), PCI_SHORT_PRI_FMT,
-				pci_addr.bus, pci_addr.devid, pci_addr.function);
-		return (n == dev_buf_len) && (!strncmp(buf, device_str, dev_buf_len));
-	}
-	if (eal_parse_pci_DomBDF(device_str, &pci_addr) == 0) {
-		size_t n = rte_snprintf(buf, sizeof(buf), PCI_PRI_FMT, pci_addr.domain,
-				pci_addr.bus, pci_addr.devid, pci_addr.function);
-		return (n == dev_buf_len) && (!strncmp(buf, device_str, dev_buf_len));
-	}
-	for (i = 0; i < NUM_PREFIXES; i++) {
-		size_t n = rte_snprintf(buf, sizeof(buf), "%s%u",
-				non_pci_prefixes[i], prefix_counts[i]);
-		if ((n == dev_buf_len) && (!strncmp(buf, device_str, dev_buf_len))) {
-			prefix_counts[i]++;
-			return 1;
-		}
-	}
-	return 0;
-}
-
-/*
- * parse a whitelist string into a set of valid devices. To be called once
- * all parameters have been added to the whitelist string.
- */
-int
-eal_dev_whitelist_parse(void)
-{
-	char *devs[RTE_MAX_ETHPORTS + 1] = { NULL };
-	int i, num_devs;
-	unsigned dev_name_len, j;
-
-	if (!eal_dev_whitelist_exists())
-		return -1;
-
-	/* strip off any extra commas */
-	if (dev_list_str[dev_list_str_len - 1] == ',')
-		dev_list_str[--dev_list_str_len] = '\0';
-
-	/* split on commas into separate device entries */
-	num_devs = rte_strsplit(dev_list_str, sizeof(dev_list_str), devs,
-			RTE_MAX_ETHPORTS+1, ',');
-	if (num_devs > RTE_MAX_ETHPORTS) {
-		RTE_LOG(ERR, EAL, "Error, too many devices specified. "
-				"[RTE_MAX_ETHPORTS = %u]\n", (unsigned)RTE_MAX_ETHPORTS);
-		return -1;
-	}
-
-	size_t buf_len_rem = sizeof(dev_list_str); /* for tracking buffer length */
-	for (i = 0; i < num_devs; i++) {
-		char *dev_n_params[2]; /* possibly split device name from params*/
-
-		size_t curr_len = strnlen(devs[i], buf_len_rem);
-		buf_len_rem-= (curr_len + 1);
-
-		int split_res = rte_strsplit(devs[i], curr_len, dev_n_params, 2, ';');
-
-		/* device names go lower case, i.e. '00:0A.0' wouldn't work
-		 * while '00:0a.0' would. */
-		dev_name_len = strnlen(dev_n_params[0], curr_len);
-		for (j = 0; j < dev_name_len; j++)
-			dev_n_params[0][j] = (char)tolower((int)dev_n_params[0][j]);
-
-		switch (split_res) {
-		case 2:
-			whitelist[i].device_params = dev_n_params[1]; /* fallthrough */
-		case 1:
-			whitelist[i].device_str = dev_n_params[0];
-			break;
-		default: /* should never ever occur */
-			rte_panic("Fatal error parsing whitelist [--use-device] options\n");
-		}
-
-		if (!is_valid_wl_entry(whitelist[i].device_str,
-				strnlen(whitelist[i].device_str, curr_len))) {
-			RTE_LOG(ERR, EAL, "Error parsing device identifier: '%s'\n",
-					whitelist[i].device_str);
-			return -1;
-		}
-	}
-	num_wl_entries = num_devs;
-	return 0;
-}
-
-/* check if a device is on the whitelist */
-int
-eal_dev_is_whitelisted(const char *device_str, const char **params)
-{
-	unsigned i;
-	if (!eal_dev_whitelist_exists())
-		return 0; /* return false if no whitelist set up */
-
-	for (i = 0; i < num_wl_entries; i++)
-		if (strncmp(device_str, whitelist[i].device_str, 32) == 0) {
-			if (params != NULL)
-				*params = whitelist[i].device_params;
-			return 1;
-		}
-
-	return 0;
-}
-
-/* clear the whole whitelist */
-void
-eal_dev_whitelist_clear(void)
-{
-	dev_list_str[0] = '\0';
-	dev_list_str_len = num_wl_entries = 0;
-}
diff --git a/lib/librte_eal/common/include/eal_private.h b/lib/librte_eal/common/include/eal_private.h
index 251f15e..f9a019b 100644
--- a/lib/librte_eal/common/include/eal_private.h
+++ b/lib/librte_eal/common/include/eal_private.h
@@ -197,44 +197,6 @@ int rte_eal_intr_init(void);
 int rte_eal_alarm_init(void);
 
 /**
- * When parsing command-line args add a new entry to the whitelist string
- * to be parsed, i.e. this is used to join multiple --use-device flags together
- *
- * This function is private to EAL
- */
-int eal_dev_whitelist_add_entry(const char *entry);
-
-/**
- * Returns true if whitelist parameters are available for parsing,
- * false otherwise.
- *
- * This function is private to EAL
- */
-int eal_dev_whitelist_exists(void);
-
-/**
- * Parse the combined whitelist options into a single white-list for later use.
- *
- * This function is private to EAL
- */
-int eal_dev_whitelist_parse(void);
-
-/**
- * Check if a particular device is whitelisted or not. Returns true if the
- * device is in the whitelist.
- *
- * This function is private to EAL
- */
-int eal_dev_is_whitelisted(const char *device_str, const char **params);
-
-/**
- * This function clears the whitelist settings.
- *
- * This function is private to the EAL.
- */
-void eal_dev_whitelist_clear(void);
-
-/**
  * This function initialises any non-PCI i.e. dummy ethernet devices
  *
  * This function is private to the EAL.
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
index 9d4f94f..0aee5ff 100644
--- a/lib/librte_eal/common/include/rte_pci.h
+++ b/lib/librte_eal/common/include/rte_pci.h
@@ -290,16 +290,6 @@ void rte_eal_pci_register(struct rte_pci_driver *driver);
  */
 void rte_eal_pci_unregister(struct rte_pci_driver *driver);
 
-/**
- * Register a list of PCI locations that will be blacklisted (not used by DPDK).
- *
- * @param blacklist
- *   List of PCI device addresses that will not be used by DPDK.
- * @param size
- *   Number of items in the list.
- */
-void rte_eal_pci_set_blacklist(struct rte_pci_addr *blacklist, unsigned size);
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index f57fda5..bdd940d 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -76,7 +76,6 @@ SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_tailqs.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_errno.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_cpuflags.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_hexdump.c
-SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_whitelist.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_devargs.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_nonpci_devs.c
 
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index db0e15c..e9e97dc 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -2,7 +2,7 @@
  *   BSD LICENSE
  * 
  *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   Copyright(c) 2012-2013 6WIND S.A.
+ *   Copyright(c) 2012-2014 6WIND S.A.
  *   All rights reserved.
  * 
  *   Redistribution and use in source and binary forms, with or without
@@ -69,6 +69,7 @@
 #include <rte_cpuflags.h>
 #include <rte_interrupts.h>
 #include <rte_pci.h>
+#include <rte_devargs.h>
 #include <rte_common.h>
 #include <rte_version.h>
 #include <rte_atomic.h>
@@ -142,8 +143,6 @@ static struct rte_config rte_config = {
 		.mem_config = &early_mem_config,
 };
 
-static struct rte_pci_addr eal_dev_blacklist[RTE_EAL_BLACKLIST_SIZE];
-
 /* internal configuration (per-core) */
 struct lcore_config lcore_config[RTE_MAX_LCORE];
 
@@ -350,9 +349,11 @@ eal_usage(const char *prgname)
 	       "  --"OPT_HUGE_DIR"   : directory where hugetlbfs is mounted\n"
 	       "  --"OPT_PROC_TYPE"  : type of this process\n"
 	       "  --"OPT_FILE_PREFIX": prefix for hugepage filenames\n"
-	       "  --"OPT_USE_DEVICE": use the specified ethernet device(s) only. "
-	    		   "Use comma-separate <[domain:]bus:devid.func> values.\n"
-	       "               [NOTE: Cannot be used with -b option]\n"
+	       "  --"OPT_USE_DEVICE": use the specified ethernet device(s) only.\n"
+	       "               The argument format is <[domain:]bus:devid.func> to add\n"
+	       "               a PCI device to the white list or <driver><id>[;key=val;...]\n"
+	       "               to add a virtual device.\n"
+	       "               [NOTE: PCI whitelist cannot be used with -b option]\n"
 	       "  --"OPT_VMWARE_TSC_MAP": use VMware TSC map instead of "
 	    		   "native RDTSC\n"
 	       "  --"OPT_BASE_VIRTADDR": specify base virtual address\n"
@@ -600,20 +601,31 @@ eal_parse_proc_type(const char *arg)
 	return RTE_PROC_INVALID;
 }
 
-static ssize_t
-eal_parse_blacklist_opt(const char *optarg, size_t idx)
+static int
+eal_parse_use_device(const char *optarg)
 {
-	if (idx >= sizeof (eal_dev_blacklist) / sizeof (eal_dev_blacklist[0])) {
-		RTE_LOG(ERR, EAL, "%s - too many devices to blacklist...\n", optarg);
-		return (-EINVAL);
-	} else if (eal_parse_pci_DomBDF(optarg, eal_dev_blacklist + idx) < 0 &&
-			eal_parse_pci_BDF(optarg, eal_dev_blacklist + idx) < 0) {
-		RTE_LOG(ERR, EAL, "%s - invalid device to blacklist...\n", optarg);
-		return (-EINVAL);
+	struct rte_pci_addr addr;
+	char *dup, *sep;
+
+	dup = strdup(optarg);
+	if (dup == NULL)
+		return -1;
+
+	/* remove arguments in 'dup' string */
+	sep = strchr(dup, ';');
+	if (sep != NULL)
+		*sep = '\0';
+
+	/* if argument is a PCI address, it's a whitelisted device */
+	if (eal_parse_pci_DomBDF(dup, &addr) == 0 ||
+		eal_parse_pci_BDF(dup, &addr) == 0) {
+		rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, optarg);
+	} else {
+		rte_eal_devargs_add(RTE_DEVTYPE_VIRTUAL, optarg);
 	}
 
-	idx += 1;
-	return (idx);
+	free(dup);
+	return 0;
 }
 
 /* Parse the argument given in the command line of the application */
@@ -624,7 +636,6 @@ eal_parse_args(int argc, char **argv)
 	char **argvopt;
 	int option_index;
 	int coremask_ok = 0;
-	ssize_t blacklist_index = 0;
 	char *prgname = argv[0];
 	static struct option lgopts[] = {
 		{OPT_NO_HUGE, 0, 0, 0},
@@ -677,8 +688,8 @@ eal_parse_args(int argc, char **argv)
 		switch (opt) {
 		/* blacklist */
 		case 'b':
-			if ((blacklist_index = eal_parse_blacklist_opt(optarg,
-			    blacklist_index)) < 0) {
+			if (rte_eal_devargs_add(RTE_DEVTYPE_BLACKLISTED_PCI,
+					optarg) < 0) {
 				eal_usage(prgname);
 				return (-1);
 			}
@@ -782,7 +793,12 @@ eal_parse_args(int argc, char **argv)
 				}
 			}
 			else if (!strcmp(lgopts[option_index].name, OPT_USE_DEVICE)) {
-				eal_dev_whitelist_add_entry(optarg);
+				if (eal_parse_use_device(optarg) < 0) {
+					RTE_LOG(ERR, EAL, "invalid parameters for --"
+							OPT_USE_DEVICE "\n");
+					eal_usage(prgname);
+					return -1;
+				}
 			}
 			else if (!strcmp(lgopts[option_index].name, OPT_SYSLOG)) {
 				if (eal_parse_syslog(optarg) < 0) {
@@ -858,20 +874,13 @@ eal_parse_args(int argc, char **argv)
 		eal_usage(prgname);
 		return -1;
 	}
-	/* if no blacklist, parse a whitelist */
-	if (blacklist_index > 0) {
-		if (eal_dev_whitelist_exists()) {
-			RTE_LOG(ERR, EAL, "Error: blacklist [-b] and whitelist "
-					"[--use-device] options cannot be used at the same time\n");
-			eal_usage(prgname);
-			return -1;
-		}
-		rte_eal_pci_set_blacklist(eal_dev_blacklist, blacklist_index);
-	} else {
-		if (eal_dev_whitelist_exists() && eal_dev_whitelist_parse() < 0) {
-			RTE_LOG(ERR,EAL, "Error parsing whitelist[--use-device] options\n");
-			return -1;
-		}
+
+	if (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_PCI) != 0 &&
+		rte_eal_devargs_type_count(RTE_DEVTYPE_BLACKLISTED_PCI) != 0) {
+		RTE_LOG(ERR, EAL, "Error: blacklist [-b] and whitelist "
+			"[--use-device] options cannot be used at the same time\n");
+		eal_usage(prgname);
+		return -1;
 	}
 
 	if (optind >= 0)
diff --git a/lib/librte_pmd_ring/rte_eth_ring.c b/lib/librte_pmd_ring/rte_eth_ring.c
index 1fed8d3..24635f3 100644
--- a/lib/librte_pmd_ring/rte_eth_ring.c
+++ b/lib/librte_pmd_ring/rte_eth_ring.c
@@ -386,7 +386,7 @@ rte_pmd_ring_init(const char *name, const char *params)
 {
 	RTE_LOG(INFO, PMD, "Initializing pmd_ring for %s\n", name);
 
-	if (params == NULL)
+	if (params == NULL || params[0] == '\0')
 		eth_dev_ring_create(name, rte_socket_id(), DEV_CREATE);
 	else {
 		RTE_LOG(INFO, PMD, "Ignoring unsupported parameters when creating"
-- 
1.8.5.3

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [dpdk-dev] [PATCH v2 09/11] device-args: replace use-device eal option by pci-whitelist and vdev
  2014-02-28 17:25 ` [dpdk-dev] [PATCH 09/11] device-args: replace use-device eal option by pci-whitelist and vdev Olivier Matz
@ 2014-03-01 12:14   ` Olivier Matz
  2014-04-10 14:06     ` Thomas Monjalon
  2014-03-03 17:14   ` [dpdk-dev] [PATCH " Richardson, Bruce
  1 sibling, 1 reply; 57+ messages in thread
From: Olivier Matz @ 2014-03-01 12:14 UTC (permalink / raw)
  To: dev

This commit splits the "--use-device" option in two new options:

- "--pci-whitelist or -w": add a PCI device in the white list
- "--vdev": instanciate a new virtual device

Before the patch, the same option "--use-device" was used for these 2
use-cases.

By the way, we also add "--pci-blacklist" in addition to the existing
"-b" for coherency with the whitelist parameter.

Test result:

echo 100 > /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages
echo 100 > /sys/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages
./app/test -c 0x15 -n 3 -m 64
RTE>>eal_flags_autotest
[...]
Test OK

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 app/test/test_eal_flags.c         | 27 +++++++-----
 lib/librte_eal/linuxapp/eal/eal.c | 88 +++++++++++++++++++++------------------
 2 files changed, 64 insertions(+), 51 deletions(-)

v2 changes:
* passed checkpatch.pl

diff --git a/app/test/test_eal_flags.c b/app/test/test_eal_flags.c
index 45d3d02..195a1f5 100644
--- a/app/test/test_eal_flags.c
+++ b/app/test/test_eal_flags.c
@@ -57,7 +57,8 @@
 #define no_hpet "--no-hpet"
 #define no_huge "--no-huge"
 #define no_shconf "--no-shconf"
-#define use_device "--use-device"
+#define pci_whitelist "--pci-whitelist"
+#define vdev "--vdev"
 #define memtest "memtest"
 #define memtest1 "memtest1"
 #define memtest2 "memtest2"
@@ -295,26 +296,30 @@ test_whitelist_flag(void)
 
 	const char *wlinval[][11] = {
 		{prgname, prefix, mp_flag, "-n", "1", "-c", "1",
-				use_device, "error", "", ""},
+				pci_whitelist, "error", "", ""},
 		{prgname, prefix, mp_flag, "-n", "1", "-c", "1",
-				use_device, "0:0:0", "", ""},
+				pci_whitelist, "0:0:0", "", ""},
 		{prgname, prefix, mp_flag, "-n", "1", "-c", "1",
-				use_device, "0:error:0.1", "", ""},
+				pci_whitelist, "0:error:0.1", "", ""},
 		{prgname, prefix, mp_flag, "-n", "1", "-c", "1",
-				use_device, "0:0:0.1error", "", ""},
+				pci_whitelist, "0:0:0.1error", "", ""},
 		{prgname, prefix, mp_flag, "-n", "1", "-c", "1",
-				use_device, "error0:0:0.1", "", ""},
+				pci_whitelist, "error0:0:0.1", "", ""},
 		{prgname, prefix, mp_flag, "-n", "1", "-c", "1",
-				use_device, "0:0:0.1.2", "", ""},
+				pci_whitelist, "0:0:0.1.2", "", ""},
 	};
 	/* Test with valid whitelist option */
 	const char *wlval1[] = {prgname, prefix, mp_flag, "-n", "1", "-c", "1",
-			use_device, "00FF:09:0B.3"};
+			pci_whitelist, "00FF:09:0B.3"};
 	const char *wlval2[] = {prgname, prefix, mp_flag, "-n", "1", "-c", "1",
-			use_device, "09:0B.3", use_device, "0a:0b.1"};
+			pci_whitelist, "09:0B.3", pci_whitelist, "0a:0b.1"};
 	const char *wlval3[] = {prgname, prefix, mp_flag, "-n", "1", "-c", "1",
-			use_device, "09:0B.3,type=test",
-			use_device, "08:00.1,type=normal"};
+			pci_whitelist, "09:0B.3,type=test",
+			pci_whitelist, "08:00.1,type=normal",
+#ifdef CONFIG_RTE_LIBRTE_PMD_RING
+			vdev, "eth_ring,arg=test",
+#endif
+	};
 
 	for (i = 0; i < sizeof(wlinval) / sizeof(wlinval[0]); i++) {
 		if (launch_proc(wlinval[i]) == 0) {
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 30fd79d..16ebec0 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -92,6 +92,9 @@
 #define OPT_FILE_PREFIX "file-prefix"
 #define OPT_SOCKET_MEM  "socket-mem"
 #define OPT_USE_DEVICE  "use-device"
+#define OPT_PCI_WHITELIST "pci-whitelist"
+#define OPT_PCI_BLACKLIST "pci-blacklist"
+#define OPT_VDEV        "vdev"
 #define OPT_SYSLOG      "syslog"
 #define OPT_BASE_VIRTADDR   "base-virtaddr"
 #define OPT_XEN_DOM0    "xen-dom0"
@@ -336,9 +339,6 @@ eal_usage(const char *prgname)
 	       "  -n NUM       : Number of memory channels\n"
 		   "  -v           : Display version information on startup\n"
 	       "  -d LIB.so    : add driver (can be used multiple times)\n"
-	       "  -b <domain:bus:devid.func>: to prevent EAL from using specified "
-           "PCI device\n"
-	       "                 (multiple -b options are allowed)\n"
 	       "  -m MB        : memory to allocate (see also --"OPT_SOCKET_MEM")\n"
 	       "  -r NUM       : force number of memory ranks (don't detect)\n"
 	       "  --"OPT_XEN_DOM0" : support application running on Xen Domain0 "
@@ -349,11 +349,17 @@ eal_usage(const char *prgname)
 	       "  --"OPT_HUGE_DIR"   : directory where hugetlbfs is mounted\n"
 	       "  --"OPT_PROC_TYPE"  : type of this process\n"
 	       "  --"OPT_FILE_PREFIX": prefix for hugepage filenames\n"
-	       "  --"OPT_USE_DEVICE": use the specified ethernet device(s) only.\n"
-	       "               The argument format is <[domain:]bus:devid.func> to add\n"
-	       "               a PCI device to the white list or <driver><id>[;key=val;...]\n"
-	       "               to add a virtual device.\n"
+	       "  --"OPT_PCI_BLACKLIST", -b: add a PCI device in black list.\n"
+	       "               Prevent EAL from using this PCI device. The argument\n"
+	       "               format is <domain:bus:devid.func>.\n"
+	       "  --"OPT_PCI_WHITELIST", -w: add a PCI device in white list.\n"
+	       "               Only use the specified PCI devices. The argument format\n"
+	       "               is <[domain:]bus:devid.func>. This option can be present\n"
+	       "               several times (once per device).\n"
 	       "               [NOTE: PCI whitelist cannot be used with -b option]\n"
+	       "  --"OPT_VDEV": add a virtual device.\n"
+	       "               The argument format is <driver><id>[,key=val,...]\n"
+	       "               (ex: --vdev=eth_pcap0,iface=eth2).\n"
 	       "  --"OPT_VMWARE_TSC_MAP": use VMware TSC map instead of "
 	    		   "native RDTSC\n"
 	       "  --"OPT_BASE_VIRTADDR": specify base virtual address\n"
@@ -601,33 +607,6 @@ eal_parse_proc_type(const char *arg)
 	return RTE_PROC_INVALID;
 }
 
-static int
-eal_parse_use_device(const char *optarg)
-{
-	struct rte_pci_addr addr;
-	char *dup, *sep;
-
-	dup = strdup(optarg);
-	if (dup == NULL)
-		return -1;
-
-	/* remove arguments in 'dup' string */
-	sep = strchr(dup, ',');
-	if (sep != NULL)
-		*sep = '\0';
-
-	/* if argument is a PCI address, it's a whitelisted device */
-	if (eal_parse_pci_DomBDF(dup, &addr) == 0 ||
-		eal_parse_pci_BDF(dup, &addr) == 0) {
-		rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI, optarg);
-	} else {
-		rte_eal_devargs_add(RTE_DEVTYPE_VIRTUAL, optarg);
-	}
-
-	free(dup);
-	return 0;
-}
-
 /* Parse the argument given in the command line of the application */
 static int
 eal_parse_args(int argc, char **argv)
@@ -647,7 +626,9 @@ eal_parse_args(int argc, char **argv)
 		{OPT_PROC_TYPE, 1, 0, 0},
 		{OPT_FILE_PREFIX, 1, 0, 0},
 		{OPT_SOCKET_MEM, 1, 0, 0},
-		{OPT_USE_DEVICE, 1, 0, 0},
+		{OPT_PCI_WHITELIST, 1, 0, 0},
+		{OPT_PCI_BLACKLIST, 1, 0, 0},
+		{OPT_VDEV, 1, 0, 0},
 		{OPT_SYSLOG, 1, NULL, 0},
 		{OPT_BASE_VIRTADDR, 1, 0, 0},
 		{OPT_XEN_DOM0, 0, 0, 0},
@@ -682,7 +663,7 @@ eal_parse_args(int argc, char **argv)
 	internal_config.vmware_tsc_map = 0;
 	internal_config.base_virtaddr = 0;
 
-	while ((opt = getopt_long(argc, argvopt, "b:c:d:m:n:r:v",
+	while ((opt = getopt_long(argc, argvopt, "b:w:c:d:m:n:r:v",
 				  lgopts, &option_index)) != EOF) {
 
 		switch (opt) {
@@ -694,6 +675,14 @@ eal_parse_args(int argc, char **argv)
 				return (-1);
 			}
 			break;
+		/* whitelist */
+		case 'w':
+			if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI,
+					optarg) < 0) {
+				eal_usage(prgname);
+				return -1;
+			}
+			break;
 		/* coremask */
 		case 'c':
 			if (eal_parse_coremask(optarg) < 0) {
@@ -793,9 +782,28 @@ eal_parse_args(int argc, char **argv)
 				}
 			}
 			else if (!strcmp(lgopts[option_index].name, OPT_USE_DEVICE)) {
-				if (eal_parse_use_device(optarg) < 0) {
-					RTE_LOG(ERR, EAL, "invalid parameters for --"
-							OPT_USE_DEVICE "\n");
+				printf("The --use-device option is deprecated, please use\n"
+					"--whitelist or --vdev instead.\n");
+				eal_usage(prgname);
+				return -1;
+			}
+			else if (!strcmp(lgopts[option_index].name, OPT_PCI_BLACKLIST)) {
+				if (rte_eal_devargs_add(RTE_DEVTYPE_BLACKLISTED_PCI,
+						optarg) < 0) {
+					eal_usage(prgname);
+					return -1;
+				}
+			}
+			else if (!strcmp(lgopts[option_index].name, OPT_PCI_WHITELIST)) {
+				if (rte_eal_devargs_add(RTE_DEVTYPE_WHITELISTED_PCI,
+						optarg) < 0) {
+					eal_usage(prgname);
+					return -1;
+				}
+			}
+			else if (!strcmp(lgopts[option_index].name, OPT_VDEV)) {
+				if (rte_eal_devargs_add(RTE_DEVTYPE_VIRTUAL,
+						optarg) < 0) {
 					eal_usage(prgname);
 					return -1;
 				}
@@ -878,7 +886,7 @@ eal_parse_args(int argc, char **argv)
 	if (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_PCI) != 0 &&
 		rte_eal_devargs_type_count(RTE_DEVTYPE_BLACKLISTED_PCI) != 0) {
 		RTE_LOG(ERR, EAL, "Error: blacklist [-b] and whitelist "
-			"[--use-device] options cannot be used at the same time\n");
+			"[-w] options cannot be used at the same time\n");
 		eal_usage(prgname);
 		return -1;
 	}
-- 
1.8.5.3

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [dpdk-dev] [PATCH v2 10/11] device-args: allow to provide per pci device command line arguments
  2014-02-28 17:25 ` [dpdk-dev] [PATCH 10/11] device-args: allow to provide per pci device command line arguments Olivier Matz
@ 2014-03-01 12:14   ` Olivier Matz
  2014-04-10 14:06     ` Thomas Monjalon
  0 siblings, 1 reply; 57+ messages in thread
From: Olivier Matz @ 2014-03-01 12:14 UTC (permalink / raw)
  To: dev

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>
---
 lib/librte_eal/common/eal_common_pci.c  | 44 ++++++++++++++-------------------
 lib/librte_eal/common/include/rte_pci.h |  6 +++--
 lib/librte_eal/linuxapp/eal/eal_pci.c   |  4 ++-
 3 files changed, 26 insertions(+), 28 deletions(-)

v2 changes:
* passed checkpatch.pl

diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c
index f9c0a8c..9f4ddb6 100644
--- a/lib/librte_eal/common/eal_common_pci.c
+++ b/lib/librte_eal/common/eal_common_pci.c
@@ -32,7 +32,7 @@
  */
 /*   BSD LICENSE
  *
- *   Copyright(c) 2013 6WIND.
+ *   Copyright(c) 2013-2014 6WIND.
  *
  *   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;
@@ -133,23 +134,6 @@ pci_probe_all_drivers(struct rte_pci_device *dev)
 }
 
 /*
- * 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
  * for discovered devices.
@@ -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);
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
index 6dd962a..3aa7d56 100644
--- a/lib/librte_eal/common/include/rte_pci.h
+++ b/lib/librte_eal/common/include/rte_pci.h
@@ -32,7 +32,7 @@
  */
 /*   BSD LICENSE
  *
- *   Copyright(c) 2013 6WIND.
+ *   Copyright(c) 2013-2014 6WIND.
  *
  *   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, ...) */
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
index f4ac8f4..9538efe 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
@@ -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;
 		}
-- 
1.8.5.3

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [dpdk-dev] [PATCH v2 11/11] testpmd: add several dump commands, useful for debug
  2014-02-28 17:25 ` [dpdk-dev] [PATCH 11/11] testpmd: add several dump commands, useful for debug Olivier Matz
@ 2014-03-01 12:15   ` Olivier Matz
  2014-04-10 14:08     ` Thomas Monjalon
  0 siblings, 1 reply; 57+ messages in thread
From: Olivier Matz @ 2014-03-01 12:15 UTC (permalink / raw)
  To: dev

Copy all the dump commands provided in app/test into app/testpmd. These
commands are useful to debug a problem when using testpmd.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 app/test-pmd/cmdline.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 113 insertions(+)

v2 changes:
* passed checkpatch.pl

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 37aa3d2..7becedc 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -2,6 +2,7 @@
  *   BSD LICENSE
  * 
  *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2014 6WIND S.A.
  *   All rights reserved.
  * 
  *   Redistribution and use in source and binary forms, with or without
@@ -72,6 +73,7 @@
 #include <rte_ether.h>
 #include <rte_ethdev.h>
 #include <rte_string_fns.h>
+#include <rte_devargs.h>
 
 #include <cmdline_rdline.h>
 #include <cmdline_parse.h>
@@ -4998,6 +5000,115 @@ cmdline_parse_inst_t cmd_reset_mirror_rule = {
 
 /* ******************************************************************************** */
 
+struct cmd_dump_result {
+	cmdline_fixed_string_t dump;
+};
+
+static void
+dump_struct_sizes(void)
+{
+#define DUMP_SIZE(t) printf("sizeof(" #t ") = %u\n", (unsigned)sizeof(t));
+	DUMP_SIZE(struct rte_mbuf);
+	DUMP_SIZE(struct rte_pktmbuf);
+	DUMP_SIZE(struct rte_ctrlmbuf);
+	DUMP_SIZE(struct rte_mempool);
+	DUMP_SIZE(struct rte_ring);
+#undef DUMP_SIZE
+}
+
+static void cmd_dump_parsed(void *parsed_result,
+			    __attribute__((unused)) struct cmdline *cl,
+			    __attribute__((unused)) void *data)
+{
+	struct cmd_dump_result *res = parsed_result;
+
+	if (!strcmp(res->dump, "dump_physmem"))
+		rte_dump_physmem_layout();
+	else if (!strcmp(res->dump, "dump_memzone"))
+		rte_memzone_dump();
+	else if (!strcmp(res->dump, "dump_log_history"))
+		rte_log_dump_history();
+	else if (!strcmp(res->dump, "dump_struct_sizes"))
+		dump_struct_sizes();
+	else if (!strcmp(res->dump, "dump_ring"))
+		rte_ring_list_dump();
+	else if (!strcmp(res->dump, "dump_mempool"))
+		rte_mempool_list_dump();
+	else if (!strcmp(res->dump, "dump_devargs"))
+		rte_eal_devargs_dump();
+}
+
+cmdline_parse_token_string_t cmd_dump_dump =
+	TOKEN_STRING_INITIALIZER(struct cmd_dump_result, dump,
+		"dump_physmem#"
+		"dump_memzone#"
+		"dump_log_history#"
+		"dump_struct_sizes#"
+		"dump_ring#"
+		"dump_mempool#"
+		"dump_devargs");
+
+cmdline_parse_inst_t cmd_dump = {
+	.f = cmd_dump_parsed,  /* function to call */
+	.data = NULL,      /* 2nd arg of func */
+	.help_str = "dump status",
+	.tokens = {        /* token list, NULL terminated */
+		(void *)&cmd_dump_dump,
+		NULL,
+	},
+};
+
+/* ******************************************************************************** */
+
+struct cmd_dump_one_result {
+	cmdline_fixed_string_t dump;
+	cmdline_fixed_string_t name;
+};
+
+static void cmd_dump_one_parsed(void *parsed_result, struct cmdline *cl,
+				__attribute__((unused)) void *data)
+{
+	struct cmd_dump_one_result *res = parsed_result;
+
+	if (!strcmp(res->dump, "dump_ring")) {
+		struct rte_ring *r;
+		r = rte_ring_lookup(res->name);
+		if (r == NULL) {
+			cmdline_printf(cl, "Cannot find ring\n");
+			return;
+		}
+		rte_ring_dump(r);
+	} else if (!strcmp(res->dump, "dump_mempool")) {
+		struct rte_mempool *mp;
+		mp = rte_mempool_lookup(res->name);
+		if (mp == NULL) {
+			cmdline_printf(cl, "Cannot find mempool\n");
+			return;
+		}
+		rte_mempool_dump(mp);
+	}
+}
+
+cmdline_parse_token_string_t cmd_dump_one_dump =
+	TOKEN_STRING_INITIALIZER(struct cmd_dump_one_result, dump,
+				 "dump_ring#dump_mempool");
+
+cmdline_parse_token_string_t cmd_dump_one_name =
+	TOKEN_STRING_INITIALIZER(struct cmd_dump_one_result, name, NULL);
+
+cmdline_parse_inst_t cmd_dump_one = {
+	.f = cmd_dump_one_parsed,  /* function to call */
+	.data = NULL,      /* 2nd arg of func */
+	.help_str = "dump one ring/mempool: dump_ring|dump_mempool <name>",
+	.tokens = {        /* token list, NULL terminated */
+		(void *)&cmd_dump_one_dump,
+		(void *)&cmd_dump_one_name,
+		NULL,
+	},
+};
+
+/* ******************************************************************************** */
+
 /* list of instructions */
 cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_help_brief,
@@ -5076,6 +5187,8 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_set_mirror_mask,
 	(cmdline_parse_inst_t *)&cmd_set_mirror_link,
 	(cmdline_parse_inst_t *)&cmd_reset_mirror_rule,
+	(cmdline_parse_inst_t *)&cmd_dump,
+	(cmdline_parse_inst_t *)&cmd_dump_one,
 	NULL,
 };
 
-- 
1.8.5.3

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [dpdk-dev] [PATCH 09/11] device-args: replace use-device eal option by pci-whitelist and vdev
  2014-02-28 17:25 ` [dpdk-dev] [PATCH 09/11] device-args: replace use-device eal option by pci-whitelist and vdev Olivier Matz
  2014-03-01 12:14   ` [dpdk-dev] [PATCH v2 " Olivier Matz
@ 2014-03-03 17:14   ` Richardson, Bruce
  2014-03-04 13:09     ` Olivier MATZ
  1 sibling, 1 reply; 57+ messages in thread
From: Richardson, Bruce @ 2014-03-03 17:14 UTC (permalink / raw)
  To: Olivier Matz, dev

> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Olivier Matz
> Sent: Friday, February 28, 2014 5:26 PM
> To: dev@dpdk.org
> Subject: [dpdk-dev] [PATCH 09/11] device-args: replace use-device eal
> option by pci-whitelist and vdev
> 
> This commit splits the "--use-device" option in two new options:
> 
> - "--pci-whitelist or -w": add a PCI device in the white list
> - "--vdev": instanciate a new virtual device
> 
> Before the patch, the same option "--use-device" was used for these 2 use-
> cases.

[BR] Reviewing the patch set, most of the changes make sense to me. This one I've a few comments on. 
Is it really necessary and beneficial to split the --use-device option into two, and have two different ways for specifying the devices to use, based on whether they are pci or virtual devices? An alternative suggestion/idea: keep a common flag (be it --use-device, or something else) to specify a device to use and that device's parameters, for all device types, pretty much as now. Then, to solve the issue of not being able to use blacklisting plus virtual devices, that could be solved by adding the --pci-whitelist like you suggest, except instead of specifying the devices there, it simply means that only the pci devices passed to use-device get used. Without --pci-whitelist, all pci devices get used, whether or not they are explicitly called out with --use-device?
In this case, the "-b" flag could also be aliased by an "--ignore-device" (or similar) flag.

Any other thoughts or suggestions?

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [dpdk-dev] [PATCH 09/11] device-args: replace use-device eal option by pci-whitelist and vdev
  2014-03-03 17:14   ` [dpdk-dev] [PATCH " Richardson, Bruce
@ 2014-03-04 13:09     ` Olivier MATZ
  2014-03-04 13:14       ` Richardson, Bruce
  0 siblings, 1 reply; 57+ messages in thread
From: Olivier MATZ @ 2014-03-04 13:09 UTC (permalink / raw)
  To: Richardson, Bruce; +Cc: dev

Hi Bruce,

On 03/03/2014 06:14 PM, Richardson, Bruce wrote:
>> Subject: [dpdk-dev] [PATCH 09/11] device-args: replace use-device eal
>> option by pci-whitelist and vdev
>>
> Reviewing the patch set, most of the changes make sense to me. This
> one I've a few comments on.

OK, thank you for your review.

> Is it really necessary and beneficial to split the --use-device option
> into two, and have two different ways for specifying the devices to
> use, based on whether they are pci or virtual devices? An alternative
> suggestion/idea: keep a common flag (be it --use-device, or something
> else) to specify a device to use and that device's parameters, for all
> device types, pretty much as now. Then, to solve the issue of not
> being able to use blacklisting plus virtual devices, that could be
> solved by adding the --pci-whitelist like you suggest, except instead
> of specifying the devices there, it simply means that only the pci
> devices passed to use-device get used. Without --pci-whitelist, all
> pci devices get used, whether or not they are explicitly called out
> with --use-device?

My initial concern was that --use-device has 2 different significations,
depending on the format of arguments:
   - instanciate a virtual driver if it looks like a vdev name
   - add a PCI device to the whitelist if it looks like a pci address
I also find strange that instanciating a virtual device changes the
PCI mode to whitelist, even if it could be fixed by adding a specific
argument for that.

Splitting into two different options looked clearer to me, but this is
of course not a blocking issue for me.

Regards,
Olivier

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [dpdk-dev] [PATCH 09/11] device-args: replace use-device eal option by pci-whitelist and vdev
  2014-03-04 13:09     ` Olivier MATZ
@ 2014-03-04 13:14       ` Richardson, Bruce
  2014-03-24 22:39         ` Thomas Monjalon
  0 siblings, 1 reply; 57+ messages in thread
From: Richardson, Bruce @ 2014-03-04 13:14 UTC (permalink / raw)
  To: Olivier MATZ; +Cc: dev

> 
> My initial concern was that --use-device has 2 different significations,
> depending on the format of arguments:
>    - instanciate a virtual driver if it looks like a vdev name
>    - add a PCI device to the whitelist if it looks like a pci address I also find
> strange that instanciating a virtual device changes the PCI mode to
> whitelist, even if it could be fixed by adding a specific argument for that.
> 
[BR] I agree that having the mode change silently like that was probably not the best design. I therefore, agree that a flag should be used to switch from normal to whitelist mode, I just think that thereafter the devices of whatever type should all be enumerated using a common flag parameter.

> Splitting into two different options looked clearer to me, but this is of
> course not a blocking issue for me.
> 
[BR] For me neither, just giving my 2c worth :-).

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [dpdk-dev] [PATCH 09/11] device-args: replace use-device eal option by pci-whitelist and vdev
  2014-03-04 13:14       ` Richardson, Bruce
@ 2014-03-24 22:39         ` Thomas Monjalon
  0 siblings, 0 replies; 57+ messages in thread
From: Thomas Monjalon @ 2014-03-24 22:39 UTC (permalink / raw)
  To: Richardson, Bruce, Olivier MATZ; +Cc: dev

Hi,

04/03/2014 13:14, Richardson, Bruce:
> 04/03/2014 14:09, Olivier MATZ:
> > My initial concern was that --use-device has 2 different significations,
> > depending on the format of arguments:
> >    - instanciate a virtual driver if it looks like a vdev name
> >    - add a PCI device to the whitelist if it looks like a pci address
> > I also find strange that instanciating a virtual device changes the PCI
> > mode to whitelist, even if it could be fixed by adding a specific argument
> > for that.
>
> [BR] I agree that having the mode change silently like that was probably not
> the best design. I therefore, agree that a flag should be used to switch
> from normal to whitelist mode, I just think that thereafter the devices of
> whatever type should all be enumerated using a common flag parameter.

I think we should split this in 2 functions because they have totally 
different meaning:
	- create a virtual device and instantiate a driver
	- whitelist a physical device for driver probing
Using the same option for vdev and whitelist would be even more confusing in 
case of blacklist because drivers would probe explicitly listed vdevs and PCI 
devs which are not blacklisted.

-- 
Thomas

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [dpdk-dev] [PATCH 01/11] mk: use whole-archive option when creating dpdk binaries
  2014-02-28 17:25 ` [dpdk-dev] [PATCH 01/11] mk: use whole-archive option when creating dpdk binaries Olivier Matz
@ 2014-04-10 13:58   ` Thomas Monjalon
  0 siblings, 0 replies; 57+ messages in thread
From: Thomas Monjalon @ 2014-04-10 13:58 UTC (permalink / raw)
  To: Olivier Matz; +Cc: dev

2014-02-28 18:25, Olivier Matz:
> To fully support dpdk extensions (loading of .so), all symbols provided
> by dpdk libraries must be available in the binaries: before this patch,
> unused functions/variables from dpdk static libraries could be stripped
> by the linker because they are not used. These symbols can be used by a
> dpdk extension that is loaded at runtime with the -d option.
> 
> Adding --whole-archive when generating a binary solves this issue.
> 
> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>

Acked-by: Thomas Monjalon <thomas.monjalon@6wind.com>

Applied for version 1.6.0r2.

-- 
Thomas

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [dpdk-dev] [PATCH v2 02/11] devices-args: introduce rte_devargs in eal
  2014-03-01 12:14       ` [dpdk-dev] [PATCH v2 " Olivier Matz
@ 2014-04-10 13:59         ` Thomas Monjalon
  0 siblings, 0 replies; 57+ messages in thread
From: Thomas Monjalon @ 2014-04-10 13:59 UTC (permalink / raw)
  To: Olivier Matz; +Cc: dev

2014-03-01 13:14, Olivier Matz:
> This commit introduces a new API for storing device arguments given by
> the user. It only adds the framework and the test. The modification of
> EAL to use this new module is done in next commit.
> 
> The final goals:
> 
> - unify pci-blacklist, pci-whitelist, and virtual devices arguments
>   in one file
> - allow to register a virtual device driver from a dpdk extension
>   provided as a shared library. For that we will require to remove
>   references to rte_pmd_ring and rte_pmd_pcap in argument parsing code
> - clarify the API of eal_common_whitelist.c, and rework its code that is
>   often complex for no reason.
> - support arguments for PCI devices and possibly future non-PCI devices
>   (other than virtual devices) without effort.
> 
> Test result:
> 
> echo 100 >
> /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages echo
> 100 >
> /sys/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages
> ./app/test -c 0x15 -n 3 -m 64
> RTE>>eal_flags_autotest
> [...]
> Test OK
> 
> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>

Acked-by: Thomas Monjalon <thomas.monjalon@6wind.com>

Applied for version 1.6.0r2 with title
	"devargs: introduce API and test"

-- 
Thomas

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [dpdk-dev] [PATCH v2 03/11] devices-args: use rte_devargs and remove old whitelist code
  2014-03-01 12:14   ` [dpdk-dev] [PATCH v2 " Olivier Matz
@ 2014-04-10 14:01     ` Thomas Monjalon
  0 siblings, 0 replies; 57+ messages in thread
From: Thomas Monjalon @ 2014-04-10 14:01 UTC (permalink / raw)
  To: Olivier Matz; +Cc: dev

2014-03-01 13:14, Olivier Matz:
> Remove old whitelist code:
> - remove references to rte_pmd_ring, rte_pmd_pcap and pmd_xenvirt in
>   is_valid_wl_entry() as we want to be able to register external virtual
>   drivers as a shared library. Moreover this code was duplicated with
>   dev_types[] from eal_common_pci.c
> - eal_common_whitelist.c was badly named: it was able to process PCI
>   devices white list and the registration of virtual devices
> - the parsing code was complex: all arguments were prepended in
>   one string dev_list_str[4096], then split again
> 
> Use the newly introduced rte_devargs to get:
> - the PCI white list
> - the PCI black list
> - the list of virtual devices
> 
> Rework the tests:
> - a part of the whitelist test can be removed as it is now tested
>   in app/test/test_devargs.c
> - the other parts are just reworked to adapt them to the new API
> 
> This commit induce a small API modification: it is not possible to specify
> several devices per "--use-device" option. This notation was anyway a bit
> cryptic. Ex:
>   --use-device="eth_ring0,eth_pcap0;iface=ixgbe0"
>   now becomes:
>   --use-device="eth_ring0" --use-device="eth_pcap0;iface=ixgbe0"
> 
> On the other hand, it is now possible to work in PCI blacklist mode and
> instanciate virtual drivers, which was not possible before this patch.
> 
> Test result:
> 
> ./app/test -c 0x15 -n 3 -m 64
> RTE>>devargs_autotest
> EAL: invalid PCI identifier <08:1>
> EAL: invalid PCI identifier <00.1>
> EAL: invalid PCI identifier <foo>
> EAL: invalid PCI identifier <>
> EAL: invalid PCI identifier <000f:0:0>
> Test OK
> 
> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>

Acked-by: Thomas Monjalon <thomas.monjalon@6wind.com>

Applied for version 1.6.0r2 with title
	"devargs: use devargs for vdev and PCI whitelist/blacklist"

-- 
Thomas

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [dpdk-dev] [PATCH 04/11] devices-args: add a dump_devargs command in basic test application
  2014-02-28 17:25 ` [dpdk-dev] [PATCH 04/11] devices-args: add a dump_devargs command in basic test application Olivier Matz
@ 2014-04-10 14:02   ` Thomas Monjalon
  0 siblings, 0 replies; 57+ messages in thread
From: Thomas Monjalon @ 2014-04-10 14:02 UTC (permalink / raw)
  To: Olivier Matz; +Cc: dev

2014-02-28 18:25, Olivier Matz:
> This is useful for debug purposes. Example:
> 
> echo 100 >
> /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages echo
> 100 >
> /sys/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages
> ./app/test -c 0x15 -n 3 -m 64 \
>   --use-dev="eth_ring0" --use-device="eth_ring1" --use-device="02:00.0"
> RTE>>dump_devargs
> User device white list:
>   VIRTUAL eth_ring0
>   VIRTUAL eth_ring1
>   PCI whitelist 0000:02:00.0
> 
> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>

Acked-by: Thomas Monjalon <thomas.monjalon@6wind.com>

Applied for version 1.6.0r2 with title
	"devargs: add dump command in test application"

-- 
Thomas

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [dpdk-dev] [PATCH 05/11] pci: rename device_list as pci_device_list
  2014-02-28 17:25 ` [dpdk-dev] [PATCH 05/11] pci: rename device_list as pci_device_list Olivier Matz
@ 2014-04-10 14:03   ` Thomas Monjalon
  0 siblings, 0 replies; 57+ messages in thread
From: Thomas Monjalon @ 2014-04-10 14:03 UTC (permalink / raw)
  To: Olivier Matz; +Cc: dev

2014-02-28 18:25, Olivier Matz:
> To avoid confusion with virtual devices, rename device_list as
> pci_device_list and driver_list as pci_driver_list.
> 
> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>

Acked-by: Thomas Monjalon <thomas.monjalon@6wind.com>

Applied for version 1.6.0r2 with title
	"pci: rename device and driver lists"

-- 
Thomas

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [dpdk-dev] [PATCH 08/11] device-args: use a comma instead of semicolon to separate key/values
  2014-02-28 17:25 ` [dpdk-dev] [PATCH 08/11] device-args: use a comma instead of semicolon to separate key/values Olivier Matz
@ 2014-04-10 14:05   ` Thomas Monjalon
  0 siblings, 0 replies; 57+ messages in thread
From: Thomas Monjalon @ 2014-04-10 14:05 UTC (permalink / raw)
  To: Olivier Matz; +Cc: dev

2014-02-28 18:25, Olivier Matz:
> This commit changes the API of --use-device. It changes the separator
> used between each key/value pairs from ';' to ','. Indeed, ';' was not
> the best choice as this character is also used to separate shell
> commands, forcing the user to surround arguments with quotes.
> 
> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>

Acked-by: Thomas Monjalon <thomas.monjalon@6wind.com>

Applied for version 1.6.0r2.

-- 
Thomas

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [dpdk-dev] [PATCH v2 09/11] device-args: replace use-device eal option by pci-whitelist and vdev
  2014-03-01 12:14   ` [dpdk-dev] [PATCH v2 " Olivier Matz
@ 2014-04-10 14:06     ` Thomas Monjalon
  0 siblings, 0 replies; 57+ messages in thread
From: Thomas Monjalon @ 2014-04-10 14:06 UTC (permalink / raw)
  To: Olivier Matz; +Cc: dev

2014-03-01 13:14, Olivier Matz:
> This commit splits the "--use-device" option in two new options:
> 
> - "--pci-whitelist or -w": add a PCI device in the white list
> - "--vdev": instanciate a new virtual device
> 
> Before the patch, the same option "--use-device" was used for these 2
> use-cases.
> 
> By the way, we also add "--pci-blacklist" in addition to the existing
> "-b" for coherency with the whitelist parameter.
> 
> Test result:
> 
> echo 100 >
> /sys/devices/system/node/node0/hugepages/hugepages-2048kB/nr_hugepages echo
> 100 >
> /sys/devices/system/node/node1/hugepages/hugepages-2048kB/nr_hugepages
> ./app/test -c 0x15 -n 3 -m 64
> RTE>>eal_flags_autotest
> [...]
> Test OK
> 
> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>

Acked-by: Thomas Monjalon <thomas.monjalon@6wind.com>

Applied for version 1.6.0r2.

-- 
Thomas

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [dpdk-dev] [PATCH v2 10/11] device-args: allow to provide per pci device command line arguments
  2014-03-01 12:14   ` [dpdk-dev] [PATCH v2 " Olivier Matz
@ 2014-04-10 14:06     ` Thomas Monjalon
  0 siblings, 0 replies; 57+ messages in thread
From: Thomas Monjalon @ 2014-04-10 14:06 UTC (permalink / raw)
  To: Olivier Matz; +Cc: dev

2014-03-01 13:14, Olivier Matz:
> 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>

Applied for version 1.6.0r2.

-- 
Thomas

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [dpdk-dev] [PATCH v2 11/11] testpmd: add several dump commands, useful for debug
  2014-03-01 12:15   ` [dpdk-dev] [PATCH v2 " Olivier Matz
@ 2014-04-10 14:08     ` Thomas Monjalon
  0 siblings, 0 replies; 57+ messages in thread
From: Thomas Monjalon @ 2014-04-10 14:08 UTC (permalink / raw)
  To: Olivier Matz; +Cc: dev

2014-03-01 13:15, Olivier Matz:
> Copy all the dump commands provided in app/test into app/testpmd. These
> commands are useful to debug a problem when using testpmd.
> 
> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>

Acked-by: Thomas Monjalon <thomas.monjalon@6wind.com>

Applied for version 1.6.0r2.

-- 
Thomas

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [dpdk-dev] [PATCH 06/11] vdev: rename eal_common_nonpci_devs.c as eal_common_vdev.c
  2014-02-28 17:25 ` [dpdk-dev] [PATCH 06/11] vdev: rename eal_common_nonpci_devs.c as eal_common_vdev.c Olivier Matz
@ 2014-04-10 14:39   ` Thomas Monjalon
  2014-04-11  7:36     ` [dpdk-dev] [PATCH v2 06/11] vdev: rename nonpci_devs as vdev Olivier Matz
  0 siblings, 1 reply; 57+ messages in thread
From: Thomas Monjalon @ 2014-04-10 14:39 UTC (permalink / raw)
  To: Olivier Matz; +Cc: dev

2014-02-28 18:25, Olivier Matz:
> The name "nonpci" for virtual devices is ambiguous. A physical device
> can be non-PCI (ex: usb, sata, ...). This file only deal with virtual
> devices so rename it to avoid confusion.
> 
> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>

> --- a/lib/librte_eal/common/Makefile
> +++ b/lib/librte_eal/common/Makefile
> @@ -38,7 +38,7 @@ INC += rte_pci_dev_ids.h rte_per_lcore.h rte_prefetch.h
> rte_random.h INC += rte_rwlock.h rte_spinlock.h rte_tailq.h
> rte_interrupts.h rte_alarm.h INC += rte_string_fns.h rte_cpuflags.h
> rte_version.h rte_tailq_elem.h INC += rte_eal_memconfig.h rte_malloc_heap.h
> -INC += rte_hexdump.h rte_devargs.h
> +INC += rte_hexdump.h rte_devargs.h rte_vdev.h

You are adding vdev.h.
It should be in patch 07/11.
Please re-submit a new version for them.

-- 
Thomas

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [dpdk-dev] [PATCH 07/11] vdev: allow external registration of virtual device drivers
  2014-02-28 17:25 ` [dpdk-dev] [PATCH 07/11] vdev: allow external registration of virtual device drivers Olivier Matz
@ 2014-04-10 14:55   ` Thomas Monjalon
  2014-04-11  7:36     ` [dpdk-dev] [PATCH v2 07/11 1/2] vdev: new registration API Olivier Matz
  0 siblings, 1 reply; 57+ messages in thread
From: Thomas Monjalon @ 2014-04-10 14:55 UTC (permalink / raw)
  To: Olivier Matz; +Cc: dev

2014-02-28 18:25, Olivier Matz:
> Instead of having a list of virtual device drivers in EAL code, add an
> API to register drivers. Thanks to this change:
> - we don't need to reference pmd_ring, pmd_pcap and pmd_xenvirt in EAL code
> - it is now possible to provide a virtual device driver as a shared
>   library.
> 
> The registration is done in an init function flaged with
> __attribute__((constructor)). The new convention is to name this
> function rte_pmd_xyz_init(). The per-device init function is renamed
> rte_pmd_xyz_devinit().
> 
> By the way the internal PMDs are now also .so/standalone ready. Let's do
> it later on. It will be required to ease maintenance.
> 
> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>

> --- a/lib/librte_eal/linuxapp/eal/eal.c
> +++ b/lib/librte_eal/linuxapp/eal/eal.c
> @@ -1039,10 +1039,8 @@ rte_eal_init(int argc, char **argv)
> 
>  	rte_eal_mcfg_complete();
> 
> -	if (rte_eal_vdev_init() < 0)
> -		rte_panic("Cannot init virtual devices\n");
> -
>  	TAILQ_FOREACH(solib, &solib_list, next) {
> +		RTE_LOG(INFO, EAL, "open shared lib %s\n", solib->name);
>  		solib->lib_handle = dlopen(solib->name, RTLD_NOW);
>  		if ((solib->lib_handle == NULL) && (solib->name[0] != '/')) {
>  			/* relative path: try again with "./" prefix */
> @@ -1054,6 +1052,9 @@ rte_eal_init(int argc, char **argv)
>  			RTE_LOG(WARNING, EAL, "%s\n", dlerror());
>  	}
> 
> +	if (rte_eal_vdev_init() < 0)
> +		rte_panic("Cannot init virtual devices\n");
> +
>  	RTE_LOG(DEBUG, EAL, "Master core %u is ready (tid=%x)\n",
>  		rte_config.master_lcore, (int)thread_id);
> 

Could you explain this move?
It seems allowing vdev as external library.
Maybe it should be in another commit.

> --- a/lib/librte_pmd_pcap/rte_eth_pcap.h
> +++ b/lib/librte_pmd_pcap/rte_eth_pcap.h
> @@ -45,8 +45,6 @@ extern "C" {
>  #undef PCAP_CAN_SEND
>  #endif
> 
> -#define RTE_ETH_PCAP_PARAM_NAME "eth_pcap"
> -
>  /* struct args_dict is declared in rte_eth_pcap_args_parser.h */
>  struct args_dict;
> 
> @@ -64,12 +62,6 @@ int rte_eth_from_pcaps_n_dumpers(pcap_t * const
> rx_queues[], const unsigned numa_node,
>  		struct args_dict *dict);
> 
> -/**
> - * For use by the EAL only. Called as part of EAL init to set up any dummy
> NICs - * configured on command line.
> - */
> -int rte_pmd_pcap_init(const char *name, const char *params);
> -
>  #ifdef __cplusplus
>  }
>  #endif

After having rebased on HEAD, do we still need a header file for pmd_pcap?

Thanks
-- 
Thomas

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [dpdk-dev] [PATCH v2 06/11] vdev: rename nonpci_devs as vdev
  2014-04-10 14:39   ` Thomas Monjalon
@ 2014-04-11  7:36     ` Olivier Matz
  2014-04-11 11:25       ` Thomas Monjalon
  0 siblings, 1 reply; 57+ messages in thread
From: Olivier Matz @ 2014-04-11  7:36 UTC (permalink / raw)
  To: dev

The name "nonpci_devs" for virtual devices is ambiguous as a physical
device can also be non-PCI (ex: usb, sata, ...). A better name for this
file is "vded" as it only deals with virtual devices.

This patch doesn't introduce any change except renaming.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 lib/librte_eal/common/eal_common_nonpci_devs.c | 111 -------------------------
 lib/librte_eal/common/eal_common_vdev.c        | 111 +++++++++++++++++++++++++
 lib/librte_eal/common/include/eal_private.h    |   4 +-
 lib/librte_eal/linuxapp/eal/Makefile           |   2 +-
 lib/librte_eal/linuxapp/eal/eal.c              |   4 +-
 5 files changed, 116 insertions(+), 116 deletions(-)
 delete mode 100644 lib/librte_eal/common/eal_common_nonpci_devs.c
 create mode 100644 lib/librte_eal/common/eal_common_vdev.c

Hi Thomas,

Here is the new version, thanks for reviewing.

diff --git a/lib/librte_eal/common/eal_common_nonpci_devs.c b/lib/librte_eal/common/eal_common_nonpci_devs.c
deleted file mode 100644
index 71cbb1e..0000000
--- a/lib/librte_eal/common/eal_common_nonpci_devs.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/*-
- *   BSD LICENSE
- * 
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   Copyright(c) 2014 6WIND S.A.
- *   All rights reserved.
- * 
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- * 
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- * 
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <inttypes.h>
-#include <rte_string_fns.h>
-#ifdef RTE_LIBRTE_PMD_RING
-#include <rte_eth_ring.h>
-#endif
-#ifdef RTE_LIBRTE_PMD_PCAP
-#include <rte_eth_pcap.h>
-#endif
-#ifdef RTE_LIBRTE_PMD_XENVIRT
-#include <rte_eth_xenvirt.h>
-#endif
-#include <rte_debug.h>
-#include <rte_devargs.h>
-#include "eal_private.h"
-
-struct device_init {
-	const char *dev_prefix;
-	int (*init_fn)(const char*, const char *);
-};
-
-#define NUM_DEV_TYPES (sizeof(dev_types)/sizeof(dev_types[0]))
-struct device_init dev_types[] = {
-#ifdef RTE_LIBRTE_PMD_RING
-		{
-			.dev_prefix = RTE_ETH_RING_PARAM_NAME,
-			.init_fn = rte_pmd_ring_init
-		},
-#endif
-#ifdef RTE_LIBRTE_PMD_PCAP
-		{
-			.dev_prefix = RTE_ETH_PCAP_PARAM_NAME,
-			.init_fn = rte_pmd_pcap_init
-		},
-#endif
-#ifdef RTE_LIBRTE_PMD_XENVIRT
-		{
-			.dev_prefix = RTE_ETH_XENVIRT_PARAM_NAME,
-			.init_fn = rte_pmd_xenvirt_init
-		},
-#endif
-		{
-			.dev_prefix = "-nodev-",
-			.init_fn = NULL
-		}
-};
-
-int
-rte_eal_non_pci_ethdev_init(void)
-{
-	struct rte_devargs *devargs;
-	uint8_t i;
-
-	/* call the init function for each virtual device */
-	TAILQ_FOREACH(devargs, &devargs_list, next) {
-
-		if (devargs->type != RTE_DEVTYPE_VIRTUAL)
-			continue;
-
-		for (i = 0; i < NUM_DEV_TYPES; i++) {
-			/* search a driver prefix in virtual device name */
-			if (!strncmp(dev_types[i].dev_prefix,
-				    devargs->virtual.drv_name,
-				     sizeof(dev_types[i].dev_prefix) - 1)) {
-				dev_types[i].init_fn(devargs->virtual.drv_name,
-						     devargs->args);
-				break;
-			}
-		}
-
-		if (i == NUM_DEV_TYPES) {
-			rte_panic("no driver found for %s\n",
-				  devargs->virtual.drv_name);
-		}
-	}
-	return 0;
-}
diff --git a/lib/librte_eal/common/eal_common_vdev.c b/lib/librte_eal/common/eal_common_vdev.c
new file mode 100644
index 0000000..02d3fd6
--- /dev/null
+++ b/lib/librte_eal/common/eal_common_vdev.c
@@ -0,0 +1,111 @@
+/*-
+ *   BSD LICENSE
+ * 
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2014 6WIND S.A.
+ *   All rights reserved.
+ * 
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ * 
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ * 
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <inttypes.h>
+#include <rte_string_fns.h>
+#ifdef RTE_LIBRTE_PMD_RING
+#include <rte_eth_ring.h>
+#endif
+#ifdef RTE_LIBRTE_PMD_PCAP
+#include <rte_eth_pcap.h>
+#endif
+#ifdef RTE_LIBRTE_PMD_XENVIRT
+#include <rte_eth_xenvirt.h>
+#endif
+#include <rte_debug.h>
+#include <rte_devargs.h>
+#include "eal_private.h"
+
+struct device_init {
+	const char *dev_prefix;
+	int (*init_fn)(const char*, const char *);
+};
+
+#define NUM_DEV_TYPES (sizeof(dev_types)/sizeof(dev_types[0]))
+struct device_init dev_types[] = {
+#ifdef RTE_LIBRTE_PMD_RING
+		{
+			.dev_prefix = RTE_ETH_RING_PARAM_NAME,
+			.init_fn = rte_pmd_ring_init
+		},
+#endif
+#ifdef RTE_LIBRTE_PMD_PCAP
+		{
+			.dev_prefix = RTE_ETH_PCAP_PARAM_NAME,
+			.init_fn = rte_pmd_pcap_init
+		},
+#endif
+#ifdef RTE_LIBRTE_PMD_XENVIRT
+		{
+			.dev_prefix = RTE_ETH_XENVIRT_PARAM_NAME,
+			.init_fn = rte_pmd_xenvirt_init
+		},
+#endif
+		{
+			.dev_prefix = "-nodev-",
+			.init_fn = NULL
+		}
+};
+
+int
+rte_eal_vdev_init(void)
+{
+	struct rte_devargs *devargs;
+	uint8_t i;
+
+	/* call the init function for each virtual device */
+	TAILQ_FOREACH(devargs, &devargs_list, next) {
+
+		if (devargs->type != RTE_DEVTYPE_VIRTUAL)
+			continue;
+
+		for (i = 0; i < NUM_DEV_TYPES; i++) {
+			/* search a driver prefix in virtual device name */
+			if (!strncmp(dev_types[i].dev_prefix,
+				    devargs->virtual.drv_name,
+				     sizeof(dev_types[i].dev_prefix) - 1)) {
+				dev_types[i].init_fn(devargs->virtual.drv_name,
+						     devargs->args);
+				break;
+			}
+		}
+
+		if (i == NUM_DEV_TYPES) {
+			rte_panic("no driver found for %s\n",
+				  devargs->virtual.drv_name);
+		}
+	}
+	return 0;
+}
diff --git a/lib/librte_eal/common/include/eal_private.h b/lib/librte_eal/common/include/eal_private.h
index f9a019b..22d8b08 100644
--- a/lib/librte_eal/common/include/eal_private.h
+++ b/lib/librte_eal/common/include/eal_private.h
@@ -197,10 +197,10 @@ int rte_eal_intr_init(void);
 int rte_eal_alarm_init(void);
 
 /**
- * This function initialises any non-PCI i.e. dummy ethernet devices
+ * This function initialises any virtual devices
  *
  * This function is private to the EAL.
  */
-int rte_eal_non_pci_ethdev_init(void);
+int rte_eal_vdev_init(void);
 
 #endif /* _EAL_PRIVATE_H_ */
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index bdd940d..00f7367 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -77,7 +77,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_errno.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_cpuflags.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_hexdump.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_devargs.c
-SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_nonpci_devs.c
+SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_vdev.c
 
 CFLAGS_eal.o := -D_GNU_SOURCE
 CFLAGS_eal_thread.o := -D_GNU_SOURCE
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 905ce37..c015a65 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -1046,8 +1046,8 @@ rte_eal_init(int argc, char **argv)
 
 	rte_eal_mcfg_complete();
 
-	if (rte_eal_non_pci_ethdev_init() < 0)
-		rte_panic("Cannot init non-PCI eth_devs\n");
+	if (rte_eal_vdev_init() < 0)
+		rte_panic("Cannot init virtual devices\n");
 
 	TAILQ_FOREACH(solib, &solib_list, next) {
 		solib->lib_handle = dlopen(solib->name, RTLD_NOW);
-- 
1.8.5.3

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [dpdk-dev] [PATCH v2 07/11 1/2] vdev: new registration API
  2014-04-10 14:55   ` Thomas Monjalon
@ 2014-04-11  7:36     ` Olivier Matz
  2014-04-11  7:36       ` [dpdk-dev] [PATCH v2 07/11 2/2] vdev: allow external registration of virtual device drivers Olivier Matz
                         ` (2 more replies)
  0 siblings, 3 replies; 57+ messages in thread
From: Olivier Matz @ 2014-04-11  7:36 UTC (permalink / raw)
  To: dev

Instead of having a list of virtual device drivers in EAL code, add an
API to register drivers. Thanks to this new registration method, we can
remove the references to pmd_ring, pmd_pcap and pmd_xenvirt in EAL code.
This also enables the ability to register a virtual device driver as
a shared library.

The registration is done in an init function flaged with
__attribute__((constructor)). The new convention is to name this
function rte_pmd_xyz_init(). The per-device init function is renamed
rte_pmd_xyz_devinit().

By the way the internal PMDs are now also .so/standalone ready. Let's do
it later on. It will be required to ease maintenance.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 app/test/test_pmd_ring.c                 |  6 +--
 lib/librte_eal/common/Makefile           |  2 +-
 lib/librte_eal/common/eal_common_vdev.c  | 80 ++++++++++++----------------
 lib/librte_eal/common/include/rte_vdev.h | 90 ++++++++++++++++++++++++++++++++
 lib/librte_pmd_pcap/Makefile             |  2 +-
 lib/librte_pmd_pcap/rte_eth_pcap.c       | 18 +++++--
 lib/librte_pmd_pcap/rte_eth_pcap.h       | 54 -------------------
 lib/librte_pmd_ring/rte_eth_ring.c       | 15 +++++-
 lib/librte_pmd_ring/rte_eth_ring.h       |  6 +--
 lib/librte_pmd_xenvirt/rte_eth_xenvirt.c | 16 +++++-
 lib/librte_pmd_xenvirt/rte_eth_xenvirt.h |  8 ---
 11 files changed, 173 insertions(+), 124 deletions(-)
 create mode 100644 lib/librte_eal/common/include/rte_vdev.h
 delete mode 100644 lib/librte_pmd_pcap/rte_eth_pcap.h

Hi Thomas,

You are right, I splitted the previous commit as requested. I also
completely remove rte_eth_pcap.h which is not used anymore.

diff --git a/app/test/test_pmd_ring.c b/app/test/test_pmd_ring.c
index c8242b3..4d9c2ba 100644
--- a/app/test/test_pmd_ring.c
+++ b/app/test/test_pmd_ring.c
@@ -315,12 +315,12 @@ test_pmd_ring_init(void)
 
 	printf("Testing ring pmd init\n");
 
-	if (rte_pmd_ring_init(name1, params_null) < 0) {
+	if (rte_pmd_ring_devinit(name1, params_null) < 0) {
 		printf("Testing ring pmd init fail\n");
 		return -1;
 	}
 
-	if (rte_pmd_ring_init(name2, params) < 0) {
+	if (rte_pmd_ring_devinit(name2, params) < 0) {
 		printf("Testing ring pmd init fail\n");
 		return -1;
 	}
@@ -372,7 +372,7 @@ test_pmd_ring_init(void)
 	rte_eth_dev_stop(RXTX_PORT2);
 
 	/* Test init same name pmd ring */
-	rte_pmd_ring_init(name1, params_null);
+	rte_pmd_ring_devinit(name1, params_null);
 	return 0;
 }
 
diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index b9f3b88..2f99bf4 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -38,7 +38,7 @@ INC += rte_pci_dev_ids.h rte_per_lcore.h rte_prefetch.h rte_random.h
 INC += rte_rwlock.h rte_spinlock.h rte_tailq.h rte_interrupts.h rte_alarm.h
 INC += rte_string_fns.h rte_cpuflags.h rte_version.h rte_tailq_elem.h
 INC += rte_eal_memconfig.h rte_malloc_heap.h
-INC += rte_hexdump.h rte_devargs.h
+INC += rte_hexdump.h rte_devargs.h rte_vdev.h
 
 ifeq ($(CONFIG_RTE_INSECURE_FUNCTION_WARNING),y)
 INC += rte_warnings.h
diff --git a/lib/librte_eal/common/eal_common_vdev.c b/lib/librte_eal/common/eal_common_vdev.c
index 02d3fd6..62d0302 100644
--- a/lib/librte_eal/common/eal_common_vdev.c
+++ b/lib/librte_eal/common/eal_common_vdev.c
@@ -34,56 +34,43 @@
 
 #include <string.h>
 #include <inttypes.h>
-#include <rte_string_fns.h>
-#ifdef RTE_LIBRTE_PMD_RING
-#include <rte_eth_ring.h>
-#endif
-#ifdef RTE_LIBRTE_PMD_PCAP
-#include <rte_eth_pcap.h>
-#endif
-#ifdef RTE_LIBRTE_PMD_XENVIRT
-#include <rte_eth_xenvirt.h>
-#endif
+#include <sys/queue.h>
+
+#include <rte_vdev.h>
+#include <rte_devargs.h>
 #include <rte_debug.h>
 #include <rte_devargs.h>
+
 #include "eal_private.h"
 
-struct device_init {
-	const char *dev_prefix;
-	int (*init_fn)(const char*, const char *);
-};
+/** Global list of virtual device drivers. */
+static struct rte_vdev_driver_list vdev_driver_list =
+	TAILQ_HEAD_INITIALIZER(vdev_driver_list);
 
-#define NUM_DEV_TYPES (sizeof(dev_types)/sizeof(dev_types[0]))
-struct device_init dev_types[] = {
-#ifdef RTE_LIBRTE_PMD_RING
-		{
-			.dev_prefix = RTE_ETH_RING_PARAM_NAME,
-			.init_fn = rte_pmd_ring_init
-		},
-#endif
-#ifdef RTE_LIBRTE_PMD_PCAP
-		{
-			.dev_prefix = RTE_ETH_PCAP_PARAM_NAME,
-			.init_fn = rte_pmd_pcap_init
-		},
-#endif
-#ifdef RTE_LIBRTE_PMD_XENVIRT
-		{
-			.dev_prefix = RTE_ETH_XENVIRT_PARAM_NAME,
-			.init_fn = rte_pmd_xenvirt_init
-		},
-#endif
-		{
-			.dev_prefix = "-nodev-",
-			.init_fn = NULL
-		}
-};
+/* register a driver */
+void
+rte_eal_vdev_driver_register(struct rte_vdev_driver *driver)
+{
+	TAILQ_INSERT_TAIL(&vdev_driver_list, driver, next);
+}
+
+/* unregister a driver */
+void
+rte_eal_vdev_driver_unregister(struct rte_vdev_driver *driver)
+{
+	TAILQ_REMOVE(&vdev_driver_list, driver, next);
+}
 
 int
 rte_eal_vdev_init(void)
 {
 	struct rte_devargs *devargs;
-	uint8_t i;
+	struct rte_vdev_driver *driver;
+
+	/* No need to register drivers that are embeded in DPDK
+	 * (pmd_pcap, pmd_ring, ...). The initialization function have
+	 * the ((constructor)) attribute so they will register at
+	 * startup. */
 
 	/* call the init function for each virtual device */
 	TAILQ_FOREACH(devargs, &devargs_list, next) {
@@ -91,18 +78,17 @@ rte_eal_vdev_init(void)
 		if (devargs->type != RTE_DEVTYPE_VIRTUAL)
 			continue;
 
-		for (i = 0; i < NUM_DEV_TYPES; i++) {
+		TAILQ_FOREACH(driver, &vdev_driver_list, next) {
 			/* search a driver prefix in virtual device name */
-			if (!strncmp(dev_types[i].dev_prefix,
-				    devargs->virtual.drv_name,
-				     sizeof(dev_types[i].dev_prefix) - 1)) {
-				dev_types[i].init_fn(devargs->virtual.drv_name,
-						     devargs->args);
+			if (!strncmp(driver->name, devargs->virtual.drv_name,
+					strlen(driver->name))) {
+				driver->init(devargs->virtual.drv_name,
+					devargs->args);
 				break;
 			}
 		}
 
-		if (i == NUM_DEV_TYPES) {
+		if (driver == NULL) {
 			rte_panic("no driver found for %s\n",
 				  devargs->virtual.drv_name);
 		}
diff --git a/lib/librte_eal/common/include/rte_vdev.h b/lib/librte_eal/common/include/rte_vdev.h
new file mode 100644
index 0000000..48f71b7
--- /dev/null
+++ b/lib/librte_eal/common/include/rte_vdev.h
@@ -0,0 +1,90 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2014 6WIND S.A.
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of 6WIND S.A. nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_VDEV_H_
+#define _RTE_VDEV_H_
+
+/**
+ * @file
+ *
+ * RTE Virtual Devices Interface
+ *
+ * This file manages the list of the virtual device drivers.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <sys/queue.h>
+
+/** Double linked list of virtual device drivers. */
+TAILQ_HEAD(rte_vdev_driver_list, rte_vdev_driver);
+
+/**
+ * Initialization function called for each virtual device probing.
+ */
+typedef int (rte_vdev_init_t)(const char *name, const char *args);
+
+/**
+ * A structure describing a virtual device driver.
+ */
+struct rte_vdev_driver {
+	TAILQ_ENTRY(rte_vdev_driver) next;  /**< Next in list. */
+	const char *name;                   /**< Driver name. */
+	rte_vdev_init_t *init;              /**< Device init. function. */
+};
+
+/**
+ * Register a virtual device driver.
+ *
+ * @param driver
+ *   A pointer to a rte_vdev structure describing the driver
+ *   to be registered.
+ */
+void rte_eal_vdev_driver_register(struct rte_vdev_driver *driver);
+
+/**
+ * Unregister a virtual device driver.
+ *
+ * @param driver
+ *   A pointer to a rte_vdev structure describing the driver
+ *   to be unregistered.
+ */
+void rte_eal_vdev_driver_unregister(struct rte_vdev_driver *driver);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_VDEV_H_ */
diff --git a/lib/librte_pmd_pcap/Makefile b/lib/librte_pmd_pcap/Makefile
index 5218f28..a8b289f 100644
--- a/lib/librte_pmd_pcap/Makefile
+++ b/lib/librte_pmd_pcap/Makefile
@@ -48,7 +48,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) += rte_eth_pcap.c
 #
 # Export include files
 #
-SYMLINK-y-include += rte_eth_pcap.h
+SYMLINK-y-include +=
 
 # this lib depends upon:
 DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) += lib/librte_mbuf
diff --git a/lib/librte_pmd_pcap/rte_eth_pcap.c b/lib/librte_pmd_pcap/rte_eth_pcap.c
index fe94a79..680dfdc 100644
--- a/lib/librte_pmd_pcap/rte_eth_pcap.c
+++ b/lib/librte_pmd_pcap/rte_eth_pcap.c
@@ -40,10 +40,11 @@
 #include <rte_string_fns.h>
 #include <rte_cycles.h>
 #include <rte_kvargs.h>
+#include <rte_vdev.h>
 
 #include <net/if.h>
 
-#include "rte_eth_pcap.h"
+#include <pcap.h>
 
 #define RTE_ETH_PCAP_SNAPSHOT_LEN 65535
 #define RTE_ETH_PCAP_SNAPLEN 4096
@@ -685,8 +686,8 @@ rte_eth_from_pcaps(pcap_t * const rx_queues[],
 }
 
 
-int
-rte_pmd_pcap_init(const char *name, const char *params)
+static int
+rte_pmd_pcap_devinit(const char *name, const char *params)
 {
 	unsigned numa_node, using_dumpers = 0;
 	int ret;
@@ -766,3 +767,14 @@ rte_pmd_pcap_init(const char *name, const char *params)
 
 }
 
+static struct rte_vdev_driver pmd_pcap_drv = {
+	.name = "eth_pcap",
+	.init = rte_pmd_pcap_devinit,
+};
+
+__attribute__((constructor))
+static void
+rte_pmd_pcap_init(void)
+{
+	rte_eal_vdev_driver_register(&pmd_pcap_drv);
+}
diff --git a/lib/librte_pmd_pcap/rte_eth_pcap.h b/lib/librte_pmd_pcap/rte_eth_pcap.h
deleted file mode 100644
index 79373c0..0000000
--- a/lib/librte_pmd_pcap/rte_eth_pcap.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*-
- *   BSD LICENSE
- * 
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- * 
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- * 
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- * 
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _RTE_ETH_PCAP_H_
-#define _RTE_ETH_PCAP_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-#include <pcap.h>
-
-#define RTE_ETH_PCAP_PARAM_NAME "eth_pcap"
-
-/**
- * For use by the EAL only. Called as part of EAL init to set up any dummy NICs
- * configured on command line.
- */
-int rte_pmd_pcap_init(const char *name, const char *params);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/lib/librte_pmd_ring/rte_eth_ring.c b/lib/librte_pmd_ring/rte_eth_ring.c
index 24635f3..cee3fff 100644
--- a/lib/librte_pmd_ring/rte_eth_ring.c
+++ b/lib/librte_pmd_ring/rte_eth_ring.c
@@ -37,6 +37,7 @@
 #include <rte_malloc.h>
 #include <rte_memcpy.h>
 #include <rte_string_fns.h>
+#include <rte_vdev.h>
 
 struct ring_queue {
 	struct rte_ring *rng;
@@ -382,7 +383,7 @@ rte_eth_ring_pair_attach(const char *name, const unsigned numa_node)
 }
 
 int
-rte_pmd_ring_init(const char *name, const char *params)
+rte_pmd_ring_devinit(const char *name, const char *params)
 {
 	RTE_LOG(INFO, PMD, "Initializing pmd_ring for %s\n", name);
 
@@ -395,3 +396,15 @@ rte_pmd_ring_init(const char *name, const char *params)
 	}
 	return 0;
 }
+
+static struct rte_vdev_driver pmd_ring_drv = {
+	.name = "eth_ring",
+	.init = rte_pmd_ring_devinit,
+};
+
+__attribute__((constructor))
+static void
+rte_pmd_ring_init(void)
+{
+	rte_eal_vdev_driver_register(&pmd_ring_drv);
+}
diff --git a/lib/librte_pmd_ring/rte_eth_ring.h b/lib/librte_pmd_ring/rte_eth_ring.h
index a222ecb..b84a29e 100644
--- a/lib/librte_pmd_ring/rte_eth_ring.h
+++ b/lib/librte_pmd_ring/rte_eth_ring.h
@@ -40,8 +40,6 @@ extern "C" {
 
 #include <rte_ring.h>
 
-#define RTE_ETH_RING_PARAM_NAME "eth_ring"
-
 int rte_eth_from_rings(struct rte_ring * const rx_queues[],
 		const unsigned nb_rx_queues,
 		struct rte_ring *const tx_queues[],
@@ -52,10 +50,10 @@ int rte_eth_ring_pair_create(const char *name, const unsigned numa_node);
 int rte_eth_ring_pair_attach(const char *name, const unsigned numa_node);
 
 /**
- * For use by the EAL only. Called as part of EAL init to set up any dummy NICs
+ * For use by test apps only. Called as part of EAL init to set up any dummy NICs
  * configured on command line.
  */
-int rte_pmd_ring_init(const char *name, const char *params);
+int rte_pmd_ring_devinit(const char *name, const char *params);
 
 #ifdef __cplusplus
 }
diff --git a/lib/librte_pmd_xenvirt/rte_eth_xenvirt.c b/lib/librte_pmd_xenvirt/rte_eth_xenvirt.c
index bad8dd4..533aa76 100644
--- a/lib/librte_pmd_xenvirt/rte_eth_xenvirt.c
+++ b/lib/librte_pmd_xenvirt/rte_eth_xenvirt.c
@@ -688,8 +688,8 @@ err:
 
 
 /*TODO: Support multiple process model */
-int
-rte_pmd_xenvirt_init(const char *name, const char *params)
+static int
+rte_pmd_xenvirt_devinit(const char *name, const char *params)
 {
 	if (virtio_idx == 0) {
 		if (xenstore_init() != 0) {
@@ -704,3 +704,15 @@ rte_pmd_xenvirt_init(const char *name, const char *params)
 	eth_dev_xenvirt_create(name, params, rte_socket_id(), DEV_CREATE);
 	return 0;
 }
+
+static struct rte_vdev_driver pmd_xenvirt_drv = {
+	.name = "eth_xenvirt",
+	.init = rte_pmd_xenvirt_devinit,
+};
+
+__attribute__((constructor))
+static void
+rte_pmd_xenvirt_init(void)
+{
+	rte_eal_vdev_driver_register(&pmd_xenvirt_drv);
+}
diff --git a/lib/librte_pmd_xenvirt/rte_eth_xenvirt.h b/lib/librte_pmd_xenvirt/rte_eth_xenvirt.h
index cb1924a..acdeb30 100644
--- a/lib/librte_pmd_xenvirt/rte_eth_xenvirt.h
+++ b/lib/librte_pmd_xenvirt/rte_eth_xenvirt.h
@@ -41,14 +41,6 @@ extern "C" {
 #include <rte_mempool.h>
 #include <rte_ring.h>
 
-#define RTE_ETH_XENVIRT_PARAM_NAME "eth_xenvirt"
-
-/**
- * For use by the EAL only. Called as part of EAL init to set up any dummy NICs
- * configured on command line.
- */
-int rte_pmd_xenvirt_init(const char *name, const char *params);
-
 /**
  * Creates mempool for xen virtio PMD.
  * This function uses memzone_reserve to allocate memory for meta data,
-- 
1.8.5.3

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [dpdk-dev] [PATCH v2 07/11 2/2] vdev: allow external registration of virtual device drivers
  2014-04-11  7:36     ` [dpdk-dev] [PATCH v2 07/11 1/2] vdev: new registration API Olivier Matz
@ 2014-04-11  7:36       ` Olivier Matz
  2014-04-11 14:31         ` Thomas Monjalon
  2014-04-11 10:49       ` [dpdk-dev] [PATCH v2 07/11 1/2] vdev: new registration API Neil Horman
  2014-04-11 14:31       ` Thomas Monjalon
  2 siblings, 1 reply; 57+ messages in thread
From: Olivier Matz @ 2014-04-11  7:36 UTC (permalink / raw)
  To: dev

The registration of an external vdev driver (a .so library) is done in a
function that has the ((constructor)) attribute. This function is called
when dlopen(driver.so) is invoked.

As a result, we need to do the dlopen() before calling
rte_eal_vdev_init() that calls the initialization functions of all
registered drivers.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 lib/librte_eal/linuxapp/eal/eal.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index c015a65..3ded563 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -1046,10 +1046,8 @@ rte_eal_init(int argc, char **argv)
 
 	rte_eal_mcfg_complete();
 
-	if (rte_eal_vdev_init() < 0)
-		rte_panic("Cannot init virtual devices\n");
-
 	TAILQ_FOREACH(solib, &solib_list, next) {
+		RTE_LOG(INFO, EAL, "open shared lib %s\n", solib->name);
 		solib->lib_handle = dlopen(solib->name, RTLD_NOW);
 		if ((solib->lib_handle == NULL) && (solib->name[0] != '/')) {
 			/* relative path: try again with "./" prefix */
@@ -1061,6 +1059,9 @@ rte_eal_init(int argc, char **argv)
 			RTE_LOG(WARNING, EAL, "%s\n", dlerror());
 	}
 
+	if (rte_eal_vdev_init() < 0)
+		rte_panic("Cannot init virtual devices\n");
+
 	RTE_LOG(DEBUG, EAL, "Master core %u is ready (tid=%x)\n",
 		rte_config.master_lcore, (int)thread_id);
 
-- 
1.8.5.3

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [dpdk-dev] [PATCH v2 07/11 1/2] vdev: new registration API
  2014-04-11  7:36     ` [dpdk-dev] [PATCH v2 07/11 1/2] vdev: new registration API Olivier Matz
  2014-04-11  7:36       ` [dpdk-dev] [PATCH v2 07/11 2/2] vdev: allow external registration of virtual device drivers Olivier Matz
@ 2014-04-11 10:49       ` Neil Horman
  2014-04-11 13:11         ` Thomas Monjalon
  2014-04-11 14:31       ` Thomas Monjalon
  2 siblings, 1 reply; 57+ messages in thread
From: Neil Horman @ 2014-04-11 10:49 UTC (permalink / raw)
  To: Olivier Matz; +Cc: dev

On Fri, Apr 11, 2014 at 09:36:52AM +0200, Olivier Matz wrote:
> Instead of having a list of virtual device drivers in EAL code, add an
> API to register drivers. Thanks to this new registration method, we can
> remove the references to pmd_ring, pmd_pcap and pmd_xenvirt in EAL code.
> This also enables the ability to register a virtual device driver as
> a shared library.
> 
> The registration is done in an init function flaged with
> __attribute__((constructor)). The new convention is to name this
> function rte_pmd_xyz_init(). The per-device init function is renamed
> rte_pmd_xyz_devinit().
> 
> By the way the internal PMDs are now also .so/standalone ready. Let's do
> it later on. It will be required to ease maintenance.
> 
> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
I just posted a patch to separate pmd linkage from the applications yesterday,
which will work with the existing API.  See my series on the introduction of the
PMD_INIT and PMD_INIT_NONPCI macros.

Neil

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [dpdk-dev] [PATCH v2 06/11] vdev: rename nonpci_devs as vdev
  2014-04-11  7:36     ` [dpdk-dev] [PATCH v2 06/11] vdev: rename nonpci_devs as vdev Olivier Matz
@ 2014-04-11 11:25       ` Thomas Monjalon
  2014-04-11 11:45         ` [dpdk-dev] [PATCH v3 " Olivier Matz
  0 siblings, 1 reply; 57+ messages in thread
From: Thomas Monjalon @ 2014-04-11 11:25 UTC (permalink / raw)
  To: Olivier Matz; +Cc: dev

2014-04-11 09:36, Olivier Matz:
> The name "nonpci_devs" for virtual devices is ambiguous as a physical
> device can also be non-PCI (ex: usb, sata, ...). A better name for this
> file is "vded" as it only deals with virtual devices.
> 
> This patch doesn't introduce any change except renaming.
> 
> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>

You probably should change the BSD Makefile also:
lib/librte_eal/bsdapp/eal/Makefile:SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_common_nonpci_devs.c

Thanks
-- 
Thomas

^ permalink raw reply	[flat|nested] 57+ messages in thread

* [dpdk-dev] [PATCH v3 06/11] vdev: rename nonpci_devs as vdev
  2014-04-11 11:25       ` Thomas Monjalon
@ 2014-04-11 11:45         ` Olivier Matz
  2014-04-11 12:37           ` Thomas Monjalon
  0 siblings, 1 reply; 57+ messages in thread
From: Olivier Matz @ 2014-04-11 11:45 UTC (permalink / raw)
  To: dev

The name "nonpci_devs" for virtual devices is ambiguous as a physical
device can also be non-PCI (ex: usb, sata, ...). A better name for this
file is "vdev" as it only deals with virtual devices.

This patch doesn't introduce any change except renaming.

Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
 lib/librte_eal/bsdapp/eal/Makefile             |   2 +-
 lib/librte_eal/bsdapp/eal/eal.c                |   4 +-
 lib/librte_eal/common/eal_common_nonpci_devs.c | 111 -------------------------
 lib/librte_eal/common/eal_common_vdev.c        | 111 +++++++++++++++++++++++++
 lib/librte_eal/common/include/eal_private.h    |   4 +-
 lib/librte_eal/linuxapp/eal/Makefile           |   2 +-
 lib/librte_eal/linuxapp/eal/eal.c              |   4 +-
 7 files changed, 119 insertions(+), 119 deletions(-)
 delete mode 100644 lib/librte_eal/common/eal_common_nonpci_devs.c
 create mode 100644 lib/librte_eal/common/eal_common_vdev.c

diff --git a/lib/librte_eal/bsdapp/eal/Makefile b/lib/librte_eal/bsdapp/eal/Makefile
index 73facae..4c2a4f1 100644
--- a/lib/librte_eal/bsdapp/eal/Makefile
+++ b/lib/librte_eal/bsdapp/eal/Makefile
@@ -69,7 +69,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_common_errno.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_common_cpuflags.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_common_hexdump.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_common_whitelist.c
-SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_common_nonpci_devs.c
+SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_common_vdev.c
 
 CFLAGS_eal.o := -D_GNU_SOURCE
 #CFLAGS_eal_thread.o := -D_GNU_SOURCE
diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
index be00f91..e944aba 100644
--- a/lib/librte_eal/bsdapp/eal/eal.c
+++ b/lib/librte_eal/bsdapp/eal/eal.c
@@ -854,8 +854,8 @@ rte_eal_init(int argc, char **argv)
 
 	rte_eal_mcfg_complete();
 
-	if (rte_eal_non_pci_ethdev_init() < 0)
-		rte_panic("Cannot init non-PCI eth_devs\n");
+	if (rte_eal_vdev_init() < 0)
+		rte_panic("Cannot init virtual devices\n");
 
 	RTE_LCORE_FOREACH_SLAVE(i) {
 
diff --git a/lib/librte_eal/common/eal_common_nonpci_devs.c b/lib/librte_eal/common/eal_common_nonpci_devs.c
deleted file mode 100644
index 71cbb1e..0000000
--- a/lib/librte_eal/common/eal_common_nonpci_devs.c
+++ /dev/null
@@ -1,111 +0,0 @@
-/*-
- *   BSD LICENSE
- * 
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   Copyright(c) 2014 6WIND S.A.
- *   All rights reserved.
- * 
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- * 
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- * 
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <string.h>
-#include <inttypes.h>
-#include <rte_string_fns.h>
-#ifdef RTE_LIBRTE_PMD_RING
-#include <rte_eth_ring.h>
-#endif
-#ifdef RTE_LIBRTE_PMD_PCAP
-#include <rte_eth_pcap.h>
-#endif
-#ifdef RTE_LIBRTE_PMD_XENVIRT
-#include <rte_eth_xenvirt.h>
-#endif
-#include <rte_debug.h>
-#include <rte_devargs.h>
-#include "eal_private.h"
-
-struct device_init {
-	const char *dev_prefix;
-	int (*init_fn)(const char*, const char *);
-};
-
-#define NUM_DEV_TYPES (sizeof(dev_types)/sizeof(dev_types[0]))
-struct device_init dev_types[] = {
-#ifdef RTE_LIBRTE_PMD_RING
-		{
-			.dev_prefix = RTE_ETH_RING_PARAM_NAME,
-			.init_fn = rte_pmd_ring_init
-		},
-#endif
-#ifdef RTE_LIBRTE_PMD_PCAP
-		{
-			.dev_prefix = RTE_ETH_PCAP_PARAM_NAME,
-			.init_fn = rte_pmd_pcap_init
-		},
-#endif
-#ifdef RTE_LIBRTE_PMD_XENVIRT
-		{
-			.dev_prefix = RTE_ETH_XENVIRT_PARAM_NAME,
-			.init_fn = rte_pmd_xenvirt_init
-		},
-#endif
-		{
-			.dev_prefix = "-nodev-",
-			.init_fn = NULL
-		}
-};
-
-int
-rte_eal_non_pci_ethdev_init(void)
-{
-	struct rte_devargs *devargs;
-	uint8_t i;
-
-	/* call the init function for each virtual device */
-	TAILQ_FOREACH(devargs, &devargs_list, next) {
-
-		if (devargs->type != RTE_DEVTYPE_VIRTUAL)
-			continue;
-
-		for (i = 0; i < NUM_DEV_TYPES; i++) {
-			/* search a driver prefix in virtual device name */
-			if (!strncmp(dev_types[i].dev_prefix,
-				    devargs->virtual.drv_name,
-				     sizeof(dev_types[i].dev_prefix) - 1)) {
-				dev_types[i].init_fn(devargs->virtual.drv_name,
-						     devargs->args);
-				break;
-			}
-		}
-
-		if (i == NUM_DEV_TYPES) {
-			rte_panic("no driver found for %s\n",
-				  devargs->virtual.drv_name);
-		}
-	}
-	return 0;
-}
diff --git a/lib/librte_eal/common/eal_common_vdev.c b/lib/librte_eal/common/eal_common_vdev.c
new file mode 100644
index 0000000..02d3fd6
--- /dev/null
+++ b/lib/librte_eal/common/eal_common_vdev.c
@@ -0,0 +1,111 @@
+/*-
+ *   BSD LICENSE
+ * 
+ *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ *   Copyright(c) 2014 6WIND S.A.
+ *   All rights reserved.
+ * 
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions
+ *   are met:
+ * 
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in
+ *       the documentation and/or other materials provided with the
+ *       distribution.
+ *     * Neither the name of Intel Corporation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
+ * 
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <inttypes.h>
+#include <rte_string_fns.h>
+#ifdef RTE_LIBRTE_PMD_RING
+#include <rte_eth_ring.h>
+#endif
+#ifdef RTE_LIBRTE_PMD_PCAP
+#include <rte_eth_pcap.h>
+#endif
+#ifdef RTE_LIBRTE_PMD_XENVIRT
+#include <rte_eth_xenvirt.h>
+#endif
+#include <rte_debug.h>
+#include <rte_devargs.h>
+#include "eal_private.h"
+
+struct device_init {
+	const char *dev_prefix;
+	int (*init_fn)(const char*, const char *);
+};
+
+#define NUM_DEV_TYPES (sizeof(dev_types)/sizeof(dev_types[0]))
+struct device_init dev_types[] = {
+#ifdef RTE_LIBRTE_PMD_RING
+		{
+			.dev_prefix = RTE_ETH_RING_PARAM_NAME,
+			.init_fn = rte_pmd_ring_init
+		},
+#endif
+#ifdef RTE_LIBRTE_PMD_PCAP
+		{
+			.dev_prefix = RTE_ETH_PCAP_PARAM_NAME,
+			.init_fn = rte_pmd_pcap_init
+		},
+#endif
+#ifdef RTE_LIBRTE_PMD_XENVIRT
+		{
+			.dev_prefix = RTE_ETH_XENVIRT_PARAM_NAME,
+			.init_fn = rte_pmd_xenvirt_init
+		},
+#endif
+		{
+			.dev_prefix = "-nodev-",
+			.init_fn = NULL
+		}
+};
+
+int
+rte_eal_vdev_init(void)
+{
+	struct rte_devargs *devargs;
+	uint8_t i;
+
+	/* call the init function for each virtual device */
+	TAILQ_FOREACH(devargs, &devargs_list, next) {
+
+		if (devargs->type != RTE_DEVTYPE_VIRTUAL)
+			continue;
+
+		for (i = 0; i < NUM_DEV_TYPES; i++) {
+			/* search a driver prefix in virtual device name */
+			if (!strncmp(dev_types[i].dev_prefix,
+				    devargs->virtual.drv_name,
+				     sizeof(dev_types[i].dev_prefix) - 1)) {
+				dev_types[i].init_fn(devargs->virtual.drv_name,
+						     devargs->args);
+				break;
+			}
+		}
+
+		if (i == NUM_DEV_TYPES) {
+			rte_panic("no driver found for %s\n",
+				  devargs->virtual.drv_name);
+		}
+	}
+	return 0;
+}
diff --git a/lib/librte_eal/common/include/eal_private.h b/lib/librte_eal/common/include/eal_private.h
index f9a019b..22d8b08 100644
--- a/lib/librte_eal/common/include/eal_private.h
+++ b/lib/librte_eal/common/include/eal_private.h
@@ -197,10 +197,10 @@ int rte_eal_intr_init(void);
 int rte_eal_alarm_init(void);
 
 /**
- * This function initialises any non-PCI i.e. dummy ethernet devices
+ * This function initialises any virtual devices
  *
  * This function is private to the EAL.
  */
-int rte_eal_non_pci_ethdev_init(void);
+int rte_eal_vdev_init(void);
 
 #endif /* _EAL_PRIVATE_H_ */
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index bdd940d..00f7367 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -77,7 +77,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_errno.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_cpuflags.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_hexdump.c
 SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_devargs.c
-SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_nonpci_devs.c
+SRCS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += eal_common_vdev.c
 
 CFLAGS_eal.o := -D_GNU_SOURCE
 CFLAGS_eal_thread.o := -D_GNU_SOURCE
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 905ce37..c015a65 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -1046,8 +1046,8 @@ rte_eal_init(int argc, char **argv)
 
 	rte_eal_mcfg_complete();
 
-	if (rte_eal_non_pci_ethdev_init() < 0)
-		rte_panic("Cannot init non-PCI eth_devs\n");
+	if (rte_eal_vdev_init() < 0)
+		rte_panic("Cannot init virtual devices\n");
 
 	TAILQ_FOREACH(solib, &solib_list, next) {
 		solib->lib_handle = dlopen(solib->name, RTLD_NOW);
-- 
1.8.5.3

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [dpdk-dev] [PATCH v3 06/11] vdev: rename nonpci_devs as vdev
  2014-04-11 11:45         ` [dpdk-dev] [PATCH v3 " Olivier Matz
@ 2014-04-11 12:37           ` Thomas Monjalon
  0 siblings, 0 replies; 57+ messages in thread
From: Thomas Monjalon @ 2014-04-11 12:37 UTC (permalink / raw)
  To: Olivier Matz; +Cc: dev

2014-04-11 13:45, Olivier Matz:
> The name "nonpci_devs" for virtual devices is ambiguous as a physical
> device can also be non-PCI (ex: usb, sata, ...). A better name for this
> file is "vdev" as it only deals with virtual devices.
> 
> This patch doesn't introduce any change except renaming.
> 
> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>

Acked-by: Thomas Monjalon <thomas.monjalon@6wind.com>

Applied for version 1.6.0r2.

Thanks
-- 
Thomas

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [dpdk-dev] [PATCH v2 07/11 1/2] vdev: new registration API
  2014-04-11 10:49       ` [dpdk-dev] [PATCH v2 07/11 1/2] vdev: new registration API Neil Horman
@ 2014-04-11 13:11         ` Thomas Monjalon
  2014-04-11 15:50           ` Neil Horman
  0 siblings, 1 reply; 57+ messages in thread
From: Thomas Monjalon @ 2014-04-11 13:11 UTC (permalink / raw)
  To: Neil Horman; +Cc: dev

Hi Neil,

2014-04-11 06:49, Neil Horman:
> On Fri, Apr 11, 2014 at 09:36:52AM +0200, Olivier Matz wrote:
> > Instead of having a list of virtual device drivers in EAL code, add an
> > API to register drivers. Thanks to this new registration method, we can
> > remove the references to pmd_ring, pmd_pcap and pmd_xenvirt in EAL code.
> > This also enables the ability to register a virtual device driver as
> > a shared library.
> > 
> > The registration is done in an init function flaged with
> > __attribute__((constructor)). The new convention is to name this
> > function rte_pmd_xyz_init(). The per-device init function is renamed
> > rte_pmd_xyz_devinit().
> > 
> > By the way the internal PMDs are now also .so/standalone ready. Let's do
> > it later on. It will be required to ease maintenance.
> > 
> > Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> 
> I just posted a patch to separate pmd linkage from the applications
> yesterday, which will work with the existing API.  See my series on the
> introduction of the PMD_INIT and PMD_INIT_NONPCI macros.

This patch serie was posted weeks ago and has been reviewed.
It's a good approach because code is simpler like this and it's a first step 
before removing rte_pmd_init_all().
Your patches are using rte_pmd_init_all() which is an useless function.

Neil, next time, don't hesitate to discuss the design approaches before doing 
such big changes. By the way, your patches have to be reviewed carefully 
because there are other insteresting changes.

Thanks
-- 
Thomas

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [dpdk-dev] [PATCH v2 07/11 1/2] vdev: new registration API
  2014-04-11  7:36     ` [dpdk-dev] [PATCH v2 07/11 1/2] vdev: new registration API Olivier Matz
  2014-04-11  7:36       ` [dpdk-dev] [PATCH v2 07/11 2/2] vdev: allow external registration of virtual device drivers Olivier Matz
  2014-04-11 10:49       ` [dpdk-dev] [PATCH v2 07/11 1/2] vdev: new registration API Neil Horman
@ 2014-04-11 14:31       ` Thomas Monjalon
  2 siblings, 0 replies; 57+ messages in thread
From: Thomas Monjalon @ 2014-04-11 14:31 UTC (permalink / raw)
  To: Olivier Matz; +Cc: dev

2014-04-11 09:36, Olivier Matz:
> Instead of having a list of virtual device drivers in EAL code, add an
> API to register drivers. Thanks to this new registration method, we can
> remove the references to pmd_ring, pmd_pcap and pmd_xenvirt in EAL code.
> This also enables the ability to register a virtual device driver as
> a shared library.
> 
> The registration is done in an init function flaged with
> __attribute__((constructor)). The new convention is to name this
> function rte_pmd_xyz_init(). The per-device init function is renamed
> rte_pmd_xyz_devinit().
> 
> By the way the internal PMDs are now also .so/standalone ready. Let's do
> it later on. It will be required to ease maintenance.
> 
> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>

Acked-by: Thomas Monjalon <thomas.monjalon@6wind.com>

Applied for version 1.6.0r2.

Thank you
-- 
Thomas

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [dpdk-dev] [PATCH v2 07/11 2/2] vdev: allow external registration of virtual device drivers
  2014-04-11  7:36       ` [dpdk-dev] [PATCH v2 07/11 2/2] vdev: allow external registration of virtual device drivers Olivier Matz
@ 2014-04-11 14:31         ` Thomas Monjalon
  0 siblings, 0 replies; 57+ messages in thread
From: Thomas Monjalon @ 2014-04-11 14:31 UTC (permalink / raw)
  To: Olivier Matz; +Cc: dev

2014-04-11 09:36, Olivier Matz:
> The registration of an external vdev driver (a .so library) is done in a
> function that has the ((constructor)) attribute. This function is called
> when dlopen(driver.so) is invoked.
> 
> As a result, we need to do the dlopen() before calling
> rte_eal_vdev_init() that calls the initialization functions of all
> registered drivers.
> 
> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>

Acked-by: Thomas Monjalon <thomas.monjalon@6wind.com>

Applied for version 1.6.0r2.

Thank you
-- 
Thomas

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [dpdk-dev] [PATCH v2 07/11 1/2] vdev: new registration API
  2014-04-11 13:11         ` Thomas Monjalon
@ 2014-04-11 15:50           ` Neil Horman
  2014-04-11 16:18             ` Thomas Monjalon
  0 siblings, 1 reply; 57+ messages in thread
From: Neil Horman @ 2014-04-11 15:50 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev

On Fri, Apr 11, 2014 at 03:11:56PM +0200, Thomas Monjalon wrote:
> Hi Neil,
> 
> 2014-04-11 06:49, Neil Horman:
> > On Fri, Apr 11, 2014 at 09:36:52AM +0200, Olivier Matz wrote:
> > > Instead of having a list of virtual device drivers in EAL code, add an
> > > API to register drivers. Thanks to this new registration method, we can
> > > remove the references to pmd_ring, pmd_pcap and pmd_xenvirt in EAL code.
> > > This also enables the ability to register a virtual device driver as
> > > a shared library.
> > > 
> > > The registration is done in an init function flaged with
> > > __attribute__((constructor)). The new convention is to name this
> > > function rte_pmd_xyz_init(). The per-device init function is renamed
> > > rte_pmd_xyz_devinit().
> > > 
> > > By the way the internal PMDs are now also .so/standalone ready. Let's do
> > > it later on. It will be required to ease maintenance.
> > > 
> > > Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> > 
> > I just posted a patch to separate pmd linkage from the applications
> > yesterday, which will work with the existing API.  See my series on the
> > introduction of the PMD_INIT and PMD_INIT_NONPCI macros.
> 
> This patch serie was posted weeks ago and has been reviewed.

When and where?  You are correct, this series was posted about 1.5 months ago:
http://dpdk.org/ml/archives/dev/2014-February/001466.html

To which there was a single comment, and no other traffic until last night, when
a few bits of the series were posted to git, followed by the remaining bits
several hours later.  I don't see any acks or indications that, after 1.5
months, this was still an active patch series.

Note also that whatever review was done, was not particularly through.  There
are still problems with the libraries after Oliviers patch series:

[nhorman@hmsreliant lib]$ ldd librte_pmd_pcap.so 
        statically linked

The DSO's built by dpdk are not actually build as shared libraries but rather
statically linked together.  My patch series corrects that

Also, the build system fails to recognize the fact applications no longer need
to link against specific pmd libraries.  testpmd for example still links to
every single pmd libraryin dpdk, despite the fact that doesn't need to happen
(at least not with my patch series)
[nhorman@hmsreliant app]$ ldd testpmd
	...
        librte_pmd_e1000.so
        librte_pmd_ixgbe.so 
        librte_pmd_virtio_uio.so 
        librte_pmd_vmxnet3_uio.so
	...

Thats just a sample, but none of the pmds need to be explicitly referenced at
link time when using DSO's.  They can be specified at run time with the -d
option. They only need to be linked when you want to avoid having to use the -d
option at run time.  My patch series corrects that.

> It's a good approach because code is simpler like this and it's a first step 
> before removing rte_pmd_init_all().
> Your patches are using rte_pmd_init_all() which is an useless function.
> 
Thats not at all true.  rte_pmd_init_all is adventageous because it is agnostic
toward the pmd that is in use.  If you use constructors in the pmds (which is
good), you don't need to reference the specific libraries in your application
code, but Oliviers approach will require that you do so.  Needing to specify a
specific pmd init function in your application destroys the usefulness of the -d
option in the eal option parsing code.  That is to say, if I have an application
that wants to use the ring_pmd, it needs to call the ring_pmd init function.
Once that is coded into the application, no other pmd can be loaded, because the
application doesn't call that pmds init function (i.e. -d is made useless).
Conversely, if an application uses rte_pmd_init_all (the way my patch series
codes it), any pmd that is either statically/dynamically loaded by the
application, or opened via a dlopen call, will be registered and initalized,
allowing any application to control which pmd is used during the build process
or at run time, without having to hard code any initalization.

> Neil, next time, don't hesitate to discuss the design approaches before doing 
> such big changes. By the way, your patches have to be reviewed carefully 
> because there are other insteresting changes.
> 
I didn't hesitate, Im happy to reach out and discuss large changes, I just
thought I would do so with code in hand (this change set only took a few days to
write).  I think my major failing was to assume that the git tree was reasonably
up to date with the mailing list.  I joined the mailing list about a month ago
(2 weeks after this patch series went up).  About a week ago I started
tinkering with this, under the impression that what was in the git tree (having
seem my assembly patch go in) was reasonably current with the mailing list.
Having a patch sit on a mailing list without comment for a month is not
condusive to doing upstream development.  Checking the mailing list for prior
work isn't helpful either, as mailman doesn't allow for the easy extraction of
patches (they're all served as html), and patches that sit for that long begin
to look suspect (are they going in or not?).

If I can make a suggestion: If you're planning on delaying patches like this for
that length of time, create a devel branch for unstable changes, which accepts
changes from the mailing list in a timely fashion.  Allow public testing to weed
out the problems, not off-list review.  Set stabilization periods for said
devel-branch and merge them to the latest release branch during those times.
Also, please don't push larger series piecemeal out to the git tree.  Stage them
all on your copy of the repo and push them at once.  As it is, my patch series
is rebased to a point that is halfway through Oliviers patch series.  I know
John Linville is on this list that maintains the wireless tree, and I'm sure he
can offer lots of good git workflow pointers.

As for this patch series, I'll rebase on top of Oliviers, fixing the things that
are still broken and resubmit.

Regards
Neil

> Thanks
> -- 
> Thomas
> 

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [dpdk-dev] [PATCH v2 07/11 1/2] vdev: new registration API
  2014-04-11 15:50           ` Neil Horman
@ 2014-04-11 16:18             ` Thomas Monjalon
  2014-04-11 17:44               ` Neil Horman
  0 siblings, 1 reply; 57+ messages in thread
From: Thomas Monjalon @ 2014-04-11 16:18 UTC (permalink / raw)
  To: Neil Horman; +Cc: dev

2014-04-11 11:50, Neil Horman:
> There are still problems with the libraries after Oliviers patch series:
> 
> [nhorman@hmsreliant lib]$ ldd librte_pmd_pcap.so
>         statically linked
> 
> The DSO's built by dpdk are not actually build as shared libraries but
> rather statically linked together.  My patch series corrects that

Yes, that's why I said that "your patches have to be reviewed carefully 
because there are other insteresting changes"

> Also, the build system fails to recognize the fact applications no longer
> need to link against specific pmd libraries.  testpmd for example still
> links to every single pmd libraryin dpdk, despite the fact that doesn't
> need to happen (at least not with my patch series)
> [nhorman@hmsreliant app]$ ldd testpmd
> 	...
>         librte_pmd_e1000.so
>         librte_pmd_ixgbe.so
>         librte_pmd_virtio_uio.so
>         librte_pmd_vmxnet3_uio.so
> 	...
> 
> Thats just a sample, but none of the pmds need to be explicitly referenced
> at link time when using DSO's.  They can be specified at run time with the
> -d option. They only need to be linked when you want to avoid having to use
> the -d option at run time.  My patch series corrects that.

I agree.

> > It's a good approach because code is simpler like this and it's a first
> > step before removing rte_pmd_init_all().
> > Your patches are using rte_pmd_init_all() which is an useless function.
> 
> Thats not at all true.  rte_pmd_init_all is adventageous because it is
> agnostic toward the pmd that is in use.

Not having rte_pmd_init_all() at all is a bit more agnostic :)

> If you use constructors in the
> pmds (which is good), you don't need to reference the specific libraries in
> your application code, but Oliviers approach will require that you do so. 
> Needing to specify a specific pmd init function in your application
> destroys the usefulness of the -d option in the eal option parsing code.

Could you point where we need to call a specific pmd init function?
If it's the case, it must simply be fixed.

> That is to say, if I have an application that wants to use the ring_pmd, it
> needs to call the ring_pmd init function. Once that is coded into the
> application, no other pmd can be loaded, because the application doesn't
> call that pmds init function (i.e. -d is made useless).

I agree that ring_pmd init should be fixed.

> Conversely, if an
> application uses rte_pmd_init_all (the way my patch series codes it), any
> pmd that is either statically/dynamically loaded by the application, or
> opened via a dlopen call, will be registered and initalized, allowing any
> application to control which pmd is used during the build process or at run
> time, without having to hard code any initalization.

It seems that your patch is not removing 
rte_eth_ring_pair_create/rte_eth_ring_pair_attach so I'm not sure you can 
dynamically change the PMD in this case.

> > Neil, next time, don't hesitate to discuss the design approaches before
> > doing such big changes. By the way, your patches have to be reviewed
> > carefully because there are other insteresting changes.
> 
> I didn't hesitate, Im happy to reach out and discuss large changes, I just
> thought I would do so with code in hand (this change set only took a few
> days to write).  I think my major failing was to assume that the git tree
> was reasonably up to date with the mailing list.  I joined the mailing list
> about a month ago (2 weeks after this patch series went up).  About a week
> ago I started tinkering with this, under the impression that what was in
> the git tree (having seem my assembly patch go in) was reasonably current
> with the mailing list. Having a patch sit on a mailing list without comment
> for a month is not condusive to doing upstream development.  Checking the
> mailing list for prior work isn't helpful either, as mailman doesn't allow
> for the easy extraction of patches (they're all served as html), and
> patches that sit for that long begin to look suspect (are they going in or
> not?).

You're right. It shouldn't stay so long without being integrated.
Using patchwork should help us here.

> If I can make a suggestion: If you're planning on delaying patches like this
> for that length of time, create a devel branch for unstable changes, which
> accepts changes from the mailing list in a timely fashion.  Allow public
> testing to weed out the problems, not off-list review.  Set stabilization
> periods for said devel-branch and merge them to the latest release branch
> during those times. Also, please don't push larger series piecemeal out to
> the git tree.  Stage them all on your copy of the repo and push them at
> once.  As it is, my patch series is rebased to a point that is halfway
> through Oliviers patch series.  I know John Linville is on this list that
> maintains the wireless tree, and I'm sure he can offer lots of good git
> workflow pointers.

I understand your comment. This workflow worked well in the first year because 
there was few contributors. Now we need another organization. And yes I'm 
thinking about a development branch.

> As for this patch series, I'll rebase on top of Oliviers, fixing the things
> that are still broken and resubmit.

OK, thank you.

-- 
Thomas

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [dpdk-dev] [PATCH v2 07/11 1/2] vdev: new registration API
  2014-04-11 16:18             ` Thomas Monjalon
@ 2014-04-11 17:44               ` Neil Horman
  2014-04-11 20:08                 ` Richardson, Bruce
  0 siblings, 1 reply; 57+ messages in thread
From: Neil Horman @ 2014-04-11 17:44 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev

On Fri, Apr 11, 2014 at 06:18:08PM +0200, Thomas Monjalon wrote:
> 2014-04-11 11:50, Neil Horman:
> > There are still problems with the libraries after Oliviers patch series:
> > 
> > [nhorman@hmsreliant lib]$ ldd librte_pmd_pcap.so
> >         statically linked
> > 
> > The DSO's built by dpdk are not actually build as shared libraries but
> > rather statically linked together.  My patch series corrects that
> 
> Yes, that's why I said that "your patches have to be reviewed carefully 
> because there are other insteresting changes"
> 
Ok, But you also said that the previous patchset was reviewed carefully.
Apologies for any confusion.

> > Also, the build system fails to recognize the fact applications no longer
> > need to link against specific pmd libraries.  testpmd for example still
> > links to every single pmd libraryin dpdk, despite the fact that doesn't
> > need to happen (at least not with my patch series)
> > [nhorman@hmsreliant app]$ ldd testpmd
> > 	...
> >         librte_pmd_e1000.so
> >         librte_pmd_ixgbe.so
> >         librte_pmd_virtio_uio.so
> >         librte_pmd_vmxnet3_uio.so
> > 	...
> > 
> > Thats just a sample, but none of the pmds need to be explicitly referenced
> > at link time when using DSO's.  They can be specified at run time with the
> > -d option. They only need to be linked when you want to avoid having to use
> > the -d option at run time.  My patch series corrects that.
> 
> I agree.
> 
> > > It's a good approach because code is simpler like this and it's a first
> > > step before removing rte_pmd_init_all().
> > > Your patches are using rte_pmd_init_all() which is an useless function.
> > 
> > Thats not at all true.  rte_pmd_init_all is adventageous because it is
> > agnostic toward the pmd that is in use.
> 
> Not having rte_pmd_init_all() at all is a bit more agnostic :)
> 
Well, that would be great, I presume you are proposing tucking the driver
initalization into the eal library as part of the eal library init, so as to
protect it from the application?

> > If you use constructors in the
> > pmds (which is good), you don't need to reference the specific libraries in
> > your application code, but Oliviers approach will require that you do so. 
> > Needing to specify a specific pmd init function in your application
> > destroys the usefulness of the -d option in the eal option parsing code.
> 
> Could you point where we need to call a specific pmd init function?
> If it's the case, it must simply be fixed.
> 
Sorry, I misread here.  I was convoluted the previous approach in which some of
the sample apps called pmd initalization functions directly.  Looking at the
patches in a web browser, I thought that was still being done in the test app.

> > That is to say, if I have an application that wants to use the ring_pmd, it
> > needs to call the ring_pmd init function. Once that is coded into the
> > application, no other pmd can be loaded, because the application doesn't
> > call that pmds init function (i.e. -d is made useless).
> 
> I agree that ring_pmd init should be fixed.
> 
> > Conversely, if an
> > application uses rte_pmd_init_all (the way my patch series codes it), any
> > pmd that is either statically/dynamically loaded by the application, or
> > opened via a dlopen call, will be registered and initalized, allowing any
> > application to control which pmd is used during the build process or at run
> > time, without having to hard code any initalization.
> 
> It seems that your patch is not removing 
> rte_eth_ring_pair_create/rte_eth_ring_pair_attach so I'm not sure you can 
> dynamically change the PMD in this case.
> 
Ew, I had missed those calls.  Yes, those should be encapsulated as some driver
ops or some such.  I'll look at that when I rebase.  Regardless however, I
didn't mean to state that pmds could be switched while running, only that the
pmd to use could be specified at run time.  Though, you're correct, pmd_ring
doesn't seem to hold in line with the other pmds in their isolation.

> > > Neil, next time, don't hesitate to discuss the design approaches before
> > > doing such big changes. By the way, your patches have to be reviewed
> > > carefully because there are other insteresting changes.
> > 
> > I didn't hesitate, Im happy to reach out and discuss large changes, I just
> > thought I would do so with code in hand (this change set only took a few
> > days to write).  I think my major failing was to assume that the git tree
> > was reasonably up to date with the mailing list.  I joined the mailing list
> > about a month ago (2 weeks after this patch series went up).  About a week
> > ago I started tinkering with this, under the impression that what was in
> > the git tree (having seem my assembly patch go in) was reasonably current
> > with the mailing list. Having a patch sit on a mailing list without comment
> > for a month is not condusive to doing upstream development.  Checking the
> > mailing list for prior work isn't helpful either, as mailman doesn't allow
> > for the easy extraction of patches (they're all served as html), and
> > patches that sit for that long begin to look suspect (are they going in or
> > not?).
> 
> You're right. It shouldn't stay so long without being integrated.
> Using patchwork should help us here.
> 
Patchwork would be good, a git branch would really be better. Anything other
than git means developers have a step 0 to undertake when starting development
in whcih they have to fetch uncomitted patches from patchwork to make sure their
code it up to date, and that introduces the possibility of errors during
appilcation (due to different developers applying patches in different oders,
etc).  Using a git branch gives you a canonical location with the latest code
that every developer sees in the same way, which is very helpful to concurrent
development.

> > If I can make a suggestion: If you're planning on delaying patches like this
> > for that length of time, create a devel branch for unstable changes, which
> > accepts changes from the mailing list in a timely fashion.  Allow public
> > testing to weed out the problems, not off-list review.  Set stabilization
> > periods for said devel-branch and merge them to the latest release branch
> > during those times. Also, please don't push larger series piecemeal out to
> > the git tree.  Stage them all on your copy of the repo and push them at
> > once.  As it is, my patch series is rebased to a point that is halfway
> > through Oliviers patch series.  I know John Linville is on this list that
> > maintains the wireless tree, and I'm sure he can offer lots of good git
> > workflow pointers.
> 
> I understand your comment. This workflow worked well in the first year because 
> there was few contributors. Now we need another organization. And yes I'm 
> thinking about a development branch.
> 
> > As for this patch series, I'll rebase on top of Oliviers, fixing the things
> > that are still broken and resubmit.
> 
> OK, thank you.
> 
Thank you!  I'll repost sometime next week

Best
Neil

> -- 
> Thomas
> 

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [dpdk-dev] [PATCH v2 07/11 1/2] vdev: new registration API
  2014-04-11 17:44               ` Neil Horman
@ 2014-04-11 20:08                 ` Richardson, Bruce
  2014-04-12  6:05                   ` Thomas Monjalon
  0 siblings, 1 reply; 57+ messages in thread
From: Richardson, Bruce @ 2014-04-11 20:08 UTC (permalink / raw)
  To: Neil Horman, Thomas Monjalon; +Cc: dev

> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Neil Horman
> Sent: Friday, April 11, 2014 6:45 PM
> To: Thomas Monjalon
> Cc: dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v2 07/11 1/2] vdev: new registration API
> 
> On Fri, Apr 11, 2014 at 06:18:08PM +0200, Thomas Monjalon wrote:
> > 2014-04-11 11:50, Neil Horman:
> >
> > It seems that your patch is not removing
> > rte_eth_ring_pair_create/rte_eth_ring_pair_attach so I'm not sure you
> > can dynamically change the PMD in this case.
> >
> Ew, I had missed those calls.  Yes, those should be encapsulated as some driver
> ops or some such.  I'll look at that when I rebase.  Regardless however, I didn't
> mean to state that pmds could be switched while running, only that the pmd to
> use could be specified at run time.  Though, you're correct, pmd_ring doesn't
> seem to hold in line with the other pmds in their isolation.
> 
The ring PMD is probably best treated separately from the other PMDs as it's not really a device poll-mode driver. Instead, it's a general library that presents an API to make a ring, or set of rings, appear as a poll-mode driver ethdev. The EAL command to have one created at startup time was just an addon after-the-fact in case someone might find it useful :-). However, it's primary purpose was to allow applications to be written which could use physical NICs or rings interchangeably. For example, an app with multiple stages in a pipeline, where each stage just reads from an ethdev without caring if it's actually reading from a port or from packets sent from another lcore/function etc. Another example might be where an application wishes to sometimes loop packets back to itself, in this case it uses the C API to create an additional ring ethdev which it uses as output port for any packets it wants looped back - no special handling needed, everything is an ethdev to it on which it calls rx_burst or tx_burst. It's also likely that in future we will develop other libraries which wish to present their functionality via rx_burst/tx_burst functions i.e. as an ethdev.

Regards,
/Bruce

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [dpdk-dev] [PATCH v2 07/11 1/2] vdev: new registration API
  2014-04-11 20:08                 ` Richardson, Bruce
@ 2014-04-12  6:05                   ` Thomas Monjalon
  2014-04-12 11:03                     ` Neil Horman
  2014-04-14 13:20                     ` John W. Linville
  0 siblings, 2 replies; 57+ messages in thread
From: Thomas Monjalon @ 2014-04-12  6:05 UTC (permalink / raw)
  To: Richardson, Bruce; +Cc: dev

Hi Bruce,

11/04/2014 20:08, Richardson, Bruce :
> From: Neil Horman
> > On Fri, Apr 11, 2014 at 06:18:08PM +0200, Thomas Monjalon wrote:
> > > It seems that your patch is not removing
> > > rte_eth_ring_pair_create/rte_eth_ring_pair_attach so I'm not sure you
> > > can dynamically change the PMD in this case.
> > 
> > Ew, I had missed those calls.  Yes, those should be encapsulated as some
> > driver ops or some such.  I'll look at that when I rebase.  Regardless
> > however, I didn't mean to state that pmds could be switched while
> > running, only that the pmd to use could be specified at run time. 
> > Though, you're correct, pmd_ring doesn't seem to hold in line with the
> > other pmds in their isolation.
> 
> The ring PMD is probably best treated separately from the other PMDs as it's
> not really a device poll-mode driver. Instead, it's a general library that
> presents an API to make a ring, or set of rings, appear as a poll-mode
> driver ethdev. The EAL command to have one created at startup time was just
> an addon after-the-fact in case someone might find it useful :-). However,
> it's primary purpose was to allow applications to be written which could
> use physical NICs or rings interchangeably. For example, an app with
> multiple stages in a pipeline, where each stage just reads from an ethdev
> without caring if it's actually reading from a port or from packets sent
> from another lcore/function etc. Another example might be where an
> application wishes to sometimes loop packets back to itself, in this case
> it uses the C API to create an additional ring ethdev which it uses as
> output port for any packets it wants looped back - no special handling
> needed, everything is an ethdev to it on which it calls rx_burst or
> tx_burst. It's also likely that in future we will develop other libraries
> which wish to present their functionality via rx_burst/tx_burst functions
> i.e. as an ethdev.

I think you are describing a vdev and you want to be able to instantiate this 
vdev in your application code. Right?
So why not make a generic API to be able to instantiate a vdev?

-- 
Thomas

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [dpdk-dev] [PATCH v2 07/11 1/2] vdev: new registration API
  2014-04-12  6:05                   ` Thomas Monjalon
@ 2014-04-12 11:03                     ` Neil Horman
  2014-04-12 11:23                       ` Richardson, Bruce
  2014-04-14 13:20                     ` John W. Linville
  1 sibling, 1 reply; 57+ messages in thread
From: Neil Horman @ 2014-04-12 11:03 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev

On Sat, Apr 12, 2014 at 08:05:22AM +0200, Thomas Monjalon wrote:
> Hi Bruce,
> 
> 11/04/2014 20:08, Richardson, Bruce :
> > From: Neil Horman
> > > On Fri, Apr 11, 2014 at 06:18:08PM +0200, Thomas Monjalon wrote:
> > > > It seems that your patch is not removing
> > > > rte_eth_ring_pair_create/rte_eth_ring_pair_attach so I'm not sure you
> > > > can dynamically change the PMD in this case.
> > > 
> > > Ew, I had missed those calls.  Yes, those should be encapsulated as some
> > > driver ops or some such.  I'll look at that when I rebase.  Regardless
> > > however, I didn't mean to state that pmds could be switched while
> > > running, only that the pmd to use could be specified at run time. 
> > > Though, you're correct, pmd_ring doesn't seem to hold in line with the
> > > other pmds in their isolation.
> > 
> > The ring PMD is probably best treated separately from the other PMDs as it's
> > not really a device poll-mode driver. Instead, it's a general library that
> > presents an API to make a ring, or set of rings, appear as a poll-mode
> > driver ethdev. The EAL command to have one created at startup time was just
> > an addon after-the-fact in case someone might find it useful :-). However,
> > it's primary purpose was to allow applications to be written which could
> > use physical NICs or rings interchangeably. For example, an app with
> > multiple stages in a pipeline, where each stage just reads from an ethdev
> > without caring if it's actually reading from a port or from packets sent
> > from another lcore/function etc. Another example might be where an
> > application wishes to sometimes loop packets back to itself, in this case
> > it uses the C API to create an additional ring ethdev which it uses as
> > output port for any packets it wants looped back - no special handling
> > needed, everything is an ethdev to it on which it calls rx_burst or
> > tx_burst. It's also likely that in future we will develop other libraries
> > which wish to present their functionality via rx_burst/tx_burst functions
> > i.e. as an ethdev.
> 
> I think you are describing a vdev and you want to be able to instantiate this 
> vdev in your application code. Right?
> So why not make a generic API to be able to instantiate a vdev?
> 
+1, thats exactly what you're describing richard, an ethernet device thats
backed by rings (or pipes, or whatever other non-phycial transport you want to
use).  Though we already have a method to generically instantiate a vdev, its
the --vdev option in the eal library.  It seems to me the simplest solution here
is to remove the ring_create/attach api from public accessibility, and call it
directly from the pmd init routine by passing parameters to it through the
--vdev command line argument.  I've actually got that in the patch series that
I'm rebasing for the PMD DSO cleanups.

Neil

> -- 
> Thomas
> 

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [dpdk-dev] [PATCH v2 07/11 1/2] vdev: new registration API
  2014-04-12 11:03                     ` Neil Horman
@ 2014-04-12 11:23                       ` Richardson, Bruce
  2014-04-12 14:06                         ` Neil Horman
  0 siblings, 1 reply; 57+ messages in thread
From: Richardson, Bruce @ 2014-04-12 11:23 UTC (permalink / raw)
  To: Neil Horman, Thomas Monjalon; +Cc: dev



> -----Original Message-----
> From: Neil Horman [mailto:nhorman@tuxdriver.com]
> Sent: Saturday, April 12, 2014 12:03 PM
> To: Thomas Monjalon
> Cc: Richardson, Bruce; dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v2 07/11 1/2] vdev: new registration API
> 
> On Sat, Apr 12, 2014 at 08:05:22AM +0200, Thomas Monjalon wrote:
> > Hi Bruce,
> >
> > 11/04/2014 20:08, Richardson, Bruce :
> > > From: Neil Horman
> > > > On Fri, Apr 11, 2014 at 06:18:08PM +0200, Thomas Monjalon wrote:
> > > > > It seems that your patch is not removing
> > > > > rte_eth_ring_pair_create/rte_eth_ring_pair_attach so I'm not
> > > > > sure you can dynamically change the PMD in this case.
> > > >
> > > > Ew, I had missed those calls.  Yes, those should be encapsulated
> > > > as some driver ops or some such.  I'll look at that when I rebase.
> > > > Regardless however, I didn't mean to state that pmds could be
> > > > switched while running, only that the pmd to use could be specified at run
> time.
> > > > Though, you're correct, pmd_ring doesn't seem to hold in line with
> > > > the other pmds in their isolation.
> > >
> > > The ring PMD is probably best treated separately from the other PMDs
> > > as it's not really a device poll-mode driver. Instead, it's a
> > > general library that presents an API to make a ring, or set of
> > > rings, appear as a poll-mode driver ethdev. The EAL command to have
> > > one created at startup time was just an addon after-the-fact in case
> > > someone might find it useful :-). However, it's primary purpose was
> > > to allow applications to be written which could use physical NICs or
> > > rings interchangeably. For example, an app with multiple stages in a
> > > pipeline, where each stage just reads from an ethdev without caring
> > > if it's actually reading from a port or from packets sent from
> > > another lcore/function etc. Another example might be where an
> > > application wishes to sometimes loop packets back to itself, in this
> > > case it uses the C API to create an additional ring ethdev which it
> > > uses as output port for any packets it wants looped back - no
> > > special handling needed, everything is an ethdev to it on which it
> > > calls rx_burst or tx_burst. It's also likely that in future we will
> > > develop other libraries which wish to present their functionality via
> rx_burst/tx_burst functions i.e. as an ethdev.
> >
> > I think you are describing a vdev and you want to be able to
> > instantiate this vdev in your application code. Right?
> > So why not make a generic API to be able to instantiate a vdev?
> >
> +1, thats exactly what you're describing richard, an ethernet device
> +thats
> backed by rings (or pipes, or whatever other non-phycial transport you want to
> use).  Though we already have a method to generically instantiate a vdev, its the
> --vdev option in the eal library.  It seems to me the simplest solution here is to
> remove the ring_create/attach api from public accessibility, and call it directly
> from the pmd init routine by passing parameters to it through the --vdev
> command line argument.  I've actually got that in the patch series that I'm
> rebasing for the PMD DSO cleanups.
> 
The issue with that approach, is how do you create vdevs which are actually backed by physical ethdevs, for example a vdev that is a set of bonded ethdevs e.g. for active/passive failover, or a vdev that actually does post-processing on packets received from a physical ethdev?

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [dpdk-dev] [PATCH v2 07/11 1/2] vdev: new registration API
  2014-04-12 11:23                       ` Richardson, Bruce
@ 2014-04-12 14:06                         ` Neil Horman
  0 siblings, 0 replies; 57+ messages in thread
From: Neil Horman @ 2014-04-12 14:06 UTC (permalink / raw)
  To: Richardson, Bruce; +Cc: dev

On Sat, Apr 12, 2014 at 11:23:50AM +0000, Richardson, Bruce wrote:
> 
> 
> > -----Original Message-----
> > From: Neil Horman [mailto:nhorman@tuxdriver.com]
> > Sent: Saturday, April 12, 2014 12:03 PM
> > To: Thomas Monjalon
> > Cc: Richardson, Bruce; dev@dpdk.org
> > Subject: Re: [dpdk-dev] [PATCH v2 07/11 1/2] vdev: new registration API
> > 
> > On Sat, Apr 12, 2014 at 08:05:22AM +0200, Thomas Monjalon wrote:
> > > Hi Bruce,
> > >
> > > 11/04/2014 20:08, Richardson, Bruce :
> > > > From: Neil Horman
> > > > > On Fri, Apr 11, 2014 at 06:18:08PM +0200, Thomas Monjalon wrote:
> > > > > > It seems that your patch is not removing
> > > > > > rte_eth_ring_pair_create/rte_eth_ring_pair_attach so I'm not
> > > > > > sure you can dynamically change the PMD in this case.
> > > > >
> > > > > Ew, I had missed those calls.  Yes, those should be encapsulated
> > > > > as some driver ops or some such.  I'll look at that when I rebase.
> > > > > Regardless however, I didn't mean to state that pmds could be
> > > > > switched while running, only that the pmd to use could be specified at run
> > time.
> > > > > Though, you're correct, pmd_ring doesn't seem to hold in line with
> > > > > the other pmds in their isolation.
> > > >
> > > > The ring PMD is probably best treated separately from the other PMDs
> > > > as it's not really a device poll-mode driver. Instead, it's a
> > > > general library that presents an API to make a ring, or set of
> > > > rings, appear as a poll-mode driver ethdev. The EAL command to have
> > > > one created at startup time was just an addon after-the-fact in case
> > > > someone might find it useful :-). However, it's primary purpose was
> > > > to allow applications to be written which could use physical NICs or
> > > > rings interchangeably. For example, an app with multiple stages in a
> > > > pipeline, where each stage just reads from an ethdev without caring
> > > > if it's actually reading from a port or from packets sent from
> > > > another lcore/function etc. Another example might be where an
> > > > application wishes to sometimes loop packets back to itself, in this
> > > > case it uses the C API to create an additional ring ethdev which it
> > > > uses as output port for any packets it wants looped back - no
> > > > special handling needed, everything is an ethdev to it on which it
> > > > calls rx_burst or tx_burst. It's also likely that in future we will
> > > > develop other libraries which wish to present their functionality via
> > rx_burst/tx_burst functions i.e. as an ethdev.
> > >
> > > I think you are describing a vdev and you want to be able to
> > > instantiate this vdev in your application code. Right?
> > > So why not make a generic API to be able to instantiate a vdev?
> > >
> > +1, thats exactly what you're describing richard, an ethernet device
> > +thats
> > backed by rings (or pipes, or whatever other non-phycial transport you want to
> > use).  Though we already have a method to generically instantiate a vdev, its the
> > --vdev option in the eal library.  It seems to me the simplest solution here is to
> > remove the ring_create/attach api from public accessibility, and call it directly
> > from the pmd init routine by passing parameters to it through the --vdev
> > command line argument.  I've actually got that in the patch series that I'm
> > rebasing for the PMD DSO cleanups.
> > 
> The issue with that approach, is how do you create vdevs which are actually backed by physical ethdevs, for example a vdev that is a set of bonded ethdevs e.g. for active/passive failover, or a vdev that actually does post-processing on packets received from a physical ethdev?
> 
I'm not sure I see your point, or more specifically how it relates to what we're
discussing here.  All I'm suggesting is that, instead of exposing two functions
( rte_eth_ring_pair_create and rte_eth_ring_pair_attach ), we call them from
within the pmd init routine, encoding the parameters to pass to the functions as
arguments to the --vdev command line option.  If you plan to do other things
between those two calls, then what you problably want is to add an ioctl type
interface (or perhaps some other dev-specific type of type-checked interface)
that is implemented in the rte_ethdev api, to let you call down to the pmd
without needing to link directly to it.  If you're hope is to back ethdevs into
bonded configurations, that definately seems to be the sort of thing for which
you need additional infrastructure code, and possibly a bonded pmd (like the
bonding driver in the linux kernel).  Either way, I'm not sure I see the
relation to doing such things, and hiding direct linkage of pmd defined
functions to an application.

Regards
Neil

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [dpdk-dev] [PATCH v2 07/11 1/2] vdev: new registration API
  2014-04-12  6:05                   ` Thomas Monjalon
  2014-04-12 11:03                     ` Neil Horman
@ 2014-04-14 13:20                     ` John W. Linville
  2014-04-14 13:45                       ` Thomas Monjalon
  1 sibling, 1 reply; 57+ messages in thread
From: John W. Linville @ 2014-04-14 13:20 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev

On Sat, Apr 12, 2014 at 08:05:22AM +0200, Thomas Monjalon wrote:
> Hi Bruce,
> 
> 11/04/2014 20:08, Richardson, Bruce :
> > From: Neil Horman
> > > On Fri, Apr 11, 2014 at 06:18:08PM +0200, Thomas Monjalon wrote:
> > > > It seems that your patch is not removing
> > > > rte_eth_ring_pair_create/rte_eth_ring_pair_attach so I'm not sure you
> > > > can dynamically change the PMD in this case.
> > > 
> > > Ew, I had missed those calls.  Yes, those should be encapsulated as some
> > > driver ops or some such.  I'll look at that when I rebase.  Regardless
> > > however, I didn't mean to state that pmds could be switched while
> > > running, only that the pmd to use could be specified at run time. 
> > > Though, you're correct, pmd_ring doesn't seem to hold in line with the
> > > other pmds in their isolation.
> > 
> > The ring PMD is probably best treated separately from the other PMDs as it's
> > not really a device poll-mode driver. Instead, it's a general library that
> > presents an API to make a ring, or set of rings, appear as a poll-mode
> > driver ethdev. The EAL command to have one created at startup time was just
> > an addon after-the-fact in case someone might find it useful :-). However,
> > it's primary purpose was to allow applications to be written which could
> > use physical NICs or rings interchangeably. For example, an app with
> > multiple stages in a pipeline, where each stage just reads from an ethdev
> > without caring if it's actually reading from a port or from packets sent
> > from another lcore/function etc. Another example might be where an
> > application wishes to sometimes loop packets back to itself, in this case
> > it uses the C API to create an additional ring ethdev which it uses as
> > output port for any packets it wants looped back - no special handling
> > needed, everything is an ethdev to it on which it calls rx_burst or
> > tx_burst. It's also likely that in future we will develop other libraries
> > which wish to present their functionality via rx_burst/tx_burst functions
> > i.e. as an ethdev.
> 
> I think you are describing a vdev and you want to be able to instantiate this 
> vdev in your application code. Right?
> So why not make a generic API to be able to instantiate a vdev?

Treating vdevs as something inherently different from the
hardware-backed PMDs continues to be the wrong approach.

Ordinarily the whole point of having an abstraction that looks like
a hardware device is so that applications can use either hardware
or that abstraction without having to know the difference.  Forcing
applications to be vdev-aware defeats the whole purpose of wrapping
those constructs inside a PMD in the first place.

John
-- 
John W. Linville		Someday the world will need a hero, and you
linville@tuxdriver.com			might be all we have.  Be ready.

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [dpdk-dev] [PATCH v2 07/11 1/2] vdev: new registration API
  2014-04-14 13:20                     ` John W. Linville
@ 2014-04-14 13:45                       ` Thomas Monjalon
  2014-04-14 13:54                         ` Neil Horman
  2014-04-14 14:10                         ` John W. Linville
  0 siblings, 2 replies; 57+ messages in thread
From: Thomas Monjalon @ 2014-04-14 13:45 UTC (permalink / raw)
  To: John W. Linville; +Cc: dev

Hi John,

2014-04-14 09:20, John W. Linville:
> On Sat, Apr 12, 2014 at 08:05:22AM +0200, Thomas Monjalon wrote:
> > 11/04/2014 20:08, Richardson, Bruce :
> > > The ring PMD is probably best treated separately from the other PMDs as
> > > it's not really a device poll-mode driver. Instead, it's a general
> > > library that presents an API to make a ring, or set of rings, appear as
> > > a poll-mode driver ethdev. The EAL command to have one created at
> > > startup time was just an addon after-the-fact in case someone might
> > > find it useful :-). However, it's primary purpose was to allow
> > > applications to be written which could use physical NICs or rings
> > > interchangeably. For example, an app with multiple stages in a
> > > pipeline, where each stage just reads from an ethdev without caring if
> > > it's actually reading from a port or from packets sent from another
> > > lcore/function etc. Another example might be where an application
> > > wishes to sometimes loop packets back to itself, in this case it uses
> > > the C API to create an additional ring ethdev which it uses as output
> > > port for any packets it wants looped back - no special handling needed,
> > > everything is an ethdev to it on which it calls rx_burst or tx_burst.
> > > It's also likely that in future we will develop other libraries which
> > > wish to present their functionality via rx_burst/tx_burst functions
> > > i.e. as an ethdev.
> > 
> > I think you are describing a vdev and you want to be able to instantiate
> > this vdev in your application code. Right?
> > So why not make a generic API to be able to instantiate a vdev?
> 
> Treating vdevs as something inherently different from the
> hardware-backed PMDs continues to be the wrong approach.
> 
> Ordinarily the whole point of having an abstraction that looks like
> a hardware device is so that applications can use either hardware
> or that abstraction without having to know the difference.  Forcing
> applications to be vdev-aware defeats the whole purpose of wrapping
> those constructs inside a PMD in the first place.

I think there is a misunderstanding here.
>From the user's point of view, it must be possible to create some virtual 
devices instead of using real ones. That's --vdev option. Then the device is 
handled as any other one thanks to its PMD.
>From the application's point of view, all devices must be handled with the 
same API (ethdev). But sometimes, application wants to force creation of 
virtual devices like pmd_ring. So we need an API for this creation part. Then 
the device is still handled with the generic ethdev API.

Do you still see any problem with this approach?

Hope it's clear.
-- 
Thomas

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [dpdk-dev] [PATCH v2 07/11 1/2] vdev: new registration API
  2014-04-14 13:45                       ` Thomas Monjalon
@ 2014-04-14 13:54                         ` Neil Horman
  2014-04-14 14:10                         ` John W. Linville
  1 sibling, 0 replies; 57+ messages in thread
From: Neil Horman @ 2014-04-14 13:54 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev

On Mon, Apr 14, 2014 at 03:45:31PM +0200, Thomas Monjalon wrote:
> Hi John,
> 
> 2014-04-14 09:20, John W. Linville:
> > On Sat, Apr 12, 2014 at 08:05:22AM +0200, Thomas Monjalon wrote:
> > > 11/04/2014 20:08, Richardson, Bruce :
> > > > The ring PMD is probably best treated separately from the other PMDs as
> > > > it's not really a device poll-mode driver. Instead, it's a general
> > > > library that presents an API to make a ring, or set of rings, appear as
> > > > a poll-mode driver ethdev. The EAL command to have one created at
> > > > startup time was just an addon after-the-fact in case someone might
> > > > find it useful :-). However, it's primary purpose was to allow
> > > > applications to be written which could use physical NICs or rings
> > > > interchangeably. For example, an app with multiple stages in a
> > > > pipeline, where each stage just reads from an ethdev without caring if
> > > > it's actually reading from a port or from packets sent from another
> > > > lcore/function etc. Another example might be where an application
> > > > wishes to sometimes loop packets back to itself, in this case it uses
> > > > the C API to create an additional ring ethdev which it uses as output
> > > > port for any packets it wants looped back - no special handling needed,
> > > > everything is an ethdev to it on which it calls rx_burst or tx_burst.
> > > > It's also likely that in future we will develop other libraries which
> > > > wish to present their functionality via rx_burst/tx_burst functions
> > > > i.e. as an ethdev.
> > > 
> > > I think you are describing a vdev and you want to be able to instantiate
> > > this vdev in your application code. Right?
> > > So why not make a generic API to be able to instantiate a vdev?
> > 
> > Treating vdevs as something inherently different from the
> > hardware-backed PMDs continues to be the wrong approach.
> > 
> > Ordinarily the whole point of having an abstraction that looks like
> > a hardware device is so that applications can use either hardware
> > or that abstraction without having to know the difference.  Forcing
> > applications to be vdev-aware defeats the whole purpose of wrapping
> > those constructs inside a PMD in the first place.
> 
> I think there is a misunderstanding here.
> From the user's point of view, it must be possible to create some virtual 
> devices instead of using real ones. That's --vdev option. Then the device is 
> handled as any other one thanks to its PMD.
> From the application's point of view, all devices must be handled with the 
> same API (ethdev). But sometimes, application wants to force creation of 
> virtual devices like pmd_ring. So we need an API for this creation part. Then 
> the device is still handled with the generic ethdev API.
> 
> Do you still see any problem with this approach?
> 
The need to pass virtual device configuration information into a given vdev pmd
is acceptible I think.  The need to have separate initalization paths inside the
libraries for dpdk is not.  I think thats what needs to get fixed here.  Theres
no reason that physical devices can't use the same init path that virtual
devices do, and just have their name and params arguments forced to NULL.  Its
creates a common path that makes coding devices easier.

Neil

> Hope it's clear.
> -- 
> Thomas
> 

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [dpdk-dev] [PATCH v2 07/11 1/2] vdev: new registration API
  2014-04-14 13:45                       ` Thomas Monjalon
  2014-04-14 13:54                         ` Neil Horman
@ 2014-04-14 14:10                         ` John W. Linville
  2014-04-14 14:39                           ` Thomas Monjalon
  1 sibling, 1 reply; 57+ messages in thread
From: John W. Linville @ 2014-04-14 14:10 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev

On Mon, Apr 14, 2014 at 03:45:31PM +0200, Thomas Monjalon wrote:
> Hi John,
> 
> 2014-04-14 09:20, John W. Linville:
> > On Sat, Apr 12, 2014 at 08:05:22AM +0200, Thomas Monjalon wrote:
> > > 11/04/2014 20:08, Richardson, Bruce :
> > > > The ring PMD is probably best treated separately from the other PMDs as
> > > > it's not really a device poll-mode driver. Instead, it's a general
> > > > library that presents an API to make a ring, or set of rings, appear as
> > > > a poll-mode driver ethdev. The EAL command to have one created at
> > > > startup time was just an addon after-the-fact in case someone might
> > > > find it useful :-). However, it's primary purpose was to allow
> > > > applications to be written which could use physical NICs or rings
> > > > interchangeably. For example, an app with multiple stages in a
> > > > pipeline, where each stage just reads from an ethdev without caring if
> > > > it's actually reading from a port or from packets sent from another
> > > > lcore/function etc. Another example might be where an application
> > > > wishes to sometimes loop packets back to itself, in this case it uses
> > > > the C API to create an additional ring ethdev which it uses as output
> > > > port for any packets it wants looped back - no special handling needed,
> > > > everything is an ethdev to it on which it calls rx_burst or tx_burst.
> > > > It's also likely that in future we will develop other libraries which
> > > > wish to present their functionality via rx_burst/tx_burst functions
> > > > i.e. as an ethdev.
> > > 
> > > I think you are describing a vdev and you want to be able to instantiate
> > > this vdev in your application code. Right?
> > > So why not make a generic API to be able to instantiate a vdev?
> > 
> > Treating vdevs as something inherently different from the
> > hardware-backed PMDs continues to be the wrong approach.
> > 
> > Ordinarily the whole point of having an abstraction that looks like
> > a hardware device is so that applications can use either hardware
> > or that abstraction without having to know the difference.  Forcing
> > applications to be vdev-aware defeats the whole purpose of wrapping
> > those constructs inside a PMD in the first place.
> 
> I think there is a misunderstanding here.

So it seems.

> From the user's point of view, it must be possible to create some virtual 
> devices instead of using real ones. That's --vdev option. Then the device is 
> handled as any other one thanks to its PMD.

Except that it isn't, or at least it wasn't -- hence my patch to make
rte_pmd_init_all initialize _all_ PMDs rather than just the hardware
ones.  I hope that will be remedied once all the dust settles with
the patchsets currently in flight.

> From the application's point of view, all devices must be handled with the 
> same API (ethdev). But sometimes, application wants to force creation of 
> virtual devices like pmd_ring. So we need an API for this creation part. Then 
> the device is still handled with the generic ethdev API.
> 
> Do you still see any problem with this approach?
> 
> Hope it's clear.

To me, it seems like a strange thing to do.  But I am ambivalent
about such an API if others want it.

My main concern on this topic is that applications can be blissfully
unaware of whether they are using virtual devices or not.  If someone
actually wants to know about that, then feel free to sell them the rope.

John
-- 
John W. Linville		Someday the world will need a hero, and you
linville@tuxdriver.com			might be all we have.  Be ready.

^ permalink raw reply	[flat|nested] 57+ messages in thread

* Re: [dpdk-dev] [PATCH v2 07/11 1/2] vdev: new registration API
  2014-04-14 14:10                         ` John W. Linville
@ 2014-04-14 14:39                           ` Thomas Monjalon
  0 siblings, 0 replies; 57+ messages in thread
From: Thomas Monjalon @ 2014-04-14 14:39 UTC (permalink / raw)
  To: John W. Linville; +Cc: dev

Neil, John,

I think we all want the same thing: simple and generic APIs.

2014-04-14 10:10, John W. Linville:
> On Mon, Apr 14, 2014 at 03:45:31PM +0200, Thomas Monjalon wrote:
> > From the user's point of view, it must be possible to create some virtual
> > devices instead of using real ones. That's --vdev option. Then the device
> > is handled as any other one thanks to its PMD.
> 
> Except that it isn't, or at least it wasn't -- hence my patch to make
> rte_pmd_init_all initialize _all_ PMDs rather than just the hardware
> ones.  I hope that will be remedied once all the dust settles with
> the patchsets currently in flight.

Yes there should not be any difference between PMDs for registering them.
And rte_pmd_init_all is not needed.
Please provide a patch to register all of them with constructors.

-- 
Thomas

^ permalink raw reply	[flat|nested] 57+ messages in thread

end of thread, other threads:[~2014-04-14 14:39 UTC | newest]

Thread overview: 57+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-02-28 17:25 [dpdk-dev] [PATCH 00/11] eal: allow virtual pmd drivers as shared lib Olivier Matz
2014-02-28 17:25 ` [dpdk-dev] [PATCH 01/11] mk: use whole-archive option when creating dpdk binaries Olivier Matz
2014-04-10 13:58   ` Thomas Monjalon
2014-02-28 17:25 ` [dpdk-dev] [PATCH 02/11] devices-args: introduce rte_devargs in eal Olivier Matz
2014-02-28 21:39   ` Stephen Hemminger
2014-03-01 12:02     ` Olivier MATZ
2014-03-01 12:14       ` [dpdk-dev] [PATCH v2 " Olivier Matz
2014-04-10 13:59         ` Thomas Monjalon
2014-02-28 17:25 ` [dpdk-dev] [PATCH 03/11] devices-args: use rte_devargs and remove old whitelist code Olivier Matz
2014-03-01 12:14   ` [dpdk-dev] [PATCH v2 " Olivier Matz
2014-04-10 14:01     ` Thomas Monjalon
2014-02-28 17:25 ` [dpdk-dev] [PATCH 04/11] devices-args: add a dump_devargs command in basic test application Olivier Matz
2014-04-10 14:02   ` Thomas Monjalon
2014-02-28 17:25 ` [dpdk-dev] [PATCH 05/11] pci: rename device_list as pci_device_list Olivier Matz
2014-04-10 14:03   ` Thomas Monjalon
2014-02-28 17:25 ` [dpdk-dev] [PATCH 06/11] vdev: rename eal_common_nonpci_devs.c as eal_common_vdev.c Olivier Matz
2014-04-10 14:39   ` Thomas Monjalon
2014-04-11  7:36     ` [dpdk-dev] [PATCH v2 06/11] vdev: rename nonpci_devs as vdev Olivier Matz
2014-04-11 11:25       ` Thomas Monjalon
2014-04-11 11:45         ` [dpdk-dev] [PATCH v3 " Olivier Matz
2014-04-11 12:37           ` Thomas Monjalon
2014-02-28 17:25 ` [dpdk-dev] [PATCH 07/11] vdev: allow external registration of virtual device drivers Olivier Matz
2014-04-10 14:55   ` Thomas Monjalon
2014-04-11  7:36     ` [dpdk-dev] [PATCH v2 07/11 1/2] vdev: new registration API Olivier Matz
2014-04-11  7:36       ` [dpdk-dev] [PATCH v2 07/11 2/2] vdev: allow external registration of virtual device drivers Olivier Matz
2014-04-11 14:31         ` Thomas Monjalon
2014-04-11 10:49       ` [dpdk-dev] [PATCH v2 07/11 1/2] vdev: new registration API Neil Horman
2014-04-11 13:11         ` Thomas Monjalon
2014-04-11 15:50           ` Neil Horman
2014-04-11 16:18             ` Thomas Monjalon
2014-04-11 17:44               ` Neil Horman
2014-04-11 20:08                 ` Richardson, Bruce
2014-04-12  6:05                   ` Thomas Monjalon
2014-04-12 11:03                     ` Neil Horman
2014-04-12 11:23                       ` Richardson, Bruce
2014-04-12 14:06                         ` Neil Horman
2014-04-14 13:20                     ` John W. Linville
2014-04-14 13:45                       ` Thomas Monjalon
2014-04-14 13:54                         ` Neil Horman
2014-04-14 14:10                         ` John W. Linville
2014-04-14 14:39                           ` Thomas Monjalon
2014-04-11 14:31       ` Thomas Monjalon
2014-02-28 17:25 ` [dpdk-dev] [PATCH 08/11] device-args: use a comma instead of semicolon to separate key/values Olivier Matz
2014-04-10 14:05   ` Thomas Monjalon
2014-02-28 17:25 ` [dpdk-dev] [PATCH 09/11] device-args: replace use-device eal option by pci-whitelist and vdev Olivier Matz
2014-03-01 12:14   ` [dpdk-dev] [PATCH v2 " Olivier Matz
2014-04-10 14:06     ` Thomas Monjalon
2014-03-03 17:14   ` [dpdk-dev] [PATCH " Richardson, Bruce
2014-03-04 13:09     ` Olivier MATZ
2014-03-04 13:14       ` Richardson, Bruce
2014-03-24 22:39         ` Thomas Monjalon
2014-02-28 17:25 ` [dpdk-dev] [PATCH 10/11] device-args: allow to provide per pci device command line arguments Olivier Matz
2014-03-01 12:14   ` [dpdk-dev] [PATCH v2 " Olivier Matz
2014-04-10 14:06     ` Thomas Monjalon
2014-02-28 17:25 ` [dpdk-dev] [PATCH 11/11] testpmd: add several dump commands, useful for debug Olivier Matz
2014-03-01 12:15   ` [dpdk-dev] [PATCH v2 " Olivier Matz
2014-04-10 14:08     ` Thomas Monjalon

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).