bus: attach / detach API
cover bus: attach / detach API
This patchset introduces the attach / detach API to rte_bus. The rte_device structure is used as the generic device representation.
This API is implemented for the virtual bus.
The functions rte_eal_dev_attach and rte_eal_dev_detach are updated to use this new interface.
Jan Blunck (9):
bus: add bus iterator to find a particular bus
bus: add device iterator
bus: add helper to find bus for a particular device
bus: add bus helper iterator to find a particular device
bus: introduce attach/detach functionality
vdev: implement find_device bus operation
vdev: implement detach bus operation
eal: make virtual driver probe and remove take rte_vdev_device
ethdev: Use embedded rte_device to detach driver
lib/librte_eal/bsdapp/eal/rte_eal_version.map | 4 + lib/librte_eal/common/eal_common_bus.c | 66 ++++++++++++++++ lib/librte_eal/common/eal_common_dev.c | 100 ++++++++++++++++++------ lib/librte_eal/common/eal_common_vdev.c | 27 +++++++ lib/librte_eal/common/include/rte_bus.h | 75 ++++++++++++++++++ lib/librte_eal/common/include/rte_dev.h | 11 +++ lib/librte_eal/linuxapp/eal/rte_eal_version.map | 3 + lib/librte_ether/rte_ethdev.c | 3 +- 8 files changed, 266 insertions(+), 23 deletions(-)
Signature · 1 line
2.1.4
PATCH 1/9 bus: add bus iterator to find a particular bus
From: Jan Blunck <[email protected]>
--- lib/librte_eal/bsdapp/eal/rte_eal_version.map | 1 + lib/librte_eal/common/eal_common_bus.c | 14 ++++++++++++++ lib/librte_eal/common/include/rte_bus.h | 20 ++++++++++++++++++++ lib/librte_eal/linuxapp/eal/rte_eal_version.map | 1 + 4 files changed, 36 insertions(+)
lib/librte_eal/bsdapp/eal/rte_eal_version.map +1 -0
@@ -162,6 +162,7 @@ DPDK_17.02 { DPDK_17.05 { global: + rte_bus_find; rte_cpu_is_supported; rte_log_dump; rte_log_register;
lib/librte_eal/common/eal_common_bus.c +14 -0
@@ -145,3 +145,17 @@ rte_bus_dump(FILE *f) } } } + +struct rte_bus * +rte_bus_find (int (*match)(const struct rte_bus *bus,const void *data), +const void *data) +{ +struct rte_bus *bus =NULL ; + + TAILQ_FOREACH(bus, &rte_bus_list, next) { +if (match (bus, data)) +break ; + } + +return bus; +}
lib/librte_eal/common/include/rte_bus.h +20 -0
@@ -141,6 +141,26 @@ int rte_bus_probe(void);void rte_bus_dump (FILE *f);/** +* Bus iterator to find a particular bus. +* +* The callback function should return 0 if the bus doesn't match and non-zero +* if it does. If the callback returns non-zero this function will stop +* iterating over any more buses. +* +* @param match +* Callback function to check bus +* +* @param data +* Data to pass to match callback +* +* @return +* A pointer to a rte_bus structure or NULL in case no bus matches +*/ +struct rte_bus *rte_bus_find ( +int (*match)(const struct rte_bus *bus,const void *data), +const void *data); + +/** * Helper for Bus registration. * The constructor has higher priority than PMD constructors. */
lib/librte_eal/linuxapp/eal/rte_eal_version.map +1 -0
@@ -166,6 +166,7 @@ DPDK_17.02 { DPDK_17.05 { global: + rte_bus_find; rte_cpu_is_supported; rte_intr_free_epoll_fd; rte_log_dump;
Signature · 1 line
2.1.4
PATCH 2/9 bus: add device iterator
In reply to Gaetan RivetFrom: Jan Blunck <[email protected]>
--- lib/librte_eal/common/eal_common_bus.c | 1 + lib/librte_eal/common/include/rte_bus.h | 8 ++++++++ 2 files changed, 9 insertions(+)
lib/librte_eal/common/eal_common_bus.c +1 -0
@@ -50,6 +50,7 @@ rte_bus_register(struct rte_bus *bus)/* A bus should mandatorily have the scan implemented */ RTE_VERIFY (bus->scan);RTE_VERIFY (bus->probe); +RTE_VERIFY (bus->find_device);TAILQ_INSERT_TAIL (&rte_bus_list, bus, next);RTE_LOG (DEBUG ,EAL ,"Registered [%s] bus.\n" , bus->name);
lib/librte_eal/common/include/rte_bus.h +8 -0
@@ -82,6 +82,13 @@ typedef int (*rte_bus_scan_t)(void);typedef int (*rte_bus_probe_t )(void );/** +* Device iterator to find a particular device on a bus. +*/ +typedef struct rte_device * (*rte_bus_find_device_t )( +int (*match)(const struct rte_device *dev,const void *data), +const void *data); + +/** * A structure describing a generic bus. */ struct rte_bus {
@@ -89,6 +96,7 @@ struct rte_bus {const char *name;/**< Name of the bus */ rte_bus_scan_t scan;/**< Scan for devices attached to bus */ rte_bus_probe_t probe;/**< Probe devices on bus */ +rte_bus_find_device_t find_device;/**< Find device on bus */ };/**
Signature · 1 line
2.1.4
PATCH 3/9 bus: add helper to find bus for a particular device
In reply to Gaetan RivetFrom: Jan Blunck <[email protected]>
--- lib/librte_eal/bsdapp/eal/rte_eal_version.map | 1 + lib/librte_eal/common/eal_common_bus.c | 22 ++++++++++++++++++++++ lib/librte_eal/common/include/rte_bus.h | 5 +++++ lib/librte_eal/linuxapp/eal/rte_eal_version.map | 1 + 4 files changed, 29 insertions(+)
lib/librte_eal/bsdapp/eal/rte_eal_version.map +1 -0
@@ -163,6 +163,7 @@ DPDK_17.05 { global: rte_bus_find; + rte_bus_find_by_device; rte_cpu_is_supported; rte_log_dump; rte_log_register;
lib/librte_eal/common/eal_common_bus.c +22 -0
@@ -160,3 +160,25 @@ rte_bus_find(int (*match)(const struct rte_bus *bus, const void *data),return bus; } + +static int +cmp_rte_device (const struct rte_device *dev,const void *_dev2) +{ +const struct rte_device *dev2 = _dev2; + +return dev == dev2; +} + +static int +bus_find_device (const struct rte_bus *bus,const void *_dev) +{ +struct rte_device *dev; + + dev = bus->find_device (cmp_rte_device, _dev); +return !!dev; +} + +struct rte_bus *rte_bus_find_by_device (const struct rte_device *dev) +{ +return rte_bus_find (bus_find_device, (const void *)dev); +}
lib/librte_eal/common/include/rte_bus.h +5 -0
@@ -169,6 +169,11 @@ struct rte_bus *rte_bus_find( const void *data);/** +* Find the registered bus for a particular device. +*/ +struct rte_bus *rte_bus_find_by_device (const struct rte_device *dev); + +/** * Helper for Bus registration. * The constructor has higher priority than PMD constructors. */
lib/librte_eal/linuxapp/eal/rte_eal_version.map +1 -0
@@ -167,6 +167,7 @@ DPDK_17.05 { global: rte_bus_find; + rte_bus_find_by_device; rte_cpu_is_supported; rte_intr_free_epoll_fd; rte_log_dump;
Signature · 1 line
2.1.4
PATCH 4/9 bus: add bus helper iterator to find a particular device
In reply to Gaetan RivetFrom: Jan Blunck <[email protected]>
--- lib/librte_eal/bsdapp/eal/rte_eal_version.map | 1 + lib/librte_eal/common/eal_common_bus.c | 26 +++++++++++++++++++++++++ lib/librte_eal/common/include/rte_bus.h | 26 +++++++++++++++++++++++++ lib/librte_eal/linuxapp/eal/rte_eal_version.map | 1 + 4 files changed, 54 insertions(+)
lib/librte_eal/bsdapp/eal/rte_eal_version.map +1 -0
@@ -164,6 +164,7 @@ DPDK_17.05 { rte_bus_find; rte_bus_find_by_device; + rte_bus_find_device; rte_cpu_is_supported; rte_log_dump; rte_log_register;
lib/librte_eal/common/eal_common_bus.c +26 -0
@@ -182,3 +182,29 @@ struct rte_bus *rte_bus_find_by_device(const struct rte_device *dev) {return rte_bus_find (bus_find_device, (const void *)dev); } + +struct rte_device * +rte_bus_find_device (const struct rte_device *start, +int (*match)(const struct rte_device *dev,const void *data), +const void *data) +{ +struct rte_bus *bus; +struct rte_device *dev =NULL ; + +if (start) { + bus =rte_bus_find_by_device (start); +if (!bus) +return NULL ; + }else + bus =TAILQ_FIRST (&rte_bus_list); + +while (bus) { + dev = bus->find_device (match, data); +if (dev) +break ; + +TAILQ_NEXT (bus, next); + } + +return dev; +}
lib/librte_eal/common/include/rte_bus.h +26 -0
@@ -169,6 +169,32 @@ struct rte_bus *rte_bus_find( const void *data);/** +* Bus iterator to find a particular device. +* +* The callback function should return 0 if the device doesn't match and +* non-zero if it does. If the callback returns non-zero this function will +* stop iterating over any more buses and devices. +* To continue a search the device of a previous search is passed via the start +* parameters. +* +* @param start +* Start device of the iteration +* +* @param match +* Callback function to check device +* +* @param data +* Data to pass to match callback +* +* @return +* A pointer to a rte_bus structure or NULL in case no bus matches +*/ +struct rte_device * +rte_bus_find_device (const struct rte_device *start, +int (*match)(const struct rte_device *dev,const void *data), +const void *data); + +/** * Find the registered bus for a particular device. */ struct rte_bus *rte_bus_find_by_device (const struct rte_device *dev);
lib/librte_eal/linuxapp/eal/rte_eal_version.map +1 -0
@@ -168,6 +168,7 @@ DPDK_17.05 { rte_bus_find; rte_bus_find_by_device; + rte_bus_find_device; rte_cpu_is_supported; rte_intr_free_epoll_fd; rte_log_dump;
Signature · 1 line
2.1.4
PATCH 5/9 bus: introduce attach/detach functionality
In reply to Gaetan RivetFrom: Jan Blunck <[email protected]>
--- lib/librte_eal/common/eal_common_bus.c | 3 +++ lib/librte_eal/common/include/rte_bus.h | 16 ++++++++++++++++ 2 files changed, 19 insertions(+)
lib/librte_eal/common/eal_common_bus.c +3 -0
@@ -52,6 +52,9 @@ rte_bus_register(struct rte_bus *bus)RTE_VERIFY (bus->probe);RTE_VERIFY (bus->find_device); +/* Buses supporting attach also require detach */ +RTE_VERIFY (!bus->attach || bus->detach); +TAILQ_INSERT_TAIL (&rte_bus_list, bus, next);RTE_LOG (DEBUG ,EAL ,"Registered [%s] bus.\n" , bus->name); }
lib/librte_eal/common/include/rte_bus.h +16 -0
@@ -89,6 +89,20 @@ typedef struct rte_device * (*rte_bus_find_device_t)( const void *data);/** +* Implementation specific probe function which is responsible for linking +* devices on that bus with applicable drivers. +* +*/ +typedef int (*rte_bus_attach_t )(struct rte_device *dev); + +/** +* Implementation specific remove function which is responsible for unlinking +* devices on that bus from assigned driver. +* +*/ +typedef int (*rte_bus_detach_t )(struct rte_device *dev); + +/** * A structure describing a generic bus. */ struct rte_bus {
@@ -97,6 +111,8 @@ struct rte_bus {rte_bus_scan_t scan;/**< Scan for devices attached to bus */ rte_bus_probe_t probe;/**< Probe devices on bus */ rte_bus_find_device_t find_device;/**< Find device on bus */ +rte_bus_attach_t attach;/**< Probe single device for drivers */ +rte_bus_detach_t detach;/**< Remove single device from driver */ };/**
Signature · 1 line
2.1.4
PATCH 6/9 vdev: implement find_device bus operation
In reply to Gaetan RivetFrom: Jan Blunck <[email protected]>
--- lib/librte_eal/common/eal_common_vdev.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
lib/librte_eal/common/eal_common_vdev.c +15 -0
@@ -338,9 +338,24 @@ vdev_probe(void)return 0 ; } +static struct rte_device * +vdev_find_device (int (*match)(const struct rte_device *dev,const void *data), +const void *data) +{ +struct rte_vdev_device *dev; + + TAILQ_FOREACH(dev, &vdev_device_list, next) { +if (match (&dev->device, data)) +return &dev->device; + } + +return NULL ; +} +static struct rte_bus rte_vdev_bus = { .scan = vdev_scan, .probe = vdev_probe, + .find_device = vdev_find_device, };RTE_INIT (rte_vdev_bus_register);
Signature · 1 line
2.1.4
PATCH 7/9 vdev: implement detach bus operation
In reply to Gaetan RivetFrom: Jan Blunck <[email protected]>
--- lib/librte_eal/common/eal_common_vdev.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
lib/librte_eal/common/eal_common_vdev.c +12 -0
@@ -352,10 +352,22 @@ vdev_find_device(int (*match)(const struct rte_device *dev, const void *data),return NULL ; } +static int +vdev_detach (struct rte_device *dev) +{ +/* +* The virtual bus doesn't support 'unattached' devices so this is +* actually equal to hotplugging removal of it. +*/ +return rte_vdev_uninit (dev->name); +} +static struct rte_bus rte_vdev_bus = { .scan = vdev_scan, .probe = vdev_probe, .find_device = vdev_find_device, +/* .attach = NULL, see comment on vdev_detach */ + .detach = vdev_detach, };RTE_INIT (rte_vdev_bus_register);
Signature · 1 line
2.1.4
PATCH 8/9 eal: make virtual driver probe and remove take rte_vdev_device
In reply to Gaetan RivetFrom: Jan Blunck <[email protected]>
This is a preparation to embed the generic rte_device into the rte_eth_dev also for virtual devices.
--- lib/librte_eal/common/eal_common_dev.c | 93 ++++++++++++++++++++++++++-------- 1 file changed, 71 insertions(+), 22 deletions(-)
lib/librte_eal/common/eal_common_dev.c +71 -22
@@ -37,6 +37,7 @@#include <inttypes.h> #include <sys/queue.h> +#include <rte_bus.h> #include <rte_dev.h> #include <rte_devargs.h> #include <rte_debug.h>
@@ -45,50 +46,98 @@#include "eal_private.h" +static int cmp_detached_dev_name (const struct rte_device *dev, +const void *_name) +{ +const char *name = _name; + +/* skip attached devices */ +if (dev->driver) +return 0 ; + +return !strcmp (dev->name, name); +} +int rte_eal_dev_attach (const char *name,const char *devargs) { -struct rte_pci_addr addr; +struct rte_device *dev; +int ret;if (name ==NULL || devargs ==NULL ) {RTE_LOG (ERR ,EAL ,"Invalid device or arguments provided\n" );return -EINVAL ; } -if (eal_parse_pci_DomBDF (name, &addr) ==0 ) { -if (rte_pci_probe_one (&addr) <0 ) - goto err; + dev =rte_bus_find_device (NULL , cmp_detached_dev_name, name); +if (dev) { +struct rte_bus *bus; + + bus =rte_bus_find_by_device (dev); +if (!bus) { +RTE_LOG (ERR ,EAL ,"Cannot find bus for device (%s)\n" , + name); +return -EINVAL ; + } - }else { -if (rte_vdev_init (name, devargs)) - goto err; +if (!bus->attach) { +RTE_LOG (ERR ,EAL ,"Bus function not supported\n" ); +return -ENOTSUP ; + } + + ret = bus->attach (dev); + goto out; } -return 0 ; +/* +* If we haven't found a bus device the user meant to "hotplug" a +* virtual device instead. +*/ + ret =rte_vdev_init (name, devargs); +out: +if (ret) +RTE_LOG (ERR ,EAL ,"Driver cannot attach the device (%s)\n" , + name); +return ret; +} + +static int cmp_dev_name (const struct rte_device *dev,const void *_name) +{ +const char *name = _name; -err: -RTE_LOG (ERR ,EAL ,"Driver cannot attach the device (%s)\n" , name); -return -EINVAL ; +return !strcmp (dev->name, name); }int rte_eal_dev_detach (const char *name) { -struct rte_pci_addr addr; +struct rte_device *dev; +struct rte_bus *bus; +int ret;if (name ==NULL ) {RTE_LOG (ERR ,EAL ,"Invalid device provided.\n" );return -EINVAL ; } -if (eal_parse_pci_DomBDF (name, &addr) ==0 ) { -if (rte_pci_detach (&addr) <0 ) - goto err; - }else { -if (rte_vdev_uninit (name)) - goto err; + dev =rte_bus_find_device (NULL , cmp_dev_name, name); +if (!dev) { +RTE_LOG (ERR ,EAL ,"Cannot find device (%s)\n" , name); +return -EINVAL ; + } + + bus =rte_bus_find_by_device (dev); +if (!bus) { +RTE_LOG (ERR ,EAL ,"Cannot find bus for device (%s)\n" , name); +return -EINVAL ; + } + +if (!bus->detach) { +RTE_LOG (ERR ,EAL ,"Bus function not supported\n" ); +return -ENOTSUP ; } -return 0 ; -err: -RTE_LOG (ERR ,EAL ,"Driver cannot detach the device (%s)\n" , name); -return -EINVAL ; + ret = bus->detach (dev); +if (ret) +RTE_LOG (ERR ,EAL ,"Driver cannot detach the device (%s)\n" , + name); +return ret; }
Signature · 1 line
2.1.4
PATCH 9/9 ethdev: Use embedded rte_device to detach driver
In reply to Gaetan RivetFrom: Jan Blunck <[email protected]>
--- lib/librte_eal/bsdapp/eal/rte_eal_version.map | 1 + lib/librte_eal/common/eal_common_dev.c | 43 ++++++++++++++++----------- lib/librte_eal/common/include/rte_dev.h | 11 +++++++ lib/librte_ether/rte_ethdev.c | 3 +- 4 files changed, 39 insertions(+), 19 deletions(-)
lib/librte_eal/bsdapp/eal/rte_eal_version.map +1 -0
@@ -162,6 +162,7 @@ DPDK_17.02 { DPDK_17.05 { global: + rte_eal_device_detach; rte_bus_find; rte_bus_find_by_device; rte_bus_find_device;
lib/librte_eal/common/eal_common_dev.c +25 -18
59 lines not on this page · raw message
lib/librte_eal/common/include/rte_dev.h +11 -0
@@ -123,6 +123,17 @@ struct rte_mem_resource {void *addr;/**< Virtual address, NULL when not mapped. */ }; +/* FIXME: Forward declare */ +struct rte_device ; + +/** +* Unplug the device from the device driver. +* +* @param dev +* A pointer to a rte_device structure. +*/ +int rte_eal_device_detach (struct rte_device *dev); +/** * A structure describing a device driver. */
lib/librte_ether/rte_ethdev.c +2 -1
@@ -440,7 +440,8 @@ rte_eth_dev_detach(uint8_t port_id, char *name)snprintf (name,sizeof (rte_eth_devices[port_id].data->name),"%s" , rte_eth_devices[port_id].data->name); - ret =rte_eal_dev_detach (name); + + ret =rte_eal_device_detach (rte_eth_devices[0 ].device);if (ret <0 ) goto err;
Signature · 1 line
2.1.4
v2 cover bus: attach / detach API
In reply to Gaetan RivetFollowing the work from Jan:
This patchset introduces the attach / detach API to rte_bus. The rte_device structure is used as the generic device representation.
This API is implemented for the virtual bus.
The functions rte_eal_dev_attach and rte_eal_dev_detach are updated to use this new interface.
--
0. API rework
-------------
I would like to propose an evolution on the API developed by Jan.
The attach / detach rte_bus API is necessary to support the attach/detach rte_dev API. Those are two different levels for one similar functionality.
Attach / detach does not allow true hotplugging, because the attach function expects the devices operated upon to already exist within the buses / sub-layers. This means that this API expects devices meta-datas (bus-internal device representation and associated device information read from the system) to be present upon attach. This part of the work is done during scanning.
While it is best to avoid changing the public rte_dev API as it already exists, nothing prevents this new rte_bus API from superseeding it. It has been said during the previous release cycle that device hotplug was a feature that interested users. True hotplug is not allowed by the current attach / detach API. Worse, this API hinders the effort to bring this new functionality by squatting its semantic field.
Thus, I propose to rename rte_bus attach / detach; plug / unplug. As it is a superset of the attach / detach functionality, it can be used to implement rte_dev attach / detach. Now is the right time to pivot to this new feature.
This should help maintainers understanding the aim of this API and the differences with the APIs higher-up, clarify the field and allow a new functionality to be proposed.
The vdev bus is inherently supporting the new API, however it has been made explicit. My implementation in the PCI bus in further patchset also follows the rte_bus hotplug API instead of only attach / detach.
One remaining problem with the vdev bus is the rte_dev attach implementation, which needs the rte_devargs rework to be properly fixed.
1. Additional evolutions in the patchset
----------------------------------------
The RTE_VERIFY on the find_device is too stringent I think and forces all buses to implement a public device iterator. While it could be argued that it would push for quicker support for the functionality, I think it's possible that some buses are not interested at all in it and should simply be ignored.
The bus devices iterator has been fixed.
The internal rte_device handle was not properly setup within the net_ring PMD.
Gaetan Rivet (2):
vdev: implement hotplug functionality
net/ring: fix dev handle in eth_dev
Jan Blunck (9):
bus: add bus iterator to find a particular bus
bus: add device iterator
bus: add helper to find bus for a particular device
bus: add bus helper iterator to find a particular device
bus: introduce hotplug functionality
vdev: implement find_device bus operation
vdev: implement unplug bus operation
eal: make virtual driver probe and remove take rte_vdev_device
ethdev: Use embedded rte_device to detach driver
drivers/net/ring/rte_eth_ring.c | 7 ++ lib/librte_eal/bsdapp/eal/rte_eal_version.map | 4 + lib/librte_eal/common/eal_common_bus.c | 65 +++++++++++++++ lib/librte_eal/common/eal_common_dev.c | 100 ++++++++++++++++++------ lib/librte_eal/common/eal_common_vdev.c | 27 +++++++ lib/librte_eal/common/include/rte_bus.h | 87 +++++++++++++++++++++ lib/librte_eal/common/include/rte_dev.h | 26 ++++++ lib/librte_eal/linuxapp/eal/rte_eal_version.map | 3 + lib/librte_ether/rte_ethdev.c | 3 +- 9 files changed, 299 insertions(+), 23 deletions(-)
Signature · 1 line
2.1.4
PATCH v2 1/11 bus: add bus iterator to find a particular bus
From: Jan Blunck <[email protected]>
--- lib/librte_eal/bsdapp/eal/rte_eal_version.map | 1 + lib/librte_eal/common/eal_common_bus.c | 13 ++++++++++ lib/librte_eal/common/include/rte_bus.h | 32 +++++++++++++++++++++++++ lib/librte_eal/linuxapp/eal/rte_eal_version.map | 1 + 4 files changed, 47 insertions(+)
lib/librte_eal/bsdapp/eal/rte_eal_version.map +1 -0
@@ -162,6 +162,7 @@ DPDK_17.02 { DPDK_17.05 { global: + rte_bus_find; rte_cpu_is_supported; rte_log_dump; rte_log_register;
lib/librte_eal/common/eal_common_bus.c +13 -0
@@ -145,3 +145,16 @@ rte_bus_dump(FILE *f) } } } + +struct rte_bus * +rte_bus_find (rte_bus_match_t match,const void *data) +{ +struct rte_bus *bus =NULL ; + + TAILQ_FOREACH(bus, &rte_bus_list, next) { +if (match (bus, data)) +break ; + } + +return bus; +}
lib/librte_eal/common/include/rte_bus.h +32 -0
@@ -141,6 +141,38 @@ int rte_bus_probe(void);void rte_bus_dump (FILE *f);/** +* Bus match function. +* +* @param bus +* bus under test. +* +* @param data +* data matched +* +* @return +* 0 if the bus does not match. +* !0 if the bus matches. +*/ +typedef int (*rte_bus_match_t )(const struct rte_bus *bus,const void *data); + +/** +* Bus iterator to find a particular bus. +* +* If the callback returns non-zero this function will stop iterating over +* any more buses. +* +* @param match +* Callback function to check bus +* +* @param data +* Data to pass to match callback +* +* @return +* A pointer to a rte_bus structure or NULL in case no bus matches +*/ +struct rte_bus *rte_bus_find (rte_bus_match_t match,const void *data); + +/** * Helper for Bus registration. * The constructor has higher priority than PMD constructors. */
lib/librte_eal/linuxapp/eal/rte_eal_version.map +1 -0
@@ -166,6 +166,7 @@ DPDK_17.02 { DPDK_17.05 { global: + rte_bus_find; rte_cpu_is_supported; rte_intr_free_epoll_fd; rte_log_dump;
Signature · 1 line
2.1.4
Re: [PATCH v2 01/11] bus: add bus iterator to find a particular bus
Hello Gaetan,
Quoted 53 lines · Gaetan Rivet
From: Jan Blunck <[email protected]>
Signed-off-by Jan Blunck <[email protected]>Signed-off-by Gaetan Rivet <[email protected]>--- lib/librte_eal/bsdapp/eal/rte_eal_version.map | 1 + lib/librte_eal/common/eal_common_bus.c | 13 ++++++++++ lib/librte_eal/common/include/rte_bus.h | 32 +++++++++++++++++++++++++ lib/librte_eal/linuxapp/eal/rte_eal_version.map | 1 + 4 files changed, 47 insertions(+)lib/librte_eal/bsdapp/eal/rte_eal_version.map +1
-0@@ -162,6 +162,7 @@ DPDK_17.02 { DPDK_17.05 { global: + rte_bus_find; rte_cpu_is_supported; rte_log_dump; rte_log_register;lib/librte_eal/common/eal_common_bus.c +13
-0@@ -145,3 +145,16 @@ rte_bus_dump(FILE *f) } } } + +struct rte_bus * +rte_bus_find (rte_bus_match_t match,const void *data) +{ +struct rte_bus *bus =NULL ; + + TAILQ_FOREACH(bus, &rte_bus_list, next) { +if (match (bus, data)) +break ; + } + +return bus; +}lib/librte_eal/common/include/rte_bus.h +1
-0@@ -141,6 +141,38 @@ int rte_bus_probe(void);void rte_bus_dump (FILE *f);/** +* Bus match function.
lib/librte_eal/common/include/rte_bus.h int rte_bus_probe(void); · line 154
Quoted 10 lines
lib/librte_eal/common/include/rte_bus.h +10
-0+* +* @param bus +* bus under test. +* +* @param data +* data matched +* +* @return +* 0 if the bus does not match. +* !0 if the bus matches.
One of the common match function implementation could be simply to match a string. strcmp itself returns '0' for a successful match. On the same lines, should this function return value be reversed? -
0 if match
!0 if not a match
-
That way, people would not have to change either the way strcmp works, for example, or the way various APIs expect '0' as success.
same for rte_device_match_t as well. (in next patch)
Quoted 37 lines
lib/librte_eal/common/include/rte_bus.h +21
-0+*/ +typedef int (*rte_bus_match_t )(const struct rte_bus *bus,const void *data); + +/** +* Bus iterator to find a particular bus. +* +* If the callback returns non-zero this function will stop iterating over +* any more buses. +* +* @param match +* Callback function to check bus +* +* @param data +* Data to pass to match callback +* +* @return +* A pointer to a rte_bus structure or NULL in case no bus matches +*/ +struct rte_bus *rte_bus_find (rte_bus_match_t match,const void *data); + +/** * Helper for Bus registration. * The constructor has higher priority than PMD constructors. */ lib/librte_eal/linuxapp/eal/rte_eal_version.map +1
-0@@ -166,6 +166,7 @@ DPDK_17.02 { DPDK_17.05 { global: + rte_bus_find; rte_cpu_is_supported; rte_intr_free_epoll_fd; rte_log_dump;
Re: [PATCH v2 01/11] bus: add bus iterator to find a particular bus
Quoted 75 lines · Shreyansh Jain
Hello Gaetan,
Quoted 51 lines · Gaetan Rivet
From: Jan Blunck <[email protected]>
Signed-off-by Jan Blunck <[email protected]>Signed-off-by Gaetan Rivet <[email protected]>--- lib/librte_eal/bsdapp/eal/rte_eal_version.map | 1 + lib/librte_eal/common/eal_common_bus.c | 13 ++++++++++ lib/librte_eal/common/include/rte_bus.h | 32 +++++++++++++++++++++++++ lib/librte_eal/linuxapp/eal/rte_eal_version.map | 1 + 4 files changed, 47 insertions(+)lib/librte_eal/bsdapp/eal/rte_eal_version.map +1
-0@@ -162,6 +162,7 @@ DPDK_17.02 { DPDK_17.05 { global: + rte_bus_find; rte_cpu_is_supported; rte_log_dump; rte_log_register;lib/librte_eal/common/eal_common_bus.c +13
-0@@ -145,3 +145,16 @@ rte_bus_dump(FILE *f) } } } + +struct rte_bus * +rte_bus_find (rte_bus_match_t match,const void *data) +{ +struct rte_bus *bus =NULL ; + + TAILQ_FOREACH(bus, &rte_bus_list, next) { +if (match (bus, data)) +break ; + } + +return bus; +}lib/librte_eal/common/include/rte_bus.h +1
-0@@ -141,6 +141,38 @@ int rte_bus_probe(void);void rte_bus_dump (FILE *f);/** +* Bus match function. lib/librte_eal/common/include/rte_bus.h int rte_bus_probe(void); · line 153
Quoted 10 lines
lib/librte_eal/common/include/rte_bus.h +10
-0+* +* @param bus +* bus under test. +* +* @param data +* data matched +* +* @return +* 0 if the bus does not match. +* !0 if the bus matches. One of the common match function implementation could be simply to match a string. strcmp itself returns '0' for a successful match. On the same lines, should this function return value be reversed? -
0 if match
!0 if not a match
-
That way, people would not have to change either the way strcmp works, for example, or the way various APIs expect '0' as success.
Quoted 2 lines
same for
rte_device_match_tas well. (in next patch)
It was actually a point I hesitated a little before submitting this version.
The logic behind strcmp is that you can express three states: greater than, equal, lower than, thus having total order within the string set.
Here, buses are not ordered (logically). Having a bus lower or greater than some arbitrary data does not mean much.
Anyway, this was my reasoning for following Jan's proposal on this, but I'm not against changing this API. Maybe having to possibility to express total order could be useful eventually. I don't have a strong opinion on this so unless someone shouts about it, I will follow your remark.
Quoted 36 lines
Quoted 36 lines
lib/librte_eal/common/include/rte_bus.h +21
-0+*/ +typedef int (*rte_bus_match_t )(const struct rte_bus *bus,const void *data); + +/** +* Bus iterator to find a particular bus. +* +* If the callback returns non-zero this function will stop iterating over +* any more buses. +* +* @param match +* Callback function to check bus +* +* @param data +* Data to pass to match callback +* +* @return +* A pointer to a rte_bus structure or NULL in case no bus matches +*/ +struct rte_bus *rte_bus_find (rte_bus_match_t match,const void *data); + +/** * Helper for Bus registration. * The constructor has higher priority than PMD constructors. */ lib/librte_eal/linuxapp/eal/rte_eal_version.map +1
-0@@ -166,6 +166,7 @@ DPDK_17.02 { DPDK_17.05 { global: + rte_bus_find; rte_cpu_is_supported; rte_intr_free_epoll_fd; rte_log_dump;
Signature · 2 lines
Gaëtan Rivet 6WIND
Re: [PATCH v2 01/11] bus: add bus iterator to find a particular bus
Quoted 39 lines · Gaëtan Rivet
Quoted 29 lines · Shreyansh Jain
Quoted 8 lines
lib/librte_eal/common/include/rte_bus.h +1
-0@@ -141,6 +141,38 @@ int rte_bus_probe(void);void rte_bus_dump (FILE *f);/** +* Bus match function. lib/librte_eal/common/include/rte_bus.h int rte_bus_probe(void); · line 153
Quoted 10 lines
lib/librte_eal/common/include/rte_bus.h +10
-0+* +* @param bus +* bus under test. +* +* @param data +* data matched +* +* @return +* 0 if the bus does not match. +* !0 if the bus matches. One of the common match function implementation could be simply to match a string. strcmp itself returns '0' for a successful match. On the same lines, should this function return value be reversed? -
0 if match
!0 if not a match
-
That way, people would not have to change either the way strcmp works, for example, or the way various APIs expect '0' as success.Quoted 2 lines
same for
rte_device_match_tas well. (in next patch)It was actually a point I hesitated a little before submitting this version.
The logic behind strcmp is that you can express three states: greater than, equal, lower than, thus having total order within the string set.
Quoted 9 lines
Here, buses are not ordered (logically). Having a bus lower or greater than some arbitrary data does not mean much.
Anyway, this was my reasoning for following Jan's proposal on this, but I'm not against changing this API. Maybe having to possibility to express total order could be useful eventually. I don't have a strong opinion on this so unless someone shouts about it, I will follow your remark.
It is better to have consistency on the match/comparator behavior. Also if it comes as a surprise to users lets change it.
Re: [PATCH v2 01/11] bus: add bus iterator to find a particular bus
In reply to Gaëtan RivetHello Gaëtan,
Quoted 93 lines
-----Original Message-----
From: Gaëtan Rivet [mailto:[email protected]]
Sent: Wednesday, June 07, 2017 6:58 PM
To: Shreyansh Jain <[email protected]>
Cc: [email protected]; Jan Blunck <[email protected]>
Subject: Re: [PATCH v2 01/11] bus: add bus iterator to find a particular busQuoted 11 lines · Shreyansh Jain
Hello Gaetan,
Quoted 8 lines · Gaetan Rivet
From: Jan Blunck <[email protected]>
Signed-off-by Jan Blunck <[email protected]>Signed-off-by Gaetan Rivet <[email protected]>--- lib/librte_eal/bsdapp/eal/rte_eal_version.map | 1 + lib/librte_eal/common/eal_common_bus.c | 13 ++++++++++ lib/librte_eal/common/include/rte_bus.h | 32+++++++++++++++++++++++++
Quoted 4 lines
Review
Quoted 4 lines
lib/librte_eal/linuxapp/eal/rte_eal_version.map | 1 + 4 files changed, 47 insertions(+)(quoted diff) +0
-0b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
Quoted 11 lines
Review
Quoted 11 lines
index 2e48a73..ed09ab2 100644
lib/librte_eal/bsdapp/eal/rte_eal_version.map +1
-0@@ -162,6 +162,7 @@ DPDK_17.02 { DPDK_17.05 { global: + rte_bus_find; rte_cpu_is_supported; rte_log_dump; rte_log_register;(quoted diff) +0
-0
b/lib/librte_eal/common/eal_common_bus.cQuoted 13 lines
Quoted 13 lines
index 8f9baf8..68f70d0 100644
lib/librte_eal/common/eal_common_bus.c +6
-0@@ -145,3 +145,16 @@ rte_bus_dump(FILE *f) } } } + +struct rte_bus * +rte_bus_find (rte_bus_match_t match,const void *data) +{ +struct rte_bus *bus =NULL ; +Quoted 8 lines
Review
Quoted 8 lines
lib/librte_eal/common/eal_common_bus.c +7
-0+ TAILQ_FOREACH(bus, &rte_bus_list, next) { +if (match (bus, data)) +break ; + } + +return bus; +}(quoted diff) +0
-0
b/lib/librte_eal/common/include/rte_bus.hQuoted 28 lines
Quoted 7 lines
index 7c36969..006feca 100644
lib/librte_eal/common/include/rte_bus.h +1
-0@@ -141,6 +141,38 @@ int rte_bus_probe(void);void rte_bus_dump (FILE *f);/** +* Bus match function. lib/librte_eal/common/include/rte_bus.h int rte_bus_probe(void); · line 153
Quoted 10 lines
lib/librte_eal/common/include/rte_bus.h +10
-0+* +* @param bus +* bus under test. +* +* @param data +* data matched +* +* @return +* 0 if the bus does not match. +* !0 if the bus matches. One of the common match function implementation could be simply to match a string. strcmp itself returns '0' for a successful match. On the same lines, should this function return value be reversed? -
0 if match
!0 if not a match
-
That way, people would not have to change either the way strcmp works, for example, or the way various APIs expect '0' as success.Quoted 2 lines
same for
rte_device_match_tas well. (in next patch)It was actually a point I hesitated a little before submitting this version.
Quoted 5 lines
The logic behind strcmp is that you can express three states: greater than, equal, lower than, thus having total order within the string set.
Here, buses are not ordered (logically). Having a bus lower or greater than some arbitrary data does not mean much.
I agree about the match() fn - but, this is not what I meant. My point was that ideally for implementation of callbacks, applications would more often use the strcmp function (matching name of the bus) than the match() callback.
Further, this semantic is being followed by other DPDK APIs as well - so, my intent was to make this also inline with those.
Quoted 6 lines
Anyway, this was my reasoning for following Jan's proposal on this, but I'm not against changing this API. Maybe having to possibility to express total order could be useful eventually. I don't have a strong opinion on this so unless someone shouts about it, I will follow your remark.
Thank you!
Quoted 1 line
<...snip...>
Re: [PATCH v2 01/11] bus: add bus iterator to find a particular bus
Quoted 101 lines · Shreyansh Jain
Hello Gaëtan,
Quoted 93 lines
-----Original Message-----
From: Gaëtan Rivet [mailto:[email protected]]
Sent: Wednesday, June 07, 2017 6:58 PM
To: Shreyansh Jain <[email protected]>
Cc: [email protected]; Jan Blunck <[email protected]>
Subject: Re: [PATCH v2 01/11] bus: add bus iterator to find a particular busQuoted 11 lines · Shreyansh Jain
Hello Gaetan,
Quoted 8 lines · Gaetan Rivet
From: Jan Blunck <[email protected]>
Signed-off-by Jan Blunck <[email protected]>Signed-off-by Gaetan Rivet <[email protected]>--- lib/librte_eal/bsdapp/eal/rte_eal_version.map | 1 + lib/librte_eal/common/eal_common_bus.c | 13 ++++++++++ lib/librte_eal/common/include/rte_bus.h | 32+++++++++++++++++++++++++
Quoted 4 lines
Review
Quoted 4 lines
lib/librte_eal/linuxapp/eal/rte_eal_version.map | 1 + 4 files changed, 47 insertions(+)(quoted diff) +0
-0b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
Quoted 11 lines
Review
Quoted 11 lines
index 2e48a73..ed09ab2 100644
lib/librte_eal/bsdapp/eal/rte_eal_version.map +1
-0@@ -162,6 +162,7 @@ DPDK_17.02 { DPDK_17.05 { global: + rte_bus_find; rte_cpu_is_supported; rte_log_dump; rte_log_register;(quoted diff) +0
-0
b/lib/librte_eal/common/eal_common_bus.cQuoted 13 lines
Quoted 13 lines
index 8f9baf8..68f70d0 100644
lib/librte_eal/common/eal_common_bus.c +6
-0@@ -145,3 +145,16 @@ rte_bus_dump(FILE *f) } } } + +struct rte_bus * +rte_bus_find (rte_bus_match_t match,const void *data) +{ +struct rte_bus *bus =NULL ; +Quoted 8 lines
Review
Quoted 8 lines
lib/librte_eal/common/eal_common_bus.c +7
-0+ TAILQ_FOREACH(bus, &rte_bus_list, next) { +if (match (bus, data)) +break ; + } + +return bus; +}(quoted diff) +0
-0
b/lib/librte_eal/common/include/rte_bus.hQuoted 28 lines
Quoted 7 lines
index 7c36969..006feca 100644
lib/librte_eal/common/include/rte_bus.h +1
-0@@ -141,6 +141,38 @@ int rte_bus_probe(void);void rte_bus_dump (FILE *f);/** +* Bus match function. lib/librte_eal/common/include/rte_bus.h int rte_bus_probe(void); · line 153
Quoted 10 lines
lib/librte_eal/common/include/rte_bus.h +10
-0+* +* @param bus +* bus under test. +* +* @param data +* data matched +* +* @return +* 0 if the bus does not match. +* !0 if the bus matches. One of the common match function implementation could be simply to match a string. strcmp itself returns '0' for a successful match. On the same lines, should this function return value be reversed? -
0 if match
!0 if not a match
-
That way, people would not have to change either the way strcmp works, for example, or the way various APIs expect '0' as success.Quoted 2 lines
same for
rte_device_match_tas well. (in next patch)It was actually a point I hesitated a little before submitting this version.
Quoted 5 lines
The logic behind strcmp is that you can express three states: greater than, equal, lower than, thus having total order within the string set.
Here, buses are not ordered (logically). Having a bus lower or greater than some arbitrary data does not mean much.
Quoted 8 lines
I agree about the
match()fn - but, this is not what I meant. My point was that ideally for implementation of callbacks, applications would more often use the strcmp function (matching name of the bus) than thematch()callback.Further, this semantic is being followed by other DPDK APIs as well - so, my intent was to make this also inline with those.
Ah, I see your point now. It makes sense.
The API is now the same.
Quoted 11 lines
Quoted 6 lines
Anyway, this was my reasoning for following Jan's proposal on this, but I'm not against changing this API. Maybe having to possibility to express total order could be useful eventually. I don't have a strong opinion on this so unless someone shouts about it, I will follow your remark.
Thank you!
Quoted 1 line
<...snip...>
Signature · 2 lines
Gaëtan Rivet 6WIND
PATCH v2 2/11 bus: add device iterator
In reply to Gaetan RivetFrom: Jan Blunck <[email protected]>
--- lib/librte_eal/common/include/rte_bus.h | 7 +++++++ lib/librte_eal/common/include/rte_dev.h | 15 +++++++++++++++ 2 files changed, 22 insertions(+)
lib/librte_eal/common/include/rte_bus.h +7 -0
@@ -82,6 +82,12 @@ typedef int (*rte_bus_scan_t)(void);typedef int (*rte_bus_probe_t )(void );/** +* Device iterator to find a particular device on a bus. +*/ +typedef struct rte_device * (*rte_bus_find_device_t )(rte_dev_match_t match, +const void *data); + +/** * A structure describing a generic bus. */ struct rte_bus {
@@ -89,6 +95,7 @@ struct rte_bus {const char *name;/**< Name of the bus */ rte_bus_scan_t scan;/**< Scan for devices attached to bus */ rte_bus_probe_t probe;/**< Probe devices on bus */ +rte_bus_find_device_t find_device;/**< Find device on bus */ };/**
lib/librte_eal/common/include/rte_dev.h +15 -0
@@ -191,6 +191,21 @@ int rte_eal_dev_attach(const char *name, const char *devargs);*/ int rte_eal_dev_detach (const char *name); +/** +* Device match function. +* +* @param dev +* Device handle. +* +* @param data +* Data to match against. +* +* @return +* 0 if the device does not match. +* !0 otherwise. +*/ +typedef int (*rte_dev_match_t )(const struct rte_device *dev,const void *data); +#define RTE_PMD_EXPORT_NAME_ARRAY (n, idx) n##idx[]#define RTE_PMD_EXPORT_NAME (name, idx) \
Signature · 1 line
2.1.4
PATCH v2 3/11 bus: add helper to find bus for a particular device
In reply to Gaetan RivetFrom: Jan Blunck <[email protected]>
--- lib/librte_eal/bsdapp/eal/rte_eal_version.map | 1 + lib/librte_eal/common/eal_common_bus.c | 24 ++++++++++++++++++++++++ lib/librte_eal/common/include/rte_bus.h | 5 +++++ lib/librte_eal/linuxapp/eal/rte_eal_version.map | 1 + 4 files changed, 31 insertions(+)
lib/librte_eal/bsdapp/eal/rte_eal_version.map +1 -0
@@ -163,6 +163,7 @@ DPDK_17.05 { global: rte_bus_find; + rte_bus_find_by_device; rte_cpu_is_supported; rte_log_dump; rte_log_register;
lib/librte_eal/common/eal_common_bus.c +24 -0
@@ -158,3 +158,27 @@ rte_bus_find(rte_bus_match_t match, const void *data)return bus; } + +static int +cmp_rte_device (const struct rte_device *dev,const void *_dev2) +{ +const struct rte_device *dev2 = _dev2; + +return dev == dev2; +} + +static int +bus_find_device (const struct rte_bus *bus,const void *_dev) +{ +struct rte_device *dev; + +if (!bus->find_device) +return 0 ; + dev = bus->find_device (cmp_rte_device, _dev); +return !!dev; +} + +struct rte_bus *rte_bus_find_by_device (const struct rte_device *dev) +{ +return rte_bus_find (bus_find_device, (const void *)dev); +}
lib/librte_eal/common/include/rte_bus.h +5 -0
@@ -180,6 +180,11 @@ typedef int (*rte_bus_match_t)(const struct rte_bus *bus, const void *data);struct rte_bus *rte_bus_find (rte_bus_match_t match,const void *data);/** +* Find the registered bus for a particular device. +*/ +struct rte_bus *rte_bus_find_by_device (const struct rte_device *dev); + +/** * Helper for Bus registration. * The constructor has higher priority than PMD constructors. */
lib/librte_eal/linuxapp/eal/rte_eal_version.map +1 -0
@@ -167,6 +167,7 @@ DPDK_17.05 { global: rte_bus_find; + rte_bus_find_by_device; rte_cpu_is_supported; rte_intr_free_epoll_fd; rte_log_dump;
Signature · 1 line
2.1.4
PATCH v2 4/11 bus: add bus helper iterator to find a particular device
In reply to Gaetan RivetFrom: Jan Blunck <[email protected]>
--- lib/librte_eal/bsdapp/eal/rte_eal_version.map | 1 + lib/librte_eal/common/eal_common_bus.c | 25 +++++++++++++++++++++++++ lib/librte_eal/common/include/rte_bus.h | 23 +++++++++++++++++++++++ lib/librte_eal/linuxapp/eal/rte_eal_version.map | 1 + 4 files changed, 50 insertions(+)
lib/librte_eal/bsdapp/eal/rte_eal_version.map +1 -0
@@ -164,6 +164,7 @@ DPDK_17.05 { rte_bus_find; rte_bus_find_by_device; + rte_bus_find_device; rte_cpu_is_supported; rte_log_dump; rte_log_register;
lib/librte_eal/common/eal_common_bus.c +25 -0
@@ -182,3 +182,28 @@ struct rte_bus *rte_bus_find_by_device(const struct rte_device *dev) {return rte_bus_find (bus_find_device, (const void *)dev); } + +struct rte_device * +rte_bus_find_device (const struct rte_device *start, +rte_dev_match_t match,const void *data) +{ +struct rte_bus *bus; +struct rte_device *dev =NULL ; +int start_seen =0 ; + + TAILQ_FOREACH(bus, &rte_bus_list, next) { +if (!bus->find_device) +continue ; +if (!!start ^ start_seen) { + dev = bus->find_device (cmp_rte_device, start); +if (dev) + start_seen =1 ; +else +continue ; + } + dev = bus->find_device (match, data); +if (dev) +break ; + } +return dev; +}
lib/librte_eal/common/include/rte_bus.h +23 -0
@@ -180,6 +180,29 @@ typedef int (*rte_bus_match_t)(const struct rte_bus *bus, const void *data);struct rte_bus *rte_bus_find (rte_bus_match_t match,const void *data);/** +* Bus iterator to find a particular device. +* +* If the callback returns non-zero this function will stop iterating over any +* more buses and devices. To continue a search the device of a previous search +* is passed via the start parameters. +* +* @param start +* Start device of the iteration +* +* @param match +* Callback function to check device +* +* @param data +* Data to pass to match callback +* +* @return +* A pointer to a rte_bus structure or NULL in case no bus matches +*/ +struct rte_device * +rte_bus_find_device (const struct rte_device *start, +rte_dev_match_t match,const void *data); + +/** * Find the registered bus for a particular device. */ struct rte_bus *rte_bus_find_by_device (const struct rte_device *dev);
lib/librte_eal/linuxapp/eal/rte_eal_version.map +1 -0
@@ -168,6 +168,7 @@ DPDK_17.05 { rte_bus_find; rte_bus_find_by_device; + rte_bus_find_device; rte_cpu_is_supported; rte_intr_free_epoll_fd; rte_log_dump;
Signature · 1 line
2.1.4
Re: [PATCH v2 04/11] bus: add bus helper iterator to find a particular device
Quoted 31 lines · Gaetan Rivet
From: Jan Blunck <[email protected]>
Signed-off-by Jan Blunck <[email protected]>Signed-off-by Gaetan Rivet <[email protected]>--- lib/librte_eal/bsdapp/eal/rte_eal_version.map | 1 + lib/librte_eal/common/eal_common_bus.c | 25 +++++++++++++++++++++++++ lib/librte_eal/common/include/rte_bus.h | 23 +++++++++++++++++++++++ lib/librte_eal/linuxapp/eal/rte_eal_version.map | 1 + 4 files changed, 50 insertions(+)lib/librte_eal/bsdapp/eal/rte_eal_version.map +1
-0@@ -164,6 +164,7 @@ DPDK_17.05 { rte_bus_find; rte_bus_find_by_device; + rte_bus_find_device; rte_cpu_is_supported; rte_log_dump; rte_log_register;lib/librte_eal/common/eal_common_bus.c +0
-0@@ -182,3 +182,28 @@ struct rte_bus *rte_bus_find_by_device(const struct rte_device *dev) {return rte_bus_find (bus_find_device, (const void *)dev); }
lib/librte_eal/common/eal_common_bus.c struct rte_bus *rte_bus_find_by_device(const struct rte_device *dev) · line 194
Quoted 10 lines
lib/librte_eal/common/eal_common_bus.c +10
-0+ +struct rte_device * +rte_bus_find_device (const struct rte_device *start, +rte_dev_match_t match,const void *data) +{ +struct rte_bus *bus; +struct rte_device *dev =NULL ; +int start_seen =0 ; + + TAILQ_FOREACH(bus, &rte_bus_list, next) {
I don't think that this should use the TAILQ_FOREACH() macro since it makes the code nesting deeper unnecessarily.
Quoted 64 lines
lib/librte_eal/common/eal_common_bus.c +15
-0+if (!bus->find_device) +continue ; +if (!!start ^ start_seen) { + dev = bus->find_device (cmp_rte_device, start); +if (dev) + start_seen =1 ; +else +continue ; + } + dev = bus->find_device (match, data); +if (dev) +break ; + } +return dev; +}lib/librte_eal/common/include/rte_bus.h +23
-0@@ -180,6 +180,29 @@ typedef int (*rte_bus_match_t)(const struct rte_bus *bus, const void *data);struct rte_bus *rte_bus_find (rte_bus_match_t match,const void *data);/** +* Bus iterator to find a particular device. +* +* If the callback returns non-zero this function will stop iterating over any +* more buses and devices. To continue a search the device of a previous search +* is passed via the start parameters. +* +* @param start +* Start device of the iteration +* +* @param match +* Callback function to check device +* +* @param data +* Data to pass to match callback +* +* @return +* A pointer to a rte_bus structure or NULL in case no bus matches +*/ +struct rte_device * +rte_bus_find_device (const struct rte_device *start, +rte_dev_match_t match,const void *data); + +/** * Find the registered bus for a particular device. */ struct rte_bus *rte_bus_find_by_device (const struct rte_device *dev);lib/librte_eal/linuxapp/eal/rte_eal_version.map +1
-1@@ -168,6 +168,7 @@ DPDK_17.05 { rte_bus_find; rte_bus_find_by_device; + rte_bus_find_device; rte_cpu_is_supported; rte_intr_free_epoll_fd; rte_log_dump; --2.1.4
Re: [PATCH v2 04/11] bus: add bus helper iterator to find a particular device
Quoted 37 lines · Jan Blunck
Quoted 36 lines · Gaetan Rivet
From: Jan Blunck <[email protected]>
Signed-off-by Jan Blunck <[email protected]>Signed-off-by Gaetan Rivet <[email protected]>--- lib/librte_eal/bsdapp/eal/rte_eal_version.map | 1 + lib/librte_eal/common/eal_common_bus.c | 25 +++++++++++++++++++++++++ lib/librte_eal/common/include/rte_bus.h | 23 +++++++++++++++++++++++ lib/librte_eal/linuxapp/eal/rte_eal_version.map | 1 + 4 files changed, 50 insertions(+)lib/librte_eal/bsdapp/eal/rte_eal_version.map +1
-0@@ -164,6 +164,7 @@ DPDK_17.05 { rte_bus_find; rte_bus_find_by_device; + rte_bus_find_device; rte_cpu_is_supported; rte_log_dump; rte_log_register;lib/librte_eal/common/eal_common_bus.c +5
-0@@ -182,3 +182,28 @@ struct rte_bus *rte_bus_find_by_device(const struct rte_device *dev) {return rte_bus_find (bus_find_device, (const void *)dev); } + +struct rte_device * +rte_bus_find_device (const struct rte_device *start, +rte_dev_match_t match,const void *data) +{
Quoted 10 lines
lib/librte_eal/common/eal_common_bus.c struct rte_bus *rte_bus_find_by_device(const struct rte_device *dev) · line 194
Quoted 5 lines
lib/librte_eal/common/eal_common_bus.c +5
-0+struct rte_bus *bus; +struct rte_device *dev =NULL ; +int start_seen =0 ; + + TAILQ_FOREACH(bus, &rte_bus_list, next) {I don't think that this should use the
TAILQ_FOREACH()macro since it makes the code nesting deeper unnecessarily.
While debugging the previous version, I found rather difficult to follow the nesting of iterators / callback calls.
I preferred laying all of it down and simplifying the flow. The nesting is either within the same scope or divided among several scopes. I proposed the former as I found it easier to write and read, but that's subjective.
Quoted 64 lines
Quoted 64 lines
lib/librte_eal/common/eal_common_bus.c +15
-0+if (!bus->find_device) +continue ; +if (!!start ^ start_seen) { + dev = bus->find_device (cmp_rte_device, start); +if (dev) + start_seen =1 ; +else +continue ; + } + dev = bus->find_device (match, data); +if (dev) +break ; + } +return dev; +}lib/librte_eal/common/include/rte_bus.h +23
-0@@ -180,6 +180,29 @@ typedef int (*rte_bus_match_t)(const struct rte_bus *bus, const void *data);struct rte_bus *rte_bus_find (rte_bus_match_t match,const void *data);/** +* Bus iterator to find a particular device. +* +* If the callback returns non-zero this function will stop iterating over any +* more buses and devices. To continue a search the device of a previous search +* is passed via the start parameters. +* +* @param start +* Start device of the iteration +* +* @param match +* Callback function to check device +* +* @param data +* Data to pass to match callback +* +* @return +* A pointer to a rte_bus structure or NULL in case no bus matches +*/ +struct rte_device * +rte_bus_find_device (const struct rte_device *start, +rte_dev_match_t match,const void *data); + +/** * Find the registered bus for a particular device. */ struct rte_bus *rte_bus_find_by_device (const struct rte_device *dev);lib/librte_eal/linuxapp/eal/rte_eal_version.map +1
-1@@ -168,6 +168,7 @@ DPDK_17.05 { rte_bus_find; rte_bus_find_by_device; + rte_bus_find_device; rte_cpu_is_supported; rte_intr_free_epoll_fd; rte_log_dump; --2.1.4
Signature · 2 lines
Gaëtan Rivet 6WIND
PATCH v2 5/11 bus: introduce hotplug functionality
In reply to Gaetan RivetFrom: Jan Blunck <[email protected]>
--- lib/librte_eal/common/eal_common_bus.c | 3 +++ lib/librte_eal/common/include/rte_bus.h | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+)
lib/librte_eal/common/eal_common_bus.c +3 -0
@@ -51,6 +51,9 @@ rte_bus_register(struct rte_bus *bus)RTE_VERIFY (bus->scan);RTE_VERIFY (bus->probe); +/* Buses supporting hotplug also require unplug */ +RTE_VERIFY (!bus->plug || bus->unplug); +TAILQ_INSERT_TAIL (&rte_bus_list, bus, next);RTE_LOG (DEBUG ,EAL ,"Registered [%s] bus.\n" , bus->name); }
lib/librte_eal/common/include/rte_bus.h +20 -0
@@ -88,6 +88,24 @@ typedef struct rte_device * (*rte_bus_find_device_t)(rte_dev_match_t match, const void *data);/** +* Implementation specific probe function which is responsible for linking +* devices on that bus with applicable drivers. +* The plugged device might already have been used previously by the bus, +* in which case some buses might prefer to detect and re-use the relevant +* information pertaining to this device. +*/ +typedef int (*rte_bus_plug_t )(struct rte_devargs *da); + +/** +* Implementation specific remove function which is responsible for unlinking +* devices on that bus from assigned driver. +* Some buses will expect the same device to be plugged-back in eventually. +* The decision to release the associated meta-data (full-fledged bus-specific +* device representation) is left to the discretion of the bus. +*/ +typedef int (*rte_bus_unplug_t )(struct rte_devargs *da); + +/** * A structure describing a generic bus. */ struct rte_bus {
@@ -96,6 +114,8 @@ struct rte_bus {rte_bus_scan_t scan;/**< Scan for devices attached to bus */ rte_bus_probe_t probe;/**< Probe devices on bus */ rte_bus_find_device_t find_device;/**< Find device on bus */ +rte_bus_plug_t plug;/**< Probe single device for drivers */ +rte_bus_unplug_t unplug;/**< Remove single device from driver */ };/**
Signature · 1 line
2.1.4
PATCH v2 6/11 vdev: implement find_device bus operation
In reply to Gaetan RivetFrom: Jan Blunck <[email protected]>
--- lib/librte_eal/common/eal_common_vdev.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
lib/librte_eal/common/eal_common_vdev.c +13 -0
@@ -338,9 +338,22 @@ vdev_probe(void)return 0 ; } +static struct rte_device * +vdev_find_device (rte_dev_match_t match,const void *data) +{ +struct rte_vdev_device *dev; + + TAILQ_FOREACH(dev, &vdev_device_list, next) { +if (match (&dev->device, data)) +return &dev->device; + } +return NULL ; +} +static struct rte_bus rte_vdev_bus = { .scan = vdev_scan, .probe = vdev_probe, + .find_device = vdev_find_device, };RTE_INIT (rte_vdev_bus_register);
Signature · 1 line
2.1.4
PATCH v2 7/11 vdev: implement hotplug functionality
In reply to Gaetan Rivet--- lib/librte_eal/common/eal_common_vdev.c | 7 +++++++ 1 file changed, 7 insertions(+)
lib/librte_eal/common/eal_common_vdev.c +7 -0
@@ -350,10 +350,17 @@ vdev_find_device(rte_dev_match_t match, const void *data)return NULL ; } +static int +vdev_plug (struct rte_devargs *da) +{ +return rte_vdev_init (da->virt.drv_name, da->args); +} +static struct rte_bus rte_vdev_bus = { .scan = vdev_scan, .probe = vdev_probe, .find_device = vdev_find_device, + .plug = vdev_plug, };RTE_INIT (rte_vdev_bus_register);
Signature · 1 line
2.1.4
PATCH v2 8/11 vdev: implement unplug bus operation
In reply to Gaetan RivetFrom: Jan Blunck <[email protected]>
--- lib/librte_eal/common/eal_common_vdev.c | 7 +++++++ 1 file changed, 7 insertions(+)
lib/librte_eal/common/eal_common_vdev.c +7 -0
@@ -356,11 +356,18 @@ vdev_plug(struct rte_devargs *da)return rte_vdev_init (da->virt.drv_name, da->args); } +static int +vdev_unplug (struct rte_devargs *da) +{ +return rte_vdev_uninit (da->virt.drv_name); +} +static struct rte_bus rte_vdev_bus = { .scan = vdev_scan, .probe = vdev_probe, .find_device = vdev_find_device, .plug = vdev_plug, + .unplug = vdev_unplug, };RTE_INIT (rte_vdev_bus_register);
Signature · 1 line
2.1.4
PATCH v2 9/11 eal: make virtual driver probe and remove take rte_vdev_device
In reply to Gaetan RivetFrom: Jan Blunck <[email protected]>
This is a preparation to embed the generic rte_device into the rte_eth_dev also for virtual devices.
--- lib/librte_eal/common/eal_common_dev.c | 93 ++++++++++++++++++++++++++-------- 1 file changed, 71 insertions(+), 22 deletions(-)
lib/librte_eal/common/eal_common_dev.c +71 -22
@@ -37,6 +37,7 @@#include <inttypes.h> #include <sys/queue.h> +#include <rte_bus.h> #include <rte_dev.h> #include <rte_devargs.h> #include <rte_debug.h>
@@ -45,50 +46,98 @@#include "eal_private.h" +static int cmp_detached_dev_name (const struct rte_device *dev, +const void *_name) +{ +const char *name = _name; + +/* skip attached devices */ +if (dev->driver) +return 0 ; + +return !strcmp (dev->name, name); +} +int rte_eal_dev_attach (const char *name,const char *devargs) { -struct rte_pci_addr addr; +struct rte_device *dev; +int ret;if (name ==NULL || devargs ==NULL ) {RTE_LOG (ERR ,EAL ,"Invalid device or arguments provided\n" );return -EINVAL ; } -if (eal_parse_pci_DomBDF (name, &addr) ==0 ) { -if (rte_pci_probe_one (&addr) <0 ) - goto err; + dev =rte_bus_find_device (NULL , cmp_detached_dev_name, name); +if (dev) { +struct rte_bus *bus; + + bus =rte_bus_find_by_device (dev); +if (!bus) { +RTE_LOG (ERR ,EAL ,"Cannot find bus for device (%s)\n" , + name); +return -EINVAL ; + } - }else { -if (rte_vdev_init (name, devargs)) - goto err; +if (!bus->plug) { +RTE_LOG (ERR ,EAL ,"Bus function not supported\n" ); +return -ENOTSUP ; + } + + ret = bus->plug (dev->devargs); + goto out; } -return 0 ; +/* +* If we haven't found a bus device the user meant to "hotplug" a +* virtual device instead. +*/ + ret =rte_vdev_init (name, devargs); +out: +if (ret) +RTE_LOG (ERR ,EAL ,"Driver cannot attach the device (%s)\n" , + name); +return ret; +} + +static int cmp_dev_name (const struct rte_device *dev,const void *_name) +{ +const char *name = _name; -err: -RTE_LOG (ERR ,EAL ,"Driver cannot attach the device (%s)\n" , name); -return -EINVAL ; +return !strcmp (dev->name, name); }int rte_eal_dev_detach (const char *name) { -struct rte_pci_addr addr; +struct rte_device *dev; +struct rte_bus *bus; +int ret;if (name ==NULL ) {RTE_LOG (ERR ,EAL ,"Invalid device provided.\n" );return -EINVAL ; } -if (eal_parse_pci_DomBDF (name, &addr) ==0 ) { -if (rte_pci_detach (&addr) <0 ) - goto err; - }else { -if (rte_vdev_uninit (name)) - goto err; + dev =rte_bus_find_device (NULL , cmp_dev_name, name); +if (!dev) { +RTE_LOG (ERR ,EAL ,"Cannot find device (%s)\n" , name); +return -EINVAL ; + } + + bus =rte_bus_find_by_device (dev); +if (!bus) { +RTE_LOG (ERR ,EAL ,"Cannot find bus for device (%s)\n" , name); +return -EINVAL ; + } + +if (!bus->unplug) { +RTE_LOG (ERR ,EAL ,"Bus function not supported\n" ); +return -ENOTSUP ; } -return 0 ; -err: -RTE_LOG (ERR ,EAL ,"Driver cannot detach the device (%s)\n" , name); -return -EINVAL ; + ret = bus->unplug (dev->devargs); +if (ret) +RTE_LOG (ERR ,EAL ,"Driver cannot detach the device (%s)\n" , + name); +return ret; }
Signature · 1 line
2.1.4
PATCH v2 10/11 ethdev: Use embedded rte_device to detach driver
In reply to Gaetan RivetFrom: Jan Blunck <[email protected]>
--- lib/librte_eal/bsdapp/eal/rte_eal_version.map | 1 + lib/librte_eal/common/eal_common_dev.c | 43 ++++++++++++++++----------- lib/librte_eal/common/include/rte_dev.h | 11 +++++++ lib/librte_ether/rte_ethdev.c | 3 +- 4 files changed, 39 insertions(+), 19 deletions(-)
lib/librte_eal/bsdapp/eal/rte_eal_version.map +1 -0
@@ -162,6 +162,7 @@ DPDK_17.02 { DPDK_17.05 { global: + rte_eal_device_detach; rte_bus_find; rte_bus_find_by_device; rte_bus_find_device;
lib/librte_eal/common/eal_common_dev.c +25 -18
59 lines not on this page · raw message
lib/librte_eal/common/include/rte_dev.h +11 -0
@@ -123,6 +123,17 @@ struct rte_mem_resource {void *addr;/**< Virtual address, NULL when not mapped. */ }; +/* FIXME: Forward declare */ +struct rte_device ; + +/** +* Unplug the device from the device driver. +* +* @param dev +* A pointer to a rte_device structure. +*/ +int rte_eal_device_detach (struct rte_device *dev); +/** * A structure describing a device driver. */
lib/librte_ether/rte_ethdev.c +2 -1
@@ -440,7 +440,8 @@ rte_eth_dev_detach(uint8_t port_id, char *name)snprintf (name,sizeof (rte_eth_devices[port_id].data->name),"%s" , rte_eth_devices[port_id].data->name); - ret =rte_eal_dev_detach (name); + + ret =rte_eal_device_detach (rte_eth_devices[0 ].device);if (ret <0 ) goto err;
Signature · 1 line
2.1.4
PATCH v2 11/11 net/ring: fix dev handle in eth_dev
In reply to Gaetan RivetThe ring PMD uses special eth_dev allocators, which cannot be updated to accept an rte_vdev_device.
Circumvent the limitation and store the rte_device handle in the rte_eth_dev structure.
vdev")
Cc: [email protected]
--- drivers/net/ring/rte_eth_ring.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/net/ring/rte_eth_ring.c +7 -0
@@ -515,6 +515,8 @@ rte_pmd_ring_probe(struct rte_vdev_device *dev)RTE_LOG (INFO ,PMD ,"Initializing pmd_ring for %s\n" , name);if (params ==NULL || params[0 ] =='\0' ) { +struct rte_eth_dev *eth_dev; + ret =eth_dev_ring_create (name,rte_socket_id (),DEV_CREATE );if (ret ==-1 ) { RTE_LOG(INFO, PMD,
@@ -522,6 +524,11 @@ rte_pmd_ring_probe(struct rte_vdev_device *dev) ret =eth_dev_ring_create (name,rte_socket_id (),DEV_ATTACH ); } +/* find an ethdev entry */ + eth_dev =rte_eth_dev_allocated (name); +if (eth_dev ==NULL ) +return -ENODEV ; + eth_dev->device = &dev->device; }else { kvlist =rte_kvargs_parse (params, valid_arguments);
Signature · 1 line
2.1.4
Quoted 78 lines · On Wed, 31 May 2017 15:17:45 +0200 Gaetan Rivet <[email protected]> wrote:
Following the work from Jan:
This patchset introduces the attach / detach API to
rte_bus. Therte_devicestructure is used as the generic device representation.This API is implemented for the virtual bus.
The functionsrte_eal_dev_attachandrte_eal_dev_detachare updated to use this new interface.--
0. API rework
-------------I would like to propose an evolution on the API developed by Jan.
The attach / detach
rte_busAPI is necessary to support the attach/detachrte_devAPI. Those are two different levels for one similar functionality.Attach / detach does not allow true hotplugging, because the attach function expects the devices operated upon to already exist within the buses / sub-layers. This means that this API expects devices meta-datas (bus-internal device representation and associated device information read from the system) to be present upon attach. This part of the work is done during scanning.
While it is best to avoid changing the public
rte_devAPI as it already exists, nothing prevents this newrte_busAPI from superseeding it. It has been said during the previous release cycle that device hotplug was a feature that interested users. True hotplug is not allowed by the current attach / detach API. Worse, this API hinders the effort to bring this new functionality by squatting its semantic field.Thus, I propose to rename
rte_busattach / detach; plug / unplug. As it is a superset of the attach / detach functionality, it can be used to implementrte_devattach / detach. Now is the right time to pivot to this new feature.This should help maintainers understanding the aim of this API and the differences with the APIs higher-up, clarify the field and allow a new functionality to be proposed.
The vdev bus is inherently supporting the new API, however it has been made explicit. My implementation in the PCI bus in further patchset also follows the
rte_bushotplug API instead of only attach / detach.One remaining problem with the vdev bus is the
rte_devattach implementation, which needs therte_devargsrework to be properly fixed.1. Additional evolutions in the patchset
----------------------------------------The
RTE_VERIFYon thefind_deviceis too stringent I think and forces all buses to implement a public device iterator. While it could be argued that it would push for quicker support for the functionality, I think it's possible that some buses are not interested at all in it and should simply be ignored.The bus devices iterator has been fixed.
The internal
rte_devicehandle was not properly setup within thenet_ringPMD.Gaetan Rivet (2):
vdev: implement hotplug functionality
net/ring: fix dev handle ineth_devJan Blunck (9):
bus: add bus iterator to find a particular bus
bus: add device iterator
bus: add helper to find bus for a particular device
bus: add bus helper iterator to find a particular device
bus: introduce hotplug functionality
vdev: implementfind_devicebus operation
vdev: implement unplug bus operation
eal: make virtual driver probe and remove takerte_vdev_device
ethdev: Use embeddedrte_deviceto detach driver
Quoted 11 lines
drivers/net/ring/rte_eth_ring.c | 7 ++ lib/librte_eal/bsdapp/eal/rte_eal_version.map | 4 + lib/librte_eal/common/eal_common_bus.c | 65 +++++++++++++++ lib/librte_eal/common/eal_common_dev.c | 100 ++++++++++++++++++------ lib/librte_eal/common/eal_common_vdev.c | 27 +++++++ lib/librte_eal/common/include/rte_bus.h | 87 +++++++++++++++++++++ lib/librte_eal/common/include/rte_dev.h | 26 ++++++ lib/librte_eal/linuxapp/eal/rte_eal_version.map | 3 + lib/librte_ether/rte_ethdev.c | 3 +- 9 files changed, 299 insertions(+), 23 deletions(-)
LGTM
Maybe we should evolve it by having both rte_bus and rte_dev API for one release and mark the rte_dev API for attach/detach as deprecated?
Hi Stephen,
Quoted 93 lines · Stephen Hemminger
Quoted 78 lines · On Wed, 31 May 2017 15:17:45 +0200 Gaetan Rivet <[email protected]> wrote:
Following the work from Jan:
This patchset introduces the attach / detach API to
rte_bus. Therte_devicestructure is used as the generic device representation.This API is implemented for the virtual bus.
The functionsrte_eal_dev_attachandrte_eal_dev_detachare updated to use this new interface.--
0. API rework
-------------I would like to propose an evolution on the API developed by Jan.
The attach / detach
rte_busAPI is necessary to support the attach/detachrte_devAPI. Those are two different levels for one similar functionality.Attach / detach does not allow true hotplugging, because the attach function expects the devices operated upon to already exist within the buses / sub-layers. This means that this API expects devices meta-datas (bus-internal device representation and associated device information read from the system) to be present upon attach. This part of the work is done during scanning.
While it is best to avoid changing the public
rte_devAPI as it already exists, nothing prevents this newrte_busAPI from superseeding it. It has been said during the previous release cycle that device hotplug was a feature that interested users. True hotplug is not allowed by the current attach / detach API. Worse, this API hinders the effort to bring this new functionality by squatting its semantic field.Thus, I propose to rename
rte_busattach / detach; plug / unplug. As it is a superset of the attach / detach functionality, it can be used to implementrte_devattach / detach. Now is the right time to pivot to this new feature.This should help maintainers understanding the aim of this API and the differences with the APIs higher-up, clarify the field and allow a new functionality to be proposed.
The vdev bus is inherently supporting the new API, however it has been made explicit. My implementation in the PCI bus in further patchset also follows the
rte_bushotplug API instead of only attach / detach.One remaining problem with the vdev bus is the
rte_devattach implementation, which needs therte_devargsrework to be properly fixed.1. Additional evolutions in the patchset
----------------------------------------The
RTE_VERIFYon thefind_deviceis too stringent I think and forces all buses to implement a public device iterator. While it could be argued that it would push for quicker support for the functionality, I think it's possible that some buses are not interested at all in it and should simply be ignored.The bus devices iterator has been fixed.
The internal
rte_devicehandle was not properly setup within thenet_ringPMD.Gaetan Rivet (2):
vdev: implement hotplug functionality
net/ring: fix dev handle ineth_devJan Blunck (9):
bus: add bus iterator to find a particular bus
bus: add device iterator
bus: add helper to find bus for a particular device
bus: add bus helper iterator to find a particular device
bus: introduce hotplug functionality
vdev: implementfind_devicebus operation
vdev: implement unplug bus operation
eal: make virtual driver probe and remove takerte_vdev_device
ethdev: Use embeddedrte_deviceto detach driverQuoted 11 lines
drivers/net/ring/rte_eth_ring.c | 7 ++ lib/librte_eal/bsdapp/eal/rte_eal_version.map | 4 + lib/librte_eal/common/eal_common_bus.c | 65 +++++++++++++++ lib/librte_eal/common/eal_common_dev.c | 100 ++++++++++++++++++------ lib/librte_eal/common/eal_common_vdev.c | 27 +++++++ lib/librte_eal/common/include/rte_bus.h | 87 +++++++++++++++++++++ lib/librte_eal/common/include/rte_dev.h | 26 ++++++ lib/librte_eal/linuxapp/eal/rte_eal_version.map | 3 + lib/librte_ether/rte_ethdev.c | 3 +- 9 files changed, 299 insertions(+), 23 deletions(-)
Quoted 4 lines
LGTM
Maybe we should evolve it by having both
rte_busandrte_devAPI for one release and mark therte_devAPI for attach/detach as deprecated?
Sorry for the late response.
I think that if the hotplug API is correctly designed, the rte_dev API could indeed be deprecated and then removed. I do not see a reason right now to keep it.
Signature · 2 lines
Gaëtan Rivet 6WIND
v3 cover bus: attach / detach API
In reply to Gaetan RivetFollowing the work from Jan:
This patchset introduces the attach / detach API to rte_bus. The rte_device structure is used as the generic device representation.
This API is implemented for the virtual bus.
The functions rte_eal_dev_attach and rte_eal_dev_detach are updated to use this new interface.
-- v2
0. API rework
-------------
I would like to propose an evolution on the API developed by Jan.
The attach / detach rte_bus API is necessary to support the attach/detach rte_dev API. Those are two different levels for one similar functionality.
Attach / detach does not allow true hotplugging, because the attach function expects the devices operated upon to already exist within the buses / sub-layers. This means that this API expects devices meta-datas (bus-internal device representation and associated device information read from the system) to be present upon attach. This part of the work is done during scanning.
While it is best to avoid changing the public rte_dev API as it already exists, nothing prevents this new rte_bus API from superseeding it. It has been said during the previous release cycle that device hotplug was a feature that interested users. True hotplug is not allowed by the current attach / detach API. Worse, this API hinders the effort to bring this new functionality by squatting its semantic field.
Thus, I propose to rename rte_bus attach / detach; plug / unplug. As it is a superset of the attach / detach functionality, it can be used to implement rte_dev attach / detach. Now is the right time to pivot to this new feature.
This should help maintainers understanding the aim of this API and the differences with the APIs higher-up, clarify the field and allow a new functionality to be proposed.
The vdev bus is inherently supporting the new API, however it has been made explicit. My implementation in the PCI bus in further patchset also follows the rte_bus hotplug API instead of only attach / detach.
One remaining problem with the vdev bus is the rte_dev attach implementation, which needs the rte_devargs rework to be properly fixed.
1. Additional evolutions in the patchset
----------------------------------------
The RTE_VERIFY on the find_device is too stringent I think and forces all buses to implement a public device iterator. While it could be argued that it would push for quicker support for the functionality, I think it's possible that some buses are not interested at all in it and should simply be ignored.
The bus devices iterator has been fixed.
The internal rte_device handle was not properly setup within the net_ring PMD.
-- v3
The new API is now
typedef struct rte_device * (*rte_bus_plug_t)(struct rte_devargs *da); typedef int (*rte_bus_unplug_t)(struct rte_device *dev);
So, plugging a device takes an rte_devargs as input and returns an rte_device. While implementing related subsystems, I found that I usually needed this rte_device handle upon a successful device plugging. This seems the sensible and useful thing to do.
As such, on error NULL is returned and rte_errno is set by the bus.
Unplugging a device however now returns to the first version, which used an rte_device. The explicit contract here is that if one has an rte_device that has been obtained by calling bus->plug(), then this handle can be used for bus->unplug().
Additionally, bus and device comparators now returns 0 on match, following strcmp-like behavior.
Gaetan Rivet (2):
vdev: implement hotplug functionality
net/ring: fix dev handle in eth_dev
Jan Blunck (8):
bus: add bus iterator to find a particular bus
bus: add device iterator
bus: add helper to find bus for a particular device
bus: add bus helper iterator to find a particular device
bus: introduce hotplug functionality
vdev: implement find_device bus operation
eal: make virtual driver probe and remove take rte_vdev_device
ethdev: use embedded rte_device to detach driver
drivers/net/ring/rte_eth_ring.c | 7 ++ lib/librte_eal/bsdapp/eal/rte_eal_version.map | 4 + lib/librte_eal/common/eal_common_bus.c | 62 +++++++++++++++ lib/librte_eal/common/eal_common_dev.c | 100 ++++++++++++++++++------ lib/librte_eal/common/eal_common_vdev.c | 49 ++++++++++++ lib/librte_eal/common/include/rte_bus.h | 100 ++++++++++++++++++++++++ lib/librte_eal/common/include/rte_dev.h | 28 +++++++ lib/librte_eal/linuxapp/eal/rte_eal_version.map | 3 + lib/librte_ether/rte_ethdev.c | 31 +++----- 9 files changed, 341 insertions(+), 43 deletions(-)
Signature · 1 line
2.1.4
PATCH v3 1/10 bus: add bus iterator to find a particular bus
From: Jan Blunck <[email protected]>
--- lib/librte_eal/bsdapp/eal/rte_eal_version.map | 1 + lib/librte_eal/common/eal_common_bus.c | 11 ++++++++ lib/librte_eal/common/include/rte_bus.h | 34 +++++++++++++++++++++++++ lib/librte_eal/linuxapp/eal/rte_eal_version.map | 1 + 4 files changed, 47 insertions(+)
lib/librte_eal/bsdapp/eal/rte_eal_version.map +1 -0
@@ -162,6 +162,7 @@ DPDK_17.02 { DPDK_17.05 { global: + rte_bus_find; rte_cpu_is_supported; rte_log_dump; rte_log_register;
lib/librte_eal/common/eal_common_bus.c +11 -0
@@ -145,3 +145,14 @@ rte_bus_dump(FILE *f) } } } + +struct rte_bus * +rte_bus_find (rte_bus_cmp_t cmp,const void *data) +{ +struct rte_bus *bus =NULL ; + + TAILQ_FOREACH(bus, &rte_bus_list, next) +if (cmp (bus, data) ==0 ) +break ; +return bus; +}
lib/librte_eal/common/include/rte_bus.h +34 -0
@@ -141,6 +141,40 @@ int rte_bus_probe(void);void rte_bus_dump (FILE *f);/** +* Bus comparison function. +* +* @param bus +* Bus under test. +* +* @param data +* Data to compare against. +* +* @return +* 0 if the bus matches the data. +* !0 if the bus does not match. +* <0 if ordering is possible and the bus is lower than the data. +* >0 if ordering is possible and the bus is greater than the data. +*/ +typedef int (*rte_bus_cmp_t )(const struct rte_bus *bus,const void *data); + +/** +* Bus iterator to find a particular bus. +* +* If the callback returns non-zero this function will stop iterating over +* any more buses. +* +* @param cmp +* Comparison function. +* +* @param data +* Data to pass to cmp callback +* +* @return +* A pointer to a rte_bus structure or NULL in case no bus matches +*/ +struct rte_bus *rte_bus_find (rte_bus_cmp_t cmp,const void *data); + +/** * Helper for Bus registration. * The constructor has higher priority than PMD constructors. */
lib/librte_eal/linuxapp/eal/rte_eal_version.map +1 -0
@@ -166,6 +166,7 @@ DPDK_17.02 { DPDK_17.05 { global: + rte_bus_find; rte_cpu_is_supported; rte_intr_free_epoll_fd; rte_log_dump;
Signature · 1 line
2.1.4
Re: [PATCH v3 01/10] bus: add bus iterator to find a particular bus
Quoted 55 lines · Gaetan Rivet
From: Jan Blunck <[email protected]>
Signed-off-by Jan Blunck <[email protected]>Signed-off-by Gaetan Rivet <[email protected]>--- lib/librte_eal/bsdapp/eal/rte_eal_version.map | 1 + lib/librte_eal/common/eal_common_bus.c | 11 ++++++++ lib/librte_eal/common/include/rte_bus.h | 34 +++++++++++++++++++++++++ lib/librte_eal/linuxapp/eal/rte_eal_version.map | 1 + 4 files changed, 47 insertions(+)lib/librte_eal/bsdapp/eal/rte_eal_version.map +1
-0@@ -162,6 +162,7 @@ DPDK_17.02 { DPDK_17.05 { global: + rte_bus_find; rte_cpu_is_supported; rte_log_dump; rte_log_register;lib/librte_eal/common/eal_common_bus.c +11
-0@@ -145,3 +145,14 @@ rte_bus_dump(FILE *f) } } } + +struct rte_bus * +rte_bus_find (rte_bus_cmp_t cmp,const void *data) +{ +struct rte_bus *bus =NULL ; + + TAILQ_FOREACH(bus, &rte_bus_list, next) +if (cmp (bus, data) ==0 ) +break ; +return bus; +}lib/librte_eal/common/include/rte_bus.h +5
-0@@ -141,6 +141,40 @@ int rte_bus_probe(void);void rte_bus_dump (FILE *f);/** +* Bus comparison function. +* +* @param bus +* Bus under test. +*
lib/librte_eal/common/include/rte_bus.h int rte_bus_probe(void); · line 158
Quoted 10 lines
lib/librte_eal/common/include/rte_bus.h +10
-0+* @param data +* Data to compare against. +* +* @return +* 0 if the bus matches the data. +* !0 if the bus does not match. +* <0 if ordering is possible and the bus is lower than the data. +* >0 if ordering is possible and the bus is greater than the data. +*/ +typedef int (*rte_bus_cmp_t )(const struct rte_bus *bus,const void *data);
Gaetan,
Thanks for doing the adjustments. I believe we should also pass the starting pointer down to the bus implementation to enable continuation of a search after the given starting pointer. Does this make sense?
Quoted 37 lines
lib/librte_eal/common/include/rte_bus.h +19
-0+ +/** +* Bus iterator to find a particular bus. +* +* If the callback returns non-zero this function will stop iterating over +* any more buses. +* +* @param cmp +* Comparison function. +* +* @param data +* Data to pass to cmp callback +* +* @return +* A pointer to a rte_bus structure or NULL in case no bus matches +*/ +struct rte_bus *rte_bus_find (rte_bus_cmp_t cmp,const void *data); + +/** * Helper for Bus registration. * The constructor has higher priority than PMD constructors. */ lib/librte_eal/linuxapp/eal/rte_eal_version.map +1
-1@@ -166,6 +166,7 @@ DPDK_17.02 { DPDK_17.05 { global: + rte_bus_find; rte_cpu_is_supported; rte_intr_free_epoll_fd; rte_log_dump; --2.1.4
Re: [PATCH v3 01/10] bus: add bus iterator to find a particular bus
Quoted 69 lines · Jan Blunck
Quoted 55 lines · Gaetan Rivet
From: Jan Blunck <[email protected]>
Signed-off-by Jan Blunck <[email protected]>Signed-off-by Gaetan Rivet <[email protected]>--- lib/librte_eal/bsdapp/eal/rte_eal_version.map | 1 + lib/librte_eal/common/eal_common_bus.c | 11 ++++++++ lib/librte_eal/common/include/rte_bus.h | 34 +++++++++++++++++++++++++ lib/librte_eal/linuxapp/eal/rte_eal_version.map | 1 + 4 files changed, 47 insertions(+)lib/librte_eal/bsdapp/eal/rte_eal_version.map +1
-0@@ -162,6 +162,7 @@ DPDK_17.02 { DPDK_17.05 { global: + rte_bus_find; rte_cpu_is_supported; rte_log_dump; rte_log_register;lib/librte_eal/common/eal_common_bus.c +11
-0@@ -145,3 +145,14 @@ rte_bus_dump(FILE *f) } } } + +struct rte_bus * +rte_bus_find (rte_bus_cmp_t cmp,const void *data) +{ +struct rte_bus *bus =NULL ; + + TAILQ_FOREACH(bus, &rte_bus_list, next) +if (cmp (bus, data) ==0 ) +break ; +return bus; +}lib/librte_eal/common/include/rte_bus.h +5
-0@@ -141,6 +141,40 @@ int rte_bus_probe(void);void rte_bus_dump (FILE *f);/** +* Bus comparison function. +* +* @param bus +* Bus under test. +* lib/librte_eal/common/include/rte_bus.h int rte_bus_probe(void); · line 158
Quoted 10 lines
lib/librte_eal/common/include/rte_bus.h +10
-0+* @param data +* Data to compare against. +* +* @return +* 0 if the bus matches the data. +* !0 if the bus does not match. +* <0 if ordering is possible and the bus is lower than the data. +* >0 if ordering is possible and the bus is greater than the data. +*/ +typedef int (*rte_bus_cmp_t )(const struct rte_bus *bus,const void *data);Gaetan,
Quoted 4 lines
Thanks for doing the adjustments. I believe we should also pass the starting pointer down to the bus implementation to enable continuation of a search after the given starting pointer. Does this make sense?
Hi Jan,
Yes it makes sense, I see no reason to restrict the API, it will probably be useful and is a pretty common functionality for iterators.
It seems I missed fixing the description to rte_bus_find anyway, I will rework this part.
Quoted 6 lines
lib/librte_eal/common/include/rte_bus.h int rte_bus_probe(void); · line 164
Quoted 6 lines
lib/librte_eal/common/include/rte_bus.h +6
-0+ +/** +* Bus iterator to find a particular bus. +* +* If the callback returns non-zero this function will stop iterating over +* any more buses.
--> returns zero this function will stop **
Quoted 31 lines
Quoted 31 lines
lib/librte_eal/common/include/rte_bus.h +13
-0+* +* @param cmp +* Comparison function. +* +* @param data +* Data to pass to cmp callback +* +* @return +* A pointer to a rte_bus structure or NULL in case no bus matches +*/ +struct rte_bus *rte_bus_find (rte_bus_cmp_t cmp,const void *data); + +/** * Helper for Bus registration. * The constructor has higher priority than PMD constructors. */ lib/librte_eal/linuxapp/eal/rte_eal_version.map +1
-1@@ -166,6 +166,7 @@ DPDK_17.02 { DPDK_17.05 { global: + rte_bus_find; rte_cpu_is_supported; rte_intr_free_epoll_fd; rte_log_dump; --2.1.4
Signature · 2 lines
Gaëtan Rivet 6WIND
PATCH v3 2/10 bus: add device iterator
In reply to Gaetan RivetFrom: Jan Blunck <[email protected]>
--- lib/librte_eal/common/include/rte_bus.h | 7 +++++++ lib/librte_eal/common/include/rte_dev.h | 17 +++++++++++++++++ 2 files changed, 24 insertions(+)
lib/librte_eal/common/include/rte_bus.h +7 -0
@@ -82,6 +82,12 @@ typedef int (*rte_bus_scan_t)(void);typedef int (*rte_bus_probe_t )(void );/** +* Device iterator to find a particular device on a bus. +*/ +typedef struct rte_device * (*rte_bus_find_device_t )(rte_dev_cmp_t match, +const void *data); + +/** * A structure describing a generic bus. */ struct rte_bus {
@@ -89,6 +95,7 @@ struct rte_bus {const char *name;/**< Name of the bus */ rte_bus_scan_t scan;/**< Scan for devices attached to bus */ rte_bus_probe_t probe;/**< Probe devices on bus */ +rte_bus_find_device_t find_device;/**< Find device on bus */ };/**
lib/librte_eal/common/include/rte_dev.h +17 -0
@@ -191,6 +191,23 @@ int rte_eal_dev_attach(const char *name, const char *devargs);*/ int rte_eal_dev_detach (const char *name); +/** +* Device comparison function. +* +* @param dev +* Device handle. +* +* @param data +* Data to compare against. +* +* @return +* 0 if the device matches the data. +* !0 if the device does not match. +* <0 if ordering is possible and the device is lower than the data. +* >0 if ordering is possible and the device is greater than the data. +*/ +typedef int (*rte_dev_cmp_t )(const struct rte_device *dev,const void *data); +#define RTE_PMD_EXPORT_NAME_ARRAY (n, idx) n##idx[]#define RTE_PMD_EXPORT_NAME (name, idx) \
Signature · 1 line
2.1.4
PATCH v3 3/10 bus: add helper to find bus for a particular device
In reply to Gaetan RivetFrom: Jan Blunck <[email protected]>
--- lib/librte_eal/bsdapp/eal/rte_eal_version.map | 1 + lib/librte_eal/common/eal_common_bus.c | 24 ++++++++++++++++++++++++ lib/librte_eal/common/include/rte_bus.h | 5 +++++ lib/librte_eal/linuxapp/eal/rte_eal_version.map | 1 + 4 files changed, 31 insertions(+)
lib/librte_eal/bsdapp/eal/rte_eal_version.map +1 -0
@@ -163,6 +163,7 @@ DPDK_17.05 { global: rte_bus_find; + rte_bus_find_by_device; rte_cpu_is_supported; rte_log_dump; rte_log_register;
lib/librte_eal/common/eal_common_bus.c +24 -0
@@ -156,3 +156,27 @@ rte_bus_find(rte_bus_cmp_t cmp, const void *data)break ;return bus; } + +static int +cmp_rte_device (const struct rte_device *dev,const void *_dev2) +{ +const struct rte_device *dev2 = _dev2; + +return !(dev == dev2); +} + +static int +bus_find_device (const struct rte_bus *bus,const void *_dev) +{ +struct rte_device *dev; + +if (!bus->find_device) +return -1 ; + dev = bus->find_device (cmp_rte_device, _dev); +return !dev; +} + +struct rte_bus *rte_bus_find_by_device (const struct rte_device *dev) +{ +return rte_bus_find (bus_find_device, (const void *)dev); +}
lib/librte_eal/common/include/rte_bus.h +5 -0
@@ -182,6 +182,11 @@ typedef int (*rte_bus_cmp_t)(const struct rte_bus *bus, const void *data);struct rte_bus *rte_bus_find (rte_bus_cmp_t cmp,const void *data);/** +* Find the registered bus for a particular device. +*/ +struct rte_bus *rte_bus_find_by_device (const struct rte_device *dev); + +/** * Helper for Bus registration. * The constructor has higher priority than PMD constructors. */
lib/librte_eal/linuxapp/eal/rte_eal_version.map +1 -0
@@ -167,6 +167,7 @@ DPDK_17.05 { global: rte_bus_find; + rte_bus_find_by_device; rte_cpu_is_supported; rte_intr_free_epoll_fd; rte_log_dump;
Signature · 1 line
2.1.4
PATCH v3 4/10 bus: add bus helper iterator to find a particular device
In reply to Gaetan RivetFrom: Jan Blunck <[email protected]>
--- lib/librte_eal/bsdapp/eal/rte_eal_version.map | 1 + lib/librte_eal/common/eal_common_bus.c | 25 +++++++++++++++++++++++++ lib/librte_eal/common/include/rte_bus.h | 23 +++++++++++++++++++++++ lib/librte_eal/linuxapp/eal/rte_eal_version.map | 1 + 4 files changed, 50 insertions(+)
lib/librte_eal/bsdapp/eal/rte_eal_version.map +1 -0
@@ -164,6 +164,7 @@ DPDK_17.05 { rte_bus_find; rte_bus_find_by_device; + rte_bus_find_device; rte_cpu_is_supported; rte_log_dump; rte_log_register;
lib/librte_eal/common/eal_common_bus.c +25 -0
@@ -180,3 +180,28 @@ struct rte_bus *rte_bus_find_by_device(const struct rte_device *dev) {return rte_bus_find (bus_find_device, (const void *)dev); } + +struct rte_device * +rte_bus_find_device (const struct rte_device *start, +rte_dev_cmp_t cmp,const void *data) +{ +struct rte_bus *bus; +struct rte_device *dev =NULL ; +int start_seen =0 ; + + TAILQ_FOREACH(bus, &rte_bus_list, next) { +if (!bus->find_device) +continue ; +if (!!start ^ start_seen) { + dev = bus->find_device (cmp_rte_device, start); +if (dev) + start_seen =1 ; +else +continue ; + } + dev = bus->find_device (cmp, data); +if (dev) +break ; + } +return dev; +}
lib/librte_eal/common/include/rte_bus.h +23 -0
@@ -182,6 +182,29 @@ typedef int (*rte_bus_cmp_t)(const struct rte_bus *bus, const void *data);struct rte_bus *rte_bus_find (rte_bus_cmp_t cmp,const void *data);/** +* Bus iterator to find a particular device. +* +* If the callback returns non-zero this function will stop iterating over any +* more buses and devices. To continue a search the device of a previous search +* is passed via the start parameters. +* +* @param start +* Start device of the iteration. +* +* @param cmp +* Callback function to check device. +* +* @param data +* Data to pass to match callback. +* +* @return +* A pointer to a rte_bus structure or NULL in case no bus matches. +*/ +struct rte_device * +rte_bus_find_device (const struct rte_device *start, +rte_dev_cmp_t cmp,const void *data); + +/** * Find the registered bus for a particular device. */ struct rte_bus *rte_bus_find_by_device (const struct rte_device *dev);
lib/librte_eal/linuxapp/eal/rte_eal_version.map +1 -0
@@ -168,6 +168,7 @@ DPDK_17.05 { rte_bus_find; rte_bus_find_by_device; + rte_bus_find_device; rte_cpu_is_supported; rte_intr_free_epoll_fd; rte_log_dump;
Signature · 1 line
2.1.4
PATCH v3 5/10 bus: introduce hotplug functionality
In reply to Gaetan RivetFrom: Jan Blunck <[email protected]>
--- lib/librte_eal/common/eal_common_bus.c | 2 ++ lib/librte_eal/common/include/rte_bus.h | 31 +++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+)
lib/librte_eal/common/eal_common_bus.c +2 -0
@@ -50,6 +50,8 @@ rte_bus_register(struct rte_bus *bus)/* A bus should mandatorily have the scan implemented */ RTE_VERIFY (bus->scan);RTE_VERIFY (bus->probe); +/* Buses supporting hotplug also require unplug. */ +RTE_VERIFY (!bus->plug || bus->unplug);TAILQ_INSERT_TAIL (&rte_bus_list, bus, next);RTE_LOG (DEBUG ,EAL ,"Registered [%s] bus.\n" , bus->name);
lib/librte_eal/common/include/rte_bus.h +31 -0
@@ -88,6 +88,35 @@ typedef struct rte_device * (*rte_bus_find_device_t)(rte_dev_cmp_t match, const void *data);/** +* Implementation specific probe function which is responsible for linking +* devices on that bus with applicable drivers. +* The plugged device might already have been used previously by the bus, +* in which case some buses might prefer to detect and re-use the relevant +* information pertaining to this device. +* +* @param da +* Device declaration. +* +* @return +* The pointer to a valid rte_device usable by the bus on success. +* NULL on error. rte_errno is then set. +*/ +typedef struct rte_device * (*rte_bus_plug_t )(struct rte_devargs *da); + +/** +* Implementation specific remove function which is responsible for unlinking +* devices on that bus from assigned driver. +* +* @param dev +* Device pointer that was returned by a previous device plug call. +* +* @return +* 0 on success. +* !0 on error. rte_errno is then set. +*/ +typedef int (*rte_bus_unplug_t )(struct rte_device *dev); + +/** * A structure describing a generic bus. */ struct rte_bus {
@@ -96,6 +125,8 @@ struct rte_bus {rte_bus_scan_t scan;/**< Scan for devices attached to bus */ rte_bus_probe_t probe;/**< Probe devices on bus */ rte_bus_find_device_t find_device;/**< Find device on bus */ +rte_bus_plug_t plug;/**< Probe single device for drivers */ +rte_bus_unplug_t unplug;/**< Remove single device from driver */ };/**
Signature · 1 line
2.1.4
PATCH v3 6/10 vdev: implement find_device bus operation
In reply to Gaetan RivetFrom: Jan Blunck <[email protected]>
--- lib/librte_eal/common/eal_common_vdev.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
lib/librte_eal/common/eal_common_vdev.c +13 -0
@@ -338,9 +338,22 @@ vdev_probe(void)return 0 ; } +static struct rte_device * +vdev_find_device (rte_dev_cmp_t cmp,const void *data) +{ +struct rte_vdev_device *dev; + + TAILQ_FOREACH(dev, &vdev_device_list, next) { +if (cmp (&dev->device, data) ==0 ) +return &dev->device; + } +return NULL ; +} +static struct rte_bus rte_vdev_bus = { .scan = vdev_scan, .probe = vdev_probe, + .find_device = vdev_find_device, };RTE_INIT (rte_vdev_bus_register);
Signature · 1 line
2.1.4
PATCH v3 7/10 vdev: implement hotplug functionality
In reply to Gaetan Rivet--- lib/librte_eal/common/eal_common_vdev.c | 36 +++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+)
lib/librte_eal/common/eal_common_vdev.c +36 -0
@@ -38,11 +38,13 @@#include <sys/queue.h> #include <rte_eal.h> +#include <rte_dev.h> #include <rte_bus.h> #include <rte_vdev.h> #include <rte_common.h> #include <rte_devargs.h> #include <rte_memory.h> +#include <rte_errno.h> /** Double linked list of virtual device drivers. */ TAILQ_HEAD (vdev_device_list, rte_vdev_device);
@@ -350,10 +352,44 @@ vdev_find_device(rte_dev_cmp_t cmp, const void *data)return NULL ; } +static struct rte_device * +vdev_plug (struct rte_devargs *da) +{ +struct rte_vdev_device *dev; +int ret; + + ret =rte_vdev_init (da->virt.drv_name, da->args); +if (ret) { + rte_errno = -ret; +return NULL ; + } + dev =find_vdev (da->virt.drv_name); +return &dev->device; +} + +static int +vdev_unplug (struct rte_device *dev) +{ +struct rte_devargs *da; +int ret; + + da = dev->devargs; +if (da ==NULL ) { + rte_errno =EINVAL ; +return -1 ; + } + ret =rte_vdev_uninit (da->virt.drv_name); +if (ret) + rte_errno = -ret; +return ret; +} +static struct rte_bus rte_vdev_bus = { .scan = vdev_scan, .probe = vdev_probe, .find_device = vdev_find_device, + .plug = vdev_plug, + .unplug = vdev_unplug, };RTE_INIT (rte_vdev_bus_register);
Signature · 1 line
2.1.4
PATCH v3 8/10 eal: make virtual driver probe and remove take rte_vdev_device
In reply to Gaetan RivetFrom: Jan Blunck <[email protected]>
This is a preparation to embed the generic rte_device into the rte_eth_dev also for virtual devices.
--- lib/librte_eal/common/eal_common_dev.c | 93 ++++++++++++++++++++++++++-------- 1 file changed, 71 insertions(+), 22 deletions(-)
lib/librte_eal/common/eal_common_dev.c +71 -22
@@ -37,6 +37,7 @@#include <inttypes.h> #include <sys/queue.h> +#include <rte_bus.h> #include <rte_dev.h> #include <rte_devargs.h> #include <rte_debug.h>
@@ -45,50 +46,98 @@#include "eal_private.h" +static int cmp_detached_dev_name (const struct rte_device *dev, +const void *_name) +{ +const char *name = _name; + +/* skip attached devices */ +if (dev->driver) +return 0 ; + +return strcmp (dev->name, name); +} +int rte_eal_dev_attach (const char *name,const char *devargs) { -struct rte_pci_addr addr; +struct rte_device *dev; +int ret;if (name ==NULL || devargs ==NULL ) {RTE_LOG (ERR ,EAL ,"Invalid device or arguments provided\n" );return -EINVAL ; } -if (eal_parse_pci_DomBDF (name, &addr) ==0 ) { -if (rte_pci_probe_one (&addr) <0 ) - goto err; + dev =rte_bus_find_device (NULL , cmp_detached_dev_name, name); +if (dev) { +struct rte_bus *bus; + + bus =rte_bus_find_by_device (dev); +if (!bus) { +RTE_LOG (ERR ,EAL ,"Cannot find bus for device (%s)\n" , + name); +return -EINVAL ; + } - }else { -if (rte_vdev_init (name, devargs)) - goto err; +if (!bus->plug) { +RTE_LOG (ERR ,EAL ,"Bus function not supported\n" ); +return -ENOTSUP ; + } + + ret = (bus->plug (dev->devargs) ==NULL ); + goto out; } -return 0 ; +/* +* If we haven't found a bus device the user meant to "hotplug" a +* virtual device instead. +*/ + ret =rte_vdev_init (name, devargs); +out: +if (ret) +RTE_LOG (ERR ,EAL ,"Driver cannot attach the device (%s)\n" , + name); +return ret; +} + +static int cmp_dev_name (const struct rte_device *dev,const void *_name) +{ +const char *name = _name; -err: -RTE_LOG (ERR ,EAL ,"Driver cannot attach the device (%s)\n" , name); -return -EINVAL ; +return strcmp (dev->name, name); }int rte_eal_dev_detach (const char *name) { -struct rte_pci_addr addr; +struct rte_device *dev; +struct rte_bus *bus; +int ret;if (name ==NULL ) {RTE_LOG (ERR ,EAL ,"Invalid device provided.\n" );return -EINVAL ; } -if (eal_parse_pci_DomBDF (name, &addr) ==0 ) { -if (rte_pci_detach (&addr) <0 ) - goto err; - }else { -if (rte_vdev_uninit (name)) - goto err; + dev =rte_bus_find_device (NULL , cmp_dev_name, name); +if (!dev) { +RTE_LOG (ERR ,EAL ,"Cannot find device (%s)\n" , name); +return -EINVAL ; + } + + bus =rte_bus_find_by_device (dev); +if (!bus) { +RTE_LOG (ERR ,EAL ,"Cannot find bus for device (%s)\n" , name); +return -EINVAL ; + } + +if (!bus->unplug) { +RTE_LOG (ERR ,EAL ,"Bus function not supported\n" ); +return -ENOTSUP ; } -return 0 ; -err: -RTE_LOG (ERR ,EAL ,"Driver cannot detach the device (%s)\n" , name); -return -EINVAL ; + ret = bus->unplug (dev); +if (ret) +RTE_LOG (ERR ,EAL ,"Driver cannot detach the device (%s)\n" , + name); +return ret; }
Signature · 1 line
2.1.4
PATCH v3 9/10 ethdev: use embedded rte_device to detach driver
In reply to Gaetan RivetFrom: Jan Blunck <[email protected]>
--- lib/librte_eal/bsdapp/eal/rte_eal_version.map | 1 + lib/librte_eal/common/eal_common_dev.c | 43 ++++++++++++++++----------- lib/librte_eal/common/include/rte_dev.h | 11 +++++++ lib/librte_ether/rte_ethdev.c | 31 +++++++------------ 4 files changed, 47 insertions(+), 39 deletions(-)
lib/librte_eal/bsdapp/eal/rte_eal_version.map +1 -0
@@ -162,6 +162,7 @@ DPDK_17.02 { DPDK_17.05 { global: + rte_eal_device_detach; rte_bus_find; rte_bus_find_by_device; rte_bus_find_device;
lib/librte_eal/common/eal_common_dev.c +25 -18
59 lines not on this page · raw message
lib/librte_eal/common/include/rte_dev.h +11 -0
@@ -123,6 +123,17 @@ struct rte_mem_resource {void *addr;/**< Virtual address, NULL when not mapped. */ }; +/* FIXME: Forward declare */ +struct rte_device ; + +/** +* Unplug the device from the device driver. +* +* @param dev +* A pointer to a rte_device structure. +*/ +int rte_eal_device_detach (struct rte_device *dev); +/** * A structure describing a device driver. */
lib/librte_ether/rte_ethdev.c +10 -21
@@ -355,26 +355,14 @@ rte_eth_dev_get_port_by_name(const char *name, uint8_t *port_id)static int rte_eth_dev_is_detachable (uint8_t port_id) { -uint32_t dev_flags; +struct rte_eth_dev *dev;RTE_ETH_VALID_PORTID_OR_ERR_RET (port_id, -EINVAL ); -switch (rte_eth_devices[port_id].data->kdrv) { -case RTE_KDRV_IGB_UIO : -case RTE_KDRV_UIO_GENERIC : -case RTE_KDRV_NIC_UIO : -case RTE_KDRV_NONE : -case RTE_KDRV_VFIO : -break ; -default : -return -ENOTSUP ; - } - dev_flags = rte_eth_devices[port_id].data->dev_flags; -if ((dev_flags &RTE_ETH_DEV_DETACHABLE ) && - (!(dev_flags &RTE_ETH_DEV_BONDED_SLAVE ))) + dev = &rte_eth_devices[port_id]; +if (dev->data->dev_flags &RTE_ETH_DEV_BONDED_SLAVE )return 0 ; -else -return 1 ; +return !!dev->device->devargs->bus->unplug; }/* attach the new device, then store port_id of the device */
@@ -427,6 +415,7 @@ rte_eth_dev_attach(const char *devargs, uint8_t *port_id)int rte_eth_dev_detach (uint8_t port_id,char *name) { +struct rte_eth_dev *dev;int ret =-1 ;if (name ==NULL ) {
@@ -435,15 +424,15 @@ rte_eth_dev_detach(uint8_t port_id, char *name) }/* FIXME: move this to eal, once device flags are relocated there */ -if (rte_eth_dev_is_detachable (port_id)) +if (!rte_eth_dev_is_detachable (port_id)) goto err; -snprintf (name,sizeof (rte_eth_devices[port_id].data->name), -"%s" , rte_eth_devices[port_id].data->name); - ret =rte_eal_dev_detach (name); + dev = &rte_eth_devices[port_id]; +snprintf (name,RTE_ETH_NAME_MAX_LEN -1 ,"%s" , dev->device->name); + ret =rte_eal_device_detach (dev->device);if (ret <0 ) goto err; - + dev->state =RTE_ETH_DEV_UNUSED ;return 0 ; err:
Signature · 1 line
2.1.4
PATCH v3 10/10 net/ring: fix dev handle in eth_dev
In reply to Gaetan RivetThe ring PMD uses special eth_dev allocators, which cannot be updated to accept an rte_vdev_device.
Circumvent the limitation and store the rte_device handle in the rte_eth_dev structure.
vdev")
Cc: [email protected]
--- drivers/net/ring/rte_eth_ring.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/net/ring/rte_eth_ring.c +7 -0
@@ -515,6 +515,8 @@ rte_pmd_ring_probe(struct rte_vdev_device *dev)RTE_LOG (INFO ,PMD ,"Initializing pmd_ring for %s\n" , name);if (params ==NULL || params[0 ] =='\0' ) { +struct rte_eth_dev *eth_dev; + ret =eth_dev_ring_create (name,rte_socket_id (),DEV_CREATE );if (ret ==-1 ) { RTE_LOG(INFO, PMD,
@@ -522,6 +524,11 @@ rte_pmd_ring_probe(struct rte_vdev_device *dev) ret =eth_dev_ring_create (name,rte_socket_id (),DEV_ATTACH ); } +/* find an ethdev entry */ + eth_dev =rte_eth_dev_allocated (name); +if (eth_dev ==NULL ) +return -ENODEV ; + eth_dev->device = &dev->device; }else { kvlist =rte_kvargs_parse (params, valid_arguments);
Signature · 1 line
2.1.4
v4 cover bus: attach / detach API
In reply to Gaetan RivetFollowing the work from Jan:
This patchset introduces the attach / detach API to rte_bus. The rte_device structure is used as the generic device representation.
This API is implemented for the virtual bus.
The functions rte_eal_dev_attach and rte_eal_dev_detach are updated to use this new interface.
-- v2
0. API rework
-------------
I would like to propose an evolution on the API developed by Jan.
The attach / detach rte_bus API is necessary to support the attach/detach rte_dev API. Those are two different levels for one similar functionality.
Attach / detach does not allow true hotplugging, because the attach function expects the devices operated upon to already exist within the buses / sub-layers. This means that this API expects devices meta-datas (bus-internal device representation and associated device information read from the system) to be present upon attach. This part of the work is done during scanning.
While it is best to avoid changing the public rte_dev API as it already exists, nothing prevents this new rte_bus API from superseeding it. It has been said during the previous release cycle that device hotplug was a feature that interested users. True hotplug is not allowed by the current attach / detach API. Worse, this API hinders the effort to bring this new functionality by squatting its semantic field.
Thus, I propose to rename rte_bus attach / detach; plug / unplug. As it is a superset of the attach / detach functionality, it can be used to implement rte_dev attach / detach. Now is the right time to pivot to this new feature.
This should help maintainers understanding the aim of this API and the differences with the APIs higher-up, clarify the field and allow a new functionality to be proposed.
The vdev bus is inherently supporting the new API, however it has been made explicit. My implementation in the PCI bus in further patchset also follows the rte_bus hotplug API instead of only attach / detach.
One remaining problem with the vdev bus is the rte_dev attach implementation, which needs the rte_devargs rework to be properly fixed.
1. Additional evolutions in the patchset
----------------------------------------
The RTE_VERIFY on the find_device is too stringent I think and forces all buses to implement a public device iterator. While it could be argued that it would push for quicker support for the functionality, I think it's possible that some buses are not interested at all in it and should simply be ignored.
The bus devices iterator has been fixed.
The internal rte_device handle was not properly setup within the net_ring PMD.
-- v3
The new API is now
typedef struct rte_device * (*rte_bus_plug_t)(struct rte_devargs *da); typedef int (*rte_bus_unplug_t)(struct rte_device *dev);
So, plugging a device takes an rte_devargs as input and returns an rte_device. While implementing related subsystems, I found that I usually needed this rte_device handle upon a successful device plugging. This seems the sensible and useful thing to do.
As such, on error NULL is returned and rte_errno is set by the bus.
Unplugging a device however now returns to the first version, which used an rte_device. The explicit contract here is that if one has an rte_device that has been obtained by calling bus->plug(), then this handle can be used for bus->unplug().
Additionally, bus and device comparators now returns 0 on match, following strcmp-like behavior.
-- v4
* rte_bus_find now takes a *start* parameter, that can be null. The bus search starts from this element if set.
* A few doc fixes.
* The rte_device field was fixed within the rte_ring PMD in a previous patch. This fix has been integrated by other means, it is not necessary anymore.
Gaetan Rivet (1):
vdev: implement hotplug functionality
Jan Blunck (8):
bus: add bus iterator to find a particular bus
bus: add device iterator
bus: add helper to find bus for a particular device
bus: add bus helper iterator to find a particular device
bus: introduce hotplug functionality
vdev: implement find_device bus operation
eal: make virtual driver probe and remove take rte_vdev_device
ethdev: use embedded rte_device to detach driver
lib/librte_eal/bsdapp/eal/rte_eal_version.map | 4 + lib/librte_eal/common/eal_common_bus.c | 70 ++++++++++++++++ lib/librte_eal/common/eal_common_dev.c | 100 +++++++++++++++++----- lib/librte_eal/common/eal_common_vdev.c | 49 +++++++++++ lib/librte_eal/common/include/rte_bus.h | 107 ++++++++++++++++++++++++ lib/librte_eal/common/include/rte_dev.h | 28 +++++++ lib/librte_eal/linuxapp/eal/rte_eal_version.map | 3 + lib/librte_ether/rte_ethdev.c | 31 +++---- 8 files changed, 349 insertions(+), 43 deletions(-)
Signature · 1 line
2.1.4
PATCH v4 1/9 bus: add bus iterator to find a particular bus
From: Jan Blunck <[email protected]>
--- lib/librte_eal/bsdapp/eal/rte_eal_version.map | 1 + lib/librte_eal/common/eal_common_bus.c | 20 ++++++++++++ lib/librte_eal/common/include/rte_bus.h | 41 +++++++++++++++++++++++++ lib/librte_eal/linuxapp/eal/rte_eal_version.map | 1 + 4 files changed, 63 insertions(+)
lib/librte_eal/bsdapp/eal/rte_eal_version.map +1 -0
@@ -162,6 +162,7 @@ DPDK_17.02 { DPDK_17.05 { global: + rte_bus_find; rte_cpu_is_supported; rte_log_dump; rte_log_register;
lib/librte_eal/common/eal_common_bus.c +20 -0
@@ -145,3 +145,23 @@ rte_bus_dump(FILE *f) } } } + +struct rte_bus * +rte_bus_find (rte_bus_cmp_t cmp, +const void *data, +const struct rte_bus *start) +{ +struct rte_bus *bus =NULL ; +int started = start ==NULL ; + + TAILQ_FOREACH(bus, &rte_bus_list, next) { +if (!started) { +if (bus == start) + started =1 ; +continue ; + } +if (cmp (bus, data) ==0 ) +break ; + } +return bus; +}
lib/librte_eal/common/include/rte_bus.h +41 -0
47 lines not on this page · raw message
lib/librte_eal/linuxapp/eal/rte_eal_version.map +1 -0
@@ -166,6 +166,7 @@ DPDK_17.02 { DPDK_17.05 { global: + rte_bus_find; rte_cpu_is_supported; rte_intr_free_epoll_fd; rte_log_dump;
Signature · 1 line
2.1.4
Re: [PATCH v4 1/9] bus: add bus iterator to find a particular bus
21/06/2017 01:29, Gaetan Rivet:
Quoted 14 lines
lib/librte_eal/common/include/rte_bus.h +13
-0+/** +* Bus iterator to find a particular bus. +* +* If the callback returns zero this function will stop iterating over +* any more buses. +* If the start parameter is non-NULL, the comparison will only be determined +* past this element. +* +* @param cmp +* Comparison function. +* +* @param data +* Data to pass to cmp callback
lib/librte_eal/common/include/rte_bus.h int rte_bus_probe(void); · line 182
Quoted 10 lines
lib/librte_eal/common/include/rte_bus.h +10
-0+* +* @param start +* Starting point for the iteration. +* +* @return +* A pointer to a rte_bus structure or NULL in case no bus matches +*/ +struct rte_bus *rte_bus_find (rte_bus_cmp_t cmp, +const void *data, +const struct rte_bus *start);
What will be the typical usage? find by name? Does it make sense to implement a helper for find_by_name?
Or is it used only for rte_bus_find_by_device()?
PATCH v4 2/9 bus: add device iterator
In reply to Gaetan RivetFrom: Jan Blunck <[email protected]>
--- lib/librte_eal/common/include/rte_bus.h | 7 +++++++ lib/librte_eal/common/include/rte_dev.h | 17 +++++++++++++++++ 2 files changed, 24 insertions(+)
lib/librte_eal/common/include/rte_bus.h +7 -0
@@ -82,6 +82,12 @@ typedef int (*rte_bus_scan_t)(void);typedef int (*rte_bus_probe_t )(void );/** +* Device iterator to find a particular device on a bus. +*/ +typedef struct rte_device * (*rte_bus_find_device_t )(rte_dev_cmp_t match, +const void *data); + +/** * A structure describing a generic bus. */ struct rte_bus {
@@ -89,6 +95,7 @@ struct rte_bus {const char *name;/**< Name of the bus */ rte_bus_scan_t scan;/**< Scan for devices attached to bus */ rte_bus_probe_t probe;/**< Probe devices on bus */ +rte_bus_find_device_t find_device;/**< Find device on bus */ };/**
lib/librte_eal/common/include/rte_dev.h +17 -0
@@ -191,6 +191,23 @@ int rte_eal_dev_attach(const char *name, const char *devargs);*/ int rte_eal_dev_detach (const char *name); +/** +* Device comparison function. +* +* @param dev +* Device handle. +* +* @param data +* Data to compare against. +* +* @return +* 0 if the device matches the data. +* !0 if the device does not match. +* <0 if ordering is possible and the device is lower than the data. +* >0 if ordering is possible and the device is greater than the data. +*/ +typedef int (*rte_dev_cmp_t )(const struct rte_device *dev,const void *data); +#define RTE_PMD_EXPORT_NAME_ARRAY (n, idx) n##idx[]#define RTE_PMD_EXPORT_NAME (name, idx) \
Signature · 1 line
2.1.4
Re: [PATCH v4 2/9] bus: add device iterator
21/06/2017 01:29, Gaetan Rivet:
Quoted 6 lines
lib/librte_eal/common/include/rte_dev.h +6
-0+/** +* Device comparison function. +* +* @param dev +* Device handle. +*
lib/librte_eal/common/include/rte_dev.h int rte_eal_dev_attach(const char *name, const char *devargs); · line 209
Quoted 10 lines
lib/librte_eal/common/include/rte_dev.h +10
-0+* @param data +* Data to compare against. +* +* @return +* 0 if the device matches the data. +* !0 if the device does not match. +* <0 if ordering is possible and the device is lower than the data. +* >0 if ordering is possible and the device is greater than the data. +*/ +typedef int (*rte_dev_cmp_t )(const struct rte_device *dev,const void *data);
data is really abstract.
Maybe a comment is missing to explain that data is better specified in bus implementations?
Why not implement it for PCI?
Re: [PATCH v4 2/9] bus: add device iterator
Quoted 13 lines · Thomas Monjalon
21/06/2017 01:29, Gaetan Rivet:
Quoted 12 lines
+/**
+ * Device comparison function.
+ *
+ * @param dev
+ * Device handle.
+ *
+ * @param data
+ * Data to compare against.
+ *
+ * @return
+ * 0 if the device matches the data.
+ * !0 if the device does not match.
Quoted 9 lines
Quoted 4 lines
+ * <0 if ordering is possible and the device is lower than the data.
+ * >0 if ordering is possible and the device is greater than the data.
+ */
+typedef int (*rte_dev_cmp_t)(const structrte_device*dev, const void *data);data is really abstract.
Maybe a comment is missing to explain that data is better specified in bus implementations?
I'm not sure it is better specified in rte_bus though :). However, the usage can be understood there, why it exists in the first place.
I think bus iterators could benefit some more explanation about the why.
Quoted 2 lines
Why not implement it for PCI?
I sent this series with only the patches from Jan, initially in the version he solely developed. Only afterward did I fix a few bugs, reworked a few APIs.
As such, two other series complete this patchset:
[dpdk-dev] [PATCH v3] pci: implement find_device bus operation
http://dpdk.org/ml/archives/dev/2017-June/067485.html
And
[dpdk-dev] [PATCH v3 0/3] eal: complete attach / detach support
http://dpdk.org/ml/archives/dev/2017-June/067516.html
It might make sense to merge all three series together.
They are conceptually linked very closely. The only reason I did not do so at first was because I was unsure about who would take responsibility for the attach / detach patchset, and if it had not be me I did not want to put undue responsibility of my patches on whomever would.
But that point is moot now.
Signature · 2 lines
Gaëtan Rivet 6WIND
PATCH v4 3/9 bus: add helper to find bus for a particular device
In reply to Gaetan RivetFrom: Jan Blunck <[email protected]>
--- lib/librte_eal/bsdapp/eal/rte_eal_version.map | 1 + lib/librte_eal/common/eal_common_bus.c | 24 ++++++++++++++++++++++++ lib/librte_eal/common/include/rte_bus.h | 5 +++++ lib/librte_eal/linuxapp/eal/rte_eal_version.map | 1 + 4 files changed, 31 insertions(+)
lib/librte_eal/bsdapp/eal/rte_eal_version.map +1 -0
@@ -163,6 +163,7 @@ DPDK_17.05 { global: rte_bus_find; + rte_bus_find_by_device; rte_cpu_is_supported; rte_log_dump; rte_log_register;
lib/librte_eal/common/eal_common_bus.c +24 -0
@@ -165,3 +165,27 @@ rte_bus_find(rte_bus_cmp_t cmp, }return bus; } + +static int +cmp_rte_device (const struct rte_device *dev,const void *_dev2) +{ +const struct rte_device *dev2 = _dev2; + +return !(dev == dev2); +} + +static int +bus_find_device (const struct rte_bus *bus,const void *_dev) +{ +struct rte_device *dev; + +if (!bus->find_device) +return -1 ; + dev = bus->find_device (cmp_rte_device, _dev); +return !dev; +} + +struct rte_bus *rte_bus_find_by_device (const struct rte_device *dev) +{ +return rte_bus_find (bus_find_device, (const void *)dev,NULL ); +}
lib/librte_eal/common/include/rte_bus.h +5 -0
@@ -189,6 +189,11 @@ struct rte_bus *rte_bus_find(rte_bus_cmp_t cmp, const struct rte_bus *start);/** +* Find the registered bus for a particular device. +*/ +struct rte_bus *rte_bus_find_by_device (const struct rte_device *dev); + +/** * Helper for Bus registration. * The constructor has higher priority than PMD constructors. */
lib/librte_eal/linuxapp/eal/rte_eal_version.map +1 -0
@@ -167,6 +167,7 @@ DPDK_17.05 { global: rte_bus_find; + rte_bus_find_by_device; rte_cpu_is_supported; rte_intr_free_epoll_fd; rte_log_dump;
Signature · 1 line
2.1.4
Re: [PATCH v4 3/9] bus: add helper to find bus for a particular device
21/06/2017 01:29, Gaetan Rivet:
lib/librte_eal/common/eal_common_bus.c rte_bus_find(rte_bus_cmp_t cmp, · line 170
Quoted 2 lines
lib/librte_eal/common/eal_common_bus.c +2
-0+static int +cmp_rte_device (const struct rte_device *dev,const void *_dev2)
Better to rename dev into dev1.
lib/librte_eal/common/eal_common_bus.c rte_bus_find(rte_bus_cmp_t cmp, · line 174
Quoted 4 lines
lib/librte_eal/common/eal_common_bus.c +4
-0+{ +const struct rte_device *dev2 = _dev2; + +return !(dev == dev2);
simpler: return dev1 != dev2
[...]
lib/librte_eal/common/eal_common_bus.c rte_bus_find(rte_bus_cmp_t cmp, · line 182
Quoted 6 lines
lib/librte_eal/common/eal_common_bus.c +6
-0+static int +bus_find_device (const struct rte_bus *bus,const void *_dev) +{ +struct rte_device *dev; + +if (!bus->find_device)
It is preferred to check pointers against NULL.
lib/librte_eal/common/eal_common_bus.c rte_bus_find(rte_bus_cmp_t cmp, · line 185
Quoted 3 lines
lib/librte_eal/common/eal_common_bus.c +3
-0+return -1 ; + dev = bus->find_device (cmp_rte_device, _dev); +return !dev;
Here also: return dev == NULL:
lib/librte_eal/common/eal_common_bus.c rte_bus_find(rte_bus_cmp_t cmp, · line 191
Quoted 6 lines
lib/librte_eal/common/eal_common_bus.c +6
-0+} + +struct rte_bus *rte_bus_find_by_device (const struct rte_device *dev) +{ +return rte_bus_find (bus_find_device, (const void *)dev,NULL ); +}
Nice
PATCH v4 4/9 bus: add bus helper iterator to find a particular device
In reply to Gaetan RivetFrom: Jan Blunck <[email protected]>
--- lib/librte_eal/bsdapp/eal/rte_eal_version.map | 1 + lib/librte_eal/common/eal_common_bus.c | 24 ++++++++++++++++++++++++ lib/librte_eal/common/include/rte_bus.h | 23 +++++++++++++++++++++++ lib/librte_eal/linuxapp/eal/rte_eal_version.map | 1 + 4 files changed, 49 insertions(+)
lib/librte_eal/bsdapp/eal/rte_eal_version.map +1 -0
@@ -164,6 +164,7 @@ DPDK_17.05 { rte_bus_find; rte_bus_find_by_device; + rte_bus_find_device; rte_cpu_is_supported; rte_log_dump; rte_log_register;
lib/librte_eal/common/eal_common_bus.c +24 -0
@@ -189,3 +189,27 @@ struct rte_bus *rte_bus_find_by_device(const struct rte_device *dev) {return rte_bus_find (bus_find_device, (const void *)dev,NULL ); } + +struct rte_device * +rte_bus_find_device (const struct rte_device *start, +rte_dev_cmp_t cmp,const void *data) +{ +struct rte_bus *bus; +struct rte_device *dev =NULL ; +int started = start ==NULL ; + + TAILQ_FOREACH(bus, &rte_bus_list, next) { +if (!bus->find_device) +continue ; +if (!started) { + dev = bus->find_device (cmp_rte_device, start); +if (dev) + started =1 ; +continue ; + } + dev = bus->find_device (cmp, data); +if (dev) +break ; + } +return dev; +}
lib/librte_eal/common/include/rte_bus.h +23 -0
@@ -189,6 +189,29 @@ struct rte_bus *rte_bus_find(rte_bus_cmp_t cmp, const struct rte_bus *start);/** +* Bus iterator to find a particular device. +* +* If the callback returns non-zero this function will stop iterating over any +* more buses and devices. To continue a search the device of a previous search +* is passed via the start parameters. +* +* @param start +* Start device of the iteration. +* +* @param cmp +* Callback function to check device. +* +* @param data +* Data to pass to match callback. +* +* @return +* A pointer to a rte_bus structure or NULL in case no bus matches. +*/ +struct rte_device * +rte_bus_find_device (const struct rte_device *start, +rte_dev_cmp_t cmp,const void *data); + +/** * Find the registered bus for a particular device. */ struct rte_bus *rte_bus_find_by_device (const struct rte_device *dev);
lib/librte_eal/linuxapp/eal/rte_eal_version.map +1 -0
@@ -168,6 +168,7 @@ DPDK_17.05 { rte_bus_find; rte_bus_find_by_device; + rte_bus_find_device; rte_cpu_is_supported; rte_intr_free_epoll_fd; rte_log_dump;
Signature · 1 line
2.1.4
Re: [PATCH v4 4/9] bus: add bus helper iterator to find a particular device
21/06/2017 01:29, Gaetan Rivet:
Quoted 2 lines
/**
+ * Bus iterator to find a particular device.
It should be said that it is iterating over every registered buses.
Quoted 17 lines
+ *
+ * If the callback returns non-zero this function will stop iterating over any
+ * more buses and devices. To continue a search the device of a previous search
+ * is passed via the start parameters.
+ *
+ * @param start
+ * Start device of the iteration.
+ *
+ * @param cmp
+ * Callback function to check device.
+ *
+ * @param data
+ * Data to pass to match callback.
+ *
+ * @return
+ * A pointer to arte_busstructure or NULL in case no bus matches.
+ */
lib/librte_eal/common/include/rte_bus.h struct rte_bus *rte_bus_find(rte_bus_cmp_t cmp, · line 212
Quoted 3 lines
lib/librte_eal/common/include/rte_bus.h +3
-0+struct rte_device * +rte_bus_find_device (const struct rte_device *start, +rte_dev_cmp_t cmp,const void *data);
The order of the parameters is different of rte_bus_find():
struct rte_bus *rte_bus_find(rte_bus_cmp_t cmp,
const void *data, const struct rte_bus *start);
PATCH v4 5/9 bus: introduce hotplug functionality
In reply to Gaetan RivetFrom: Jan Blunck <[email protected]>
--- lib/librte_eal/common/eal_common_bus.c | 2 ++ lib/librte_eal/common/include/rte_bus.h | 31 +++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+)
lib/librte_eal/common/eal_common_bus.c +2 -0
@@ -50,6 +50,8 @@ rte_bus_register(struct rte_bus *bus)/* A bus should mandatorily have the scan implemented */ RTE_VERIFY (bus->scan);RTE_VERIFY (bus->probe); +/* Buses supporting hotplug also require unplug. */ +RTE_VERIFY (!bus->plug || bus->unplug);TAILQ_INSERT_TAIL (&rte_bus_list, bus, next);RTE_LOG (DEBUG ,EAL ,"Registered [%s] bus.\n" , bus->name);
lib/librte_eal/common/include/rte_bus.h +31 -0
@@ -88,6 +88,35 @@ typedef struct rte_device * (*rte_bus_find_device_t)(rte_dev_cmp_t match, const void *data);/** +* Implementation specific probe function which is responsible for linking +* devices on that bus with applicable drivers. +* The plugged device might already have been used previously by the bus, +* in which case some buses might prefer to detect and re-use the relevant +* information pertaining to this device. +* +* @param da +* Device declaration. +* +* @return +* The pointer to a valid rte_device usable by the bus on success. +* NULL on error. rte_errno is then set. +*/ +typedef struct rte_device * (*rte_bus_plug_t )(struct rte_devargs *da); + +/** +* Implementation specific remove function which is responsible for unlinking +* devices on that bus from assigned driver. +* +* @param dev +* Device pointer that was returned by a previous device plug call. +* +* @return +* 0 on success. +* !0 on error. rte_errno is then set. +*/ +typedef int (*rte_bus_unplug_t )(struct rte_device *dev); + +/** * A structure describing a generic bus. */ struct rte_bus {
@@ -96,6 +125,8 @@ struct rte_bus {rte_bus_scan_t scan;/**< Scan for devices attached to bus */ rte_bus_probe_t probe;/**< Probe devices on bus */ rte_bus_find_device_t find_device;/**< Find device on bus */ +rte_bus_plug_t plug;/**< Probe single device for drivers */ +rte_bus_unplug_t unplug;/**< Remove single device from driver */ };/**
Signature · 1 line
2.1.4
PATCH v4 6/9 vdev: implement find_device bus operation
In reply to Gaetan RivetFrom: Jan Blunck <[email protected]>
--- lib/librte_eal/common/eal_common_vdev.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
lib/librte_eal/common/eal_common_vdev.c +13 -0
@@ -338,9 +338,22 @@ vdev_probe(void)return 0 ; } +static struct rte_device * +vdev_find_device (rte_dev_cmp_t cmp,const void *data) +{ +struct rte_vdev_device *dev; + + TAILQ_FOREACH(dev, &vdev_device_list, next) { +if (cmp (&dev->device, data) ==0 ) +return &dev->device; + } +return NULL ; +} +static struct rte_bus rte_vdev_bus = { .scan = vdev_scan, .probe = vdev_probe, + .find_device = vdev_find_device, };RTE_INIT (rte_vdev_bus_register);
Signature · 1 line
2.1.4
PATCH v4 7/9 vdev: implement hotplug functionality
In reply to Gaetan Rivet--- lib/librte_eal/common/eal_common_vdev.c | 36 +++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+)
lib/librte_eal/common/eal_common_vdev.c +36 -0
@@ -38,11 +38,13 @@#include <sys/queue.h> #include <rte_eal.h> +#include <rte_dev.h> #include <rte_bus.h> #include <rte_vdev.h> #include <rte_common.h> #include <rte_devargs.h> #include <rte_memory.h> +#include <rte_errno.h> /** Double linked list of virtual device drivers. */ TAILQ_HEAD (vdev_device_list, rte_vdev_device);
@@ -350,10 +352,44 @@ vdev_find_device(rte_dev_cmp_t cmp, const void *data)return NULL ; } +static struct rte_device * +vdev_plug (struct rte_devargs *da) +{ +struct rte_vdev_device *dev; +int ret; + + ret =rte_vdev_init (da->virt.drv_name, da->args); +if (ret) { + rte_errno = -ret; +return NULL ; + } + dev =find_vdev (da->virt.drv_name); +return &dev->device; +} + +static int +vdev_unplug (struct rte_device *dev) +{ +struct rte_devargs *da; +int ret; + + da = dev->devargs; +if (da ==NULL ) { + rte_errno =EINVAL ; +return -1 ; + } + ret =rte_vdev_uninit (da->virt.drv_name); +if (ret) + rte_errno = -ret; +return ret; +} +static struct rte_bus rte_vdev_bus = { .scan = vdev_scan, .probe = vdev_probe, .find_device = vdev_find_device, + .plug = vdev_plug, + .unplug = vdev_unplug, };RTE_INIT (rte_vdev_bus_register);
Signature · 1 line
2.1.4
PATCH v4 8/9 eal: make virtual driver probe and remove take rte_vdev_device
In reply to Gaetan RivetFrom: Jan Blunck <[email protected]>
This is a preparation to embed the generic rte_device into the rte_eth_dev also for virtual devices.
--- lib/librte_eal/common/eal_common_dev.c | 93 ++++++++++++++++++++++++++-------- 1 file changed, 71 insertions(+), 22 deletions(-)
lib/librte_eal/common/eal_common_dev.c +71 -22
@@ -37,6 +37,7 @@#include <inttypes.h> #include <sys/queue.h> +#include <rte_bus.h> #include <rte_dev.h> #include <rte_devargs.h> #include <rte_debug.h>
@@ -45,50 +46,98 @@#include "eal_private.h" +static int cmp_detached_dev_name (const struct rte_device *dev, +const void *_name) +{ +const char *name = _name; + +/* skip attached devices */ +if (dev->driver) +return 0 ; + +return strcmp (dev->name, name); +} +int rte_eal_dev_attach (const char *name,const char *devargs) { -struct rte_pci_addr addr; +struct rte_device *dev; +int ret;if (name ==NULL || devargs ==NULL ) {RTE_LOG (ERR ,EAL ,"Invalid device or arguments provided\n" );return -EINVAL ; } -if (eal_parse_pci_DomBDF (name, &addr) ==0 ) { -if (rte_pci_probe_one (&addr) <0 ) - goto err; + dev =rte_bus_find_device (NULL , cmp_detached_dev_name, name); +if (dev) { +struct rte_bus *bus; + + bus =rte_bus_find_by_device (dev); +if (!bus) { +RTE_LOG (ERR ,EAL ,"Cannot find bus for device (%s)\n" , + name); +return -EINVAL ; + } - }else { -if (rte_vdev_init (name, devargs)) - goto err; +if (!bus->plug) { +RTE_LOG (ERR ,EAL ,"Bus function not supported\n" ); +return -ENOTSUP ; + } + + ret = (bus->plug (dev->devargs) ==NULL ); + goto out; } -return 0 ; +/* +* If we haven't found a bus device the user meant to "hotplug" a +* virtual device instead. +*/ + ret =rte_vdev_init (name, devargs); +out: +if (ret) +RTE_LOG (ERR ,EAL ,"Driver cannot attach the device (%s)\n" , + name); +return ret; +} + +static int cmp_dev_name (const struct rte_device *dev,const void *_name) +{ +const char *name = _name; -err: -RTE_LOG (ERR ,EAL ,"Driver cannot attach the device (%s)\n" , name); -return -EINVAL ; +return strcmp (dev->name, name); }int rte_eal_dev_detach (const char *name) { -struct rte_pci_addr addr; +struct rte_device *dev; +struct rte_bus *bus; +int ret;if (name ==NULL ) {RTE_LOG (ERR ,EAL ,"Invalid device provided.\n" );return -EINVAL ; } -if (eal_parse_pci_DomBDF (name, &addr) ==0 ) { -if (rte_pci_detach (&addr) <0 ) - goto err; - }else { -if (rte_vdev_uninit (name)) - goto err; + dev =rte_bus_find_device (NULL , cmp_dev_name, name); +if (!dev) { +RTE_LOG (ERR ,EAL ,"Cannot find device (%s)\n" , name); +return -EINVAL ; + } + + bus =rte_bus_find_by_device (dev); +if (!bus) { +RTE_LOG (ERR ,EAL ,"Cannot find bus for device (%s)\n" , name); +return -EINVAL ; + } + +if (!bus->unplug) { +RTE_LOG (ERR ,EAL ,"Bus function not supported\n" ); +return -ENOTSUP ; } -return 0 ; -err: -RTE_LOG (ERR ,EAL ,"Driver cannot detach the device (%s)\n" , name); -return -EINVAL ; + ret = bus->unplug (dev); +if (ret) +RTE_LOG (ERR ,EAL ,"Driver cannot detach the device (%s)\n" , + name); +return ret; }
Signature · 1 line
2.1.4
PATCH v4 9/9 ethdev: use embedded rte_device to detach driver
In reply to Gaetan RivetFrom: Jan Blunck <[email protected]>
--- lib/librte_eal/bsdapp/eal/rte_eal_version.map | 1 + lib/librte_eal/common/eal_common_dev.c | 43 ++++++++++++++++----------- lib/librte_eal/common/include/rte_dev.h | 11 +++++++ lib/librte_ether/rte_ethdev.c | 31 +++++++------------ 4 files changed, 47 insertions(+), 39 deletions(-)
lib/librte_eal/bsdapp/eal/rte_eal_version.map +1 -0
@@ -162,6 +162,7 @@ DPDK_17.02 { DPDK_17.05 { global: + rte_eal_device_detach; rte_bus_find; rte_bus_find_by_device; rte_bus_find_device;
lib/librte_eal/common/eal_common_dev.c +25 -18
59 lines not on this page · raw message
lib/librte_eal/common/include/rte_dev.h +11 -0
@@ -123,6 +123,17 @@ struct rte_mem_resource {void *addr;/**< Virtual address, NULL when not mapped. */ }; +/* FIXME: Forward declare */ +struct rte_device ; + +/** +* Unplug the device from the device driver. +* +* @param dev +* A pointer to a rte_device structure. +*/ +int rte_eal_device_detach (struct rte_device *dev); +/** * A structure describing a device driver. */
lib/librte_ether/rte_ethdev.c +10 -21
@@ -354,26 +354,14 @@ rte_eth_dev_get_port_by_name(const char *name, uint8_t *port_id)static int rte_eth_dev_is_detachable (uint8_t port_id) { -uint32_t dev_flags; +struct rte_eth_dev *dev;RTE_ETH_VALID_PORTID_OR_ERR_RET (port_id, -EINVAL ); -switch (rte_eth_devices[port_id].data->kdrv) { -case RTE_KDRV_IGB_UIO : -case RTE_KDRV_UIO_GENERIC : -case RTE_KDRV_NIC_UIO : -case RTE_KDRV_NONE : -case RTE_KDRV_VFIO : -break ; -default : -return -ENOTSUP ; - } - dev_flags = rte_eth_devices[port_id].data->dev_flags; -if ((dev_flags &RTE_ETH_DEV_DETACHABLE ) && - (!(dev_flags &RTE_ETH_DEV_BONDED_SLAVE ))) + dev = &rte_eth_devices[port_id]; +if (dev->data->dev_flags &RTE_ETH_DEV_BONDED_SLAVE )return 0 ; -else -return 1 ; +return !!dev->device->devargs->bus->unplug; }/* attach the new device, then store port_id of the device */
@@ -426,6 +414,7 @@ rte_eth_dev_attach(const char *devargs, uint8_t *port_id)int rte_eth_dev_detach (uint8_t port_id,char *name) { +struct rte_eth_dev *dev;int ret =-1 ;if (name ==NULL ) {
@@ -434,15 +423,15 @@ rte_eth_dev_detach(uint8_t port_id, char *name) }/* FIXME: move this to eal, once device flags are relocated there */ -if (rte_eth_dev_is_detachable (port_id)) +if (!rte_eth_dev_is_detachable (port_id)) goto err; -snprintf (name,sizeof (rte_eth_devices[port_id].data->name), -"%s" , rte_eth_devices[port_id].data->name); - ret =rte_eal_dev_detach (name); + dev = &rte_eth_devices[port_id]; +snprintf (name,RTE_ETH_NAME_MAX_LEN -1 ,"%s" , dev->device->name); + ret =rte_eal_device_detach (dev->device);if (ret <0 ) goto err; - + dev->state =RTE_ETH_DEV_UNUSED ;return 0 ; err:
Signature · 1 line
2.1.4
Re: [PATCH v4 9/9] ethdev: use embedded rte_device to detach driver
21/06/2017 01:29, Gaetan Rivet:
Quoted 21 lines
lib/librte_ether/rte_ethdev.c +1
-11@@ -354,26 +354,14 @@ rte_eth_dev_get_port_by_name(const char *name, uint8_t *port_id)static int rte_eth_dev_is_detachable (uint8_t port_id) { -uint32_t dev_flags; +struct rte_eth_dev *dev;RTE_ETH_VALID_PORTID_OR_ERR_RET (port_id, -EINVAL ); -switch (rte_eth_devices[port_id].data->kdrv) { -case RTE_KDRV_IGB_UIO : -case RTE_KDRV_UIO_GENERIC : -case RTE_KDRV_NIC_UIO : -case RTE_KDRV_NONE : -case RTE_KDRV_VFIO : -break ; -default : -return -ENOTSUP ; - }
lib/librte_ether/rte_ethdev.c rte_eth_dev_get_port_by_name(const char *name, uint8_t *port_id) · line 365
Quoted 10 lines
lib/librte_ether/rte_ethdev.c +3
-5- dev_flags = rte_eth_devices[port_id].data->dev_flags; -if ((dev_flags &RTE_ETH_DEV_DETACHABLE ) && - (!(dev_flags &RTE_ETH_DEV_BONDED_SLAVE ))) + dev = &rte_eth_devices[port_id]; +if (dev->data->dev_flags &RTE_ETH_DEV_BONDED_SLAVE )return 0 ; -else -return 1 ; +return !!dev->device->devargs->bus->unplug; }
The changes in rte_eth_dev_is_detachable() deserves a separate commit.
Are you removing RTE_ETH_DEV_DETACHABLE flag?
I think this change cannot be done before implementing unplug in PCI.
Re: [PATCH v4 9/9] ethdev: use embedded rte_device to detach driver
In reply to Gaetan Rivet21/06/2017 01:29, Gaetan Rivet:
lib/librte_ether/rte_ethdev.c rte_eth_dev_get_port_by_name(const char *name, uint8_t *port_id) · line 364
Quoted 1 line
lib/librte_ether/rte_ethdev.c +1
-0+return !!dev->device->devargs->bus->unplug;
lib/librte_ether/rte_ethdev.c:364:33: fatal error:
no member named 'bus' in 'struct rte_devargs'
Please move this patch alone, specifying the right dependency.