All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC] eal: allow hotplug to skip an already probed device
@ 2018-09-07 23:09 Thomas Monjalon
  2018-09-13  6:29 ` Ophir Munk
                   ` (4 more replies)
  0 siblings, 5 replies; 58+ messages in thread
From: Thomas Monjalon @ 2018-09-07 23:09 UTC (permalink / raw)
  To: dev; +Cc: gaetan.rivet

In the devargs syntax for device representors, it is possible to add
several devices at once: -w dbdf,representor=[0-3]
It will become a more frequent case when introducing wildcards
and ranges in the new devargs syntax.

If a devargs string is provided for probing, and updated with a bigger
range for a new probing, then we do not want it to fail because
part of this range was already probed previously.

On the opposite, we could require rte_eal_hotplug_add() to try
to add all matching devices, and fail if one is already probed.

That's why a new parameter is added to specify if the function
must fail or not when trying to add an already probed device.

Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
---
This patch contains only the change in the function itself as RFC.

This idea was presented at Dublin during the "hotplug talk".
---
 lib/librte_eal/common/eal_common_dev.c  | 4 +++-
 lib/librte_eal/common/include/rte_dev.h | 5 ++++-
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c
index 678dbcac7..17d7e9089 100644
--- a/lib/librte_eal/common/eal_common_dev.c
+++ b/lib/librte_eal/common/eal_common_dev.c
@@ -128,7 +128,7 @@ int rte_eal_dev_detach(struct rte_device *dev)
 }
 
 int __rte_experimental rte_eal_hotplug_add(const char *busname, const char *devname,
-			const char *devargs)
+			const char *devargs, bool fail_existing)
 {
 	struct rte_bus *bus;
 	struct rte_device *dev;
@@ -173,6 +173,8 @@ int __rte_experimental rte_eal_hotplug_add(const char *busname, const char *devn
 	}
 
 	if (dev->driver != NULL) {
+		if (!fail_existing)
+			return 0;
 		RTE_LOG(ERR, EAL, "Device is already plugged\n");
 		return -EEXIST;
 	}
diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
index b80a80598..10a1cd2b4 100644
--- a/lib/librte_eal/common/include/rte_dev.h
+++ b/lib/librte_eal/common/include/rte_dev.h
@@ -201,11 +201,14 @@ int rte_eal_dev_detach(struct rte_device *dev);
  *   capable of handling it and pass it to the driver probing function.
  * @param devargs
  *   Device arguments to be passed to the driver.
+ * @param fail_existing
+ *   If true and a matching device is already probed, then return -EEXIST.
+ *   If false, then skip the already probed device without returning an error.
  * @return
  *   0 on success, negative on error.
  */
 int __rte_experimental rte_eal_hotplug_add(const char *busname, const char *devname,
-			const char *devargs);
+			const char *devargs, bool fail_existing);
 
 /**
  * @warning
-- 
2.18.0

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

* Re: [RFC] eal: allow hotplug to skip an already probed device
  2018-09-07 23:09 [RFC] eal: allow hotplug to skip an already probed device Thomas Monjalon
@ 2018-09-13  6:29 ` Ophir Munk
  2018-09-16 10:14   ` Ophir Munk
  2018-09-28 16:40 ` [PATCH v2 0/3] " Thomas Monjalon
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 58+ messages in thread
From: Ophir Munk @ 2018-09-13  6:29 UTC (permalink / raw)
  To: Thomas Monjalon, dev; +Cc: gaetan.rivet, Olga Shern, Shahaf Shuler, Asaf Penso



> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Thomas Monjalon
> Sent: Saturday, September 08, 2018 2:10 AM
> To: dev@dpdk.org
> Cc: gaetan.rivet@6wind.com
> Subject: [dpdk-dev] [RFC] eal: allow hotplug to skip an already probed device
> 
> In the devargs syntax for device representors, it is possible to add several
> devices at once: -w dbdf,representor=[0-3] It will become a more frequent
> case when introducing wildcards and ranges in the new devargs syntax.
> 
> If a devargs string is provided for probing, and updated with a bigger range
> for a new probing, then we do not want it to fail because part of this range
> was already probed previously.
> 

When having devargs with representors ("dbdf,representor=<args>") there is actually just one PCI device to probe (whose address is "dbdf", the master) while the representors themselves are net devices all using the same PCI "dbdf" address. 
The way to see it: when running "lspci": only the "dpdf" PCI device appears while when executing "ifconfig" - all representors are shown as net devices.
When calling rte_eal_hotplug_add() for the first time there is a flow which eventually calls the PMD probe callback (e.g. mlx5_pci_probe() in case of mlx5 PMD). 
When calling rte_eal_hotplug_add() for several times we should skip failures till we reach the PMD probe callback.

Skipping failures can be done as follows:
1. In file ./lib/librte_eal/common/eal_common_dev.c, function: rte_eal_hotplug_add(), remove the following code:

if (dev->driver != NULL) {
	RTE_LOG(ERR, EAL, "Device is already plugged\n");
	return -EEXIST}

2. In file ./drivers/bus/pci/pci_common.cm function: pci_probe_all_drivers(), remove the following code:

/* Check if a driver is already loaded */ if (dev->driver != NULL)
	return -1;


However the substantial major changes are in each individual PMD probe callback when it is called several times with different devargs. For example it should not fail an already probed PCI device and just create new eth devices for new representors.


> On the opposite, we could require rte_eal_hotplug_add() to try to add all
> matching devices, and fail if one is already probed.
> 
> That's why a new parameter is added to specify if the function must fail or
> not when trying to add an already probed device.
> 

Please note this new parameter ("fail_existing") will have to be propagated to all PMD probe callbacks.
Otherwise, in case (fail_existing == false) a second call to rte_eal_hotplug_add() will call the PMD probe callback, which may fail unless it is aware of "fail_existing" parameter.
Alternatively "fail_existing" may be better named "enable_multi_probes".
Anyway - if the PMD probe() callback has to be updated to return a success/failure value (for more than one probe) - maybe we do not need a new parameter and can rely on the PMD probe() callback the take the decision by returning success/failure value.

The counter part of rte_eal_hotplug_add() is rte_eal_hotplug_remove() which must be updated as well. For example when representors 1 and 2 exist - then removing just representor 1 will have to make sure that the PCI device used for both representors is not unplugged since representor 2 is not removed and it uses the same PCI device as representor 1.

> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
> ---
> This patch contains only the change in the function itself as RFC.
> 
> This idea was presented at Dublin during the "hotplug talk".
> ---
>  lib/librte_eal/common/eal_common_dev.c  | 4 +++-
> lib/librte_eal/common/include/rte_dev.h | 5 ++++-
>  2 files changed, 7 insertions(+), 2 deletions(-)
> 
> diff --git a/lib/librte_eal/common/eal_common_dev.c
> b/lib/librte_eal/common/eal_common_dev.c
> index 678dbcac7..17d7e9089 100644
> --- a/lib/librte_eal/common/eal_common_dev.c
> +++ b/lib/librte_eal/common/eal_common_dev.c
> @@ -128,7 +128,7 @@ int rte_eal_dev_detach(struct rte_device *dev)  }
> 
>  int __rte_experimental rte_eal_hotplug_add(const char *busname, const
> char *devname,
> -			const char *devargs)
> +			const char *devargs, bool fail_existing)
>  {
>  	struct rte_bus *bus;
>  	struct rte_device *dev;
> @@ -173,6 +173,8 @@ int __rte_experimental rte_eal_hotplug_add(const
> char *busname, const char *devn
>  	}
> 
>  	if (dev->driver != NULL) {
> +		if (!fail_existing)
> +			return 0;
>  		RTE_LOG(ERR, EAL, "Device is already plugged\n");
>  		return -EEXIST;
>  	}
> diff --git a/lib/librte_eal/common/include/rte_dev.h
> b/lib/librte_eal/common/include/rte_dev.h
> index b80a80598..10a1cd2b4 100644
> --- a/lib/librte_eal/common/include/rte_dev.h
> +++ b/lib/librte_eal/common/include/rte_dev.h
> @@ -201,11 +201,14 @@ int rte_eal_dev_detach(struct rte_device *dev);
>   *   capable of handling it and pass it to the driver probing function.
>   * @param devargs
>   *   Device arguments to be passed to the driver.
> + * @param fail_existing
> + *   If true and a matching device is already probed, then return -EEXIST.
> + *   If false, then skip the already probed device without returning an error.
>   * @return
>   *   0 on success, negative on error.
>   */
>  int __rte_experimental rte_eal_hotplug_add(const char *busname, const
> char *devname,
> -			const char *devargs);
> +			const char *devargs, bool fail_existing);
> 
>  /**
>   * @warning
> --
> 2.18.0

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

* Re: [RFC] eal: allow hotplug to skip an already probed device
  2018-09-13  6:29 ` Ophir Munk
@ 2018-09-16 10:14   ` Ophir Munk
  0 siblings, 0 replies; 58+ messages in thread
From: Ophir Munk @ 2018-09-16 10:14 UTC (permalink / raw)
  To: Thomas Monjalon, dev; +Cc: gaetan.rivet, Olga Shern, Shahaf Shuler, Asaf Penso



> -----Original Message-----
> From: Ophir Munk
> Sent: Thursday, September 13, 2018 9:30 AM
> To: Thomas Monjalon <thomas@monjalon.net>; dev@dpdk.org
> Cc: gaetan.rivet@6wind.com; Olga Shern <olgas@mellanox.com>; Shahaf
> Shuler <shahafs@mellanox.com>; Asaf Penso <asafp@mellanox.com>
> Subject: RE: [dpdk-dev] [RFC] eal: allow hotplug to skip an already probed
> device
> 
> 
> 
> > -----Original Message-----
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Thomas Monjalon
> > Sent: Saturday, September 08, 2018 2:10 AM
> > To: dev@dpdk.org
> > Cc: gaetan.rivet@6wind.com
> > Subject: [dpdk-dev] [RFC] eal: allow hotplug to skip an already probed
> > device
> >
> > In the devargs syntax for device representors, it is possible to add
> > several devices at once: -w dbdf,representor=[0-3] It will become a
> > more frequent case when introducing wildcards and ranges in the new
> devargs syntax.
> >
> > If a devargs string is provided for probing, and updated with a bigger
> > range for a new probing, then we do not want it to fail because part
> > of this range was already probed previously.
> >
> 
> When having devargs with representors ("dbdf,representor=<args>") there is
> actually just one PCI device to probe (whose address is "dbdf", the master)
> while the representors themselves are net devices all using the same PCI
> "dbdf" address.
> The way to see it: when running "lspci": only the "dpdf" PCI device appears
> while when executing "ifconfig" - all representors are shown as net devices.
> When calling rte_eal_hotplug_add() for the first time there is a flow which
> eventually calls the PMD probe callback (e.g. mlx5_pci_probe() in case of
> mlx5 PMD).
> When calling rte_eal_hotplug_add() for several times we should skip failures
> till we reach the PMD probe callback.
> 
> Skipping failures can be done as follows:
> 1. In file ./lib/librte_eal/common/eal_common_dev.c, function:
> rte_eal_hotplug_add(), remove the following code:
> 
> if (dev->driver != NULL) {
> 	RTE_LOG(ERR, EAL, "Device is already plugged\n");
> 	return -EEXIST}
> 
> 2. In file ./drivers/bus/pci/pci_common.cm function: pci_probe_all_drivers(),
> remove the following code:
> 
> /* Check if a driver is already loaded */ if (dev->driver != NULL)
> 	return -1;
> 
> 
> However the substantial major changes are in each individual PMD probe
> callback when it is called several times with different devargs. For example it
> should not fail an already probed PCI device and just create new eth devices
> for new representors.
> 
> 
> > On the opposite, we could require rte_eal_hotplug_add() to try to add
> > all matching devices, and fail if one is already probed.
> >
> > That's why a new parameter is added to specify if the function must
> > fail or not when trying to add an already probed device.
> >
> 
> Please note this new parameter ("fail_existing") will have to be propagated
> to all PMD probe callbacks.
> Otherwise, in case (fail_existing == false) a second call to
> rte_eal_hotplug_add() will call the PMD probe callback, which may fail unless
> it is aware of "fail_existing" parameter.
> Alternatively "fail_existing" may be better named "enable_multi_probes".
> Anyway - if the PMD probe() callback has to be updated to return a
> success/failure value (for more than one probe) - maybe we do not need a
> new parameter and can rely on the PMD probe() callback the take the
> decision by returning success/failure value.
> 
> The counter part of rte_eal_hotplug_add() is rte_eal_hotplug_remove()
> which must be updated as well. For example when representors 1 and 2 exist
> - then removing just representor 1 will have to make sure that the PCI device
> used for both representors is not unplugged since representor 2 is not
> removed and it uses the same PCI device as representor 1.
> 

To make it clearer: the flow initiated by calling rte_eal_hotplug_removed() should eventually call the PMD remote() callback which in turn should manage a reference count to all representor devices and decide which ones should be closed.

> > Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
> > ---
> > This patch contains only the change in the function itself as RFC.
> >
> > This idea was presented at Dublin during the "hotplug talk".
> > ---
> >  lib/librte_eal/common/eal_common_dev.c  | 4 +++-
> > lib/librte_eal/common/include/rte_dev.h | 5 ++++-
> >  2 files changed, 7 insertions(+), 2 deletions(-)
> >
> > diff --git a/lib/librte_eal/common/eal_common_dev.c
> > b/lib/librte_eal/common/eal_common_dev.c
> > index 678dbcac7..17d7e9089 100644
> > --- a/lib/librte_eal/common/eal_common_dev.c
> > +++ b/lib/librte_eal/common/eal_common_dev.c
> > @@ -128,7 +128,7 @@ int rte_eal_dev_detach(struct rte_device *dev)  }
> >
> >  int __rte_experimental rte_eal_hotplug_add(const char *busname, const
> > char *devname,
> > -			const char *devargs)
> > +			const char *devargs, bool fail_existing)
> >  {
> >  	struct rte_bus *bus;
> >  	struct rte_device *dev;
> > @@ -173,6 +173,8 @@ int __rte_experimental rte_eal_hotplug_add(const
> > char *busname, const char *devn
> >  	}
> >
> >  	if (dev->driver != NULL) {
> > +		if (!fail_existing)
> > +			return 0;
> >  		RTE_LOG(ERR, EAL, "Device is already plugged\n");
> >  		return -EEXIST;
> >  	}
> > diff --git a/lib/librte_eal/common/include/rte_dev.h
> > b/lib/librte_eal/common/include/rte_dev.h
> > index b80a80598..10a1cd2b4 100644
> > --- a/lib/librte_eal/common/include/rte_dev.h
> > +++ b/lib/librte_eal/common/include/rte_dev.h
> > @@ -201,11 +201,14 @@ int rte_eal_dev_detach(struct rte_device *dev);
> >   *   capable of handling it and pass it to the driver probing function.
> >   * @param devargs
> >   *   Device arguments to be passed to the driver.
> > + * @param fail_existing
> > + *   If true and a matching device is already probed, then return -EEXIST.
> > + *   If false, then skip the already probed device without returning an
> error.
> >   * @return
> >   *   0 on success, negative on error.
> >   */
> >  int __rte_experimental rte_eal_hotplug_add(const char *busname, const
> > char *devname,
> > -			const char *devargs);
> > +			const char *devargs, bool fail_existing);
> >
> >  /**
> >   * @warning
> > --
> > 2.18.0

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

* [PATCH v2 0/3] eal: allow hotplug to skip an already probed device
  2018-09-07 23:09 [RFC] eal: allow hotplug to skip an already probed device Thomas Monjalon
  2018-09-13  6:29 ` Ophir Munk
@ 2018-09-28 16:40 ` Thomas Monjalon
  2018-09-28 16:40   ` [PATCH v2 1/3] drivers/bus: move driver assignment to end of probing Thomas Monjalon
                     ` (2 more replies)
  2018-10-07 22:09 ` [PATCH v3 0/3] eal: allow hotplug to skip an already probed device Thomas Monjalon
                   ` (2 subsequent siblings)
  4 siblings, 3 replies; 58+ messages in thread
From: Thomas Monjalon @ 2018-09-28 16:40 UTC (permalink / raw)
  To: dev; +Cc: gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit

This is a follow-up of an idea presented at Dublin
during the "hotplug talk".

The idea is to ease probing of range of ports attached
to the same rte_device.
I becomes possible to allow probing again the same device
but with a bigger range of ports in the devargs.

Instead of adding a parameter to the hotplug functions, as in the RFC,
the check of an already probed device is moved to the PMDs.
It gives flexibility to drivers for managing range of ports.


This series is based on top of
https://patches.dpdk.org/project/dpdk/list/?series=1579

Depends on: project/dpdk/list/?series=1579
(proposed syntax for dependencies)


Thomas Monjalon (3):
  drivers/bus: move driver assignment to end of probing
  eal: add function to query device status
  eal: allow probing a device again

 drivers/bus/dpaa/dpaa_bus.c                |  3 +++
 drivers/bus/fslmc/fslmc_bus.c              |  3 +++
 drivers/bus/ifpga/ifpga_bus.c              | 22 +++++++++--------
 drivers/bus/pci/pci_common.c               | 20 +++++++++-------
 drivers/bus/pci/rte_bus_pci.h              |  2 +-
 drivers/bus/vdev/vdev.c                    | 12 ++++++----
 drivers/bus/vmbus/vmbus_common.c           | 28 ++++++++++++----------
 drivers/common/qat/Makefile                |  3 ++-
 drivers/common/qat/meson.build             |  1 +
 drivers/common/qat/qat_device.c            |  3 +++
 drivers/compress/octeontx/otx_zip_pmd.c    |  3 +++
 drivers/crypto/virtio/Makefile             |  1 +
 drivers/crypto/virtio/meson.build          |  1 +
 drivers/crypto/virtio/virtio_cryptodev.c   |  3 +++
 drivers/event/octeontx/ssovf_probe.c       |  6 +++++
 drivers/event/skeleton/Makefile            |  1 +
 drivers/event/skeleton/meson.build         |  1 +
 drivers/mempool/octeontx/Makefile          |  1 +
 drivers/mempool/octeontx/meson.build       |  2 ++
 drivers/mempool/octeontx/octeontx_fpavf.c  |  3 +++
 drivers/net/ark/Makefile                   |  1 +
 drivers/net/ark/meson.build                |  1 +
 drivers/net/avf/Makefile                   |  1 +
 drivers/net/avp/Makefile                   |  1 +
 drivers/net/avp/meson.build                |  1 +
 drivers/net/axgbe/Makefile                 |  1 +
 drivers/net/axgbe/meson.build              |  2 ++
 drivers/net/bnx2x/Makefile                 |  1 +
 drivers/net/bnx2x/meson.build              |  1 +
 drivers/net/bnxt/Makefile                  |  1 +
 drivers/net/bnxt/meson.build               |  1 +
 drivers/net/cxgbe/Makefile                 |  1 +
 drivers/net/cxgbe/meson.build              |  2 ++
 drivers/net/e1000/Makefile                 |  1 +
 drivers/net/e1000/meson.build              |  2 ++
 drivers/net/enic/Makefile                  |  1 +
 drivers/net/enic/meson.build               |  2 ++
 drivers/net/fm10k/Makefile                 |  1 +
 drivers/net/fm10k/meson.build              |  2 ++
 drivers/net/i40e/i40e_ethdev.c             |  3 +++
 drivers/net/i40e/i40e_vf_representor.c     |  3 ---
 drivers/net/ifc/ifcvf_vdpa.c               |  3 +++
 drivers/net/ixgbe/ixgbe_ethdev.c           |  3 +++
 drivers/net/liquidio/Makefile              |  1 +
 drivers/net/liquidio/meson.build           |  1 +
 drivers/net/mlx4/mlx4.c                    |  5 +++-
 drivers/net/mlx5/mlx5.c                    |  5 +++-
 drivers/net/netvsc/hn_ethdev.c             |  9 ++++---
 drivers/net/nfp/Makefile                   |  1 +
 drivers/net/nfp/meson.build                |  1 +
 drivers/net/nfp/nfp_net.c                  |  3 +++
 drivers/net/octeontx/Makefile              |  3 +--
 drivers/net/octeontx/base/meson.build      |  2 +-
 drivers/net/octeontx/base/octeontx_pkivf.c |  3 +++
 drivers/net/octeontx/base/octeontx_pkovf.c |  3 +++
 drivers/net/qede/Makefile                  |  1 +
 drivers/net/qede/meson.build               |  2 ++
 drivers/net/szedata2/Makefile              |  1 +
 drivers/net/szedata2/meson.build           |  1 +
 drivers/net/szedata2/rte_eth_szedata2.c    |  3 +++
 drivers/net/thunderx/Makefile              |  1 +
 drivers/net/thunderx/meson.build           |  2 ++
 drivers/raw/ifpga_rawdev/ifpga_rawdev.c    |  3 +++
 lib/librte_eal/common/eal_common_dev.c     | 12 ++++++----
 lib/librte_eal/common/include/rte_dev.h    | 18 ++++++++++++--
 lib/librte_eal/rte_eal_version.map         |  1 +
 lib/librte_ethdev/rte_ethdev_pci.h         |  3 +++
 lib/librte_eventdev/rte_eventdev_pmd_pci.h |  3 +++
 68 files changed, 187 insertions(+), 56 deletions(-)

-- 
2.19.0

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

* [PATCH v2 1/3] drivers/bus: move driver assignment to end of probing
  2018-09-28 16:40 ` [PATCH v2 0/3] " Thomas Monjalon
@ 2018-09-28 16:40   ` Thomas Monjalon
  2018-09-28 16:40   ` [PATCH v2 2/3] eal: add function to query device status Thomas Monjalon
  2018-09-28 16:40   ` [PATCH v2 3/3] eal: allow probing a device again Thomas Monjalon
  2 siblings, 0 replies; 58+ messages in thread
From: Thomas Monjalon @ 2018-09-28 16:40 UTC (permalink / raw)
  To: dev; +Cc: gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit

The PCI mapping requires to know the PCI driver to use,
even before the probing is done. That's why the PCI driver is
referenced early inside the PCI device structure. See
1d20a073fa5e ("bus/pci: reference driver structure before mapping")

However the rte_driver does not need to be referenced in rte_device
before the device probing is done.
By moving back this assignment at the end of the device probing,
it becomes possible to make clear the status of a rte_device.

Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
---
 drivers/bus/ifpga/ifpga_bus.c           | 9 ++++-----
 drivers/bus/pci/pci_common.c            | 7 +++----
 drivers/bus/pci/rte_bus_pci.h           | 2 +-
 drivers/bus/vdev/vdev.c                 | 5 ++---
 drivers/bus/vmbus/vmbus_common.c        | 5 +++--
 drivers/net/i40e/i40e_vf_representor.c  | 3 ---
 drivers/net/mlx4/mlx4.c                 | 1 -
 drivers/net/mlx5/mlx5.c                 | 1 -
 lib/librte_eal/common/include/rte_dev.h | 2 +-
 9 files changed, 14 insertions(+), 21 deletions(-)

diff --git a/drivers/bus/ifpga/ifpga_bus.c b/drivers/bus/ifpga/ifpga_bus.c
index 3ef035b7e..a20afb5c7 100644
--- a/drivers/bus/ifpga/ifpga_bus.c
+++ b/drivers/bus/ifpga/ifpga_bus.c
@@ -279,14 +279,13 @@ ifpga_probe_one_driver(struct rte_afu_driver *drv,
 
 	/* reference driver structure */
 	afu_dev->driver = drv;
-	afu_dev->device.driver = &drv->driver;
 
 	/* call the driver probe() function */
 	ret = drv->probe(afu_dev);
-	if (ret) {
+	if (ret)
 		afu_dev->driver = NULL;
-		afu_dev->device.driver = NULL;
-	}
+	else
+		afu_dev->device.driver = &drv->driver;
 
 	return ret;
 }
@@ -301,7 +300,7 @@ ifpga_probe_all_drivers(struct rte_afu_device *afu_dev)
 		return -1;
 
 	/* Check if a driver is already loaded */
-	if (afu_dev->driver != NULL)
+	if (afu_dev->device.driver != NULL)
 		return 0;
 
 	TAILQ_FOREACH(drv, &ifpga_afu_drv_list, next) {
diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
index 7736b3f9c..a0adc99c8 100644
--- a/drivers/bus/pci/pci_common.c
+++ b/drivers/bus/pci/pci_common.c
@@ -162,14 +162,12 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
 	 * driver flags for adjusting configuration.
 	 */
 	dev->driver = dr;
-	dev->device.driver = &dr->driver;
 
 	if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) {
 		/* map resources for devices that use igb_uio */
 		ret = rte_pci_map_device(dev);
 		if (ret != 0) {
 			dev->driver = NULL;
-			dev->device.driver = NULL;
 			return ret;
 		}
 	}
@@ -178,7 +176,6 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
 	ret = dr->probe(dr, dev);
 	if (ret) {
 		dev->driver = NULL;
-		dev->device.driver = NULL;
 		if ((dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) &&
 			/* Don't unmap if device is unsupported and
 			 * driver needs mapped resources.
@@ -186,6 +183,8 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
 			!(ret > 0 &&
 				(dr->drv_flags & RTE_PCI_DRV_KEEP_MAPPED_RES)))
 			rte_pci_unmap_device(dev);
+	} else {
+		dev->device.driver = &dr->driver;
 	}
 
 	return ret;
@@ -246,7 +245,7 @@ pci_probe_all_drivers(struct rte_pci_device *dev)
 		return -1;
 
 	/* Check if a driver is already loaded */
-	if (dev->driver != NULL)
+	if (dev->device.driver != NULL)
 		return 0;
 
 	FOREACH_DRIVER_ON_PCIBUS(dr) {
diff --git a/drivers/bus/pci/rte_bus_pci.h b/drivers/bus/pci/rte_bus_pci.h
index 0d1955ffe..984df2b37 100644
--- a/drivers/bus/pci/rte_bus_pci.h
+++ b/drivers/bus/pci/rte_bus_pci.h
@@ -62,7 +62,7 @@ struct rte_pci_device {
 	struct rte_mem_resource mem_resource[PCI_MAX_RESOURCE];
 					    /**< PCI Memory Resource */
 	struct rte_intr_handle intr_handle; /**< Interrupt handle */
-	struct rte_pci_driver *driver;      /**< Associated driver */
+	struct rte_pci_driver *driver;      /**< PCI driver used in probing */
 	uint16_t max_vfs;                   /**< sriov enable if not zero */
 	enum rte_kernel_driver kdrv;        /**< Kernel driver passthrough */
 	char name[PCI_PRI_STR_SIZE+1];      /**< PCI location (ASCII) */
diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
index 390c2ce70..e7f321706 100644
--- a/drivers/bus/vdev/vdev.c
+++ b/drivers/bus/vdev/vdev.c
@@ -149,10 +149,9 @@ vdev_probe_all_drivers(struct rte_vdev_device *dev)
 
 	if (vdev_parse(name, &driver))
 		return -1;
-	dev->device.driver = &driver->driver;
 	ret = driver->probe(dev);
-	if (ret)
-		dev->device.driver = NULL;
+	if (ret == 0)
+		dev->device.driver = &driver->driver;
 	return ret;
 }
 
diff --git a/drivers/bus/vmbus/vmbus_common.c b/drivers/bus/vmbus/vmbus_common.c
index e3ceb6906..de5548aa4 100644
--- a/drivers/bus/vmbus/vmbus_common.c
+++ b/drivers/bus/vmbus/vmbus_common.c
@@ -111,7 +111,6 @@ vmbus_probe_one_driver(struct rte_vmbus_driver *dr,
 
 	/* reference driver structure */
 	dev->driver = dr;
-	dev->device.driver = &dr->driver;
 
 	if (dev->device.numa_node < 0) {
 		VMBUS_LOG(WARNING, "  Invalid NUMA socket, default to 0");
@@ -124,6 +123,8 @@ vmbus_probe_one_driver(struct rte_vmbus_driver *dr,
 	if (ret) {
 		dev->driver = NULL;
 		rte_vmbus_unmap_device(dev);
+	} else {
+		dev->device.driver = &dr->driver;
 	}
 
 	return ret;
@@ -142,7 +143,7 @@ vmbus_probe_all_drivers(struct rte_vmbus_device *dev)
 	int rc;
 
 	/* Check if a driver is already loaded */
-	if (dev->driver != NULL) {
+	if (dev->device.driver != NULL) {
 		VMBUS_LOG(DEBUG, "VMBUS driver already loaded");
 		return 0;
 	}
diff --git a/drivers/net/i40e/i40e_vf_representor.c b/drivers/net/i40e/i40e_vf_representor.c
index f9f131611..1e9998278 100644
--- a/drivers/net/i40e/i40e_vf_representor.c
+++ b/drivers/net/i40e/i40e_vf_representor.c
@@ -486,9 +486,6 @@ i40e_vf_representor_init(struct rte_eth_dev *ethdev, void *init_params)
 	if (representor->vf_id >= pf->vf_num)
 		return -ENODEV;
 
-	/** representor shares the same driver as it's PF device */
-	ethdev->device->driver = representor->adapter->eth_dev->device->driver;
-
 	/* Set representor device ops */
 	ethdev->dev_ops = &i40e_representor_dev_ops;
 
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index defc0d4b0..3de7bc53e 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -734,7 +734,6 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 		eth_dev->data->mac_addrs = priv->mac;
 		eth_dev->device = &pci_dev->device;
 		rte_eth_copy_pci_info(eth_dev, pci_dev);
-		eth_dev->device->driver = &mlx4_driver.driver;
 		/* Initialize local interrupt handle for current port. */
 		priv->intr_handle = (struct rte_intr_handle){
 			.fd = -1,
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 30d4e70a7..f5f3a3d19 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -1081,7 +1081,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	priv->dev_data = eth_dev->data;
 	eth_dev->data->mac_addrs = priv->mac;
 	eth_dev->device = dpdk_dev;
-	eth_dev->device->driver = &mlx5_driver.driver;
 	err = mlx5_uar_init_primary(eth_dev);
 	if (err) {
 		err = rte_errno;
diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
index ee77e4006..61542c7d1 100644
--- a/lib/librte_eal/common/include/rte_dev.h
+++ b/lib/librte_eal/common/include/rte_dev.h
@@ -156,7 +156,7 @@ struct rte_driver {
 struct rte_device {
 	TAILQ_ENTRY(rte_device) next; /**< Next device */
 	const char *name;             /**< Device name */
-	const struct rte_driver *driver;/**< Associated driver */
+	const struct rte_driver *driver; /**< Driver associated after probing */
 	int numa_node;                /**< NUMA node connection */
 	struct rte_devargs *devargs;  /**< Device user arguments */
 };
-- 
2.19.0

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

* [PATCH v2 2/3] eal: add function to query device status
  2018-09-28 16:40 ` [PATCH v2 0/3] " Thomas Monjalon
  2018-09-28 16:40   ` [PATCH v2 1/3] drivers/bus: move driver assignment to end of probing Thomas Monjalon
@ 2018-09-28 16:40   ` Thomas Monjalon
  2018-09-28 16:40   ` [PATCH v2 3/3] eal: allow probing a device again Thomas Monjalon
  2 siblings, 0 replies; 58+ messages in thread
From: Thomas Monjalon @ 2018-09-28 16:40 UTC (permalink / raw)
  To: dev; +Cc: gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit

The function rte_dev_is_probed() is added in order to improve semantic
and enforce proper check of the probing status of a device.

It will answer this rte_device query:
Is it already successfully probed or not?

Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
---
 drivers/bus/ifpga/ifpga_bus.c           |  4 ++--
 drivers/bus/pci/pci_common.c            |  2 +-
 drivers/bus/vdev/vdev.c                 |  2 +-
 drivers/bus/vmbus/vmbus_common.c        |  2 +-
 lib/librte_eal/common/eal_common_dev.c  |  9 ++++++++-
 lib/librte_eal/common/include/rte_dev.h | 14 ++++++++++++++
 lib/librte_eal/rte_eal_version.map      |  1 +
 7 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/drivers/bus/ifpga/ifpga_bus.c b/drivers/bus/ifpga/ifpga_bus.c
index a20afb5c7..5ce886d13 100644
--- a/drivers/bus/ifpga/ifpga_bus.c
+++ b/drivers/bus/ifpga/ifpga_bus.c
@@ -300,7 +300,7 @@ ifpga_probe_all_drivers(struct rte_afu_device *afu_dev)
 		return -1;
 
 	/* Check if a driver is already loaded */
-	if (afu_dev->device.driver != NULL)
+	if (rte_dev_is_probed(&afu_dev->device))
 		return 0;
 
 	TAILQ_FOREACH(drv, &ifpga_afu_drv_list, next) {
@@ -324,7 +324,7 @@ ifpga_probe(void)
 	int ret = 0;
 
 	TAILQ_FOREACH(afu_dev, &ifpga_afu_dev_list, next) {
-		if (afu_dev->device.driver)
+		if (rte_dev_is_probed(&afu_dev->device))
 			continue;
 
 		ret = ifpga_probe_all_drivers(afu_dev);
diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
index a0adc99c8..d95410e19 100644
--- a/drivers/bus/pci/pci_common.c
+++ b/drivers/bus/pci/pci_common.c
@@ -245,7 +245,7 @@ pci_probe_all_drivers(struct rte_pci_device *dev)
 		return -1;
 
 	/* Check if a driver is already loaded */
-	if (dev->device.driver != NULL)
+	if (rte_dev_is_probed(&dev->device))
 		return 0;
 
 	FOREACH_DRIVER_ON_PCIBUS(dr) {
diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
index e7f321706..514d9d5c6 100644
--- a/drivers/bus/vdev/vdev.c
+++ b/drivers/bus/vdev/vdev.c
@@ -479,7 +479,7 @@ vdev_probe(void)
 		 * we call each driver probe.
 		 */
 
-		if (dev->device.driver)
+		if (rte_dev_is_probed(&dev->device))
 			continue;
 
 		if (vdev_probe_all_drivers(dev)) {
diff --git a/drivers/bus/vmbus/vmbus_common.c b/drivers/bus/vmbus/vmbus_common.c
index de5548aa4..48a219f73 100644
--- a/drivers/bus/vmbus/vmbus_common.c
+++ b/drivers/bus/vmbus/vmbus_common.c
@@ -143,7 +143,7 @@ vmbus_probe_all_drivers(struct rte_vmbus_device *dev)
 	int rc;
 
 	/* Check if a driver is already loaded */
-	if (dev->device.driver != NULL) {
+	if (rte_dev_is_probed(&dev->device)) {
 		VMBUS_LOG(DEBUG, "VMBUS driver already loaded");
 		return 0;
 	}
diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c
index b40e4c0d0..907c5c481 100644
--- a/lib/librte_eal/common/eal_common_dev.c
+++ b/lib/librte_eal/common/eal_common_dev.c
@@ -74,6 +74,13 @@ static int cmp_dev_name(const struct rte_device *dev, const void *_name)
 	return strcmp(dev->name, name);
 }
 
+int __rte_experimental
+rte_dev_is_probed(const struct rte_device *dev)
+{
+	/* The field driver should be set only when the probe is successful. */
+	return dev->driver != NULL;
+}
+
 int rte_eal_dev_attach(const char *name, const char *devargs)
 {
 	struct rte_bus *bus;
@@ -184,7 +191,7 @@ rte_dev_probe(const char *devargs)
 		goto err_devarg;
 	}
 
-	if (dev->driver != NULL) {
+	if (rte_dev_is_probed(dev)) {
 		RTE_LOG(ERR, EAL, "Device is already plugged\n");
 		return -EEXIST;
 	}
diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
index 61542c7d1..5b16ee27b 100644
--- a/lib/librte_eal/common/include/rte_dev.h
+++ b/lib/librte_eal/common/include/rte_dev.h
@@ -161,6 +161,20 @@ struct rte_device {
 	struct rte_devargs *devargs;  /**< Device user arguments */
 };
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Query status of a device.
+ *
+ * @param dev
+ *   Generic device pointer.
+ * @return
+ *   (int)true if already probed successfully, 0 otherwise.
+ */
+__rte_experimental
+int rte_dev_is_probed(const struct rte_device *dev);
+
 /**
  * Attach a device to a registered driver.
  *
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index 2ea7a870a..dddcb81ea 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -279,6 +279,7 @@ EXPERIMENTAL {
 	rte_dev_event_callback_unregister;
 	rte_dev_event_monitor_start;
 	rte_dev_event_monitor_stop;
+	rte_dev_is_probed;
 	rte_dev_iterator_init;
 	rte_dev_iterator_next;
 	rte_dev_probe;
-- 
2.19.0

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

* [PATCH v2 3/3] eal: allow probing a device again
  2018-09-28 16:40 ` [PATCH v2 0/3] " Thomas Monjalon
  2018-09-28 16:40   ` [PATCH v2 1/3] drivers/bus: move driver assignment to end of probing Thomas Monjalon
  2018-09-28 16:40   ` [PATCH v2 2/3] eal: add function to query device status Thomas Monjalon
@ 2018-09-28 16:40   ` Thomas Monjalon
  2018-10-04  9:44     ` Doherty, Declan
  2 siblings, 1 reply; 58+ messages in thread
From: Thomas Monjalon @ 2018-09-28 16:40 UTC (permalink / raw)
  To: dev; +Cc: gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit

In the devargs syntax for device representors, it is possible to add
several devices at once: -w dbdf,representor=[0-3]
It will become a more frequent case when introducing wildcards
and ranges in the new devargs syntax.

If a devargs string is provided for probing, and updated with a bigger
range for a new probing, then we do not want it to fail because
part of this range was already probed previously.
There can be new ports to create from an existing rte_device.

That's why the checks for an already probed device
are moved as PMD responsibility.
Only the PMD knows the ports attached to one rte_device.

In the case of vdev, a global check is kept in insert_vdev(),
assuming that a vdev will always have only one port.
In the case of NXP buses, the probing is done only once (no hotplug),
though a check is added at bus level for consistency.

As another consequence of being able to probe in several steps,
the field rte_device.devargs must not be considered as a full
representation of the rte_device, but only the latest probing args.
Anyway, the field rte_device.devargs is used only for probing.

Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
---
 drivers/bus/dpaa/dpaa_bus.c                |  3 +++
 drivers/bus/fslmc/fslmc_bus.c              |  3 +++
 drivers/bus/ifpga/ifpga_bus.c              | 13 ++++++-----
 drivers/bus/pci/pci_common.c               | 15 +++++++------
 drivers/bus/vdev/vdev.c                    |  5 +++++
 drivers/bus/vmbus/vmbus_common.c           | 25 +++++++++++-----------
 drivers/common/qat/Makefile                |  3 ++-
 drivers/common/qat/meson.build             |  1 +
 drivers/common/qat/qat_device.c            |  3 +++
 drivers/compress/octeontx/otx_zip_pmd.c    |  3 +++
 drivers/crypto/virtio/Makefile             |  1 +
 drivers/crypto/virtio/meson.build          |  1 +
 drivers/crypto/virtio/virtio_cryptodev.c   |  3 +++
 drivers/event/octeontx/ssovf_probe.c       |  6 ++++++
 drivers/event/skeleton/Makefile            |  1 +
 drivers/event/skeleton/meson.build         |  1 +
 drivers/mempool/octeontx/Makefile          |  1 +
 drivers/mempool/octeontx/meson.build       |  2 ++
 drivers/mempool/octeontx/octeontx_fpavf.c  |  3 +++
 drivers/net/ark/Makefile                   |  1 +
 drivers/net/ark/meson.build                |  1 +
 drivers/net/avf/Makefile                   |  1 +
 drivers/net/avp/Makefile                   |  1 +
 drivers/net/avp/meson.build                |  1 +
 drivers/net/axgbe/Makefile                 |  1 +
 drivers/net/axgbe/meson.build              |  2 ++
 drivers/net/bnx2x/Makefile                 |  1 +
 drivers/net/bnx2x/meson.build              |  1 +
 drivers/net/bnxt/Makefile                  |  1 +
 drivers/net/bnxt/meson.build               |  1 +
 drivers/net/cxgbe/Makefile                 |  1 +
 drivers/net/cxgbe/meson.build              |  2 ++
 drivers/net/e1000/Makefile                 |  1 +
 drivers/net/e1000/meson.build              |  2 ++
 drivers/net/enic/Makefile                  |  1 +
 drivers/net/enic/meson.build               |  2 ++
 drivers/net/fm10k/Makefile                 |  1 +
 drivers/net/fm10k/meson.build              |  2 ++
 drivers/net/i40e/i40e_ethdev.c             |  3 +++
 drivers/net/ifc/ifcvf_vdpa.c               |  3 +++
 drivers/net/ixgbe/ixgbe_ethdev.c           |  3 +++
 drivers/net/liquidio/Makefile              |  1 +
 drivers/net/liquidio/meson.build           |  1 +
 drivers/net/mlx4/mlx4.c                    |  4 ++++
 drivers/net/mlx5/mlx5.c                    |  4 ++++
 drivers/net/netvsc/hn_ethdev.c             |  9 +++++---
 drivers/net/nfp/Makefile                   |  1 +
 drivers/net/nfp/meson.build                |  1 +
 drivers/net/nfp/nfp_net.c                  |  3 +++
 drivers/net/octeontx/Makefile              |  3 +--
 drivers/net/octeontx/base/meson.build      |  2 +-
 drivers/net/octeontx/base/octeontx_pkivf.c |  3 +++
 drivers/net/octeontx/base/octeontx_pkovf.c |  3 +++
 drivers/net/qede/Makefile                  |  1 +
 drivers/net/qede/meson.build               |  2 ++
 drivers/net/szedata2/Makefile              |  1 +
 drivers/net/szedata2/meson.build           |  1 +
 drivers/net/szedata2/rte_eth_szedata2.c    |  3 +++
 drivers/net/thunderx/Makefile              |  1 +
 drivers/net/thunderx/meson.build           |  2 ++
 drivers/raw/ifpga_rawdev/ifpga_rawdev.c    |  3 +++
 lib/librte_eal/common/eal_common_dev.c     |  5 -----
 lib/librte_eal/common/include/rte_dev.h    |  2 +-
 lib/librte_ethdev/rte_ethdev_pci.h         |  3 +++
 lib/librte_eventdev/rte_eventdev_pmd_pci.h |  3 +++
 65 files changed, 152 insertions(+), 36 deletions(-)

diff --git a/drivers/bus/dpaa/dpaa_bus.c b/drivers/bus/dpaa/dpaa_bus.c
index 49cd04dbb..5be9da0fa 100644
--- a/drivers/bus/dpaa/dpaa_bus.c
+++ b/drivers/bus/dpaa/dpaa_bus.c
@@ -553,6 +553,9 @@ rte_dpaa_bus_probe(void)
 			if (ret)
 				continue;
 
+			if (rte_dev_is_probed(&dev->device))
+				continue;
+
 			if (!drv->probe ||
 			    (dev->device.devargs &&
 			    dev->device.devargs->policy == RTE_DEV_BLACKLISTED))
diff --git a/drivers/bus/fslmc/fslmc_bus.c b/drivers/bus/fslmc/fslmc_bus.c
index bfe81e236..9011eb74c 100644
--- a/drivers/bus/fslmc/fslmc_bus.c
+++ b/drivers/bus/fslmc/fslmc_bus.c
@@ -384,6 +384,9 @@ rte_fslmc_probe(void)
 			if (!drv->probe)
 				continue;
 
+			if (rte_dev_is_probed(&dev->device))
+				continue;
+
 			if (dev->device.devargs &&
 			  dev->device.devargs->policy == RTE_DEV_BLACKLISTED) {
 				DPAA2_BUS_LOG(DEBUG, "%s Blacklisted, skipping",
diff --git a/drivers/bus/ifpga/ifpga_bus.c b/drivers/bus/ifpga/ifpga_bus.c
index 5ce886d13..a10f54f7b 100644
--- a/drivers/bus/ifpga/ifpga_bus.c
+++ b/drivers/bus/ifpga/ifpga_bus.c
@@ -5,6 +5,7 @@
 #include <string.h>
 #include <inttypes.h>
 #include <stdint.h>
+#include <stdbool.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <sys/queue.h>
@@ -272,16 +273,22 @@ ifpga_probe_one_driver(struct rte_afu_driver *drv,
 			struct rte_afu_device *afu_dev)
 {
 	int ret;
+	bool already_probed;
 
 	if (!rte_afu_match(drv, afu_dev))
 		/* Match of device and driver failed */
 		return 1;
 
+	already_probed = rte_dev_is_probed(&afu_dev->device);
+
 	/* reference driver structure */
-	afu_dev->driver = drv;
+	if (!already_probed)
+		afu_dev->driver = drv;
 
 	/* call the driver probe() function */
 	ret = drv->probe(afu_dev);
+	if (already_probed)
+		return ret; /* no rollback if already succeeded earlier */
 	if (ret)
 		afu_dev->driver = NULL;
 	else
@@ -299,10 +306,6 @@ ifpga_probe_all_drivers(struct rte_afu_device *afu_dev)
 	if (afu_dev == NULL)
 		return -1;
 
-	/* Check if a driver is already loaded */
-	if (rte_dev_is_probed(&afu_dev->device))
-		return 0;
-
 	TAILQ_FOREACH(drv, &ifpga_afu_drv_list, next) {
 		if (ifpga_probe_one_driver(drv, afu_dev)) {
 			ret = -1;
diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
index d95410e19..46f65b415 100644
--- a/drivers/bus/pci/pci_common.c
+++ b/drivers/bus/pci/pci_common.c
@@ -6,6 +6,7 @@
 #include <string.h>
 #include <inttypes.h>
 #include <stdint.h>
+#include <stdbool.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <sys/queue.h>
@@ -123,6 +124,7 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
 			 struct rte_pci_device *dev)
 {
 	int ret;
+	bool already_probed;
 	struct rte_pci_addr *loc;
 
 	if ((dr == NULL) || (dev == NULL))
@@ -153,6 +155,8 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
 		dev->device.numa_node = 0;
 	}
 
+	already_probed = rte_dev_is_probed(&dev->device);
+
 	RTE_LOG(INFO, EAL, "  probe driver: %x:%x %s\n", dev->id.vendor_id,
 		dev->id.device_id, dr->driver.name);
 
@@ -161,9 +165,10 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
 	 * This needs to be before rte_pci_map_device(), as it enables to use
 	 * driver flags for adjusting configuration.
 	 */
-	dev->driver = dr;
+	if (!already_probed)
+		dev->driver = dr;
 
-	if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) {
+	if (!already_probed && (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING)) {
 		/* map resources for devices that use igb_uio */
 		ret = rte_pci_map_device(dev);
 		if (ret != 0) {
@@ -174,6 +179,8 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
 
 	/* call the driver probe() function */
 	ret = dr->probe(dr, dev);
+	if (already_probed)
+		return ret; /* no rollback if already succeeded earlier */
 	if (ret) {
 		dev->driver = NULL;
 		if ((dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) &&
@@ -244,10 +251,6 @@ pci_probe_all_drivers(struct rte_pci_device *dev)
 	if (dev == NULL)
 		return -1;
 
-	/* Check if a driver is already loaded */
-	if (rte_dev_is_probed(&dev->device))
-		return 0;
-
 	FOREACH_DRIVER_ON_PCIBUS(dr) {
 		rc = rte_pci_probe_one_driver(dr, dev);
 		if (rc < 0)
diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
index 514d9d5c6..05a006d15 100644
--- a/drivers/bus/vdev/vdev.c
+++ b/drivers/bus/vdev/vdev.c
@@ -225,6 +225,11 @@ insert_vdev(const char *name, const char *args, struct rte_vdev_device **p_dev)
 	dev->device.name = devargs->name;
 
 	if (find_vdev(name)) {
+		/*
+		 * A vdev is expected to have only one port.
+		 * So there is no reason to try probing again,
+		 * even with new arguments.
+		 */
 		ret = -EEXIST;
 		goto fail;
 	}
diff --git a/drivers/bus/vmbus/vmbus_common.c b/drivers/bus/vmbus/vmbus_common.c
index 48a219f73..eff5c01f5 100644
--- a/drivers/bus/vmbus/vmbus_common.c
+++ b/drivers/bus/vmbus/vmbus_common.c
@@ -3,6 +3,7 @@
  * All Rights Reserved.
  */
 
+#include <stdbool.h>
 #include <string.h>
 #include <unistd.h>
 #include <dirent.h>
@@ -93,6 +94,7 @@ vmbus_probe_one_driver(struct rte_vmbus_driver *dr,
 		       struct rte_vmbus_device *dev)
 {
 	char guid[RTE_UUID_STRLEN];
+	bool already_probed;
 	int ret;
 
 	if (!vmbus_match(dr, dev))
@@ -104,13 +106,16 @@ vmbus_probe_one_driver(struct rte_vmbus_driver *dr,
 
 	/* TODO add blacklisted */
 
-	/* map resources for device */
-	ret = rte_vmbus_map_device(dev);
-	if (ret != 0)
-		return ret;
+	already_probed = rte_dev_is_probed(&dev->device);
+	if (!already_probed) {
+		/* map resources for device */
+		ret = rte_vmbus_map_device(dev);
+		if (ret != 0)
+			return ret;
 
-	/* reference driver structure */
-	dev->driver = dr;
+		/* reference driver structure */
+		dev->driver = dr;
+	}
 
 	if (dev->device.numa_node < 0) {
 		VMBUS_LOG(WARNING, "  Invalid NUMA socket, default to 0");
@@ -120,6 +125,8 @@ vmbus_probe_one_driver(struct rte_vmbus_driver *dr,
 	/* call the driver probe() function */
 	VMBUS_LOG(INFO, "  probe driver: %s", dr->driver.name);
 	ret = dr->probe(dr, dev);
+	if (already_probed)
+		return ret; /* no rollback if already succeeded earlier */
 	if (ret) {
 		dev->driver = NULL;
 		rte_vmbus_unmap_device(dev);
@@ -142,12 +149,6 @@ vmbus_probe_all_drivers(struct rte_vmbus_device *dev)
 	struct rte_vmbus_driver *dr;
 	int rc;
 
-	/* Check if a driver is already loaded */
-	if (rte_dev_is_probed(&dev->device)) {
-		VMBUS_LOG(DEBUG, "VMBUS driver already loaded");
-		return 0;
-	}
-
 	FOREACH_DRIVER_ON_VMBUS(dr) {
 		rc = vmbus_probe_one_driver(dr, dev);
 		if (rc < 0) /* negative is an error */
diff --git a/drivers/common/qat/Makefile b/drivers/common/qat/Makefile
index c68a032a5..294da4927 100644
--- a/drivers/common/qat/Makefile
+++ b/drivers/common/qat/Makefile
@@ -8,6 +8,8 @@ QAT_CRYPTO_DIR := $(RTE_SDK)/drivers/crypto/qat
 QAT_COMPRESS_DIR := $(RTE_SDK)/drivers/compress/qat
 VPATH=$(QAT_CRYPTO_DIR):$(QAT_COMPRESS_DIR)
 
+CFLAGS += -DALLOW_EXPERIMENTAL_API
+
 # external library include paths
 CFLAGS += -I$(SRCDIR)/qat_adf
 CFLAGS += -I$(SRCDIR)
@@ -16,7 +18,6 @@ CFLAGS += -I$(QAT_COMPRESS_DIR)
 
 
 ifeq ($(CONFIG_RTE_LIBRTE_COMPRESSDEV),y)
-	CFLAGS += -DALLOW_EXPERIMENTAL_API
 	LDLIBS += -lrte_compressdev
 	SRCS-y += qat_comp.c
 	SRCS-y += qat_comp_pmd.c
diff --git a/drivers/common/qat/meson.build b/drivers/common/qat/meson.build
index 80b6b25a8..584642917 100644
--- a/drivers/common/qat/meson.build
+++ b/drivers/common/qat/meson.build
@@ -12,3 +12,4 @@ qat_sources = files('qat_common.c',
 qat_includes = [include_directories('.', 'qat_adf')]
 qat_ext_deps = []
 qat_cflags = []
+allow_experimental_apis = true
diff --git a/drivers/common/qat/qat_device.c b/drivers/common/qat/qat_device.c
index f32d72358..da33faa9e 100644
--- a/drivers/common/qat/qat_device.c
+++ b/drivers/common/qat/qat_device.c
@@ -194,6 +194,9 @@ static int qat_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 			pci_dev->addr.devid,
 			pci_dev->addr.function);
 
+	if (rte_dev_is_probed(&pci_dev->device))
+		return -EEXIST;
+
 	qat_pci_dev = qat_pci_device_allocate(pci_dev);
 	if (qat_pci_dev == NULL)
 		return -ENODEV;
diff --git a/drivers/compress/octeontx/otx_zip_pmd.c b/drivers/compress/octeontx/otx_zip_pmd.c
index 9d13f9331..9894bb97c 100644
--- a/drivers/compress/octeontx/otx_zip_pmd.c
+++ b/drivers/compress/octeontx/otx_zip_pmd.c
@@ -569,6 +569,9 @@ zip_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 			(unsigned int)pci_dev->id.vendor_id,
 			(unsigned int)pci_dev->id.device_id);
 
+	if (rte_dev_is_probed(&pci_dev->device))
+		return -EEXIST;
+
 	rte_pci_device_name(&pci_dev->addr, compressdev_name,
 			    sizeof(compressdev_name));
 
diff --git a/drivers/crypto/virtio/Makefile b/drivers/crypto/virtio/Makefile
index be7b828fe..26c4edc2c 100644
--- a/drivers/crypto/virtio/Makefile
+++ b/drivers/crypto/virtio/Makefile
@@ -14,6 +14,7 @@ LIB = librte_pmd_virtio_crypto.a
 CFLAGS += -I$(RTE_SDK)/lib/librte_vhost
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 EXPORT_MAP := rte_pmd_virtio_crypto_version.map
 
diff --git a/drivers/crypto/virtio/meson.build b/drivers/crypto/virtio/meson.build
index b15b3f9fa..cb7b5ab99 100644
--- a/drivers/crypto/virtio/meson.build
+++ b/drivers/crypto/virtio/meson.build
@@ -6,3 +6,4 @@ deps += 'bus_pci'
 name = 'virtio_crypto'
 sources = files('virtio_cryptodev.c', 'virtio_pci.c',
 		'virtio_rxtx.c', 'virtqueue.c')
+allow_experimental_apis = true
diff --git a/drivers/crypto/virtio/virtio_cryptodev.c b/drivers/crypto/virtio/virtio_cryptodev.c
index 568b5a406..f0fb2fe1e 100644
--- a/drivers/crypto/virtio/virtio_cryptodev.c
+++ b/drivers/crypto/virtio/virtio_cryptodev.c
@@ -1439,6 +1439,9 @@ crypto_virtio_pci_probe(
 			pci_dev->addr.devid,
 			pci_dev->addr.function);
 
+	if (rte_dev_is_probed(&pci_dev->device))
+		return -EEXIST;
+
 	rte_pci_device_name(&pci_dev->addr, name, sizeof(name));
 
 	return crypto_virtio_create(name, pci_dev, &init_params);
diff --git a/drivers/event/octeontx/ssovf_probe.c b/drivers/event/octeontx/ssovf_probe.c
index b3db596d4..602012024 100644
--- a/drivers/event/octeontx/ssovf_probe.c
+++ b/drivers/event/octeontx/ssovf_probe.c
@@ -150,6 +150,9 @@ ssowvf_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
 
+	if (rte_dev_is_probed(&pci_dev->device))
+		return -EEXIST;
+
 	if (pci_dev->mem_resource[0].addr == NULL ||
 			pci_dev->mem_resource[2].addr == NULL ||
 			pci_dev->mem_resource[4].addr == NULL) {
@@ -230,6 +233,9 @@ ssovf_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
 
+	if (rte_dev_is_probed(&pci_dev->device))
+		return -EEXIST;
+
 	if (pci_dev->mem_resource[0].addr == NULL ||
 			pci_dev->mem_resource[2].addr == NULL) {
 		mbox_log_err("Empty bars %p %p",
diff --git a/drivers/event/skeleton/Makefile b/drivers/event/skeleton/Makefile
index 0f7f07eaf..fd75b1dd6 100644
--- a/drivers/event/skeleton/Makefile
+++ b/drivers/event/skeleton/Makefile
@@ -9,6 +9,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 #
 LIB = librte_pmd_skeleton_event.a
 
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_eal -lrte_eventdev
 LDLIBS += -lrte_pci -lrte_bus_pci
diff --git a/drivers/event/skeleton/meson.build b/drivers/event/skeleton/meson.build
index acfe15653..773bed4ae 100644
--- a/drivers/event/skeleton/meson.build
+++ b/drivers/event/skeleton/meson.build
@@ -3,3 +3,4 @@
 
 sources = files('skeleton_eventdev.c')
 deps += ['bus_pci', 'bus_vdev']
+allow_experimental_apis = true
diff --git a/drivers/mempool/octeontx/Makefile b/drivers/mempool/octeontx/Makefile
index a3e1dce88..b9c9e0268 100644
--- a/drivers/mempool/octeontx/Makefile
+++ b/drivers/mempool/octeontx/Makefile
@@ -9,6 +9,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 #
 LIB = librte_mempool_octeontx.a
 
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += $(WERROR_FLAGS)
 CFLAGS += -I$(RTE_SDK)/drivers/common/octeontx/
 EXPORT_MAP := rte_mempool_octeontx_version.map
diff --git a/drivers/mempool/octeontx/meson.build b/drivers/mempool/octeontx/meson.build
index 3baaf7db2..cdf5bbe24 100644
--- a/drivers/mempool/octeontx/meson.build
+++ b/drivers/mempool/octeontx/meson.build
@@ -5,4 +5,6 @@ sources = files('octeontx_fpavf.c',
 		'rte_mempool_octeontx.c'
 )
 
+allow_experimental_apis = true
+
 deps += ['mbuf', 'bus_pci', 'common_octeontx']
diff --git a/drivers/mempool/octeontx/octeontx_fpavf.c b/drivers/mempool/octeontx/octeontx_fpavf.c
index 4cf387e8f..a9998f8c3 100644
--- a/drivers/mempool/octeontx/octeontx_fpavf.c
+++ b/drivers/mempool/octeontx/octeontx_fpavf.c
@@ -764,6 +764,9 @@ fpavf_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
 
+	if (rte_dev_is_probed(&pci_dev->device))
+		return -EEXIST;
+
 	if (pci_dev->mem_resource[0].addr == NULL) {
 		fpavf_log_err("Empty bars %p ", pci_dev->mem_resource[0].addr);
 		return -ENODEV;
diff --git a/drivers/net/ark/Makefile b/drivers/net/ark/Makefile
index 2e232be85..a873a774a 100644
--- a/drivers/net/ark/Makefile
+++ b/drivers/net/ark/Makefile
@@ -8,6 +8,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 #
 LIB = librte_pmd_ark.a
 
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3 -I./
 CFLAGS += $(WERROR_FLAGS) -Werror
 
diff --git a/drivers/net/ark/meson.build b/drivers/net/ark/meson.build
index 99151bba1..a5886cd01 100644
--- a/drivers/net/ark/meson.build
+++ b/drivers/net/ark/meson.build
@@ -11,3 +11,4 @@ sources = files('ark_ddm.c',
 	'ark_pktgen.c',
 	'ark_rqp.c',
 	'ark_udm.c')
+allow_experimental_apis = true
diff --git a/drivers/net/avf/Makefile b/drivers/net/avf/Makefile
index 3f815bbc4..fec88ea38 100644
--- a/drivers/net/avf/Makefile
+++ b/drivers/net/avf/Makefile
@@ -8,6 +8,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 #
 LIB = librte_pmd_avf.a
 
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_hash
diff --git a/drivers/net/avp/Makefile b/drivers/net/avp/Makefile
index c9db667f3..6fcdc05f5 100644
--- a/drivers/net/avp/Makefile
+++ b/drivers/net/avp/Makefile
@@ -8,6 +8,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 #
 LIB = librte_pmd_avp.a
 
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR)
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
diff --git a/drivers/net/avp/meson.build b/drivers/net/avp/meson.build
index 6076c31b9..4c282ebe2 100644
--- a/drivers/net/avp/meson.build
+++ b/drivers/net/avp/meson.build
@@ -3,3 +3,4 @@
 
 sources = files('avp_ethdev.c')
 install_headers('rte_avp_common.h', 'rte_avp_fifo.h')
+allow_experimental_apis = true
diff --git a/drivers/net/axgbe/Makefile b/drivers/net/axgbe/Makefile
index 72215aeda..1bc0412b4 100644
--- a/drivers/net/axgbe/Makefile
+++ b/drivers/net/axgbe/Makefile
@@ -8,6 +8,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 #
 LIB = librte_pmd_axgbe.a
 
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 
diff --git a/drivers/net/axgbe/meson.build b/drivers/net/axgbe/meson.build
index 548ffff7a..c865b739f 100644
--- a/drivers/net/axgbe/meson.build
+++ b/drivers/net/axgbe/meson.build
@@ -17,3 +17,5 @@ cflags += '-Wno-cast-qual'
 if arch_subdir == 'x86'
 	sources += files('axgbe_rxtx_vec_sse.c')
 endif
+
+allow_experimental_apis = true
diff --git a/drivers/net/bnx2x/Makefile b/drivers/net/bnx2x/Makefile
index 55d1ad6e0..82ad0ead9 100644
--- a/drivers/net/bnx2x/Makefile
+++ b/drivers/net/bnx2x/Makefile
@@ -9,6 +9,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 #
 LIB = librte_pmd_bnx2x.a
 
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 CFLAGS += -DZLIB_CONST
diff --git a/drivers/net/bnx2x/meson.build b/drivers/net/bnx2x/meson.build
index e3c688869..734499ceb 100644
--- a/drivers/net/bnx2x/meson.build
+++ b/drivers/net/bnx2x/meson.build
@@ -12,3 +12,4 @@ sources = files('bnx2x.c',
 	'bnx2x_vfpf.c',
 	'ecore_sp.c',
 	'elink.c')
+allow_experimental_apis = true
diff --git a/drivers/net/bnxt/Makefile b/drivers/net/bnxt/Makefile
index 8be3cb0e4..ce84ec64d 100644
--- a/drivers/net/bnxt/Makefile
+++ b/drivers/net/bnxt/Makefile
@@ -15,6 +15,7 @@ EXPORT_MAP := rte_pmd_bnxt_version.map
 
 LIBABIVER := 2
 
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
diff --git a/drivers/net/bnxt/meson.build b/drivers/net/bnxt/meson.build
index e130f2712..d1f50cb6d 100644
--- a/drivers/net/bnxt/meson.build
+++ b/drivers/net/bnxt/meson.build
@@ -18,3 +18,4 @@ sources = files('bnxt_cpr.c',
 	'bnxt_util.c',
 	'bnxt_vnic.c',
 	'rte_pmd_bnxt.c')
+allow_experimental_apis = true
diff --git a/drivers/net/cxgbe/Makefile b/drivers/net/cxgbe/Makefile
index 68466f13e..36388a746 100644
--- a/drivers/net/cxgbe/Makefile
+++ b/drivers/net/cxgbe/Makefile
@@ -13,6 +13,7 @@ CFLAGS += -I$(SRCDIR)/base/
 CFLAGS += -I$(SRCDIR)
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 
 EXPORT_MAP := rte_pmd_cxgbe_version.map
 
diff --git a/drivers/net/cxgbe/meson.build b/drivers/net/cxgbe/meson.build
index c51af26e9..d8c3b9e5c 100644
--- a/drivers/net/cxgbe/meson.build
+++ b/drivers/net/cxgbe/meson.build
@@ -14,3 +14,5 @@ sources = files('cxgbe_ethdev.c',
 	'base/t4_hw.c',
 	'base/t4vf_hw.c')
 includes += include_directories('base')
+
+allow_experimental_apis = true
diff --git a/drivers/net/e1000/Makefile b/drivers/net/e1000/Makefile
index 9c87e883b..825234dc8 100644
--- a/drivers/net/e1000/Makefile
+++ b/drivers/net/e1000/Makefile
@@ -8,6 +8,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 #
 LIB = librte_pmd_e1000.a
 
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
diff --git a/drivers/net/e1000/meson.build b/drivers/net/e1000/meson.build
index cf456995c..997013de3 100644
--- a/drivers/net/e1000/meson.build
+++ b/drivers/net/e1000/meson.build
@@ -15,3 +15,5 @@ sources = files(
 )
 
 includes += include_directories('base')
+
+allow_experimental_apis = true
diff --git a/drivers/net/enic/Makefile b/drivers/net/enic/Makefile
index 7c6c29cc0..bebed0dd5 100644
--- a/drivers/net/enic/Makefile
+++ b/drivers/net/enic/Makefile
@@ -13,6 +13,7 @@ EXPORT_MAP := rte_pmd_enic_version.map
 
 LIBABIVER := 1
 
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -I$(SRCDIR)/base/
 CFLAGS += -I$(SRCDIR)
 CFLAGS += -O3
diff --git a/drivers/net/enic/meson.build b/drivers/net/enic/meson.build
index bfd4e2373..4df6bd457 100644
--- a/drivers/net/enic/meson.build
+++ b/drivers/net/enic/meson.build
@@ -17,3 +17,5 @@ sources = files(
 	)
 deps += ['hash']
 includes += include_directories('base')
+
+allow_experimental_apis = true
diff --git a/drivers/net/fm10k/Makefile b/drivers/net/fm10k/Makefile
index d657dff8a..a53a3ece6 100644
--- a/drivers/net/fm10k/Makefile
+++ b/drivers/net/fm10k/Makefile
@@ -8,6 +8,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 #
 LIB = librte_pmd_fm10k.a
 
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 
diff --git a/drivers/net/fm10k/meson.build b/drivers/net/fm10k/meson.build
index 2772ea4df..a99aecfa7 100644
--- a/drivers/net/fm10k/meson.build
+++ b/drivers/net/fm10k/meson.build
@@ -14,3 +14,5 @@ if arch_subdir == 'x86'
 endif
 
 includes += include_directories('base')
+
+allow_experimental_apis = true
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 24d73f2ff..67f29f282 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -633,6 +633,9 @@ eth_i40e_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 	struct rte_eth_devargs eth_da = { .nb_representor_ports = 0 };
 	int i, retval;
 
+	if (rte_dev_is_probed(&pci_dev->device))
+		return -EEXIST;
+
 	if (pci_dev->device.devargs) {
 		retval = rte_eth_devargs_parse(pci_dev->device.devargs->args,
 				&eth_da);
diff --git a/drivers/net/ifc/ifcvf_vdpa.c b/drivers/net/ifc/ifcvf_vdpa.c
index 88d814037..192368395 100644
--- a/drivers/net/ifc/ifcvf_vdpa.c
+++ b/drivers/net/ifc/ifcvf_vdpa.c
@@ -682,6 +682,9 @@ ifcvf_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
 
+	if (rte_dev_is_probed(&pci_dev->device))
+		return -EEXIST;
+
 	list = rte_zmalloc("ifcvf", sizeof(*list), 0);
 	if (list == NULL)
 		goto error;
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index cee886754..8a6d5f972 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -1735,6 +1735,9 @@ eth_ixgbe_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 	struct rte_eth_devargs eth_da;
 	int i, retval;
 
+	if (rte_dev_is_probed(&pci_dev->device))
+		return -EEXIST;
+
 	if (pci_dev->device.devargs) {
 		retval = rte_eth_devargs_parse(pci_dev->device.devargs->args,
 				&eth_da);
diff --git a/drivers/net/liquidio/Makefile b/drivers/net/liquidio/Makefile
index f1092851a..19a9f8fe6 100644
--- a/drivers/net/liquidio/Makefile
+++ b/drivers/net/liquidio/Makefile
@@ -9,6 +9,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 #
 LIB = librte_pmd_lio.a
 
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR)/base -I$(SRCDIR)
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
diff --git a/drivers/net/liquidio/meson.build b/drivers/net/liquidio/meson.build
index 9ae48e213..091114349 100644
--- a/drivers/net/liquidio/meson.build
+++ b/drivers/net/liquidio/meson.build
@@ -6,3 +6,4 @@ sources = files('base/lio_23xx_vf.c',
 	'lio_ethdev.c',
 	'lio_rxtx.c')
 includes += include_directories('base')
+allow_experimental_apis = true
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index 3de7bc53e..c3acb469a 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -523,6 +523,10 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 
 	(void)pci_drv;
 	assert(pci_drv == &mlx4_driver);
+
+	if (rte_dev_is_probed(&pci_dev->device))
+		return -EEXIST;
+
 	list = mlx4_glue->get_device_list(&i);
 	if (list == NULL) {
 		rte_errno = errno;
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index f5f3a3d19..b488910a8 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -1296,6 +1296,10 @@ mlx5_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 
 	assert(pci_drv == &mlx5_driver);
 	errno = 0;
+
+	if (rte_dev_is_probed(&pci_dev->device))
+		return -EEXIST;
+
 	ibv_list = mlx5_glue->get_device_list(&ret);
 	if (!ibv_list) {
 		rte_errno = errno ? errno : ENOSYS;
diff --git a/drivers/net/netvsc/hn_ethdev.c b/drivers/net/netvsc/hn_ethdev.c
index b67cce1ba..991a1a91a 100644
--- a/drivers/net/netvsc/hn_ethdev.c
+++ b/drivers/net/netvsc/hn_ethdev.c
@@ -75,9 +75,6 @@ eth_dev_vmbus_allocate(struct rte_vmbus_device *dev, size_t private_data_size)
 	struct rte_eth_dev *eth_dev;
 	const char *name;
 
-	if (!dev)
-		return NULL;
-
 	name = dev->device.name;
 
 	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
@@ -824,6 +821,12 @@ static int eth_hn_probe(struct rte_vmbus_driver *drv __rte_unused,
 
 	PMD_INIT_FUNC_TRACE();
 
+	if (!dev)
+		return -EINVAL;
+
+	if (rte_dev_is_probed(&dev->device))
+		return -EEXIST;
+
 	eth_dev = eth_dev_vmbus_allocate(dev, sizeof(struct hn_data));
 	if (!eth_dev)
 		return -ENOMEM;
diff --git a/drivers/net/nfp/Makefile b/drivers/net/nfp/Makefile
index ab4e0a7d9..0188144da 100644
--- a/drivers/net/nfp/Makefile
+++ b/drivers/net/nfp/Makefile
@@ -8,6 +8,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 #
 LIB = librte_pmd_nfp.a
 
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 
diff --git a/drivers/net/nfp/meson.build b/drivers/net/nfp/meson.build
index 3ba37e279..1cae381fa 100644
--- a/drivers/net/nfp/meson.build
+++ b/drivers/net/nfp/meson.build
@@ -14,3 +14,4 @@ sources = files('nfpcore/nfp_cpp_pcie_ops.c',
 	'nfpcore/nfp_nsp_eth.c',
 	'nfpcore/nfp_hwinfo.c',
 	'nfp_net.c')
+allow_experimental_apis = true
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index 168088c6d..c9438f655 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -3121,6 +3121,9 @@ static int nfp_pf_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 	if (!dev)
 		return ret;
 
+	if (rte_dev_is_probed(&dev->device))
+		return -EEXIST;
+
 	/*
 	 * When device bound to UIO, the device could be used, by mistake,
 	 * by two DPDK apps, and the UIO driver does not avoid it. This
diff --git a/drivers/net/octeontx/Makefile b/drivers/net/octeontx/Makefile
index 885f17684..060ba873d 100644
--- a/drivers/net/octeontx/Makefile
+++ b/drivers/net/octeontx/Makefile
@@ -9,6 +9,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 #
 LIB = librte_pmd_octeontx.a
 
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += $(WERROR_FLAGS)
 CFLAGS += -I$(RTE_SDK)/drivers/common/octeontx/
 CFLAGS += -I$(RTE_SDK)/drivers/mempool/octeontx/
@@ -44,8 +45,6 @@ else
 CFLAGS_octeontx_rxtx.o += -O3 -Ofast
 endif
 
-CFLAGS_octeontx_ethdev.o += -DALLOW_EXPERIMENTAL_API
-
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
 LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_common_octeontx
 LDLIBS += -lrte_mempool_octeontx
diff --git a/drivers/net/octeontx/base/meson.build b/drivers/net/octeontx/base/meson.build
index 09f657abb..738164beb 100644
--- a/drivers/net/octeontx/base/meson.build
+++ b/drivers/net/octeontx/base/meson.build
@@ -14,7 +14,7 @@ foreach d: depends
 endforeach
 
 base_lib = static_library('octeontx_base', sources,
-	c_args: cflags,
+	c_args: cflags + ['-DALLOW_EXPERIMENTAL_API'],
 	dependencies: static_objs,
 )
 
diff --git a/drivers/net/octeontx/base/octeontx_pkivf.c b/drivers/net/octeontx/base/octeontx_pkivf.c
index 1babea0e8..4c8a0a345 100644
--- a/drivers/net/octeontx/base/octeontx_pkivf.c
+++ b/drivers/net/octeontx/base/octeontx_pkivf.c
@@ -120,6 +120,9 @@ pkivf_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
 
+	if (rte_dev_is_probed(&pci_dev->device))
+		return -EEXIST;
+
 	return 0;
 }
 
diff --git a/drivers/net/octeontx/base/octeontx_pkovf.c b/drivers/net/octeontx/base/octeontx_pkovf.c
index 0a6d64b8e..19b1f3c65 100644
--- a/drivers/net/octeontx/base/octeontx_pkovf.c
+++ b/drivers/net/octeontx/base/octeontx_pkovf.c
@@ -536,6 +536,9 @@ pkovf_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
 
+	if (rte_dev_is_probed(&pci_dev->device))
+		return -EEXIST;
+
 	if (pci_dev->mem_resource[0].addr == NULL ||
 	    pci_dev->mem_resource[2].addr == NULL) {
 		octeontx_log_err("Empty bars %p %p",
diff --git a/drivers/net/qede/Makefile b/drivers/net/qede/Makefile
index 488ca1d92..455f076f9 100644
--- a/drivers/net/qede/Makefile
+++ b/drivers/net/qede/Makefile
@@ -10,6 +10,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 #
 LIB = librte_pmd_qede.a
 
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
diff --git a/drivers/net/qede/meson.build b/drivers/net/qede/meson.build
index 6280073a5..1978c0b51 100644
--- a/drivers/net/qede/meson.build
+++ b/drivers/net/qede/meson.build
@@ -10,3 +10,5 @@ sources = files(
 	'qede_main.c',
 	'qede_rxtx.c',
 )
+
+allow_experimental_apis = true
diff --git a/drivers/net/szedata2/Makefile b/drivers/net/szedata2/Makefile
index b77fae16d..6a9198bfd 100644
--- a/drivers/net/szedata2/Makefile
+++ b/drivers/net/szedata2/Makefile
@@ -8,6 +8,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 #
 LIB = librte_pmd_szedata2.a
 
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += -O3
 CFLAGS += $(WERROR_FLAGS)
 LDLIBS += -lsze2
diff --git a/drivers/net/szedata2/meson.build b/drivers/net/szedata2/meson.build
index da3733743..157b32e15 100644
--- a/drivers/net/szedata2/meson.build
+++ b/drivers/net/szedata2/meson.build
@@ -5,3 +5,4 @@ dep = cc.find_library('sze2', required: false)
 build = dep.found()
 ext_deps += dep
 sources = files('rte_eth_szedata2.c')
+allow_experimental_apis = true
diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
index 8f92e72f2..0adc0ff4c 100644
--- a/drivers/net/szedata2/rte_eth_szedata2.c
+++ b/drivers/net/szedata2/rte_eth_szedata2.c
@@ -1804,6 +1804,9 @@ static int szedata2_eth_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 
 	PMD_INIT_FUNC_TRACE();
 
+	if (rte_dev_is_probed(&pci_dev->device))
+		return -EEXIST;
+
 	ret = get_port_info(pci_dev, &port_count, port_info,
 			SZEDATA2_MAX_PORTS);
 	if (ret != 0)
diff --git a/drivers/net/thunderx/Makefile b/drivers/net/thunderx/Makefile
index e6bf49752..c08ef9277 100644
--- a/drivers/net/thunderx/Makefile
+++ b/drivers/net/thunderx/Makefile
@@ -9,6 +9,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
 #
 LIB = librte_pmd_thunderx_nicvf.a
 
+CFLAGS += -DALLOW_EXPERIMENTAL_API
 CFLAGS += $(WERROR_FLAGS)
 
 LDLIBS += -lm
diff --git a/drivers/net/thunderx/meson.build b/drivers/net/thunderx/meson.build
index 69819a97f..bcba1489f 100644
--- a/drivers/net/thunderx/meson.build
+++ b/drivers/net/thunderx/meson.build
@@ -18,3 +18,5 @@ if cc.has_argument('-Wno-maybe-uninitialized')
 endif
 
 includes += include_directories('base')
+
+allow_experimental_apis = true
diff --git a/drivers/raw/ifpga_rawdev/ifpga_rawdev.c b/drivers/raw/ifpga_rawdev/ifpga_rawdev.c
index 3fed05781..cfaa0d39e 100644
--- a/drivers/raw/ifpga_rawdev/ifpga_rawdev.c
+++ b/drivers/raw/ifpga_rawdev/ifpga_rawdev.c
@@ -378,6 +378,9 @@ ifpga_rawdev_create(struct rte_pci_device *pci_dev,
 		goto cleanup;
 	}
 
+	if (rte_dev_is_probed(&pci_dev->device))
+		return -EEXIST;
+
 	memset(name, 0, sizeof(name));
 	snprintf(name, RTE_RAWDEV_NAME_MAX_LEN, "IFPGA:%x:%02x.%x",
 		pci_dev->addr.bus, pci_dev->addr.devid, pci_dev->addr.function);
diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c
index 907c5c481..cbd7a3419 100644
--- a/lib/librte_eal/common/eal_common_dev.c
+++ b/lib/librte_eal/common/eal_common_dev.c
@@ -191,11 +191,6 @@ rte_dev_probe(const char *devargs)
 		goto err_devarg;
 	}
 
-	if (rte_dev_is_probed(dev)) {
-		RTE_LOG(ERR, EAL, "Device is already plugged\n");
-		return -EEXIST;
-	}
-
 	ret = da->bus->plug(dev);
 	if (ret) {
 		RTE_LOG(ERR, EAL, "Driver cannot attach the device (%s)\n",
diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
index 5b16ee27b..6ba16f8b3 100644
--- a/lib/librte_eal/common/include/rte_dev.h
+++ b/lib/librte_eal/common/include/rte_dev.h
@@ -158,7 +158,7 @@ struct rte_device {
 	const char *name;             /**< Device name */
 	const struct rte_driver *driver; /**< Driver associated after probing */
 	int numa_node;                /**< NUMA node connection */
-	struct rte_devargs *devargs;  /**< Device user arguments */
+	struct rte_devargs *devargs;  /**< Arguments for latest probing */
 };
 
 /**
diff --git a/lib/librte_ethdev/rte_ethdev_pci.h b/lib/librte_ethdev/rte_ethdev_pci.h
index f652596f4..4080fa6f5 100644
--- a/lib/librte_ethdev/rte_ethdev_pci.h
+++ b/lib/librte_ethdev/rte_ethdev_pci.h
@@ -167,6 +167,9 @@ rte_eth_dev_pci_generic_probe(struct rte_pci_device *pci_dev,
 	struct rte_eth_dev *eth_dev;
 	int ret;
 
+	if (rte_dev_is_probed(&pci_dev->device))
+		return -EEXIST;
+
 	eth_dev = rte_eth_dev_pci_allocate(pci_dev, private_data_size);
 	if (!eth_dev)
 		return -ENOMEM;
diff --git a/lib/librte_eventdev/rte_eventdev_pmd_pci.h b/lib/librte_eventdev/rte_eventdev_pmd_pci.h
index 8fb61386f..97fa2cc97 100644
--- a/lib/librte_eventdev/rte_eventdev_pmd_pci.h
+++ b/lib/librte_eventdev/rte_eventdev_pmd_pci.h
@@ -50,6 +50,9 @@ rte_event_pmd_pci_probe(struct rte_pci_driver *pci_drv,
 	if (devinit == NULL)
 		return -EINVAL;
 
+	if (rte_dev_is_probed(&pci_dev->device))
+		return -EEXIST;
+
 	rte_pci_device_name(&pci_dev->addr, eventdev_name,
 			sizeof(eventdev_name));
 
-- 
2.19.0

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

* Re: [PATCH v2 3/3] eal: allow probing a device again
  2018-09-28 16:40   ` [PATCH v2 3/3] eal: allow probing a device again Thomas Monjalon
@ 2018-10-04  9:44     ` Doherty, Declan
  2018-10-04 14:25       ` Thomas Monjalon
  0 siblings, 1 reply; 58+ messages in thread
From: Doherty, Declan @ 2018-10-04  9:44 UTC (permalink / raw)
  To: Thomas Monjalon, dev; +Cc: gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit

On 28/09/2018 5:40 PM, Thomas Monjalon wrote:
> In the devargs syntax for device representors, it is possible to add
> several devices at once: -w dbdf,representor=[0-3]
> It will become a more frequent case when introducing wildcards
> and ranges in the new devargs syntax.
> 
> If a devargs string is provided for probing, and updated with a bigger
> range for a new probing, then we do not want it to fail because
> part of this range was already probed previously.
> There can be new ports to create from an existing rte_device.
> 
> That's why the checks for an already probed device
> are moved as PMD responsibility.
> Only the PMD knows the ports attached to one rte_device.
> 
> In the case of vdev, a global check is kept in insert_vdev(),
> assuming that a vdev will always have only one port.
> In the case of NXP buses, the probing is done only once (no hotplug),
> though a check is added at bus level for consistency.
> 
> As another consequence of being able to probe in several steps,
> the field rte_device.devargs must not be considered as a full
> representation of the rte_device, but only the latest probing args.
> Anyway, the field rte_device.devargs is used only for probing.
> 
> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
> ---
...
> 

Hey Thomas, did you consider of adding a driver flags to the rte_driver 
structure which has a driver re-probe flag. If this flag is disabled by 
default, current drivers could be left unmodified and any new driver 
which want to support re-probing enable this flag and then support the 
functionality in there probe function. Then we could check this flag in 
the bus driver on making a call on whether to re-probe.

Declan

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

* Re: [PATCH v2 3/3] eal: allow probing a device again
  2018-10-04  9:44     ` Doherty, Declan
@ 2018-10-04 14:25       ` Thomas Monjalon
  0 siblings, 0 replies; 58+ messages in thread
From: Thomas Monjalon @ 2018-10-04 14:25 UTC (permalink / raw)
  To: Doherty, Declan
  Cc: dev, gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit, arybchenko,
	konstantin.ananyev, bruce.richardson, jerin.jacob,
	hemant.agrawal

04/10/2018 11:44, Doherty, Declan:
> On 28/09/2018 5:40 PM, Thomas Monjalon wrote:
> > In the devargs syntax for device representors, it is possible to add
> > several devices at once: -w dbdf,representor=[0-3]
> > It will become a more frequent case when introducing wildcards
> > and ranges in the new devargs syntax.
> > 
> > If a devargs string is provided for probing, and updated with a bigger
> > range for a new probing, then we do not want it to fail because
> > part of this range was already probed previously.
> > There can be new ports to create from an existing rte_device.
> > 
> > That's why the checks for an already probed device
> > are moved as PMD responsibility.
> > Only the PMD knows the ports attached to one rte_device.
> > 
> > In the case of vdev, a global check is kept in insert_vdev(),
> > assuming that a vdev will always have only one port.
> > In the case of NXP buses, the probing is done only once (no hotplug),
> > though a check is added at bus level for consistency.
> > 
> > As another consequence of being able to probe in several steps,
> > the field rte_device.devargs must not be considered as a full
> > representation of the rte_device, but only the latest probing args.
> > Anyway, the field rte_device.devargs is used only for probing.
> > 
> > Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
> > ---
> 
> Hey Thomas, did you consider of adding a driver flags to the rte_driver 
> structure which has a driver re-probe flag. If this flag is disabled by 
> default, current drivers could be left unmodified and any new driver 
> which want to support re-probing enable this flag and then support the 
> functionality in there probe function. Then we could check this flag in 
> the bus driver on making a call on whether to re-probe.

I really don't know what is best:
- have a standard expectation for all drivers
- add a driver flag in order to remove a check

If your option is preferred, where the flag should be added?
- in rte_driver which has no flag at all so far
- in rte_pci_driver.drv_flags which may be enough (at least for now)

Opinions?

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

* [PATCH v3 0/3] eal: allow hotplug to skip an already probed device
  2018-09-07 23:09 [RFC] eal: allow hotplug to skip an already probed device Thomas Monjalon
  2018-09-13  6:29 ` Ophir Munk
  2018-09-28 16:40 ` [PATCH v2 0/3] " Thomas Monjalon
@ 2018-10-07 22:09 ` Thomas Monjalon
  2018-10-07 22:09   ` [PATCH v3 1/3] drivers/bus: move driver assignment to end of probing Thomas Monjalon
                     ` (2 more replies)
  2018-10-11 21:02 ` [PATCH v4 0/4] eal: allow hotplug to skip an already probed device Thomas Monjalon
  2018-10-14 20:47 ` [PATCH v5 0/7] " Thomas Monjalon
  4 siblings, 3 replies; 58+ messages in thread
From: Thomas Monjalon @ 2018-10-07 22:09 UTC (permalink / raw)
  To: dev; +Cc: gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit

This is a follow-up of an idea presented at Dublin
during the "hotplug talk".

The idea is to ease probing of range of ports attached
to the same rte_device.
I becomes possible to allow probing again the same device
but with a bigger range of ports in the devargs.

Instead of adding a parameter to the hotplug functions, as in the RFC,
the check of an already probed device is moved to the bus and enabled PMDs.
It gives flexibility to drivers for managing range of ports.


This series is based on top of
https://patches.dpdk.org/project/dpdk/list/?series=1734

Depends on: project/dpdk/list/?series=1734
(proposed syntax for dependencies)


Changes in v3 - after Declan's review:
  - return error in all buses but PCI
  - add a PCI driver flag to enable feature per driver
  - return -EEXIST if probing again is not supported


Thomas Monjalon (3):
  drivers/bus: move driver assignment to end of probing
  eal: add function to query device status
  eal: allow probing a device again

 drivers/bus/dpaa/dpaa_bus.c             |  3 ++
 drivers/bus/fslmc/fslmc_bus.c           |  3 ++
 drivers/bus/ifpga/ifpga_bus.c           | 21 +++++++-------
 drivers/bus/pci/pci_common.c            | 38 ++++++++++++++++---------
 drivers/bus/pci/rte_bus_pci.h           |  6 ++--
 drivers/bus/vdev/vdev.c                 | 12 +++++---
 drivers/bus/vmbus/vmbus_common.c        |  5 ++--
 drivers/net/i40e/i40e_vf_representor.c  |  3 --
 drivers/net/mlx4/mlx4.c                 |  1 -
 drivers/net/mlx5/mlx5.c                 |  1 -
 lib/librte_eal/common/eal_common_dev.c  | 14 +++++----
 lib/librte_eal/common/include/rte_dev.h | 18 ++++++++++--
 lib/librte_eal/rte_eal_version.map      |  1 +
 13 files changed, 82 insertions(+), 44 deletions(-)

-- 
2.19.0

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

* [PATCH v3 1/3] drivers/bus: move driver assignment to end of probing
  2018-10-07 22:09 ` [PATCH v3 0/3] eal: allow hotplug to skip an already probed device Thomas Monjalon
@ 2018-10-07 22:09   ` Thomas Monjalon
  2018-10-08  8:05     ` Andrew Rybchenko
  2018-10-11 10:53     ` Andrew Rybchenko
  2018-10-07 22:09   ` [PATCH v3 2/3] eal: add function to query device status Thomas Monjalon
  2018-10-07 22:09   ` [PATCH v3 3/3] eal: allow probing a device again Thomas Monjalon
  2 siblings, 2 replies; 58+ messages in thread
From: Thomas Monjalon @ 2018-10-07 22:09 UTC (permalink / raw)
  To: dev; +Cc: gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit

The PCI mapping requires to know the PCI driver to use,
even before the probing is done. That's why the PCI driver is
referenced early inside the PCI device structure. See
1d20a073fa5e ("bus/pci: reference driver structure before mapping")

However the rte_driver does not need to be referenced in rte_device
before the device probing is done.
By moving back this assignment at the end of the device probing,
it becomes possible to make clear the status of a rte_device.

Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
---
 drivers/bus/ifpga/ifpga_bus.c           | 9 ++++-----
 drivers/bus/pci/pci_common.c            | 7 +++----
 drivers/bus/pci/rte_bus_pci.h           | 2 +-
 drivers/bus/vdev/vdev.c                 | 5 ++---
 drivers/bus/vmbus/vmbus_common.c        | 5 +++--
 drivers/net/i40e/i40e_vf_representor.c  | 3 ---
 drivers/net/mlx4/mlx4.c                 | 1 -
 drivers/net/mlx5/mlx5.c                 | 1 -
 lib/librte_eal/common/include/rte_dev.h | 2 +-
 9 files changed, 14 insertions(+), 21 deletions(-)

diff --git a/drivers/bus/ifpga/ifpga_bus.c b/drivers/bus/ifpga/ifpga_bus.c
index 80663328a..fca2dbace 100644
--- a/drivers/bus/ifpga/ifpga_bus.c
+++ b/drivers/bus/ifpga/ifpga_bus.c
@@ -280,14 +280,13 @@ ifpga_probe_one_driver(struct rte_afu_driver *drv,
 
 	/* reference driver structure */
 	afu_dev->driver = drv;
-	afu_dev->device.driver = &drv->driver;
 
 	/* call the driver probe() function */
 	ret = drv->probe(afu_dev);
-	if (ret) {
+	if (ret)
 		afu_dev->driver = NULL;
-		afu_dev->device.driver = NULL;
-	}
+	else
+		afu_dev->device.driver = &drv->driver;
 
 	return ret;
 }
@@ -302,7 +301,7 @@ ifpga_probe_all_drivers(struct rte_afu_device *afu_dev)
 		return -1;
 
 	/* Check if a driver is already loaded */
-	if (afu_dev->driver != NULL)
+	if (afu_dev->device.driver != NULL)
 		return 0;
 
 	TAILQ_FOREACH(drv, &ifpga_afu_drv_list, next) {
diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
index c7695d108..d63e68045 100644
--- a/drivers/bus/pci/pci_common.c
+++ b/drivers/bus/pci/pci_common.c
@@ -160,14 +160,12 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
 	 * driver flags for adjusting configuration.
 	 */
 	dev->driver = dr;
-	dev->device.driver = &dr->driver;
 
 	if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) {
 		/* map resources for devices that use igb_uio */
 		ret = rte_pci_map_device(dev);
 		if (ret != 0) {
 			dev->driver = NULL;
-			dev->device.driver = NULL;
 			return ret;
 		}
 	}
@@ -176,7 +174,6 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
 	ret = dr->probe(dr, dev);
 	if (ret) {
 		dev->driver = NULL;
-		dev->device.driver = NULL;
 		if ((dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) &&
 			/* Don't unmap if device is unsupported and
 			 * driver needs mapped resources.
@@ -184,6 +181,8 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
 			!(ret > 0 &&
 				(dr->drv_flags & RTE_PCI_DRV_KEEP_MAPPED_RES)))
 			rte_pci_unmap_device(dev);
+	} else {
+		dev->device.driver = &dr->driver;
 	}
 
 	return ret;
@@ -244,7 +243,7 @@ pci_probe_all_drivers(struct rte_pci_device *dev)
 		return -1;
 
 	/* Check if a driver is already loaded */
-	if (dev->driver != NULL)
+	if (dev->device.driver != NULL)
 		return 0;
 
 	FOREACH_DRIVER_ON_PCIBUS(dr) {
diff --git a/drivers/bus/pci/rte_bus_pci.h b/drivers/bus/pci/rte_bus_pci.h
index 0d1955ffe..984df2b37 100644
--- a/drivers/bus/pci/rte_bus_pci.h
+++ b/drivers/bus/pci/rte_bus_pci.h
@@ -62,7 +62,7 @@ struct rte_pci_device {
 	struct rte_mem_resource mem_resource[PCI_MAX_RESOURCE];
 					    /**< PCI Memory Resource */
 	struct rte_intr_handle intr_handle; /**< Interrupt handle */
-	struct rte_pci_driver *driver;      /**< Associated driver */
+	struct rte_pci_driver *driver;      /**< PCI driver used in probing */
 	uint16_t max_vfs;                   /**< sriov enable if not zero */
 	enum rte_kernel_driver kdrv;        /**< Kernel driver passthrough */
 	char name[PCI_PRI_STR_SIZE+1];      /**< PCI location (ASCII) */
diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
index 0142fb2c8..3f27f3510 100644
--- a/drivers/bus/vdev/vdev.c
+++ b/drivers/bus/vdev/vdev.c
@@ -150,10 +150,9 @@ vdev_probe_all_drivers(struct rte_vdev_device *dev)
 
 	if (vdev_parse(name, &driver))
 		return -1;
-	dev->device.driver = &driver->driver;
 	ret = driver->probe(dev);
-	if (ret)
-		dev->device.driver = NULL;
+	if (ret == 0)
+		dev->device.driver = &driver->driver;
 	return ret;
 }
 
diff --git a/drivers/bus/vmbus/vmbus_common.c b/drivers/bus/vmbus/vmbus_common.c
index e3ceb6906..de5548aa4 100644
--- a/drivers/bus/vmbus/vmbus_common.c
+++ b/drivers/bus/vmbus/vmbus_common.c
@@ -111,7 +111,6 @@ vmbus_probe_one_driver(struct rte_vmbus_driver *dr,
 
 	/* reference driver structure */
 	dev->driver = dr;
-	dev->device.driver = &dr->driver;
 
 	if (dev->device.numa_node < 0) {
 		VMBUS_LOG(WARNING, "  Invalid NUMA socket, default to 0");
@@ -124,6 +123,8 @@ vmbus_probe_one_driver(struct rte_vmbus_driver *dr,
 	if (ret) {
 		dev->driver = NULL;
 		rte_vmbus_unmap_device(dev);
+	} else {
+		dev->device.driver = &dr->driver;
 	}
 
 	return ret;
@@ -142,7 +143,7 @@ vmbus_probe_all_drivers(struct rte_vmbus_device *dev)
 	int rc;
 
 	/* Check if a driver is already loaded */
-	if (dev->driver != NULL) {
+	if (dev->device.driver != NULL) {
 		VMBUS_LOG(DEBUG, "VMBUS driver already loaded");
 		return 0;
 	}
diff --git a/drivers/net/i40e/i40e_vf_representor.c b/drivers/net/i40e/i40e_vf_representor.c
index 0bfbb4f60..24751d13c 100644
--- a/drivers/net/i40e/i40e_vf_representor.c
+++ b/drivers/net/i40e/i40e_vf_representor.c
@@ -487,9 +487,6 @@ i40e_vf_representor_init(struct rte_eth_dev *ethdev, void *init_params)
 	if (representor->vf_id >= pf->vf_num)
 		return -ENODEV;
 
-	/** representor shares the same driver as it's PF device */
-	ethdev->device->driver = representor->adapter->eth_dev->device->driver;
-
 	/* Set representor device ops */
 	ethdev->dev_ops = &i40e_representor_dev_ops;
 
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index defc0d4b0..3de7bc53e 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -734,7 +734,6 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 		eth_dev->data->mac_addrs = priv->mac;
 		eth_dev->device = &pci_dev->device;
 		rte_eth_copy_pci_info(eth_dev, pci_dev);
-		eth_dev->device->driver = &mlx4_driver.driver;
 		/* Initialize local interrupt handle for current port. */
 		priv->intr_handle = (struct rte_intr_handle){
 			.fd = -1,
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index fd89e2af3..cf258345f 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -1081,7 +1081,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	priv->dev_data = eth_dev->data;
 	eth_dev->data->mac_addrs = priv->mac;
 	eth_dev->device = dpdk_dev;
-	eth_dev->device->driver = &mlx5_driver.driver;
 	err = mlx5_uar_init_primary(eth_dev);
 	if (err) {
 		err = rte_errno;
diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
index 036180ff3..5084c645b 100644
--- a/lib/librte_eal/common/include/rte_dev.h
+++ b/lib/librte_eal/common/include/rte_dev.h
@@ -156,7 +156,7 @@ struct rte_driver {
 struct rte_device {
 	TAILQ_ENTRY(rte_device) next; /**< Next device */
 	const char *name;             /**< Device name */
-	const struct rte_driver *driver;/**< Associated driver */
+	const struct rte_driver *driver; /**< Driver assigned after probing */
 	const struct rte_bus *bus;    /**< Bus handle assigned on scan */
 	int numa_node;                /**< NUMA node connection */
 	struct rte_devargs *devargs;  /**< Device user arguments */
-- 
2.19.0

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

* [PATCH v3 2/3] eal: add function to query device status
  2018-10-07 22:09 ` [PATCH v3 0/3] eal: allow hotplug to skip an already probed device Thomas Monjalon
  2018-10-07 22:09   ` [PATCH v3 1/3] drivers/bus: move driver assignment to end of probing Thomas Monjalon
@ 2018-10-07 22:09   ` Thomas Monjalon
  2018-10-08  8:05     ` Andrew Rybchenko
  2018-10-07 22:09   ` [PATCH v3 3/3] eal: allow probing a device again Thomas Monjalon
  2 siblings, 1 reply; 58+ messages in thread
From: Thomas Monjalon @ 2018-10-07 22:09 UTC (permalink / raw)
  To: dev; +Cc: gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit

The function rte_dev_is_probed() is added in order to improve semantic
and enforce proper check of the probing status of a device.

It will answer this rte_device query:
Is it already successfully probed or not?

Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
---
 drivers/bus/ifpga/ifpga_bus.c           |  4 ++--
 drivers/bus/pci/pci_common.c            |  2 +-
 drivers/bus/vdev/vdev.c                 |  2 +-
 drivers/bus/vmbus/vmbus_common.c        |  2 +-
 lib/librte_eal/common/eal_common_dev.c  |  9 ++++++++-
 lib/librte_eal/common/include/rte_dev.h | 14 ++++++++++++++
 lib/librte_eal/rte_eal_version.map      |  1 +
 7 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/drivers/bus/ifpga/ifpga_bus.c b/drivers/bus/ifpga/ifpga_bus.c
index fca2dbace..2ca1efa72 100644
--- a/drivers/bus/ifpga/ifpga_bus.c
+++ b/drivers/bus/ifpga/ifpga_bus.c
@@ -301,7 +301,7 @@ ifpga_probe_all_drivers(struct rte_afu_device *afu_dev)
 		return -1;
 
 	/* Check if a driver is already loaded */
-	if (afu_dev->device.driver != NULL)
+	if (rte_dev_is_probed(&afu_dev->device))
 		return 0;
 
 	TAILQ_FOREACH(drv, &ifpga_afu_drv_list, next) {
@@ -325,7 +325,7 @@ ifpga_probe(void)
 	int ret = 0;
 
 	TAILQ_FOREACH(afu_dev, &ifpga_afu_dev_list, next) {
-		if (afu_dev->device.driver)
+		if (rte_dev_is_probed(&afu_dev->device))
 			continue;
 
 		ret = ifpga_probe_all_drivers(afu_dev);
diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
index d63e68045..62b17fba9 100644
--- a/drivers/bus/pci/pci_common.c
+++ b/drivers/bus/pci/pci_common.c
@@ -243,7 +243,7 @@ pci_probe_all_drivers(struct rte_pci_device *dev)
 		return -1;
 
 	/* Check if a driver is already loaded */
-	if (dev->device.driver != NULL)
+	if (rte_dev_is_probed(&dev->device))
 		return 0;
 
 	FOREACH_DRIVER_ON_PCIBUS(dr) {
diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
index 3f27f3510..f666099e6 100644
--- a/drivers/bus/vdev/vdev.c
+++ b/drivers/bus/vdev/vdev.c
@@ -481,7 +481,7 @@ vdev_probe(void)
 		 * we call each driver probe.
 		 */
 
-		if (dev->device.driver)
+		if (rte_dev_is_probed(&dev->device))
 			continue;
 
 		if (vdev_probe_all_drivers(dev)) {
diff --git a/drivers/bus/vmbus/vmbus_common.c b/drivers/bus/vmbus/vmbus_common.c
index de5548aa4..48a219f73 100644
--- a/drivers/bus/vmbus/vmbus_common.c
+++ b/drivers/bus/vmbus/vmbus_common.c
@@ -143,7 +143,7 @@ vmbus_probe_all_drivers(struct rte_vmbus_device *dev)
 	int rc;
 
 	/* Check if a driver is already loaded */
-	if (dev->device.driver != NULL) {
+	if (rte_dev_is_probed(&dev->device)) {
 		VMBUS_LOG(DEBUG, "VMBUS driver already loaded");
 		return 0;
 	}
diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c
index 7663eaa3f..7e8a9b260 100644
--- a/lib/librte_eal/common/eal_common_dev.c
+++ b/lib/librte_eal/common/eal_common_dev.c
@@ -74,6 +74,13 @@ static int cmp_dev_name(const struct rte_device *dev, const void *_name)
 	return strcmp(dev->name, name);
 }
 
+int __rte_experimental
+rte_dev_is_probed(const struct rte_device *dev)
+{
+	/* The field driver should be set only when the probe is successful. */
+	return dev->driver != NULL;
+}
+
 int rte_eal_dev_attach(const char *name, const char *devargs)
 {
 	struct rte_bus *bus;
@@ -189,7 +196,7 @@ rte_dev_probe(const char *devargs)
 		goto err_devarg;
 	}
 
-	if (dev->driver != NULL) {
+	if (rte_dev_is_probed(dev)) {
 		RTE_LOG(ERR, EAL, "Device is already plugged\n");
 		return -EEXIST;
 	}
diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
index 5084c645b..9f169e3b3 100644
--- a/lib/librte_eal/common/include/rte_dev.h
+++ b/lib/librte_eal/common/include/rte_dev.h
@@ -162,6 +162,20 @@ struct rte_device {
 	struct rte_devargs *devargs;  /**< Device user arguments */
 };
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Query status of a device.
+ *
+ * @param dev
+ *   Generic device pointer.
+ * @return
+ *   (int)true if already probed successfully, 0 otherwise.
+ */
+__rte_experimental
+int rte_dev_is_probed(const struct rte_device *dev);
+
 /**
  * Attach a device to a registered driver.
  *
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index 2ea7a870a..dddcb81ea 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -279,6 +279,7 @@ EXPERIMENTAL {
 	rte_dev_event_callback_unregister;
 	rte_dev_event_monitor_start;
 	rte_dev_event_monitor_stop;
+	rte_dev_is_probed;
 	rte_dev_iterator_init;
 	rte_dev_iterator_next;
 	rte_dev_probe;
-- 
2.19.0

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

* [PATCH v3 3/3] eal: allow probing a device again
  2018-10-07 22:09 ` [PATCH v3 0/3] eal: allow hotplug to skip an already probed device Thomas Monjalon
  2018-10-07 22:09   ` [PATCH v3 1/3] drivers/bus: move driver assignment to end of probing Thomas Monjalon
  2018-10-07 22:09   ` [PATCH v3 2/3] eal: add function to query device status Thomas Monjalon
@ 2018-10-07 22:09   ` Thomas Monjalon
  2018-10-08  8:05     ` Andrew Rybchenko
  2 siblings, 1 reply; 58+ messages in thread
From: Thomas Monjalon @ 2018-10-07 22:09 UTC (permalink / raw)
  To: dev; +Cc: gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit

In the devargs syntax for device representors, it is possible to add
several devices at once: -w dbdf,representor=[0-3]
It will become a more frequent case when introducing wildcards
and ranges in the new devargs syntax.

If a devargs string is provided for probing, and updated with a bigger
range for a new probing, then we do not want it to fail because
part of this range was already probed previously.
There can be new ports to create from an existing rte_device.

That's why the check for an already probed device
is moved as bus responsibility.
In the case of vdev, a global check is kept in insert_vdev(),
assuming that a vdev will always have only one port.
In the case of ifpga and vmbus, already probed devices are checked.
In the case of NXP buses, the probing is done only once (no hotplug),
though a check is added at bus level for consistency.
In the case of PCI, a driver flag is added to allow PMD probing again.
Only the PMD knows the ports attached to one rte_device.

As another consequence of being able to probe in several steps,
the field rte_device.devargs must not be considered as a full
representation of the rte_device, but only the latest probing args.
Anyway, the field rte_device.devargs is used only for probing.

Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
---
 drivers/bus/dpaa/dpaa_bus.c             |  3 +++
 drivers/bus/fslmc/fslmc_bus.c           |  3 +++
 drivers/bus/ifpga/ifpga_bus.c           | 14 ++++++-----
 drivers/bus/pci/pci_common.c            | 33 ++++++++++++++++---------
 drivers/bus/pci/rte_bus_pci.h           |  4 ++-
 drivers/bus/vdev/vdev.c                 |  5 ++++
 lib/librte_eal/common/eal_common_dev.c  |  7 ++----
 lib/librte_eal/common/include/rte_dev.h |  2 +-
 8 files changed, 47 insertions(+), 24 deletions(-)

diff --git a/drivers/bus/dpaa/dpaa_bus.c b/drivers/bus/dpaa/dpaa_bus.c
index 138e0f98d..89d1e415d 100644
--- a/drivers/bus/dpaa/dpaa_bus.c
+++ b/drivers/bus/dpaa/dpaa_bus.c
@@ -555,6 +555,9 @@ rte_dpaa_bus_probe(void)
 			if (ret)
 				continue;
 
+			if (rte_dev_is_probed(&dev->device))
+				continue;
+
 			if (!drv->probe ||
 			    (dev->device.devargs &&
 			    dev->device.devargs->policy == RTE_DEV_BLACKLISTED))
diff --git a/drivers/bus/fslmc/fslmc_bus.c b/drivers/bus/fslmc/fslmc_bus.c
index 960f55071..7ebd980aa 100644
--- a/drivers/bus/fslmc/fslmc_bus.c
+++ b/drivers/bus/fslmc/fslmc_bus.c
@@ -386,6 +386,9 @@ rte_fslmc_probe(void)
 			if (!drv->probe)
 				continue;
 
+			if (rte_dev_is_probed(&dev->device))
+				continue;
+
 			if (dev->device.devargs &&
 			  dev->device.devargs->policy == RTE_DEV_BLACKLISTED) {
 				DPAA2_BUS_LOG(DEBUG, "%s Blacklisted, skipping",
diff --git a/drivers/bus/ifpga/ifpga_bus.c b/drivers/bus/ifpga/ifpga_bus.c
index 2ca1efa72..5f23ed8b4 100644
--- a/drivers/bus/ifpga/ifpga_bus.c
+++ b/drivers/bus/ifpga/ifpga_bus.c
@@ -301,8 +301,11 @@ ifpga_probe_all_drivers(struct rte_afu_device *afu_dev)
 		return -1;
 
 	/* Check if a driver is already loaded */
-	if (rte_dev_is_probed(&afu_dev->device))
-		return 0;
+	if (rte_dev_is_probed(&afu_dev->device)) {
+		IFPGA_BUS_DEBUG("Device %s is already probed\n",
+				rte_ifpga_device_name(afu_dev));
+		return -EEXIST;
+	}
 
 	TAILQ_FOREACH(drv, &ifpga_afu_drv_list, next) {
 		if (ifpga_probe_one_driver(drv, afu_dev)) {
@@ -325,14 +328,13 @@ ifpga_probe(void)
 	int ret = 0;
 
 	TAILQ_FOREACH(afu_dev, &ifpga_afu_dev_list, next) {
-		if (rte_dev_is_probed(&afu_dev->device))
-			continue;
-
 		ret = ifpga_probe_all_drivers(afu_dev);
+		if (ret == -EEXIST)
+			continue;
 		if (ret < 0)
 			IFPGA_BUS_ERR("failed to initialize %s device\n",
 				rte_ifpga_device_name(afu_dev));
-		}
+	}
 
 	return ret;
 }
diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
index 62b17fba9..11c5da587 100644
--- a/drivers/bus/pci/pci_common.c
+++ b/drivers/bus/pci/pci_common.c
@@ -6,6 +6,7 @@
 #include <string.h>
 #include <inttypes.h>
 #include <stdint.h>
+#include <stdbool.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <sys/queue.h>
@@ -121,6 +122,7 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
 			 struct rte_pci_device *dev)
 {
 	int ret;
+	bool already_probed;
 	struct rte_pci_addr *loc;
 
 	if ((dr == NULL) || (dev == NULL))
@@ -151,6 +153,13 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
 		dev->device.numa_node = 0;
 	}
 
+	already_probed = rte_dev_is_probed(&dev->device);
+	if (already_probed && !(dr->drv_flags & RTE_PCI_DRV_PROBE_AGAIN)) {
+		RTE_LOG(DEBUG, EAL, "Device %s is already probed\n",
+				dev->device.name);
+		return -EEXIST;
+	}
+
 	RTE_LOG(INFO, EAL, "  probe driver: %x:%x %s\n", dev->id.vendor_id,
 		dev->id.device_id, dr->driver.name);
 
@@ -159,9 +168,10 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
 	 * This needs to be before rte_pci_map_device(), as it enables to use
 	 * driver flags for adjusting configuration.
 	 */
-	dev->driver = dr;
+	if (!already_probed)
+		dev->driver = dr;
 
-	if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) {
+	if (!already_probed && (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING)) {
 		/* map resources for devices that use igb_uio */
 		ret = rte_pci_map_device(dev);
 		if (ret != 0) {
@@ -172,6 +182,8 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
 
 	/* call the driver probe() function */
 	ret = dr->probe(dr, dev);
+	if (already_probed)
+		return ret; /* no rollback if already succeeded earlier */
 	if (ret) {
 		dev->driver = NULL;
 		if ((dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) &&
@@ -242,10 +254,6 @@ pci_probe_all_drivers(struct rte_pci_device *dev)
 	if (dev == NULL)
 		return -1;
 
-	/* Check if a driver is already loaded */
-	if (rte_dev_is_probed(&dev->device))
-		return 0;
-
 	FOREACH_DRIVER_ON_PCIBUS(dr) {
 		rc = rte_pci_probe_one_driver(dr, dev);
 		if (rc < 0)
@@ -287,11 +295,14 @@ rte_pci_probe(void)
 			devargs->policy == RTE_DEV_WHITELISTED)
 			ret = pci_probe_all_drivers(dev);
 		if (ret < 0) {
-			RTE_LOG(ERR, EAL, "Requested device " PCI_PRI_FMT
-				 " cannot be used\n", dev->addr.domain, dev->addr.bus,
-				 dev->addr.devid, dev->addr.function);
-			rte_errno = errno;
-			failed++;
+			if (ret != -EEXIST) {
+				RTE_LOG(ERR, EAL, "Requested device "
+					PCI_PRI_FMT " cannot be used\n",
+					dev->addr.domain, dev->addr.bus,
+					dev->addr.devid, dev->addr.function);
+				rte_errno = errno;
+				failed++;
+			}
 			ret = 0;
 		}
 	}
diff --git a/drivers/bus/pci/rte_bus_pci.h b/drivers/bus/pci/rte_bus_pci.h
index 984df2b37..a3baa2895 100644
--- a/drivers/bus/pci/rte_bus_pci.h
+++ b/drivers/bus/pci/rte_bus_pci.h
@@ -121,7 +121,7 @@ struct rte_pci_driver {
 	pci_probe_t *probe;                /**< Device Probe function. */
 	pci_remove_t *remove;              /**< Device Remove function. */
 	const struct rte_pci_id *id_table; /**< ID table, NULL terminated. */
-	uint32_t drv_flags;                /**< Flags contolling handling of device. */
+	uint32_t drv_flags;                /**< Flags RTE_PCI_DRV_*. */
 };
 
 /**
@@ -137,6 +137,8 @@ struct rte_pci_bus {
 #define RTE_PCI_DRV_NEED_MAPPING 0x0001
 /** Device needs PCI BAR mapping with enabled write combining (wc) */
 #define RTE_PCI_DRV_WC_ACTIVATE 0x0002
+/** Device already probed can be probed again to check for new ports. */
+#define RTE_PCI_DRV_PROBE_AGAIN 0x0004
 /** Device driver supports link state interrupt */
 #define RTE_PCI_DRV_INTR_LSC	0x0008
 /** Device driver supports device removal interrupt */
diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
index f666099e6..06f314843 100644
--- a/drivers/bus/vdev/vdev.c
+++ b/drivers/bus/vdev/vdev.c
@@ -226,6 +226,11 @@ insert_vdev(const char *name, const char *args, struct rte_vdev_device **p_dev)
 	dev->device.name = devargs->name;
 
 	if (find_vdev(name)) {
+		/*
+		 * A vdev is expected to have only one port.
+		 * So there is no reason to try probing again,
+		 * even with new arguments.
+		 */
 		ret = -EEXIST;
 		goto fail;
 	}
diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c
index 7e8a9b260..e733eb779 100644
--- a/lib/librte_eal/common/eal_common_dev.c
+++ b/lib/librte_eal/common/eal_common_dev.c
@@ -196,13 +196,10 @@ rte_dev_probe(const char *devargs)
 		goto err_devarg;
 	}
 
-	if (rte_dev_is_probed(dev)) {
-		RTE_LOG(ERR, EAL, "Device is already plugged\n");
-		return -EEXIST;
-	}
-
 	ret = dev->bus->plug(dev);
 	if (ret) {
+		if (rte_dev_is_probed(dev)) /* if already succeeded earlier */
+			return ret; /* no rollback */
 		RTE_LOG(ERR, EAL, "Driver cannot attach the device (%s)\n",
 			dev->name);
 		goto err_devarg;
diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
index 9f169e3b3..a7ec8ec25 100644
--- a/lib/librte_eal/common/include/rte_dev.h
+++ b/lib/librte_eal/common/include/rte_dev.h
@@ -159,7 +159,7 @@ struct rte_device {
 	const struct rte_driver *driver; /**< Driver assigned after probing */
 	const struct rte_bus *bus;    /**< Bus handle assigned on scan */
 	int numa_node;                /**< NUMA node connection */
-	struct rte_devargs *devargs;  /**< Device user arguments */
+	struct rte_devargs *devargs;  /**< Arguments for latest probing */
 };
 
 /**
-- 
2.19.0

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

* Re: [PATCH v3 1/3] drivers/bus: move driver assignment to end of probing
  2018-10-07 22:09   ` [PATCH v3 1/3] drivers/bus: move driver assignment to end of probing Thomas Monjalon
@ 2018-10-08  8:05     ` Andrew Rybchenko
  2018-10-11 10:53     ` Andrew Rybchenko
  1 sibling, 0 replies; 58+ messages in thread
From: Andrew Rybchenko @ 2018-10-08  8:05 UTC (permalink / raw)
  To: Thomas Monjalon, dev; +Cc: gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit

On 10/8/18 1:09 AM, Thomas Monjalon wrote:
> The PCI mapping requires to know the PCI driver to use,
> even before the probing is done. That's why the PCI driver is
> referenced early inside the PCI device structure. See
> 1d20a073fa5e ("bus/pci: reference driver structure before mapping")
>
> However the rte_driver does not need to be referenced in rte_device
> before the device probing is done.
> By moving back this assignment at the end of the device probing,
> it becomes possible to make clear the status of a rte_device.
>
> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>

Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>

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

* Re: [PATCH v3 2/3] eal: add function to query device status
  2018-10-07 22:09   ` [PATCH v3 2/3] eal: add function to query device status Thomas Monjalon
@ 2018-10-08  8:05     ` Andrew Rybchenko
  0 siblings, 0 replies; 58+ messages in thread
From: Andrew Rybchenko @ 2018-10-08  8:05 UTC (permalink / raw)
  To: Thomas Monjalon, dev; +Cc: gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit

On 10/8/18 1:09 AM, Thomas Monjalon wrote:
> The function rte_dev_is_probed() is added in order to improve semantic
> and enforce proper check of the probing status of a device.
>
> It will answer this rte_device query:
> Is it already successfully probed or not?
>
> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>

Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>

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

* Re: [PATCH v3 3/3] eal: allow probing a device again
  2018-10-07 22:09   ` [PATCH v3 3/3] eal: allow probing a device again Thomas Monjalon
@ 2018-10-08  8:05     ` Andrew Rybchenko
  0 siblings, 0 replies; 58+ messages in thread
From: Andrew Rybchenko @ 2018-10-08  8:05 UTC (permalink / raw)
  To: Thomas Monjalon, dev; +Cc: gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit

On 10/8/18 1:09 AM, Thomas Monjalon wrote:
> In the devargs syntax for device representors, it is possible to add
> several devices at once: -w dbdf,representor=[0-3]
> It will become a more frequent case when introducing wildcards
> and ranges in the new devargs syntax.
>
> If a devargs string is provided for probing, and updated with a bigger
> range for a new probing, then we do not want it to fail because
> part of this range was already probed previously.
> There can be new ports to create from an existing rte_device.
>
> That's why the check for an already probed device
> is moved as bus responsibility.
> In the case of vdev, a global check is kept in insert_vdev(),
> assuming that a vdev will always have only one port.
> In the case of ifpga and vmbus, already probed devices are checked.
> In the case of NXP buses, the probing is done only once (no hotplug),
> though a check is added at bus level for consistency.
> In the case of PCI, a driver flag is added to allow PMD probing again.
> Only the PMD knows the ports attached to one rte_device.
>
> As another consequence of being able to probe in several steps,
> the field rte_device.devargs must not be considered as a full
> representation of the rte_device, but only the latest probing args.
> Anyway, the field rte_device.devargs is used only for probing.
>
> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>

Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>

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

* Re: [PATCH v3 1/3] drivers/bus: move driver assignment to end of probing
  2018-10-07 22:09   ` [PATCH v3 1/3] drivers/bus: move driver assignment to end of probing Thomas Monjalon
  2018-10-08  8:05     ` Andrew Rybchenko
@ 2018-10-11 10:53     ` Andrew Rybchenko
  2018-10-11 11:45       ` Thomas Monjalon
  1 sibling, 1 reply; 58+ messages in thread
From: Andrew Rybchenko @ 2018-10-11 10:53 UTC (permalink / raw)
  To: Thomas Monjalon, dev; +Cc: gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit

On 10/8/18 1:09 AM, Thomas Monjalon wrote:
> The PCI mapping requires to know the PCI driver to use,
> even before the probing is done. That's why the PCI driver is
> referenced early inside the PCI device structure. See
> 1d20a073fa5e ("bus/pci: reference driver structure before mapping")
>
> However the rte_driver does not need to be referenced in rte_device
> before the device probing is done.
> By moving back this assignment at the end of the device probing,
> it becomes possible to make clear the status of a rte_device.
>
> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
> ---
> diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
> index c7695d108..d63e68045 100644
> --- a/drivers/bus/pci/pci_common.c
> +++ b/drivers/bus/pci/pci_common.c
> @@ -160,14 +160,12 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
>   	 * driver flags for adjusting configuration.
>   	 */
>   	dev->driver = dr;
> -	dev->device.driver = &dr->driver;

It breaks net/sfc and I guess other drivers which use 
rte_eth_dma_zone_reserve()
from probe. The function makes zone name using dev->device->driver->name.

Andrew.

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

* Re: [PATCH v3 1/3] drivers/bus: move driver assignment to end of probing
  2018-10-11 10:53     ` Andrew Rybchenko
@ 2018-10-11 11:45       ` Thomas Monjalon
  2018-10-11 11:54         ` Andrew Rybchenko
  0 siblings, 1 reply; 58+ messages in thread
From: Thomas Monjalon @ 2018-10-11 11:45 UTC (permalink / raw)
  To: Andrew Rybchenko; +Cc: dev, gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit

11/10/2018 12:53, Andrew Rybchenko:
> On 10/8/18 1:09 AM, Thomas Monjalon wrote:
> > The PCI mapping requires to know the PCI driver to use,
> > even before the probing is done. That's why the PCI driver is
> > referenced early inside the PCI device structure. See
> > 1d20a073fa5e ("bus/pci: reference driver structure before mapping")
> >
> > However the rte_driver does not need to be referenced in rte_device
> > before the device probing is done.
> > By moving back this assignment at the end of the device probing,
> > it becomes possible to make clear the status of a rte_device.
> >
> > Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
> > ---
> > diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
> > index c7695d108..d63e68045 100644
> > --- a/drivers/bus/pci/pci_common.c
> > +++ b/drivers/bus/pci/pci_common.c
> > @@ -160,14 +160,12 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
> >   	 * driver flags for adjusting configuration.
> >   	 */
> >   	dev->driver = dr;
> > -	dev->device.driver = &dr->driver;
> 
> It breaks net/sfc and I guess other drivers which use 
> rte_eth_dma_zone_reserve()
> from probe. The function makes zone name using dev->device->driver->name.

Please, can you show code line where we does such access?

I checked such access before and did not find some.
Anyway, it can be fixed by accessing rte_pci_driver->driver->name.
Note that rte_pci_driver is referenced in rte_pci_device.

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

* Re: [PATCH v3 1/3] drivers/bus: move driver assignment to end of probing
  2018-10-11 11:45       ` Thomas Monjalon
@ 2018-10-11 11:54         ` Andrew Rybchenko
  2018-10-11 12:59           ` Thomas Monjalon
  0 siblings, 1 reply; 58+ messages in thread
From: Andrew Rybchenko @ 2018-10-11 11:54 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev, gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit

On 10/11/18 2:45 PM, Thomas Monjalon wrote:
> 11/10/2018 12:53, Andrew Rybchenko:
>> On 10/8/18 1:09 AM, Thomas Monjalon wrote:
>>> The PCI mapping requires to know the PCI driver to use,
>>> even before the probing is done. That's why the PCI driver is
>>> referenced early inside the PCI device structure. See
>>> 1d20a073fa5e ("bus/pci: reference driver structure before mapping")
>>>
>>> However the rte_driver does not need to be referenced in rte_device
>>> before the device probing is done.
>>> By moving back this assignment at the end of the device probing,
>>> it becomes possible to make clear the status of a rte_device.
>>>
>>> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
>>> ---
>>> diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
>>> index c7695d108..d63e68045 100644
>>> --- a/drivers/bus/pci/pci_common.c
>>> +++ b/drivers/bus/pci/pci_common.c
>>> @@ -160,14 +160,12 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
>>>    	 * driver flags for adjusting configuration.
>>>    	 */
>>>    	dev->driver = dr;
>>> -	dev->device.driver = &dr->driver;
>> It breaks net/sfc and I guess other drivers which use
>> rte_eth_dma_zone_reserve()
>> from probe. The function makes zone name using dev->device->driver->name.
> Please, can you show code line where we does such access?
>
> I checked such access before and did not find some.
> Anyway, it can be fixed by accessing rte_pci_driver->driver->name.
> Note that rte_pci_driver is referenced in rte_pci_device.

Below in snprintf(), in theory it can be called for vdev as well.

const struct rte_memzone *
rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char 
*ring_name,
                          uint16_t queue_id, size_t size, unsigned align,
                          int socket_id)
{
         char z_name[RTE_MEMZONE_NAMESIZE];
         const struct rte_memzone *mz;

         snprintf(z_name, sizeof(z_name), "%s_%s_%d_%d",
                  dev->device->driver->name, ring_name,
                  dev->data->port_id, queue_id);

         mz = rte_memzone_lookup(z_name);
         if (mz)
                 return mz;

         return rte_memzone_reserve_aligned(z_name, size, socket_id,
                         RTE_MEMZONE_IOVA_CONTIG, align);
}

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

* Re: [PATCH v3 1/3] drivers/bus: move driver assignment to end of probing
  2018-10-11 11:54         ` Andrew Rybchenko
@ 2018-10-11 12:59           ` Thomas Monjalon
  2018-10-11 13:15             ` Andrew Rybchenko
  0 siblings, 1 reply; 58+ messages in thread
From: Thomas Monjalon @ 2018-10-11 12:59 UTC (permalink / raw)
  To: Andrew Rybchenko; +Cc: dev, gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit

11/10/2018 13:54, Andrew Rybchenko:
> On 10/11/18 2:45 PM, Thomas Monjalon wrote:
> > 11/10/2018 12:53, Andrew Rybchenko:
> >> On 10/8/18 1:09 AM, Thomas Monjalon wrote:
> >>> The PCI mapping requires to know the PCI driver to use,
> >>> even before the probing is done. That's why the PCI driver is
> >>> referenced early inside the PCI device structure. See
> >>> 1d20a073fa5e ("bus/pci: reference driver structure before mapping")
> >>>
> >>> However the rte_driver does not need to be referenced in rte_device
> >>> before the device probing is done.
> >>> By moving back this assignment at the end of the device probing,
> >>> it becomes possible to make clear the status of a rte_device.
> >>>
> >>> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
> >>> ---
> >>> diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
> >>> index c7695d108..d63e68045 100644
> >>> --- a/drivers/bus/pci/pci_common.c
> >>> +++ b/drivers/bus/pci/pci_common.c
> >>> @@ -160,14 +160,12 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
> >>>    	 * driver flags for adjusting configuration.
> >>>    	 */
> >>>    	dev->driver = dr;
> >>> -	dev->device.driver = &dr->driver;
> >> It breaks net/sfc and I guess other drivers which use
> >> rte_eth_dma_zone_reserve()
> >> from probe. The function makes zone name using dev->device->driver->name.
> > Please, can you show code line where we does such access?
> >
> > I checked such access before and did not find some.
> > Anyway, it can be fixed by accessing rte_pci_driver->driver->name.
> > Note that rte_pci_driver is referenced in rte_pci_device.
> 
> Below in snprintf(), in theory it can be called for vdev as well.
> 
> const struct rte_memzone *
> rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char 
> *ring_name,
>                           uint16_t queue_id, size_t size, unsigned align,
>                           int socket_id)
> {
>          char z_name[RTE_MEMZONE_NAMESIZE];
>          const struct rte_memzone *mz;
> 
>          snprintf(z_name, sizeof(z_name), "%s_%s_%d_%d",
>                   dev->device->driver->name, ring_name,
>                   dev->data->port_id, queue_id);

I see, I missed it.

I think it's strange to use rte_device name for ethdev memory.
Should we use the ethdev name instead?

        snprintf(z_name, sizeof(z_name), "%s_%s_%d_%d",
-                dev->device->driver->name, ring_name,
+                dev->data->name, ring_name,
                 dev->data->port_id, queue_id);

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

* Re: [PATCH v3 1/3] drivers/bus: move driver assignment to end of probing
  2018-10-11 12:59           ` Thomas Monjalon
@ 2018-10-11 13:15             ` Andrew Rybchenko
  2018-10-11 15:29               ` Thomas Monjalon
  0 siblings, 1 reply; 58+ messages in thread
From: Andrew Rybchenko @ 2018-10-11 13:15 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev, gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit

On 10/11/18 3:59 PM, Thomas Monjalon wrote:
> 11/10/2018 13:54, Andrew Rybchenko:
>> On 10/11/18 2:45 PM, Thomas Monjalon wrote:
>>> 11/10/2018 12:53, Andrew Rybchenko:
>>>> On 10/8/18 1:09 AM, Thomas Monjalon wrote:
>>>>> The PCI mapping requires to know the PCI driver to use,
>>>>> even before the probing is done. That's why the PCI driver is
>>>>> referenced early inside the PCI device structure. See
>>>>> 1d20a073fa5e ("bus/pci: reference driver structure before mapping")
>>>>>
>>>>> However the rte_driver does not need to be referenced in rte_device
>>>>> before the device probing is done.
>>>>> By moving back this assignment at the end of the device probing,
>>>>> it becomes possible to make clear the status of a rte_device.
>>>>>
>>>>> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
>>>>> ---
>>>>> diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
>>>>> index c7695d108..d63e68045 100644
>>>>> --- a/drivers/bus/pci/pci_common.c
>>>>> +++ b/drivers/bus/pci/pci_common.c
>>>>> @@ -160,14 +160,12 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
>>>>>     	 * driver flags for adjusting configuration.
>>>>>     	 */
>>>>>     	dev->driver = dr;
>>>>> -	dev->device.driver = &dr->driver;
>>>> It breaks net/sfc and I guess other drivers which use
>>>> rte_eth_dma_zone_reserve()
>>>> from probe. The function makes zone name using dev->device->driver->name.
>>> Please, can you show code line where we does such access?
>>>
>>> I checked such access before and did not find some.
>>> Anyway, it can be fixed by accessing rte_pci_driver->driver->name.
>>> Note that rte_pci_driver is referenced in rte_pci_device.
>> Below in snprintf(), in theory it can be called for vdev as well.
>>
>> const struct rte_memzone *
>> rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char
>> *ring_name,
>>                            uint16_t queue_id, size_t size, unsigned align,
>>                            int socket_id)
>> {
>>           char z_name[RTE_MEMZONE_NAMESIZE];
>>           const struct rte_memzone *mz;
>>
>>           snprintf(z_name, sizeof(z_name), "%s_%s_%d_%d",
>>                    dev->device->driver->name, ring_name,
>>                    dev->data->port_id, queue_id);
> I see, I missed it.
>
> I think it's strange to use rte_device name for ethdev memory.
> Should we use the ethdev name instead?
>
>          snprintf(z_name, sizeof(z_name), "%s_%s_%d_%d",
> -                dev->device->driver->name, ring_name,
> +                dev->data->name, ring_name,
>                   dev->data->port_id, queue_id);

data->name could be update to 63 characters (RTE_DEV_NAME_MAX_LEN=64).
RTE_MEMZONE_NAMESIZE is 32. Sounds like a problem.
It is especially a problem if name may be specified/set by user.

Right now device driver writer knows the driver name, choose ring name and
have limits on port and queue ID. So, the writer at least has possibility to
be sure that the results will always fit z_name.

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

* Re: [PATCH v3 1/3] drivers/bus: move driver assignment to end of probing
  2018-10-11 13:15             ` Andrew Rybchenko
@ 2018-10-11 15:29               ` Thomas Monjalon
  2018-10-11 15:41                 ` Andrew Rybchenko
  0 siblings, 1 reply; 58+ messages in thread
From: Thomas Monjalon @ 2018-10-11 15:29 UTC (permalink / raw)
  To: Andrew Rybchenko; +Cc: dev, gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit

11/10/2018 15:15, Andrew Rybchenko:
> On 10/11/18 3:59 PM, Thomas Monjalon wrote:
> > 11/10/2018 13:54, Andrew Rybchenko:
> >> On 10/11/18 2:45 PM, Thomas Monjalon wrote:
> >>> 11/10/2018 12:53, Andrew Rybchenko:
> >>>> On 10/8/18 1:09 AM, Thomas Monjalon wrote:
> >>>>> The PCI mapping requires to know the PCI driver to use,
> >>>>> even before the probing is done. That's why the PCI driver is
> >>>>> referenced early inside the PCI device structure. See
> >>>>> 1d20a073fa5e ("bus/pci: reference driver structure before mapping")
> >>>>>
> >>>>> However the rte_driver does not need to be referenced in rte_device
> >>>>> before the device probing is done.
> >>>>> By moving back this assignment at the end of the device probing,
> >>>>> it becomes possible to make clear the status of a rte_device.
> >>>>>
> >>>>> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
> >>>>> ---
> >>>>> diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
> >>>>> index c7695d108..d63e68045 100644
> >>>>> --- a/drivers/bus/pci/pci_common.c
> >>>>> +++ b/drivers/bus/pci/pci_common.c
> >>>>> @@ -160,14 +160,12 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
> >>>>>     	 * driver flags for adjusting configuration.
> >>>>>     	 */
> >>>>>     	dev->driver = dr;
> >>>>> -	dev->device.driver = &dr->driver;
> >>>> It breaks net/sfc and I guess other drivers which use
> >>>> rte_eth_dma_zone_reserve()
> >>>> from probe. The function makes zone name using dev->device->driver->name.
> >>> Please, can you show code line where we does such access?
> >>>
> >>> I checked such access before and did not find some.
> >>> Anyway, it can be fixed by accessing rte_pci_driver->driver->name.
> >>> Note that rte_pci_driver is referenced in rte_pci_device.
> >> Below in snprintf(), in theory it can be called for vdev as well.
> >>
> >> const struct rte_memzone *
> >> rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char
> >> *ring_name,
> >>                            uint16_t queue_id, size_t size, unsigned align,
> >>                            int socket_id)
> >> {
> >>           char z_name[RTE_MEMZONE_NAMESIZE];
> >>           const struct rte_memzone *mz;
> >>
> >>           snprintf(z_name, sizeof(z_name), "%s_%s_%d_%d",
> >>                    dev->device->driver->name, ring_name,
> >>                    dev->data->port_id, queue_id);
> > I see, I missed it.
> >
> > I think it's strange to use rte_device name for ethdev memory.
> > Should we use the ethdev name instead?
> >
> >          snprintf(z_name, sizeof(z_name), "%s_%s_%d_%d",
> > -                dev->device->driver->name, ring_name,
> > +                dev->data->name, ring_name,
> >                   dev->data->port_id, queue_id);
> 
> data->name could be update to 63 characters (RTE_DEV_NAME_MAX_LEN=64).
> RTE_MEMZONE_NAMESIZE is 32. Sounds like a problem.
> It is especially a problem if name may be specified/set by user.
> 
> Right now device driver writer knows the driver name, choose ring name and
> have limits on port and queue ID. So, the writer at least has possibility to
> be sure that the results will always fit z_name.

What about removing the device name from the memzone name?
It is already unique thanks to port_id, queue_id and ring_name.

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

* Re: [PATCH v3 1/3] drivers/bus: move driver assignment to end of probing
  2018-10-11 15:29               ` Thomas Monjalon
@ 2018-10-11 15:41                 ` Andrew Rybchenko
  2018-10-11 16:00                   ` Thomas Monjalon
  0 siblings, 1 reply; 58+ messages in thread
From: Andrew Rybchenko @ 2018-10-11 15:41 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: dev, gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit

On 10/11/18 6:29 PM, Thomas Monjalon wrote:
> 11/10/2018 15:15, Andrew Rybchenko:
>> On 10/11/18 3:59 PM, Thomas Monjalon wrote:
>>> 11/10/2018 13:54, Andrew Rybchenko:
>>>> On 10/11/18 2:45 PM, Thomas Monjalon wrote:
>>>>> 11/10/2018 12:53, Andrew Rybchenko:
>>>>>> On 10/8/18 1:09 AM, Thomas Monjalon wrote:
>>>>>>> The PCI mapping requires to know the PCI driver to use,
>>>>>>> even before the probing is done. That's why the PCI driver is
>>>>>>> referenced early inside the PCI device structure. See
>>>>>>> 1d20a073fa5e ("bus/pci: reference driver structure before mapping")
>>>>>>>
>>>>>>> However the rte_driver does not need to be referenced in rte_device
>>>>>>> before the device probing is done.
>>>>>>> By moving back this assignment at the end of the device probing,
>>>>>>> it becomes possible to make clear the status of a rte_device.
>>>>>>>
>>>>>>> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
>>>>>>> ---
>>>>>>> diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
>>>>>>> index c7695d108..d63e68045 100644
>>>>>>> --- a/drivers/bus/pci/pci_common.c
>>>>>>> +++ b/drivers/bus/pci/pci_common.c
>>>>>>> @@ -160,14 +160,12 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
>>>>>>>      	 * driver flags for adjusting configuration.
>>>>>>>      	 */
>>>>>>>      	dev->driver = dr;
>>>>>>> -	dev->device.driver = &dr->driver;
>>>>>> It breaks net/sfc and I guess other drivers which use
>>>>>> rte_eth_dma_zone_reserve()
>>>>>> from probe. The function makes zone name using dev->device->driver->name.
>>>>> Please, can you show code line where we does such access?
>>>>>
>>>>> I checked such access before and did not find some.
>>>>> Anyway, it can be fixed by accessing rte_pci_driver->driver->name.
>>>>> Note that rte_pci_driver is referenced in rte_pci_device.
>>>> Below in snprintf(), in theory it can be called for vdev as well.
>>>>
>>>> const struct rte_memzone *
>>>> rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char
>>>> *ring_name,
>>>>                             uint16_t queue_id, size_t size, unsigned align,
>>>>                             int socket_id)
>>>> {
>>>>            char z_name[RTE_MEMZONE_NAMESIZE];
>>>>            const struct rte_memzone *mz;
>>>>
>>>>            snprintf(z_name, sizeof(z_name), "%s_%s_%d_%d",
>>>>                     dev->device->driver->name, ring_name,
>>>>                     dev->data->port_id, queue_id);
>>> I see, I missed it.
>>>
>>> I think it's strange to use rte_device name for ethdev memory.
>>> Should we use the ethdev name instead?
>>>
>>>           snprintf(z_name, sizeof(z_name), "%s_%s_%d_%d",
>>> -                dev->device->driver->name, ring_name,
>>> +                dev->data->name, ring_name,
>>>                    dev->data->port_id, queue_id);
>> data->name could be update to 63 characters (RTE_DEV_NAME_MAX_LEN=64).
>> RTE_MEMZONE_NAMESIZE is 32. Sounds like a problem.
>> It is especially a problem if name may be specified/set by user.
>>
>> Right now device driver writer knows the driver name, choose ring name and
>> have limits on port and queue ID. So, the writer at least has possibility to
>> be sure that the results will always fit z_name.
> What about removing the device name from the memzone name?
> It is already unique thanks to port_id, queue_id and ring_name.

Driver name is nice since it simplify buggy code identification, but
not that critical. Maybe we should highlight that it is ethdev
(not other port/queue), i.e. ethdev_%s_%d_%d, to be sure
that port_id and queue_id uniquely identify it.

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

* Re: [PATCH v3 1/3] drivers/bus: move driver assignment to end of probing
  2018-10-11 15:41                 ` Andrew Rybchenko
@ 2018-10-11 16:00                   ` Thomas Monjalon
  0 siblings, 0 replies; 58+ messages in thread
From: Thomas Monjalon @ 2018-10-11 16:00 UTC (permalink / raw)
  To: Andrew Rybchenko; +Cc: dev, gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit

11/10/2018 17:41, Andrew Rybchenko:
> On 10/11/18 6:29 PM, Thomas Monjalon wrote:
> > 11/10/2018 15:15, Andrew Rybchenko:
> >> On 10/11/18 3:59 PM, Thomas Monjalon wrote:
> >>> 11/10/2018 13:54, Andrew Rybchenko:
> >>>> On 10/11/18 2:45 PM, Thomas Monjalon wrote:
> >>>>> 11/10/2018 12:53, Andrew Rybchenko:
> >>>>>> On 10/8/18 1:09 AM, Thomas Monjalon wrote:
> >>>>>>> The PCI mapping requires to know the PCI driver to use,
> >>>>>>> even before the probing is done. That's why the PCI driver is
> >>>>>>> referenced early inside the PCI device structure. See
> >>>>>>> 1d20a073fa5e ("bus/pci: reference driver structure before mapping")
> >>>>>>>
> >>>>>>> However the rte_driver does not need to be referenced in rte_device
> >>>>>>> before the device probing is done.
> >>>>>>> By moving back this assignment at the end of the device probing,
> >>>>>>> it becomes possible to make clear the status of a rte_device.
> >>>>>>>
> >>>>>>> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
> >>>>>>> ---
> >>>>>>> diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
> >>>>>>> index c7695d108..d63e68045 100644
> >>>>>>> --- a/drivers/bus/pci/pci_common.c
> >>>>>>> +++ b/drivers/bus/pci/pci_common.c
> >>>>>>> @@ -160,14 +160,12 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
> >>>>>>>      	 * driver flags for adjusting configuration.
> >>>>>>>      	 */
> >>>>>>>      	dev->driver = dr;
> >>>>>>> -	dev->device.driver = &dr->driver;
> >>>>>> It breaks net/sfc and I guess other drivers which use
> >>>>>> rte_eth_dma_zone_reserve()
> >>>>>> from probe. The function makes zone name using dev->device->driver->name.
> >>>>> Please, can you show code line where we does such access?
> >>>>>
> >>>>> I checked such access before and did not find some.
> >>>>> Anyway, it can be fixed by accessing rte_pci_driver->driver->name.
> >>>>> Note that rte_pci_driver is referenced in rte_pci_device.
> >>>> Below in snprintf(), in theory it can be called for vdev as well.
> >>>>
> >>>> const struct rte_memzone *
> >>>> rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char
> >>>> *ring_name,
> >>>>                             uint16_t queue_id, size_t size, unsigned align,
> >>>>                             int socket_id)
> >>>> {
> >>>>            char z_name[RTE_MEMZONE_NAMESIZE];
> >>>>            const struct rte_memzone *mz;
> >>>>
> >>>>            snprintf(z_name, sizeof(z_name), "%s_%s_%d_%d",
> >>>>                     dev->device->driver->name, ring_name,
> >>>>                     dev->data->port_id, queue_id);
> >>> I see, I missed it.
> >>>
> >>> I think it's strange to use rte_device name for ethdev memory.
> >>> Should we use the ethdev name instead?
> >>>
> >>>           snprintf(z_name, sizeof(z_name), "%s_%s_%d_%d",
> >>> -                dev->device->driver->name, ring_name,
> >>> +                dev->data->name, ring_name,
> >>>                    dev->data->port_id, queue_id);
> >> data->name could be update to 63 characters (RTE_DEV_NAME_MAX_LEN=64).
> >> RTE_MEMZONE_NAMESIZE is 32. Sounds like a problem.
> >> It is especially a problem if name may be specified/set by user.
> >>
> >> Right now device driver writer knows the driver name, choose ring name and
> >> have limits on port and queue ID. So, the writer at least has possibility to
> >> be sure that the results will always fit z_name.
> > What about removing the device name from the memzone name?
> > It is already unique thanks to port_id, queue_id and ring_name.
> 
> Driver name is nice since it simplify buggy code identification, but
> not that critical. Maybe we should highlight that it is ethdev
> (not other port/queue), i.e. ethdev_%s_%d_%d, to be sure
> that port_id and queue_id uniquely identify it.

OK, I send a patch then.

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

* [PATCH v4 0/4] eal: allow hotplug to skip an already probed device
  2018-09-07 23:09 [RFC] eal: allow hotplug to skip an already probed device Thomas Monjalon
                   ` (2 preceding siblings ...)
  2018-10-07 22:09 ` [PATCH v3 0/3] eal: allow hotplug to skip an already probed device Thomas Monjalon
@ 2018-10-11 21:02 ` Thomas Monjalon
  2018-10-11 21:02   ` [PATCH v4 1/4] ethdev: rename memzones allocated for DMA Thomas Monjalon
                     ` (4 more replies)
  2018-10-14 20:47 ` [PATCH v5 0/7] " Thomas Monjalon
  4 siblings, 5 replies; 58+ messages in thread
From: Thomas Monjalon @ 2018-10-11 21:02 UTC (permalink / raw)
  To: dev; +Cc: gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit

This is a follow-up of an idea presented at Dublin
during the "hotplug talk".

The idea is to ease probing of range of ports attached
to the same rte_device.
I becomes possible to allow probing again the same device
but with a bigger range of ports in the devargs.

Instead of adding a parameter to the hotplug functions, as in the RFC,
the check of an already probed device is moved to the bus and enabled PMDs.
It gives flexibility to drivers for managing range of ports.


Changes in v4 - after Andrew's review:
  - remove access to rte_device.driver during probing (patch 1)

Changes in v3 - after Declan's review:
  - return error in all buses but PCI
  - add a PCI driver flag to enable feature per driver
  - return -EEXIST if probing again is not supported


Thomas Monjalon (4):
  ethdev: rename memzones allocated for DMA
  drivers/bus: move driver assignment to end of probing
  eal: add function to query device status
  eal: allow probing a device again

 drivers/bus/dpaa/dpaa_bus.c             |  3 ++
 drivers/bus/fslmc/fslmc_bus.c           |  3 ++
 drivers/bus/ifpga/ifpga_bus.c           | 21 +++++++-------
 drivers/bus/pci/pci_common.c            | 38 ++++++++++++++++---------
 drivers/bus/pci/rte_bus_pci.h           |  6 ++--
 drivers/bus/vdev/vdev.c                 | 12 +++++---
 drivers/bus/vmbus/vmbus_common.c        |  5 ++--
 drivers/net/i40e/i40e_vf_representor.c  |  3 --
 drivers/net/mlx4/mlx4.c                 |  1 -
 drivers/net/mlx5/mlx5.c                 |  1 -
 lib/librte_eal/common/eal_common_dev.c  | 14 +++++----
 lib/librte_eal/common/include/rte_dev.h | 18 ++++++++++--
 lib/librte_eal/rte_eal_version.map      |  1 +
 lib/librte_ethdev/rte_ethdev.c          |  5 ++--
 14 files changed, 84 insertions(+), 47 deletions(-)

-- 
2.19.0

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

* [PATCH v4 1/4] ethdev: rename memzones allocated for DMA
  2018-10-11 21:02 ` [PATCH v4 0/4] eal: allow hotplug to skip an already probed device Thomas Monjalon
@ 2018-10-11 21:02   ` Thomas Monjalon
  2018-10-12  7:53     ` Andrew Rybchenko
  2018-10-11 21:02   ` [PATCH v4 2/4] drivers/bus: move driver assignment to end of probing Thomas Monjalon
                     ` (3 subsequent siblings)
  4 siblings, 1 reply; 58+ messages in thread
From: Thomas Monjalon @ 2018-10-11 21:02 UTC (permalink / raw)
  To: dev; +Cc: gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit

The helper rte_eth_dma_zone_reserve() is called by PMDs
when probing a new port.
It creates a new memzone with an unique name.
The name of this memzone was using the name of the driver
doing the probe.

In order to avoid assigning the driver before the end of the probing
(next patch), the driver name is removed from these memzone names.
The ethdev name (data->name) is not used because it may be too long
and may be not set at this stage of probing.

Syntax of old name: <driver>_<ring>_<port>_<queue>
Syntax of new name: eth_p<port>_q<queue>_<ring>

Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
---
 lib/librte_ethdev/rte_ethdev.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index ef99f7068..ec443def5 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -3441,9 +3441,8 @@ rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name,
 	char z_name[RTE_MEMZONE_NAMESIZE];
 	const struct rte_memzone *mz;
 
-	snprintf(z_name, sizeof(z_name), "%s_%s_%d_%d",
-		 dev->device->driver->name, ring_name,
-		 dev->data->port_id, queue_id);
+	snprintf(z_name, sizeof(z_name), "eth_p%d_q%d_%s",
+		 dev->data->port_id, queue_id, ring_name);
 
 	mz = rte_memzone_lookup(z_name);
 	if (mz)
-- 
2.19.0

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

* [PATCH v4 2/4] drivers/bus: move driver assignment to end of probing
  2018-10-11 21:02 ` [PATCH v4 0/4] eal: allow hotplug to skip an already probed device Thomas Monjalon
  2018-10-11 21:02   ` [PATCH v4 1/4] ethdev: rename memzones allocated for DMA Thomas Monjalon
@ 2018-10-11 21:02   ` Thomas Monjalon
  2018-10-12  7:44     ` Andrew Rybchenko
  2018-10-11 21:02   ` [PATCH v4 3/4] eal: add function to query device status Thomas Monjalon
                     ` (2 subsequent siblings)
  4 siblings, 1 reply; 58+ messages in thread
From: Thomas Monjalon @ 2018-10-11 21:02 UTC (permalink / raw)
  To: dev; +Cc: gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit

The PCI mapping requires to know the PCI driver to use,
even before the probing is done. That's why the PCI driver is
referenced early inside the PCI device structure. See
commit 1d20a073fa5e ("bus/pci: reference driver structure before mapping")

However the rte_driver does not need to be referenced in rte_device
before the device probing is done.
By moving back this assignment at the end of the device probing,
it becomes possible to make clear the status of a rte_device.

Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/bus/ifpga/ifpga_bus.c           | 9 ++++-----
 drivers/bus/pci/pci_common.c            | 7 +++----
 drivers/bus/pci/rte_bus_pci.h           | 2 +-
 drivers/bus/vdev/vdev.c                 | 5 ++---
 drivers/bus/vmbus/vmbus_common.c        | 5 +++--
 drivers/net/i40e/i40e_vf_representor.c  | 3 ---
 drivers/net/mlx4/mlx4.c                 | 1 -
 drivers/net/mlx5/mlx5.c                 | 1 -
 lib/librte_eal/common/include/rte_dev.h | 2 +-
 9 files changed, 14 insertions(+), 21 deletions(-)

diff --git a/drivers/bus/ifpga/ifpga_bus.c b/drivers/bus/ifpga/ifpga_bus.c
index 80663328a..fca2dbace 100644
--- a/drivers/bus/ifpga/ifpga_bus.c
+++ b/drivers/bus/ifpga/ifpga_bus.c
@@ -280,14 +280,13 @@ ifpga_probe_one_driver(struct rte_afu_driver *drv,
 
 	/* reference driver structure */
 	afu_dev->driver = drv;
-	afu_dev->device.driver = &drv->driver;
 
 	/* call the driver probe() function */
 	ret = drv->probe(afu_dev);
-	if (ret) {
+	if (ret)
 		afu_dev->driver = NULL;
-		afu_dev->device.driver = NULL;
-	}
+	else
+		afu_dev->device.driver = &drv->driver;
 
 	return ret;
 }
@@ -302,7 +301,7 @@ ifpga_probe_all_drivers(struct rte_afu_device *afu_dev)
 		return -1;
 
 	/* Check if a driver is already loaded */
-	if (afu_dev->driver != NULL)
+	if (afu_dev->device.driver != NULL)
 		return 0;
 
 	TAILQ_FOREACH(drv, &ifpga_afu_drv_list, next) {
diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
index c7695d108..d63e68045 100644
--- a/drivers/bus/pci/pci_common.c
+++ b/drivers/bus/pci/pci_common.c
@@ -160,14 +160,12 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
 	 * driver flags for adjusting configuration.
 	 */
 	dev->driver = dr;
-	dev->device.driver = &dr->driver;
 
 	if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) {
 		/* map resources for devices that use igb_uio */
 		ret = rte_pci_map_device(dev);
 		if (ret != 0) {
 			dev->driver = NULL;
-			dev->device.driver = NULL;
 			return ret;
 		}
 	}
@@ -176,7 +174,6 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
 	ret = dr->probe(dr, dev);
 	if (ret) {
 		dev->driver = NULL;
-		dev->device.driver = NULL;
 		if ((dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) &&
 			/* Don't unmap if device is unsupported and
 			 * driver needs mapped resources.
@@ -184,6 +181,8 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
 			!(ret > 0 &&
 				(dr->drv_flags & RTE_PCI_DRV_KEEP_MAPPED_RES)))
 			rte_pci_unmap_device(dev);
+	} else {
+		dev->device.driver = &dr->driver;
 	}
 
 	return ret;
@@ -244,7 +243,7 @@ pci_probe_all_drivers(struct rte_pci_device *dev)
 		return -1;
 
 	/* Check if a driver is already loaded */
-	if (dev->driver != NULL)
+	if (dev->device.driver != NULL)
 		return 0;
 
 	FOREACH_DRIVER_ON_PCIBUS(dr) {
diff --git a/drivers/bus/pci/rte_bus_pci.h b/drivers/bus/pci/rte_bus_pci.h
index 0d1955ffe..984df2b37 100644
--- a/drivers/bus/pci/rte_bus_pci.h
+++ b/drivers/bus/pci/rte_bus_pci.h
@@ -62,7 +62,7 @@ struct rte_pci_device {
 	struct rte_mem_resource mem_resource[PCI_MAX_RESOURCE];
 					    /**< PCI Memory Resource */
 	struct rte_intr_handle intr_handle; /**< Interrupt handle */
-	struct rte_pci_driver *driver;      /**< Associated driver */
+	struct rte_pci_driver *driver;      /**< PCI driver used in probing */
 	uint16_t max_vfs;                   /**< sriov enable if not zero */
 	enum rte_kernel_driver kdrv;        /**< Kernel driver passthrough */
 	char name[PCI_PRI_STR_SIZE+1];      /**< PCI location (ASCII) */
diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
index 0142fb2c8..3f27f3510 100644
--- a/drivers/bus/vdev/vdev.c
+++ b/drivers/bus/vdev/vdev.c
@@ -150,10 +150,9 @@ vdev_probe_all_drivers(struct rte_vdev_device *dev)
 
 	if (vdev_parse(name, &driver))
 		return -1;
-	dev->device.driver = &driver->driver;
 	ret = driver->probe(dev);
-	if (ret)
-		dev->device.driver = NULL;
+	if (ret == 0)
+		dev->device.driver = &driver->driver;
 	return ret;
 }
 
diff --git a/drivers/bus/vmbus/vmbus_common.c b/drivers/bus/vmbus/vmbus_common.c
index e3ceb6906..de5548aa4 100644
--- a/drivers/bus/vmbus/vmbus_common.c
+++ b/drivers/bus/vmbus/vmbus_common.c
@@ -111,7 +111,6 @@ vmbus_probe_one_driver(struct rte_vmbus_driver *dr,
 
 	/* reference driver structure */
 	dev->driver = dr;
-	dev->device.driver = &dr->driver;
 
 	if (dev->device.numa_node < 0) {
 		VMBUS_LOG(WARNING, "  Invalid NUMA socket, default to 0");
@@ -124,6 +123,8 @@ vmbus_probe_one_driver(struct rte_vmbus_driver *dr,
 	if (ret) {
 		dev->driver = NULL;
 		rte_vmbus_unmap_device(dev);
+	} else {
+		dev->device.driver = &dr->driver;
 	}
 
 	return ret;
@@ -142,7 +143,7 @@ vmbus_probe_all_drivers(struct rte_vmbus_device *dev)
 	int rc;
 
 	/* Check if a driver is already loaded */
-	if (dev->driver != NULL) {
+	if (dev->device.driver != NULL) {
 		VMBUS_LOG(DEBUG, "VMBUS driver already loaded");
 		return 0;
 	}
diff --git a/drivers/net/i40e/i40e_vf_representor.c b/drivers/net/i40e/i40e_vf_representor.c
index 0bfbb4f60..24751d13c 100644
--- a/drivers/net/i40e/i40e_vf_representor.c
+++ b/drivers/net/i40e/i40e_vf_representor.c
@@ -487,9 +487,6 @@ i40e_vf_representor_init(struct rte_eth_dev *ethdev, void *init_params)
 	if (representor->vf_id >= pf->vf_num)
 		return -ENODEV;
 
-	/** representor shares the same driver as it's PF device */
-	ethdev->device->driver = representor->adapter->eth_dev->device->driver;
-
 	/* Set representor device ops */
 	ethdev->dev_ops = &i40e_representor_dev_ops;
 
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index defc0d4b0..3de7bc53e 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -734,7 +734,6 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 		eth_dev->data->mac_addrs = priv->mac;
 		eth_dev->device = &pci_dev->device;
 		rte_eth_copy_pci_info(eth_dev, pci_dev);
-		eth_dev->device->driver = &mlx4_driver.driver;
 		/* Initialize local interrupt handle for current port. */
 		priv->intr_handle = (struct rte_intr_handle){
 			.fd = -1,
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index af4a78ce9..f23ef2c26 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -1083,7 +1083,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	priv->dev_data = eth_dev->data;
 	eth_dev->data->mac_addrs = priv->mac;
 	eth_dev->device = dpdk_dev;
-	eth_dev->device->driver = &mlx5_driver.driver;
 	err = mlx5_uar_init_primary(eth_dev);
 	if (err) {
 		err = rte_errno;
diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
index 036180ff3..5084c645b 100644
--- a/lib/librte_eal/common/include/rte_dev.h
+++ b/lib/librte_eal/common/include/rte_dev.h
@@ -156,7 +156,7 @@ struct rte_driver {
 struct rte_device {
 	TAILQ_ENTRY(rte_device) next; /**< Next device */
 	const char *name;             /**< Device name */
-	const struct rte_driver *driver;/**< Associated driver */
+	const struct rte_driver *driver; /**< Driver assigned after probing */
 	const struct rte_bus *bus;    /**< Bus handle assigned on scan */
 	int numa_node;                /**< NUMA node connection */
 	struct rte_devargs *devargs;  /**< Device user arguments */
-- 
2.19.0

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

* [PATCH v4 3/4] eal: add function to query device status
  2018-10-11 21:02 ` [PATCH v4 0/4] eal: allow hotplug to skip an already probed device Thomas Monjalon
  2018-10-11 21:02   ` [PATCH v4 1/4] ethdev: rename memzones allocated for DMA Thomas Monjalon
  2018-10-11 21:02   ` [PATCH v4 2/4] drivers/bus: move driver assignment to end of probing Thomas Monjalon
@ 2018-10-11 21:02   ` Thomas Monjalon
  2018-10-11 21:02   ` [PATCH v4 4/4] eal: allow probing a device again Thomas Monjalon
  2018-10-12  9:26   ` [PATCH v4 0/4] eal: allow hotplug to skip an already probed device Andrew Rybchenko
  4 siblings, 0 replies; 58+ messages in thread
From: Thomas Monjalon @ 2018-10-11 21:02 UTC (permalink / raw)
  To: dev; +Cc: gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit

The function rte_dev_is_probed() is added in order to improve semantic
and enforce proper check of the probing status of a device.

It will answer this rte_device query:
Is it already successfully probed or not?

Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/bus/ifpga/ifpga_bus.c           |  4 ++--
 drivers/bus/pci/pci_common.c            |  2 +-
 drivers/bus/vdev/vdev.c                 |  2 +-
 drivers/bus/vmbus/vmbus_common.c        |  2 +-
 lib/librte_eal/common/eal_common_dev.c  |  9 ++++++++-
 lib/librte_eal/common/include/rte_dev.h | 14 ++++++++++++++
 lib/librte_eal/rte_eal_version.map      |  1 +
 7 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/drivers/bus/ifpga/ifpga_bus.c b/drivers/bus/ifpga/ifpga_bus.c
index fca2dbace..2ca1efa72 100644
--- a/drivers/bus/ifpga/ifpga_bus.c
+++ b/drivers/bus/ifpga/ifpga_bus.c
@@ -301,7 +301,7 @@ ifpga_probe_all_drivers(struct rte_afu_device *afu_dev)
 		return -1;
 
 	/* Check if a driver is already loaded */
-	if (afu_dev->device.driver != NULL)
+	if (rte_dev_is_probed(&afu_dev->device))
 		return 0;
 
 	TAILQ_FOREACH(drv, &ifpga_afu_drv_list, next) {
@@ -325,7 +325,7 @@ ifpga_probe(void)
 	int ret = 0;
 
 	TAILQ_FOREACH(afu_dev, &ifpga_afu_dev_list, next) {
-		if (afu_dev->device.driver)
+		if (rte_dev_is_probed(&afu_dev->device))
 			continue;
 
 		ret = ifpga_probe_all_drivers(afu_dev);
diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
index d63e68045..62b17fba9 100644
--- a/drivers/bus/pci/pci_common.c
+++ b/drivers/bus/pci/pci_common.c
@@ -243,7 +243,7 @@ pci_probe_all_drivers(struct rte_pci_device *dev)
 		return -1;
 
 	/* Check if a driver is already loaded */
-	if (dev->device.driver != NULL)
+	if (rte_dev_is_probed(&dev->device))
 		return 0;
 
 	FOREACH_DRIVER_ON_PCIBUS(dr) {
diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
index 3f27f3510..f666099e6 100644
--- a/drivers/bus/vdev/vdev.c
+++ b/drivers/bus/vdev/vdev.c
@@ -481,7 +481,7 @@ vdev_probe(void)
 		 * we call each driver probe.
 		 */
 
-		if (dev->device.driver)
+		if (rte_dev_is_probed(&dev->device))
 			continue;
 
 		if (vdev_probe_all_drivers(dev)) {
diff --git a/drivers/bus/vmbus/vmbus_common.c b/drivers/bus/vmbus/vmbus_common.c
index de5548aa4..48a219f73 100644
--- a/drivers/bus/vmbus/vmbus_common.c
+++ b/drivers/bus/vmbus/vmbus_common.c
@@ -143,7 +143,7 @@ vmbus_probe_all_drivers(struct rte_vmbus_device *dev)
 	int rc;
 
 	/* Check if a driver is already loaded */
-	if (dev->device.driver != NULL) {
+	if (rte_dev_is_probed(&dev->device)) {
 		VMBUS_LOG(DEBUG, "VMBUS driver already loaded");
 		return 0;
 	}
diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c
index 7663eaa3f..7e8a9b260 100644
--- a/lib/librte_eal/common/eal_common_dev.c
+++ b/lib/librte_eal/common/eal_common_dev.c
@@ -74,6 +74,13 @@ static int cmp_dev_name(const struct rte_device *dev, const void *_name)
 	return strcmp(dev->name, name);
 }
 
+int __rte_experimental
+rte_dev_is_probed(const struct rte_device *dev)
+{
+	/* The field driver should be set only when the probe is successful. */
+	return dev->driver != NULL;
+}
+
 int rte_eal_dev_attach(const char *name, const char *devargs)
 {
 	struct rte_bus *bus;
@@ -189,7 +196,7 @@ rte_dev_probe(const char *devargs)
 		goto err_devarg;
 	}
 
-	if (dev->driver != NULL) {
+	if (rte_dev_is_probed(dev)) {
 		RTE_LOG(ERR, EAL, "Device is already plugged\n");
 		return -EEXIST;
 	}
diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
index 5084c645b..9f169e3b3 100644
--- a/lib/librte_eal/common/include/rte_dev.h
+++ b/lib/librte_eal/common/include/rte_dev.h
@@ -162,6 +162,20 @@ struct rte_device {
 	struct rte_devargs *devargs;  /**< Device user arguments */
 };
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Query status of a device.
+ *
+ * @param dev
+ *   Generic device pointer.
+ * @return
+ *   (int)true if already probed successfully, 0 otherwise.
+ */
+__rte_experimental
+int rte_dev_is_probed(const struct rte_device *dev);
+
 /**
  * Attach a device to a registered driver.
  *
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index e968edc2e..e628c3930 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -279,6 +279,7 @@ EXPERIMENTAL {
 	rte_dev_event_callback_unregister;
 	rte_dev_event_monitor_start;
 	rte_dev_event_monitor_stop;
+	rte_dev_is_probed;
 	rte_dev_iterator_init;
 	rte_dev_iterator_next;
 	rte_dev_probe;
-- 
2.19.0

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

* [PATCH v4 4/4] eal: allow probing a device again
  2018-10-11 21:02 ` [PATCH v4 0/4] eal: allow hotplug to skip an already probed device Thomas Monjalon
                     ` (2 preceding siblings ...)
  2018-10-11 21:02   ` [PATCH v4 3/4] eal: add function to query device status Thomas Monjalon
@ 2018-10-11 21:02   ` Thomas Monjalon
  2018-10-12  9:26   ` [PATCH v4 0/4] eal: allow hotplug to skip an already probed device Andrew Rybchenko
  4 siblings, 0 replies; 58+ messages in thread
From: Thomas Monjalon @ 2018-10-11 21:02 UTC (permalink / raw)
  To: dev; +Cc: gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit

In the devargs syntax for device representors, it is possible to add
several devices at once: -w dbdf,representor=[0-3]
It will become a more frequent case when introducing wildcards
and ranges in the new devargs syntax.

If a devargs string is provided for probing, and updated with a bigger
range for a new probing, then we do not want it to fail because
part of this range was already probed previously.
There can be new ports to create from an existing rte_device.

That's why the check for an already probed device
is moved as bus responsibility.
In the case of vdev, a global check is kept in insert_vdev(),
assuming that a vdev will always have only one port.
In the case of ifpga and vmbus, already probed devices are checked.
In the case of NXP buses, the probing is done only once (no hotplug),
though a check is added at bus level for consistency.
In the case of PCI, a driver flag is added to allow PMD probing again.
Only the PMD knows the ports attached to one rte_device.

As another consequence of being able to probe in several steps,
the field rte_device.devargs must not be considered as a full
representation of the rte_device, but only the latest probing args.
Anyway, the field rte_device.devargs is used only for probing.

Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/bus/dpaa/dpaa_bus.c             |  3 +++
 drivers/bus/fslmc/fslmc_bus.c           |  3 +++
 drivers/bus/ifpga/ifpga_bus.c           | 14 ++++++-----
 drivers/bus/pci/pci_common.c            | 33 ++++++++++++++++---------
 drivers/bus/pci/rte_bus_pci.h           |  4 ++-
 drivers/bus/vdev/vdev.c                 |  5 ++++
 lib/librte_eal/common/eal_common_dev.c  |  7 ++----
 lib/librte_eal/common/include/rte_dev.h |  2 +-
 8 files changed, 47 insertions(+), 24 deletions(-)

diff --git a/drivers/bus/dpaa/dpaa_bus.c b/drivers/bus/dpaa/dpaa_bus.c
index 138e0f98d..89d1e415d 100644
--- a/drivers/bus/dpaa/dpaa_bus.c
+++ b/drivers/bus/dpaa/dpaa_bus.c
@@ -555,6 +555,9 @@ rte_dpaa_bus_probe(void)
 			if (ret)
 				continue;
 
+			if (rte_dev_is_probed(&dev->device))
+				continue;
+
 			if (!drv->probe ||
 			    (dev->device.devargs &&
 			    dev->device.devargs->policy == RTE_DEV_BLACKLISTED))
diff --git a/drivers/bus/fslmc/fslmc_bus.c b/drivers/bus/fslmc/fslmc_bus.c
index 960f55071..7ebd980aa 100644
--- a/drivers/bus/fslmc/fslmc_bus.c
+++ b/drivers/bus/fslmc/fslmc_bus.c
@@ -386,6 +386,9 @@ rte_fslmc_probe(void)
 			if (!drv->probe)
 				continue;
 
+			if (rte_dev_is_probed(&dev->device))
+				continue;
+
 			if (dev->device.devargs &&
 			  dev->device.devargs->policy == RTE_DEV_BLACKLISTED) {
 				DPAA2_BUS_LOG(DEBUG, "%s Blacklisted, skipping",
diff --git a/drivers/bus/ifpga/ifpga_bus.c b/drivers/bus/ifpga/ifpga_bus.c
index 2ca1efa72..5f23ed8b4 100644
--- a/drivers/bus/ifpga/ifpga_bus.c
+++ b/drivers/bus/ifpga/ifpga_bus.c
@@ -301,8 +301,11 @@ ifpga_probe_all_drivers(struct rte_afu_device *afu_dev)
 		return -1;
 
 	/* Check if a driver is already loaded */
-	if (rte_dev_is_probed(&afu_dev->device))
-		return 0;
+	if (rte_dev_is_probed(&afu_dev->device)) {
+		IFPGA_BUS_DEBUG("Device %s is already probed\n",
+				rte_ifpga_device_name(afu_dev));
+		return -EEXIST;
+	}
 
 	TAILQ_FOREACH(drv, &ifpga_afu_drv_list, next) {
 		if (ifpga_probe_one_driver(drv, afu_dev)) {
@@ -325,14 +328,13 @@ ifpga_probe(void)
 	int ret = 0;
 
 	TAILQ_FOREACH(afu_dev, &ifpga_afu_dev_list, next) {
-		if (rte_dev_is_probed(&afu_dev->device))
-			continue;
-
 		ret = ifpga_probe_all_drivers(afu_dev);
+		if (ret == -EEXIST)
+			continue;
 		if (ret < 0)
 			IFPGA_BUS_ERR("failed to initialize %s device\n",
 				rte_ifpga_device_name(afu_dev));
-		}
+	}
 
 	return ret;
 }
diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
index 62b17fba9..11c5da587 100644
--- a/drivers/bus/pci/pci_common.c
+++ b/drivers/bus/pci/pci_common.c
@@ -6,6 +6,7 @@
 #include <string.h>
 #include <inttypes.h>
 #include <stdint.h>
+#include <stdbool.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <sys/queue.h>
@@ -121,6 +122,7 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
 			 struct rte_pci_device *dev)
 {
 	int ret;
+	bool already_probed;
 	struct rte_pci_addr *loc;
 
 	if ((dr == NULL) || (dev == NULL))
@@ -151,6 +153,13 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
 		dev->device.numa_node = 0;
 	}
 
+	already_probed = rte_dev_is_probed(&dev->device);
+	if (already_probed && !(dr->drv_flags & RTE_PCI_DRV_PROBE_AGAIN)) {
+		RTE_LOG(DEBUG, EAL, "Device %s is already probed\n",
+				dev->device.name);
+		return -EEXIST;
+	}
+
 	RTE_LOG(INFO, EAL, "  probe driver: %x:%x %s\n", dev->id.vendor_id,
 		dev->id.device_id, dr->driver.name);
 
@@ -159,9 +168,10 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
 	 * This needs to be before rte_pci_map_device(), as it enables to use
 	 * driver flags for adjusting configuration.
 	 */
-	dev->driver = dr;
+	if (!already_probed)
+		dev->driver = dr;
 
-	if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) {
+	if (!already_probed && (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING)) {
 		/* map resources for devices that use igb_uio */
 		ret = rte_pci_map_device(dev);
 		if (ret != 0) {
@@ -172,6 +182,8 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
 
 	/* call the driver probe() function */
 	ret = dr->probe(dr, dev);
+	if (already_probed)
+		return ret; /* no rollback if already succeeded earlier */
 	if (ret) {
 		dev->driver = NULL;
 		if ((dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) &&
@@ -242,10 +254,6 @@ pci_probe_all_drivers(struct rte_pci_device *dev)
 	if (dev == NULL)
 		return -1;
 
-	/* Check if a driver is already loaded */
-	if (rte_dev_is_probed(&dev->device))
-		return 0;
-
 	FOREACH_DRIVER_ON_PCIBUS(dr) {
 		rc = rte_pci_probe_one_driver(dr, dev);
 		if (rc < 0)
@@ -287,11 +295,14 @@ rte_pci_probe(void)
 			devargs->policy == RTE_DEV_WHITELISTED)
 			ret = pci_probe_all_drivers(dev);
 		if (ret < 0) {
-			RTE_LOG(ERR, EAL, "Requested device " PCI_PRI_FMT
-				 " cannot be used\n", dev->addr.domain, dev->addr.bus,
-				 dev->addr.devid, dev->addr.function);
-			rte_errno = errno;
-			failed++;
+			if (ret != -EEXIST) {
+				RTE_LOG(ERR, EAL, "Requested device "
+					PCI_PRI_FMT " cannot be used\n",
+					dev->addr.domain, dev->addr.bus,
+					dev->addr.devid, dev->addr.function);
+				rte_errno = errno;
+				failed++;
+			}
 			ret = 0;
 		}
 	}
diff --git a/drivers/bus/pci/rte_bus_pci.h b/drivers/bus/pci/rte_bus_pci.h
index 984df2b37..a3baa2895 100644
--- a/drivers/bus/pci/rte_bus_pci.h
+++ b/drivers/bus/pci/rte_bus_pci.h
@@ -121,7 +121,7 @@ struct rte_pci_driver {
 	pci_probe_t *probe;                /**< Device Probe function. */
 	pci_remove_t *remove;              /**< Device Remove function. */
 	const struct rte_pci_id *id_table; /**< ID table, NULL terminated. */
-	uint32_t drv_flags;                /**< Flags contolling handling of device. */
+	uint32_t drv_flags;                /**< Flags RTE_PCI_DRV_*. */
 };
 
 /**
@@ -137,6 +137,8 @@ struct rte_pci_bus {
 #define RTE_PCI_DRV_NEED_MAPPING 0x0001
 /** Device needs PCI BAR mapping with enabled write combining (wc) */
 #define RTE_PCI_DRV_WC_ACTIVATE 0x0002
+/** Device already probed can be probed again to check for new ports. */
+#define RTE_PCI_DRV_PROBE_AGAIN 0x0004
 /** Device driver supports link state interrupt */
 #define RTE_PCI_DRV_INTR_LSC	0x0008
 /** Device driver supports device removal interrupt */
diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
index f666099e6..06f314843 100644
--- a/drivers/bus/vdev/vdev.c
+++ b/drivers/bus/vdev/vdev.c
@@ -226,6 +226,11 @@ insert_vdev(const char *name, const char *args, struct rte_vdev_device **p_dev)
 	dev->device.name = devargs->name;
 
 	if (find_vdev(name)) {
+		/*
+		 * A vdev is expected to have only one port.
+		 * So there is no reason to try probing again,
+		 * even with new arguments.
+		 */
 		ret = -EEXIST;
 		goto fail;
 	}
diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c
index 7e8a9b260..e733eb779 100644
--- a/lib/librte_eal/common/eal_common_dev.c
+++ b/lib/librte_eal/common/eal_common_dev.c
@@ -196,13 +196,10 @@ rte_dev_probe(const char *devargs)
 		goto err_devarg;
 	}
 
-	if (rte_dev_is_probed(dev)) {
-		RTE_LOG(ERR, EAL, "Device is already plugged\n");
-		return -EEXIST;
-	}
-
 	ret = dev->bus->plug(dev);
 	if (ret) {
+		if (rte_dev_is_probed(dev)) /* if already succeeded earlier */
+			return ret; /* no rollback */
 		RTE_LOG(ERR, EAL, "Driver cannot attach the device (%s)\n",
 			dev->name);
 		goto err_devarg;
diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
index 9f169e3b3..a7ec8ec25 100644
--- a/lib/librte_eal/common/include/rte_dev.h
+++ b/lib/librte_eal/common/include/rte_dev.h
@@ -159,7 +159,7 @@ struct rte_device {
 	const struct rte_driver *driver; /**< Driver assigned after probing */
 	const struct rte_bus *bus;    /**< Bus handle assigned on scan */
 	int numa_node;                /**< NUMA node connection */
-	struct rte_devargs *devargs;  /**< Device user arguments */
+	struct rte_devargs *devargs;  /**< Arguments for latest probing */
 };
 
 /**
-- 
2.19.0

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

* Re: [PATCH v4 2/4] drivers/bus: move driver assignment to end of probing
  2018-10-11 21:02   ` [PATCH v4 2/4] drivers/bus: move driver assignment to end of probing Thomas Monjalon
@ 2018-10-12  7:44     ` Andrew Rybchenko
  2018-10-12  8:32       ` Jan Remeš
  2018-10-12 15:50       ` Thomas Monjalon
  0 siblings, 2 replies; 58+ messages in thread
From: Andrew Rybchenko @ 2018-10-12  7:44 UTC (permalink / raw)
  To: Thomas Monjalon, dev
  Cc: gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit, Jan Remes,
	Shahaf Shuler, Yongseok Koh

Hi, Thomas,

On 10/12/18 12:02 AM, Thomas Monjalon wrote:
> The PCI mapping requires to know the PCI driver to use,
> even before the probing is done. That's why the PCI driver is
> referenced early inside the PCI device structure. See
> commit 1d20a073fa5e ("bus/pci: reference driver structure before mapping")
>
> However the rte_driver does not need to be referenced in rte_device
> before the device probing is done.
> By moving back this assignment at the end of the device probing,
> it becomes possible to make clear the status of a rte_device.
>
> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
> Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>

Have you seen driver->name usage in drivers/net/szedata2/rte_eth_szedata2.c
rte_szedata2_eth_dev_init() which is used from probe?

It looks like drivers/net/mlx5/mlx5.c
mlx5_pci_probe()->mlx5_dev_spawn()->mlx5_dev_to_port_id() goes
to device->driver. Is the code OK with the move?

I've added above drivers maintainers in CC.

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

* Re: [PATCH v4 1/4] ethdev: rename memzones allocated for DMA
  2018-10-11 21:02   ` [PATCH v4 1/4] ethdev: rename memzones allocated for DMA Thomas Monjalon
@ 2018-10-12  7:53     ` Andrew Rybchenko
  2018-10-12 16:40       ` Thomas Monjalon
  0 siblings, 1 reply; 58+ messages in thread
From: Andrew Rybchenko @ 2018-10-12  7:53 UTC (permalink / raw)
  To: Thomas Monjalon, dev
  Cc: gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit, Ananyev,
	Konstantin, Ajit Khaparde, Somnath Kotur, Rahul Lakkireddy

On 10/12/18 12:02 AM, Thomas Monjalon wrote:
> The helper rte_eth_dma_zone_reserve() is called by PMDs
> when probing a new port.
> It creates a new memzone with an unique name.
> The name of this memzone was using the name of the driver
> doing the probe.
>
> In order to avoid assigning the driver before the end of the probing
> (next patch), the driver name is removed from these memzone names.
> The ethdev name (data->name) is not used because it may be too long
> and may be not set at this stage of probing.
>
> Syntax of old name: <driver>_<ring>_<port>_<queue>
> Syntax of new name: eth_p<port>_q<queue>_<ring>
>
> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
> ---
>   lib/librte_ethdev/rte_ethdev.c | 5 ++---
>   1 file changed, 2 insertions(+), 3 deletions(-)
>
> diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
> index ef99f7068..ec443def5 100644
> --- a/lib/librte_ethdev/rte_ethdev.c
> +++ b/lib/librte_ethdev/rte_ethdev.c
> @@ -3441,9 +3441,8 @@ rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name,
>   	char z_name[RTE_MEMZONE_NAMESIZE];
>   	const struct rte_memzone *mz;
>   
> -	snprintf(z_name, sizeof(z_name), "%s_%s_%d_%d",
> -		 dev->device->driver->name, ring_name,
> -		 dev->data->port_id, queue_id);
> +	snprintf(z_name, sizeof(z_name), "eth_p%d_q%d_%s",
> +		 dev->data->port_id, queue_id, ring_name);
>   
>   	mz = rte_memzone_lookup(z_name);
>   	if (mz)

LGTM, but I've found more places where the pattern is duplicate
and testpmd frightens me:
  - app/test-pmd/config.c ring_dma_zone_lookup() which is used
    to look at descriptors (looks like Intel specific since has
    RTE_LIBRTE_I40E_16BYTE_RX_DESC conditional code)
  - drivers/net/bnx2x/bnx2x_rxtx.c
  - drivers/net/cxgbe/sge.c (few times)

I've not dig why bnx2x and cxgbe do not use rte_eth_dma_zone_reserve().

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

* Re: [PATCH v4 2/4] drivers/bus: move driver assignment to end of probing
  2018-10-12  7:44     ` Andrew Rybchenko
@ 2018-10-12  8:32       ` Jan Remeš
  2018-10-12 10:45         ` Thomas Monjalon
  2018-10-12 15:50       ` Thomas Monjalon
  1 sibling, 1 reply; 58+ messages in thread
From: Jan Remeš @ 2018-10-12  8:32 UTC (permalink / raw)
  To: arybchenko
  Cc: Thomas Monjalon, dev, gaetan.rivet, ophirmu, qi.z.zhang,
	Ferruh Yigit, shahafs, yskoh

Hi Andrew,

On Fri, Oct 12, 2018 at 9:45 AM Andrew Rybchenko
<arybchenko@solarflare.com> wrote:
>
> Hi, Thomas,
>
> On 10/12/18 12:02 AM, Thomas Monjalon wrote:
> > The PCI mapping requires to know the PCI driver to use,
> > even before the probing is done. That's why the PCI driver is
> > referenced early inside the PCI device structure. See
> > commit 1d20a073fa5e ("bus/pci: reference driver structure before mapping")
> >
> > However the rte_driver does not need to be referenced in rte_device
> > before the device probing is done.
> > By moving back this assignment at the end of the device probing,
> > it becomes possible to make clear the status of a rte_device.
> >
> > Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
> > Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
>
> Have you seen driver->name usage in drivers/net/szedata2/rte_eth_szedata2.c
> rte_szedata2_eth_dev_init() which is used from probe?
>

for szedata2, this is easily fixed by using the driver name directly
from the #define above.

diff --git a/drivers/net/szedata2/rte_eth_szedata2.c
b/drivers/net/szedata2/rte_eth_szedata2.c
index 8f92e72..4e5e01c 100644
--- a/drivers/net/szedata2/rte_eth_szedata2.c
+++ b/drivers/net/szedata2/rte_eth_szedata2.c
@@ -1474,7 +1474,7 @@ struct szedata2_tx_queue {
        PMD_INIT_FUNC_TRACE();

        PMD_INIT_LOG(INFO, "Initializing eth_dev %s (driver %s)", data->name,
-                       dev->device->driver->name);
+                       RTE_STR(RTE_SZEDATA2_DRIVER_NAME));

        /* Fill internal private structure. */
        internals->dev = dev;
@@ -1525,7 +1525,7 @@ struct szedata2_tx_queue {
        ether_addr_copy(&eth_addr, data->mac_addrs);

        PMD_INIT_LOG(INFO, "%s device %s successfully initialized",
-                       dev->device->driver->name, data->name);
+                       RTE_STR(RTE_SZEDATA2_DRIVER_NAME), data->name);

        return 0;
 }
@@ -1547,7 +1547,7 @@ struct szedata2_tx_queue {
        rte_free(dev->data->mac_addrs);

        PMD_DRV_LOG(INFO, "%s device %s successfully uninitialized",
-                       dev->device->driver->name, dev->data->name);
+                       RTE_STR(RTE_SZEDATA2_DRIVER_NAME), dev->data->name);

        return 0;
 }

> It looks like drivers/net/mlx5/mlx5.c
> mlx5_pci_probe()->mlx5_dev_spawn()->mlx5_dev_to_port_id() goes
> to device->driver. Is the code OK with the move?
>
> I've added above drivers maintainers in CC.

Jan

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

* Re: [PATCH v4 0/4] eal: allow hotplug to skip an already probed device
  2018-10-11 21:02 ` [PATCH v4 0/4] eal: allow hotplug to skip an already probed device Thomas Monjalon
                     ` (3 preceding siblings ...)
  2018-10-11 21:02   ` [PATCH v4 4/4] eal: allow probing a device again Thomas Monjalon
@ 2018-10-12  9:26   ` Andrew Rybchenko
  4 siblings, 0 replies; 58+ messages in thread
From: Andrew Rybchenko @ 2018-10-12  9:26 UTC (permalink / raw)
  To: Thomas Monjalon, dev; +Cc: gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit

On 10/12/18 12:02 AM, Thomas Monjalon wrote:
> This is a follow-up of an idea presented at Dublin
> during the "hotplug talk".
>
> The idea is to ease probing of range of ports attached
> to the same rte_device.
> I becomes possible to allow probing again the same device
> but with a bigger range of ports in the devargs.
>
> Instead of adding a parameter to the hotplug functions, as in the RFC,
> the check of an already probed device is moved to the bus and enabled PMDs.
> It gives flexibility to drivers for managing range of ports.

For the series:
Tested-by: Andrew Rybchenko <arybchenko@solarflare.com>

As I underestand it requires fix for szedata2 and has open
questions for mlx5, bnx2x, cxgbe and testpmd.

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

* Re: [PATCH v4 2/4] drivers/bus: move driver assignment to end of probing
  2018-10-12  8:32       ` Jan Remeš
@ 2018-10-12 10:45         ` Thomas Monjalon
  0 siblings, 0 replies; 58+ messages in thread
From: Thomas Monjalon @ 2018-10-12 10:45 UTC (permalink / raw)
  To: Jan Remeš, arybchenko
  Cc: dev, gaetan.rivet, ophirmu, qi.z.zhang, Ferruh Yigit, shahafs, yskoh

12/10/2018 10:32, Jan Remeš:
> Hi Andrew,
> 
> On Fri, Oct 12, 2018 at 9:45 AM Andrew Rybchenko
> <arybchenko@solarflare.com> wrote:
> >
> > Hi, Thomas,
> >
> > On 10/12/18 12:02 AM, Thomas Monjalon wrote:
> > > The PCI mapping requires to know the PCI driver to use,
> > > even before the probing is done. That's why the PCI driver is
> > > referenced early inside the PCI device structure. See
> > > commit 1d20a073fa5e ("bus/pci: reference driver structure before mapping")
> > >
> > > However the rte_driver does not need to be referenced in rte_device
> > > before the device probing is done.
> > > By moving back this assignment at the end of the device probing,
> > > it becomes possible to make clear the status of a rte_device.
> > >
> > > Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
> > > Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
> >
> > Have you seen driver->name usage in drivers/net/szedata2/rte_eth_szedata2.c
> > rte_szedata2_eth_dev_init() which is used from probe?
> >
> 
> for szedata2, this is easily fixed by using the driver name directly
> from the #define above.
> 
> diff --git a/drivers/net/szedata2/rte_eth_szedata2.c
> b/drivers/net/szedata2/rte_eth_szedata2.c
> index 8f92e72..4e5e01c 100644
> --- a/drivers/net/szedata2/rte_eth_szedata2.c
> +++ b/drivers/net/szedata2/rte_eth_szedata2.c
> @@ -1474,7 +1474,7 @@ struct szedata2_tx_queue {
>         PMD_INIT_FUNC_TRACE();
> 
>         PMD_INIT_LOG(INFO, "Initializing eth_dev %s (driver %s)", data->name,
> -                       dev->device->driver->name);
> +                       RTE_STR(RTE_SZEDATA2_DRIVER_NAME));
> 
>         /* Fill internal private structure. */
>         internals->dev = dev;
> @@ -1525,7 +1525,7 @@ struct szedata2_tx_queue {
>         ether_addr_copy(&eth_addr, data->mac_addrs);
> 
>         PMD_INIT_LOG(INFO, "%s device %s successfully initialized",
> -                       dev->device->driver->name, data->name);
> +                       RTE_STR(RTE_SZEDATA2_DRIVER_NAME), data->name);
> 
>         return 0;
>  }
> @@ -1547,7 +1547,7 @@ struct szedata2_tx_queue {
>         rte_free(dev->data->mac_addrs);
> 
>         PMD_DRV_LOG(INFO, "%s device %s successfully uninitialized",
> -                       dev->device->driver->name, dev->data->name);
> +                       RTE_STR(RTE_SZEDATA2_DRIVER_NAME), dev->data->name);
> 
>         return 0;
>  }

OK, I'll include such change in next version.

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

* Re: [PATCH v4 2/4] drivers/bus: move driver assignment to end of probing
  2018-10-12  7:44     ` Andrew Rybchenko
  2018-10-12  8:32       ` Jan Remeš
@ 2018-10-12 15:50       ` Thomas Monjalon
  1 sibling, 0 replies; 58+ messages in thread
From: Thomas Monjalon @ 2018-10-12 15:50 UTC (permalink / raw)
  To: Andrew Rybchenko
  Cc: dev, gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit, Jan Remes,
	Shahaf Shuler, Yongseok Koh

12/10/2018 09:44, Andrew Rybchenko:
> Hi, Thomas,
> 
> On 10/12/18 12:02 AM, Thomas Monjalon wrote:
> > The PCI mapping requires to know the PCI driver to use,
> > even before the probing is done. That's why the PCI driver is
> > referenced early inside the PCI device structure. See
> > commit 1d20a073fa5e ("bus/pci: reference driver structure before mapping")
> >
> > However the rte_driver does not need to be referenced in rte_device
> > before the device probing is done.
> > By moving back this assignment at the end of the device probing,
> > it becomes possible to make clear the status of a rte_device.
> >
> > Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
> > Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
> 
> Have you seen driver->name usage in drivers/net/szedata2/rte_eth_szedata2.c
> rte_szedata2_eth_dev_init() which is used from probe?
> 
> It looks like drivers/net/mlx5/mlx5.c
> mlx5_pci_probe()->mlx5_dev_spawn()->mlx5_dev_to_port_id() goes
> to device->driver. Is the code OK with the move?

This access in mlx5 looks useless.
It is comparing driver names while already comparing rte_device pointers.
If 2 devices are the same, they will have the same driver...
I will remove it.

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

* Re: [PATCH v4 1/4] ethdev: rename memzones allocated for DMA
  2018-10-12  7:53     ` Andrew Rybchenko
@ 2018-10-12 16:40       ` Thomas Monjalon
  2018-10-12 16:42         ` Andrew Rybchenko
  0 siblings, 1 reply; 58+ messages in thread
From: Thomas Monjalon @ 2018-10-12 16:40 UTC (permalink / raw)
  To: Andrew Rybchenko
  Cc: dev, gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit, Ananyev,
	Konstantin, Ajit Khaparde, Somnath Kotur, Rahul Lakkireddy

12/10/2018 09:53, Andrew Rybchenko:
> On 10/12/18 12:02 AM, Thomas Monjalon wrote:
> > The helper rte_eth_dma_zone_reserve() is called by PMDs
> > when probing a new port.
> > It creates a new memzone with an unique name.
> > The name of this memzone was using the name of the driver
> > doing the probe.
> >
> > In order to avoid assigning the driver before the end of the probing
> > (next patch), the driver name is removed from these memzone names.
> > The ethdev name (data->name) is not used because it may be too long
> > and may be not set at this stage of probing.
> >
> > Syntax of old name: <driver>_<ring>_<port>_<queue>
> > Syntax of new name: eth_p<port>_q<queue>_<ring>
> >
> > Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
> > ---
> >   lib/librte_ethdev/rte_ethdev.c | 5 ++---
> >   1 file changed, 2 insertions(+), 3 deletions(-)
> >
> > diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
> > index ef99f7068..ec443def5 100644
> > --- a/lib/librte_ethdev/rte_ethdev.c
> > +++ b/lib/librte_ethdev/rte_ethdev.c
> > @@ -3441,9 +3441,8 @@ rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name,
> >   	char z_name[RTE_MEMZONE_NAMESIZE];
> >   	const struct rte_memzone *mz;
> >   
> > -	snprintf(z_name, sizeof(z_name), "%s_%s_%d_%d",
> > -		 dev->device->driver->name, ring_name,
> > -		 dev->data->port_id, queue_id);
> > +	snprintf(z_name, sizeof(z_name), "eth_p%d_q%d_%s",
> > +		 dev->data->port_id, queue_id, ring_name);
> >   
> >   	mz = rte_memzone_lookup(z_name);
> >   	if (mz)
> 
> LGTM, but I've found more places where the pattern is duplicate
> and testpmd frightens me:
>   - app/test-pmd/config.c ring_dma_zone_lookup() which is used
>     to look at descriptors (looks like Intel specific since has
>     RTE_LIBRTE_I40E_16BYTE_RX_DESC conditional code)

>From what I see there is no access to rte_device.driver here,
except one in exit function.

>   - drivers/net/bnx2x/bnx2x_rxtx.c
>   - drivers/net/cxgbe/sge.c (few times)

In bnx2x and cxgbe, it is accessed after probing (queue setup or configure steps).

> I've not dig why bnx2x and cxgbe do not use rte_eth_dma_zone_reserve().

Yes may be interesting to standardize them.
I will add them to this patch.

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

* Re: [PATCH v4 1/4] ethdev: rename memzones allocated for DMA
  2018-10-12 16:40       ` Thomas Monjalon
@ 2018-10-12 16:42         ` Andrew Rybchenko
  2018-10-12 16:46           ` Andrew Rybchenko
  0 siblings, 1 reply; 58+ messages in thread
From: Andrew Rybchenko @ 2018-10-12 16:42 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: dev, gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit, Ananyev,
	Konstantin, Ajit Khaparde, Somnath Kotur, Rahul Lakkireddy

On 10/12/18 7:40 PM, Thomas Monjalon wrote:
> 12/10/2018 09:53, Andrew Rybchenko:
>> On 10/12/18 12:02 AM, Thomas Monjalon wrote:
>>> The helper rte_eth_dma_zone_reserve() is called by PMDs
>>> when probing a new port.
>>> It creates a new memzone with an unique name.
>>> The name of this memzone was using the name of the driver
>>> doing the probe.
>>>
>>> In order to avoid assigning the driver before the end of the probing
>>> (next patch), the driver name is removed from these memzone names.
>>> The ethdev name (data->name) is not used because it may be too long
>>> and may be not set at this stage of probing.
>>>
>>> Syntax of old name: <driver>_<ring>_<port>_<queue>
>>> Syntax of new name: eth_p<port>_q<queue>_<ring>
>>>
>>> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
>>> ---
>>>    lib/librte_ethdev/rte_ethdev.c | 5 ++---
>>>    1 file changed, 2 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
>>> index ef99f7068..ec443def5 100644
>>> --- a/lib/librte_ethdev/rte_ethdev.c
>>> +++ b/lib/librte_ethdev/rte_ethdev.c
>>> @@ -3441,9 +3441,8 @@ rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name,
>>>    	char z_name[RTE_MEMZONE_NAMESIZE];
>>>    	const struct rte_memzone *mz;
>>>    
>>> -	snprintf(z_name, sizeof(z_name), "%s_%s_%d_%d",
>>> -		 dev->device->driver->name, ring_name,
>>> -		 dev->data->port_id, queue_id);
>>> +	snprintf(z_name, sizeof(z_name), "eth_p%d_q%d_%s",
>>> +		 dev->data->port_id, queue_id, ring_name);
>>>    
>>>    	mz = rte_memzone_lookup(z_name);
>>>    	if (mz)
>> LGTM, but I've found more places where the pattern is duplicate
>> and testpmd frightens me:
>>    - app/test-pmd/config.c ring_dma_zone_lookup() which is used
>>      to look at descriptors (looks like Intel specific since has
>>      RTE_LIBRTE_I40E_16BYTE_RX_DESC conditional code)
> >From what I see there is no access to rte_device.driver here,
> except one in exit function.

Yes, but testpmd will fail to find the memzone and command to
take a look at descriptors will be broken.

May be it is already broken etc. I think someone from Intel should
comment it.

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

* Re: [PATCH v4 1/4] ethdev: rename memzones allocated for DMA
  2018-10-12 16:42         ` Andrew Rybchenko
@ 2018-10-12 16:46           ` Andrew Rybchenko
  2018-10-12 17:18             ` Thomas Monjalon
  0 siblings, 1 reply; 58+ messages in thread
From: Andrew Rybchenko @ 2018-10-12 16:46 UTC (permalink / raw)
  To: Andrew Rybchenko, Thomas Monjalon
  Cc: dev, gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit, Ananyev,
	Konstantin, Ajit Khaparde, Somnath Kotur, Rahul Lakkireddy

On 10/12/18 7:42 PM, Andrew Rybchenko wrote:
> On 10/12/18 7:40 PM, Thomas Monjalon wrote:
>> 12/10/2018 09:53, Andrew Rybchenko:
>>> On 10/12/18 12:02 AM, Thomas Monjalon wrote:
>>>> The helper rte_eth_dma_zone_reserve() is called by PMDs
>>>> when probing a new port.
>>>> It creates a new memzone with an unique name.
>>>> The name of this memzone was using the name of the driver
>>>> doing the probe.
>>>>
>>>> In order to avoid assigning the driver before the end of the probing
>>>> (next patch), the driver name is removed from these memzone names.
>>>> The ethdev name (data->name) is not used because it may be too long
>>>> and may be not set at this stage of probing.
>>>>
>>>> Syntax of old name: <driver>_<ring>_<port>_<queue>
>>>> Syntax of new name: eth_p<port>_q<queue>_<ring>
>>>>
>>>> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
>>>> ---
>>>>    lib/librte_ethdev/rte_ethdev.c | 5 ++---
>>>>    1 file changed, 2 insertions(+), 3 deletions(-)
>>>>
>>>> diff --git a/lib/librte_ethdev/rte_ethdev.c 
>>>> b/lib/librte_ethdev/rte_ethdev.c
>>>> index ef99f7068..ec443def5 100644
>>>> --- a/lib/librte_ethdev/rte_ethdev.c
>>>> +++ b/lib/librte_ethdev/rte_ethdev.c
>>>> @@ -3441,9 +3441,8 @@ rte_eth_dma_zone_reserve(const struct 
>>>> rte_eth_dev *dev, const char *ring_name,
>>>>        char z_name[RTE_MEMZONE_NAMESIZE];
>>>>        const struct rte_memzone *mz;
>>>>    -    snprintf(z_name, sizeof(z_name), "%s_%s_%d_%d",
>>>> -         dev->device->driver->name, ring_name,
>>>> -         dev->data->port_id, queue_id);
>>>> +    snprintf(z_name, sizeof(z_name), "eth_p%d_q%d_%s",
>>>> +         dev->data->port_id, queue_id, ring_name);
>>>>           mz = rte_memzone_lookup(z_name);
>>>>        if (mz)
>>> LGTM, but I've found more places where the pattern is duplicate
>>> and testpmd frightens me:
>>>    - app/test-pmd/config.c ring_dma_zone_lookup() which is used
>>>      to look at descriptors (looks like Intel specific since has
>>>      RTE_LIBRTE_I40E_16BYTE_RX_DESC conditional code)
>> >From what I see there is no access to rte_device.driver here,
>> except one in exit function.
>
> Yes, but testpmd will fail to find the memzone and command to
> take a look at descriptors will be broken.
>
> May be it is already broken etc. I think someone from Intel should
> comment it.

Potentially the following drivers may use it:
$ git grep -w \"rx_ring\" drivers/net/
drivers/net/avf/avf_rxtx.c:380: mz = rte_eth_dma_zone_reserve(dev, 
"rx_ring", queue_idx,
drivers/net/axgbe/axgbe_rxtx.c:91:      dma = 
rte_eth_dma_zone_reserve(dev, "rx_ring", queue_idx, size, 12
drivers/net/cxgbe/sge.c:1878:            fwevtq ? "fwq_ring" : "rx_ring",
drivers/net/e1000/em_rxtx.c:1437:       rz = 
rte_eth_dma_zone_reserve(dev, "rx_ring", queue_idx, rsize,
drivers/net/e1000/igb_rxtx.c:1734:      rz = 
rte_eth_dma_zone_reserve(dev, "rx_ring", queue_idx, size,
drivers/net/fm10k/fm10k_ethdev.c:1878:  mz = 
rte_eth_dma_zone_reserve(dev, "rx_ring", queue_id,
drivers/net/i40e/i40e_rxtx.c:1853:      rz = 
rte_eth_dma_zone_reserve(dev, "rx_ring", queue_idx,
drivers/net/ixgbe/ixgbe_rxtx.c:2966:    rz = 
rte_eth_dma_zone_reserve(dev, "rx_ring", queue_idx,
drivers/net/nfp/nfp_net.c:1516: tz = rte_eth_dma_zone_reserve(dev, 
"rx_ring", queue_idx,

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

* Re: [PATCH v4 1/4] ethdev: rename memzones allocated for DMA
  2018-10-12 16:46           ` Andrew Rybchenko
@ 2018-10-12 17:18             ` Thomas Monjalon
  2018-10-12 17:21               ` Thomas Monjalon
  0 siblings, 1 reply; 58+ messages in thread
From: Thomas Monjalon @ 2018-10-12 17:18 UTC (permalink / raw)
  To: Andrew Rybchenko
  Cc: dev, gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit, Ananyev,
	Konstantin, Ajit Khaparde, Somnath Kotur, Rahul Lakkireddy

12/10/2018 18:46, Andrew Rybchenko:
> On 10/12/18 7:42 PM, Andrew Rybchenko wrote:
> > On 10/12/18 7:40 PM, Thomas Monjalon wrote:
> >> 12/10/2018 09:53, Andrew Rybchenko:
> >>> On 10/12/18 12:02 AM, Thomas Monjalon wrote:
> >>>> The helper rte_eth_dma_zone_reserve() is called by PMDs
> >>>> when probing a new port.
> >>>> It creates a new memzone with an unique name.
> >>>> The name of this memzone was using the name of the driver
> >>>> doing the probe.
> >>>>
> >>>> In order to avoid assigning the driver before the end of the probing
> >>>> (next patch), the driver name is removed from these memzone names.
> >>>> The ethdev name (data->name) is not used because it may be too long
> >>>> and may be not set at this stage of probing.
> >>>>
> >>>> Syntax of old name: <driver>_<ring>_<port>_<queue>
> >>>> Syntax of new name: eth_p<port>_q<queue>_<ring>
> >>>>
> >>>> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
> >>>> ---
> >>>>    lib/librte_ethdev/rte_ethdev.c | 5 ++---
> >>>>    1 file changed, 2 insertions(+), 3 deletions(-)
> >>>>
> >>>> diff --git a/lib/librte_ethdev/rte_ethdev.c 
> >>>> b/lib/librte_ethdev/rte_ethdev.c
> >>>> index ef99f7068..ec443def5 100644
> >>>> --- a/lib/librte_ethdev/rte_ethdev.c
> >>>> +++ b/lib/librte_ethdev/rte_ethdev.c
> >>>> @@ -3441,9 +3441,8 @@ rte_eth_dma_zone_reserve(const struct 
> >>>> rte_eth_dev *dev, const char *ring_name,
> >>>>        char z_name[RTE_MEMZONE_NAMESIZE];
> >>>>        const struct rte_memzone *mz;
> >>>>    -    snprintf(z_name, sizeof(z_name), "%s_%s_%d_%d",
> >>>> -         dev->device->driver->name, ring_name,
> >>>> -         dev->data->port_id, queue_id);
> >>>> +    snprintf(z_name, sizeof(z_name), "eth_p%d_q%d_%s",
> >>>> +         dev->data->port_id, queue_id, ring_name);
> >>>>           mz = rte_memzone_lookup(z_name);
> >>>>        if (mz)
> >>> LGTM, but I've found more places where the pattern is duplicate
> >>> and testpmd frightens me:
> >>>    - app/test-pmd/config.c ring_dma_zone_lookup() which is used
> >>>      to look at descriptors (looks like Intel specific since has
> >>>      RTE_LIBRTE_I40E_16BYTE_RX_DESC conditional code)
> >> >From what I see there is no access to rte_device.driver here,
> >> except one in exit function.
> >
> > Yes, but testpmd will fail to find the memzone and command to
> > take a look at descriptors will be broken.
> >
> > May be it is already broken etc. I think someone from Intel should
> > comment it.
> 
> Potentially the following drivers may use it:
> $ git grep -w \"rx_ring\" drivers/net/
> drivers/net/avf/avf_rxtx.c:380: mz = rte_eth_dma_zone_reserve(dev, 
> "rx_ring", queue_idx,
> drivers/net/axgbe/axgbe_rxtx.c:91:      dma = 
> rte_eth_dma_zone_reserve(dev, "rx_ring", queue_idx, size, 12
> drivers/net/cxgbe/sge.c:1878:            fwevtq ? "fwq_ring" : "rx_ring",
> drivers/net/e1000/em_rxtx.c:1437:       rz = 
> rte_eth_dma_zone_reserve(dev, "rx_ring", queue_idx, rsize,
> drivers/net/e1000/igb_rxtx.c:1734:      rz = 
> rte_eth_dma_zone_reserve(dev, "rx_ring", queue_idx, size,
> drivers/net/fm10k/fm10k_ethdev.c:1878:  mz = 
> rte_eth_dma_zone_reserve(dev, "rx_ring", queue_id,
> drivers/net/i40e/i40e_rxtx.c:1853:      rz = 
> rte_eth_dma_zone_reserve(dev, "rx_ring", queue_idx,
> drivers/net/ixgbe/ixgbe_rxtx.c:2966:    rz = 
> rte_eth_dma_zone_reserve(dev, "rx_ring", queue_idx,
> drivers/net/nfp/nfp_net.c:1516: tz = rte_eth_dma_zone_reserve(dev, 
> "rx_ring", queue_idx,

Excuse me, I really don't understand what you mean.

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

* Re: [PATCH v4 1/4] ethdev: rename memzones allocated for DMA
  2018-10-12 17:18             ` Thomas Monjalon
@ 2018-10-12 17:21               ` Thomas Monjalon
  2018-10-12 17:51                 ` Andrew Rybchenko
  0 siblings, 1 reply; 58+ messages in thread
From: Thomas Monjalon @ 2018-10-12 17:21 UTC (permalink / raw)
  To: Andrew Rybchenko
  Cc: dev, gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit, Ananyev,
	Konstantin, Ajit Khaparde, Somnath Kotur, Rahul Lakkireddy

12/10/2018 19:18, Thomas Monjalon:
> 12/10/2018 18:46, Andrew Rybchenko:
> > On 10/12/18 7:42 PM, Andrew Rybchenko wrote:
> > > On 10/12/18 7:40 PM, Thomas Monjalon wrote:
> > >> 12/10/2018 09:53, Andrew Rybchenko:
> > >>> On 10/12/18 12:02 AM, Thomas Monjalon wrote:
> > >>>> The helper rte_eth_dma_zone_reserve() is called by PMDs
> > >>>> when probing a new port.
> > >>>> It creates a new memzone with an unique name.
> > >>>> The name of this memzone was using the name of the driver
> > >>>> doing the probe.
> > >>>>
> > >>>> In order to avoid assigning the driver before the end of the probing
> > >>>> (next patch), the driver name is removed from these memzone names.
> > >>>> The ethdev name (data->name) is not used because it may be too long
> > >>>> and may be not set at this stage of probing.
> > >>>>
> > >>>> Syntax of old name: <driver>_<ring>_<port>_<queue>
> > >>>> Syntax of new name: eth_p<port>_q<queue>_<ring>
> > >>>>
> > >>>> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
> > >>>> ---
> > >>>>    lib/librte_ethdev/rte_ethdev.c | 5 ++---
> > >>>>    1 file changed, 2 insertions(+), 3 deletions(-)
> > >>>>
> > >>>> diff --git a/lib/librte_ethdev/rte_ethdev.c 
> > >>>> b/lib/librte_ethdev/rte_ethdev.c
> > >>>> index ef99f7068..ec443def5 100644
> > >>>> --- a/lib/librte_ethdev/rte_ethdev.c
> > >>>> +++ b/lib/librte_ethdev/rte_ethdev.c
> > >>>> @@ -3441,9 +3441,8 @@ rte_eth_dma_zone_reserve(const struct 
> > >>>> rte_eth_dev *dev, const char *ring_name,
> > >>>>        char z_name[RTE_MEMZONE_NAMESIZE];
> > >>>>        const struct rte_memzone *mz;
> > >>>>    -    snprintf(z_name, sizeof(z_name), "%s_%s_%d_%d",
> > >>>> -         dev->device->driver->name, ring_name,
> > >>>> -         dev->data->port_id, queue_id);
> > >>>> +    snprintf(z_name, sizeof(z_name), "eth_p%d_q%d_%s",
> > >>>> +         dev->data->port_id, queue_id, ring_name);
> > >>>>           mz = rte_memzone_lookup(z_name);
> > >>>>        if (mz)
> > >>> LGTM, but I've found more places where the pattern is duplicate
> > >>> and testpmd frightens me:
> > >>>    - app/test-pmd/config.c ring_dma_zone_lookup() which is used
> > >>>      to look at descriptors (looks like Intel specific since has
> > >>>      RTE_LIBRTE_I40E_16BYTE_RX_DESC conditional code)
> > >> >From what I see there is no access to rte_device.driver here,
> > >> except one in exit function.
> > >
> > > Yes, but testpmd will fail to find the memzone and command to
> > > take a look at descriptors will be broken.
> > >
> > > May be it is already broken etc. I think someone from Intel should
> > > comment it.
> > 
> > Potentially the following drivers may use it:
> > $ git grep -w \"rx_ring\" drivers/net/
> > drivers/net/avf/avf_rxtx.c:380: mz = rte_eth_dma_zone_reserve(dev, 
> > "rx_ring", queue_idx,
> > drivers/net/axgbe/axgbe_rxtx.c:91:      dma = 
> > rte_eth_dma_zone_reserve(dev, "rx_ring", queue_idx, size, 12
> > drivers/net/cxgbe/sge.c:1878:            fwevtq ? "fwq_ring" : "rx_ring",
> > drivers/net/e1000/em_rxtx.c:1437:       rz = 
> > rte_eth_dma_zone_reserve(dev, "rx_ring", queue_idx, rsize,
> > drivers/net/e1000/igb_rxtx.c:1734:      rz = 
> > rte_eth_dma_zone_reserve(dev, "rx_ring", queue_idx, size,
> > drivers/net/fm10k/fm10k_ethdev.c:1878:  mz = 
> > rte_eth_dma_zone_reserve(dev, "rx_ring", queue_id,
> > drivers/net/i40e/i40e_rxtx.c:1853:      rz = 
> > rte_eth_dma_zone_reserve(dev, "rx_ring", queue_idx,
> > drivers/net/ixgbe/ixgbe_rxtx.c:2966:    rz = 
> > rte_eth_dma_zone_reserve(dev, "rx_ring", queue_idx,
> > drivers/net/nfp/nfp_net.c:1516: tz = rte_eth_dma_zone_reserve(dev, 
> > "rx_ring", queue_idx,
> 
> Excuse me, I really don't understand what you mean.

Oh, got it!
You mean the call to rte_memzone_lookup() must expect the new memzone name.
So I must update it here too, right?

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

* Re: [PATCH v4 1/4] ethdev: rename memzones allocated for DMA
  2018-10-12 17:21               ` Thomas Monjalon
@ 2018-10-12 17:51                 ` Andrew Rybchenko
  0 siblings, 0 replies; 58+ messages in thread
From: Andrew Rybchenko @ 2018-10-12 17:51 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: dev, gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit, Ananyev,
	Konstantin, Ajit Khaparde, Somnath Kotur, Rahul Lakkireddy



On October 12, 2018 20:21:32 Thomas Monjalon <thomas@monjalon.net> wrote:

> 12/10/2018 19:18, Thomas Monjalon:
>> 12/10/2018 18:46, Andrew Rybchenko:
>> > On 10/12/18 7:42 PM, Andrew Rybchenko wrote:
>> > > On 10/12/18 7:40 PM, Thomas Monjalon wrote:
>> > >> 12/10/2018 09:53, Andrew Rybchenko:
>> > >>> On 10/12/18 12:02 AM, Thomas Monjalon wrote:
>> > >>>> The helper rte_eth_dma_zone_reserve() is called by PMDs
>> > >>>> when probing a new port.
>> > >>>> It creates a new memzone with an unique name.
>> > >>>> The name of this memzone was using the name of the driver
>> > >>>> doing the probe.
>> > >>>>
>> > >>>> In order to avoid assigning the driver before the end of the probing
>> > >>>> (next patch), the driver name is removed from these memzone names.
>> > >>>> The ethdev name (data->name) is not used because it may be too long
>> > >>>> and may be not set at this stage of probing.
>> > >>>>
>> > >>>> Syntax of old name: <driver>_<ring>_<port>_<queue>
>> > >>>> Syntax of new name: eth_p<port>_q<queue>_<ring>
>> > >>>>
>> > >>>> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
>> > >>>> ---
>> > >>>>    lib/librte_ethdev/rte_ethdev.c | 5 ++---
>> > >>>>    1 file changed, 2 insertions(+), 3 deletions(-)
>> > >>>>
>> > >>>> diff --git a/lib/librte_ethdev/rte_ethdev.c
>> > >>>> b/lib/librte_ethdev/rte_ethdev.c
>> > >>>> index ef99f7068..ec443def5 100644
>> > >>>> --- a/lib/librte_ethdev/rte_ethdev.c
>> > >>>> +++ b/lib/librte_ethdev/rte_ethdev.c
>> > >>>> @@ -3441,9 +3441,8 @@ rte_eth_dma_zone_reserve(const struct
>> > >>>> rte_eth_dev *dev, const char *ring_name,
>> > >>>>        char z_name[RTE_MEMZONE_NAMESIZE];
>> > >>>>        const struct rte_memzone *mz;
>> > >>>>    -    snprintf(z_name, sizeof(z_name), "%s_%s_%d_%d",
>> > >>>> -         dev->device->driver->name, ring_name,
>> > >>>> -         dev->data->port_id, queue_id);
>> > >>>> +    snprintf(z_name, sizeof(z_name), "eth_p%d_q%d_%s",
>> > >>>> +         dev->data->port_id, queue_id, ring_name);
>> > >>>>           mz = rte_memzone_lookup(z_name);
>> > >>>>        if (mz)
>> > >>> LGTM, but I've found more places where the pattern is duplicate
>> > >>> and testpmd frightens me:
>> > >>>    - app/test-pmd/config.c ring_dma_zone_lookup() which is used
>> > >>>      to look at descriptors (looks like Intel specific since has
>> > >>>      RTE_LIBRTE_I40E_16BYTE_RX_DESC conditional code)
>> > >> >From what I see there is no access to rte_device.driver here,
>> > >> except one in exit function.
>> > >
>> > > Yes, but testpmd will fail to find the memzone and command to
>> > > take a look at descriptors will be broken.
>> > >
>> > > May be it is already broken etc. I think someone from Intel should
>> > > comment it.
>> >
>> > Potentially the following drivers may use it:
>> > $ git grep -w \"rx_ring\" drivers/net/
>> > drivers/net/avf/avf_rxtx.c:380: mz = rte_eth_dma_zone_reserve(dev,
>> > "rx_ring", queue_idx,
>> > drivers/net/axgbe/axgbe_rxtx.c:91:      dma =
>> > rte_eth_dma_zone_reserve(dev, "rx_ring", queue_idx, size, 12
>> > drivers/net/cxgbe/sge.c:1878:            fwevtq ? "fwq_ring" : "rx_ring",
>> > drivers/net/e1000/em_rxtx.c:1437:       rz =
>> > rte_eth_dma_zone_reserve(dev, "rx_ring", queue_idx, rsize,
>> > drivers/net/e1000/igb_rxtx.c:1734:      rz =
>> > rte_eth_dma_zone_reserve(dev, "rx_ring", queue_idx, size,
>> > drivers/net/fm10k/fm10k_ethdev.c:1878:  mz =
>> > rte_eth_dma_zone_reserve(dev, "rx_ring", queue_id,
>> > drivers/net/i40e/i40e_rxtx.c:1853:      rz =
>> > rte_eth_dma_zone_reserve(dev, "rx_ring", queue_idx,
>> > drivers/net/ixgbe/ixgbe_rxtx.c:2966:    rz =
>> > rte_eth_dma_zone_reserve(dev, "rx_ring", queue_idx,
>> > drivers/net/nfp/nfp_net.c:1516: tz = rte_eth_dma_zone_reserve(dev,
>> > "rx_ring", queue_idx,
>>
>> Excuse me, I really don't understand what you mean.
>
> Oh, got it!
> You mean the call to rte_memzone_lookup() must expect the new memzone name.
> So I must update it here too, right?
Yes

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

* [PATCH v5 0/7] allow hotplug to skip an already probed device
  2018-09-07 23:09 [RFC] eal: allow hotplug to skip an already probed device Thomas Monjalon
                   ` (3 preceding siblings ...)
  2018-10-11 21:02 ` [PATCH v4 0/4] eal: allow hotplug to skip an already probed device Thomas Monjalon
@ 2018-10-14 20:47 ` Thomas Monjalon
  2018-10-14 20:47   ` [PATCH v5 1/7] net/mlx5: remove useless driver name comparison Thomas Monjalon
                     ` (7 more replies)
  4 siblings, 8 replies; 58+ messages in thread
From: Thomas Monjalon @ 2018-10-14 20:47 UTC (permalink / raw)
  To: dev; +Cc: gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit

This is a follow-up of an idea presented at Dublin
during the "hotplug talk".

The idea is to ease probing of range of ports attached
to the same rte_device.
I becomes possible to allow probing again the same device
but with a bigger range of ports in the devargs.

Instead of adding a parameter to the hotplug functions, as in the RFC,
the check of an already probed device is moved to the bus and enabled PMDs.
It gives flexibility to drivers for managing range of ports.


Changes in v5 - after Andrew's review:
  - remove driver name usage in mlx5/szedata2 probing and crypto/compress logs
  - update DMA ring names in bnx2x, cxgbe, vmxnet3 and testpmd lookup

Changes in v4 - after Andrew's review:
  - remove access to rte_device.driver during probing (patch 1)

Changes in v3 - after Declan's review:
  - return error in all buses but PCI
  - add a PCI driver flag to enable feature per driver
  - return -EEXIST if probing again is not supported


Thomas Monjalon (7):
  net/mlx5: remove useless driver name comparison
  ethdev: rename memzones allocated for DMA
  cryptodev: remove driver name from logs
  compressdev: remove driver name from logs
  drivers/bus: move driver assignment to end of probing
  eal: add function to query device status
  eal: allow probing a device again

 app/test-pmd/config.c                        |  4 +--
 drivers/bus/dpaa/dpaa_bus.c                  |  3 ++
 drivers/bus/fslmc/fslmc_bus.c                |  3 ++
 drivers/bus/ifpga/ifpga_bus.c                | 21 +++++------
 drivers/bus/pci/pci_common.c                 | 38 ++++++++++++--------
 drivers/bus/pci/rte_bus_pci.h                |  6 ++--
 drivers/bus/vdev/vdev.c                      | 12 ++++---
 drivers/bus/vmbus/vmbus_common.c             |  5 +--
 drivers/net/bnx2x/bnx2x_rxtx.c               | 15 ++------
 drivers/net/cxgbe/sge.c                      | 24 ++++++-------
 drivers/net/i40e/i40e_vf_representor.c       |  3 --
 drivers/net/mlx4/mlx4.c                      |  1 -
 drivers/net/mlx5/mlx5.c                      |  1 -
 drivers/net/mlx5/mlx5_ethdev.c               |  5 +--
 drivers/net/szedata2/rte_eth_szedata2.c      |  6 ++--
 drivers/net/vmxnet3/vmxnet3_ethdev.c         |  4 +--
 lib/librte_compressdev/rte_compressdev_pmd.c | 23 +++++-------
 lib/librte_cryptodev/rte_cryptodev_pmd.c     | 23 +++++-------
 lib/librte_eal/common/eal_common_dev.c       | 14 +++++---
 lib/librte_eal/common/include/rte_dev.h      | 18 ++++++++--
 lib/librte_eal/rte_eal_version.map           |  1 +
 lib/librte_ethdev/rte_ethdev.c               |  5 ++-
 22 files changed, 121 insertions(+), 114 deletions(-)

-- 
2.19.0

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

* [PATCH v5 1/7] net/mlx5: remove useless driver name comparison
  2018-10-14 20:47 ` [PATCH v5 0/7] " Thomas Monjalon
@ 2018-10-14 20:47   ` Thomas Monjalon
  2018-10-14 20:49     ` Thomas Monjalon
  2018-10-14 20:47   ` [PATCH v5 2/7] ethdev: rename memzones allocated for DMA Thomas Monjalon
                     ` (6 subsequent siblings)
  7 siblings, 1 reply; 58+ messages in thread
From: Thomas Monjalon @ 2018-10-14 20:47 UTC (permalink / raw)
  To: dev; +Cc: gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit

The function mlx5_dev_to_port_id() is returning all the ports
associated to a rte_device.
It was comparing driver names while already comparing rte_device pointers.
If two devices are the same, they will have the same driver.
So the useless driver name comparison is removed.

Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
---
 drivers/net/mlx5/mlx5_ethdev.c | 5 +----
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
index 61eda537b..cacdf8e18 100644
--- a/drivers/net/mlx5/mlx5_ethdev.c
+++ b/drivers/net/mlx5/mlx5_ethdev.c
@@ -1305,10 +1305,7 @@ mlx5_dev_to_port_id(const struct rte_device *dev, uint16_t *port_list,
 	RTE_ETH_FOREACH_DEV(id) {
 		struct rte_eth_dev *ldev = &rte_eth_devices[id];
 
-		if (!ldev->device ||
-		    !ldev->device->driver ||
-		    strcmp(ldev->device->driver->name, MLX5_DRIVER_NAME) ||
-		    ldev->device != dev)
+		if (ldev->device != dev)
 			continue;
 		if (n < port_list_n)
 			port_list[n] = id;
-- 
2.19.0

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

* [PATCH v5 2/7] ethdev: rename memzones allocated for DMA
  2018-10-14 20:47 ` [PATCH v5 0/7] " Thomas Monjalon
  2018-10-14 20:47   ` [PATCH v5 1/7] net/mlx5: remove useless driver name comparison Thomas Monjalon
@ 2018-10-14 20:47   ` Thomas Monjalon
  2018-10-14 20:47   ` [PATCH v5 3/7] cryptodev: remove driver name from logs Thomas Monjalon
                     ` (5 subsequent siblings)
  7 siblings, 0 replies; 58+ messages in thread
From: Thomas Monjalon @ 2018-10-14 20:47 UTC (permalink / raw)
  To: dev; +Cc: gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit

The helper rte_eth_dma_zone_reserve() is called by PMDs
when probing a new port.
It creates a new memzone with an unique name.
The name of this memzone was using the name of the driver
doing the probe.

In order to avoid assigning the driver before the end of the probing,
the driver name is removed from these memzone names.
The ethdev name (data->name) is not used because it may be too long
and may be not set at this stage of probing.

Syntax of old name: <driver>_<ring>_<port>_<queue>
Syntax of new name: eth_p<port>_q<queue>_<ring>

Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
Tested-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 app/test-pmd/config.c                |  4 ++--
 drivers/net/bnx2x/bnx2x_rxtx.c       | 15 ++-------------
 drivers/net/cxgbe/sge.c              | 24 ++++++++++--------------
 drivers/net/vmxnet3/vmxnet3_ethdev.c |  4 ++--
 lib/librte_ethdev/rte_ethdev.c       |  5 ++---
 5 files changed, 18 insertions(+), 34 deletions(-)

diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index bf3cd0a8c..a6db5df0c 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -1479,8 +1479,8 @@ ring_dma_zone_lookup(const char *ring_name, portid_t port_id, uint16_t q_id)
 	char mz_name[RTE_MEMZONE_NAMESIZE];
 	const struct rte_memzone *mz;
 
-	snprintf(mz_name, sizeof(mz_name), "%s_%s_%d_%d",
-		 ports[port_id].dev_info.driver_name, ring_name, port_id, q_id);
+	snprintf(mz_name, sizeof(mz_name), "eth_p%d_q%d_%s",
+			port_id, q_id, ring_name);
 	mz = rte_memzone_lookup(mz_name);
 	if (mz == NULL)
 		printf("%s ring memory zoneof (port %d, queue %d) not"
diff --git a/drivers/net/bnx2x/bnx2x_rxtx.c b/drivers/net/bnx2x/bnx2x_rxtx.c
index 589735ecd..ca28aaccf 100644
--- a/drivers/net/bnx2x/bnx2x_rxtx.c
+++ b/drivers/net/bnx2x/bnx2x_rxtx.c
@@ -12,19 +12,8 @@ static const struct rte_memzone *
 ring_dma_zone_reserve(struct rte_eth_dev *dev, const char *ring_name,
 		      uint16_t queue_id, uint32_t ring_size, int socket_id)
 {
-	char z_name[RTE_MEMZONE_NAMESIZE];
-	const struct rte_memzone *mz;
-
-	snprintf(z_name, sizeof(z_name), "%s_%s_%d_%d",
-			dev->device->driver->name, ring_name,
-			dev->data->port_id, queue_id);
-
-	mz = rte_memzone_lookup(z_name);
-	if (mz)
-		return mz;
-
-	return rte_memzone_reserve_aligned(z_name, ring_size, socket_id,
-			RTE_MEMZONE_IOVA_CONTIG, BNX2X_PAGE_SIZE);
+	return rte_eth_dma_zone_reserve(dev, ring_name, queue_id,
+			ring_size, BNX2X_PAGE_SIZE, socket_id);
 }
 
 static void
diff --git a/drivers/net/cxgbe/sge.c b/drivers/net/cxgbe/sge.c
index 4ea40d191..f9d2d48a0 100644
--- a/drivers/net/cxgbe/sge.c
+++ b/drivers/net/cxgbe/sge.c
@@ -1873,10 +1873,9 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq,
 	/* Size needs to be multiple of 16, including status entry. */
 	iq->size = cxgbe_roundup(iq->size, 16);
 
-	snprintf(z_name, sizeof(z_name), "%s_%s_%d_%d",
-		 eth_dev->device->driver->name,
-		 fwevtq ? "fwq_ring" : "rx_ring",
-		 eth_dev->data->port_id, queue_id);
+	snprintf(z_name, sizeof(z_name), "eth_p%d_q%d_%s",
+			eth_dev->data->port_id, queue_id,
+			fwevtq ? "fwq_ring" : "rx_ring");
 	snprintf(z_name_sw, sizeof(z_name_sw), "%s_sw_ring", z_name);
 
 	iq->desc = alloc_ring(iq->size, iq->iqe_len, 0, &iq->phys_addr, NULL, 0,
@@ -1938,10 +1937,9 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq,
 			fl->size = s->fl_starve_thres - 1 + 2 * 8;
 		fl->size = cxgbe_roundup(fl->size, 8);
 
-		snprintf(z_name, sizeof(z_name), "%s_%s_%d_%d",
-			 eth_dev->device->driver->name,
-			 fwevtq ? "fwq_ring" : "fl_ring",
-			 eth_dev->data->port_id, queue_id);
+		snprintf(z_name, sizeof(z_name), "eth_p%d_q%d_%s",
+				eth_dev->data->port_id, queue_id,
+				fwevtq ? "fwq_ring" : "fl_ring");
 		snprintf(z_name_sw, sizeof(z_name_sw), "%s_sw_ring", z_name);
 
 		fl->desc = alloc_ring(fl->size, sizeof(__be64),
@@ -2144,9 +2142,8 @@ int t4_sge_alloc_eth_txq(struct adapter *adap, struct sge_eth_txq *txq,
 	/* Add status entries */
 	nentries = txq->q.size + s->stat_len / sizeof(struct tx_desc);
 
-	snprintf(z_name, sizeof(z_name), "%s_%s_%d_%d",
-		 eth_dev->device->driver->name, "tx_ring",
-		 eth_dev->data->port_id, queue_id);
+	snprintf(z_name, sizeof(z_name), "eth_p%d_q%d_%s",
+			eth_dev->data->port_id, queue_id, "tx_ring");
 	snprintf(z_name_sw, sizeof(z_name_sw), "%s_sw_ring", z_name);
 
 	txq->q.desc = alloc_ring(txq->q.size, sizeof(struct tx_desc),
@@ -2223,9 +2220,8 @@ int t4_sge_alloc_ctrl_txq(struct adapter *adap, struct sge_ctrl_txq *txq,
 	/* Add status entries */
 	nentries = txq->q.size + s->stat_len / sizeof(struct tx_desc);
 
-	snprintf(z_name, sizeof(z_name), "%s_%s_%d_%d",
-		 eth_dev->device->driver->name, "ctrl_tx_ring",
-		 eth_dev->data->port_id, queue_id);
+	snprintf(z_name, sizeof(z_name), "eth_p%d_q%d_%s",
+			eth_dev->data->port_id, queue_id, "ctrl_tx_ring");
 	snprintf(z_name_sw, sizeof(z_name_sw), "%s_sw_ring", z_name);
 
 	txq->q.desc = alloc_ring(txq->q.size, sizeof(struct tx_desc),
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index e41fa499b..78e5b7680 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -161,8 +161,8 @@ gpa_zone_reserve(struct rte_eth_dev *dev, uint32_t size,
 	char z_name[RTE_MEMZONE_NAMESIZE];
 	const struct rte_memzone *mz;
 
-	snprintf(z_name, sizeof(z_name), "%s_%d_%s",
-		 dev->device->driver->name, dev->data->port_id, post_string);
+	snprintf(z_name, sizeof(z_name), "eth_p%d_%s",
+			dev->data->port_id, post_string);
 
 	mz = rte_memzone_lookup(z_name);
 	if (!reuse) {
diff --git a/lib/librte_ethdev/rte_ethdev.c b/lib/librte_ethdev/rte_ethdev.c
index 21f1dfbe4..14fc7e328 100644
--- a/lib/librte_ethdev/rte_ethdev.c
+++ b/lib/librte_ethdev/rte_ethdev.c
@@ -3481,9 +3481,8 @@ rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name,
 	char z_name[RTE_MEMZONE_NAMESIZE];
 	const struct rte_memzone *mz;
 
-	snprintf(z_name, sizeof(z_name), "%s_%s_%d_%d",
-		 dev->device->driver->name, ring_name,
-		 dev->data->port_id, queue_id);
+	snprintf(z_name, sizeof(z_name), "eth_p%d_q%d_%s",
+		 dev->data->port_id, queue_id, ring_name);
 
 	mz = rte_memzone_lookup(z_name);
 	if (mz)
-- 
2.19.0

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

* [PATCH v5 3/7] cryptodev: remove driver name from logs
  2018-10-14 20:47 ` [PATCH v5 0/7] " Thomas Monjalon
  2018-10-14 20:47   ` [PATCH v5 1/7] net/mlx5: remove useless driver name comparison Thomas Monjalon
  2018-10-14 20:47   ` [PATCH v5 2/7] ethdev: rename memzones allocated for DMA Thomas Monjalon
@ 2018-10-14 20:47   ` Thomas Monjalon
  2018-10-15  8:51     ` Thomas Monjalon
  2018-10-14 20:47   ` [PATCH v5 4/7] compressdev: " Thomas Monjalon
                     ` (4 subsequent siblings)
  7 siblings, 1 reply; 58+ messages in thread
From: Thomas Monjalon @ 2018-10-14 20:47 UTC (permalink / raw)
  To: dev; +Cc: gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit

The logs printed by CDEV_LOG_* were prefixed with the driver name.

In order to avoid assigning the driver before the end of the probing,
the driver name is removed from the cryptodev library logs.

Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
---
 lib/librte_cryptodev/rte_cryptodev_pmd.c | 23 ++++++++---------------
 1 file changed, 8 insertions(+), 15 deletions(-)

diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.c b/lib/librte_cryptodev/rte_cryptodev_pmd.c
index 2088ac3f3..f03bdbd5e 100644
--- a/lib/librte_cryptodev/rte_cryptodev_pmd.c
+++ b/lib/librte_cryptodev/rte_cryptodev_pmd.c
@@ -93,24 +93,20 @@ rte_cryptodev_pmd_create(const char *name,
 	struct rte_cryptodev *cryptodev;
 
 	if (params->name[0] != '\0') {
-		CDEV_LOG_INFO("[%s] User specified device name = %s\n",
-				device->driver->name, params->name);
+		CDEV_LOG_INFO("User specified device name = %s\n", params->name);
 		name = params->name;
 	}
 
-	CDEV_LOG_INFO("[%s] - Creating cryptodev %s\n",
-			device->driver->name, name);
+	CDEV_LOG_INFO("Creating cryptodev %s\n", name);
 
-	CDEV_LOG_INFO("[%s] - Initialisation parameters - name: %s,"
+	CDEV_LOG_INFO("Initialisation parameters - name: %s,"
 			"socket id: %d, max queue pairs: %u",
-			device->driver->name, name,
-			params->socket_id, params->max_nb_queue_pairs);
+			name, params->socket_id, params->max_nb_queue_pairs);
 
 	/* allocate device structure */
 	cryptodev = rte_cryptodev_pmd_allocate(name, params->socket_id);
 	if (cryptodev == NULL) {
-		CDEV_LOG_ERR("[%s] Failed to allocate crypto device for %s",
-				device->driver->name, name);
+		CDEV_LOG_ERR("Failed to allocate crypto device for %s", name);
 		return NULL;
 	}
 
@@ -123,9 +119,8 @@ rte_cryptodev_pmd_create(const char *name,
 						params->socket_id);
 
 		if (cryptodev->data->dev_private == NULL) {
-			CDEV_LOG_ERR("[%s] Cannot allocate memory for "
-					"cryptodev %s private data",
-					device->driver->name, name);
+			CDEV_LOG_ERR("Cannot allocate memory for cryptodev %s"
+					" private data", name);
 
 			rte_cryptodev_pmd_release_device(cryptodev);
 			return NULL;
@@ -145,9 +140,7 @@ rte_cryptodev_pmd_destroy(struct rte_cryptodev *cryptodev)
 {
 	int retval;
 
-	CDEV_LOG_INFO("[%s] Closing crypto device %s",
-			cryptodev->device->driver->name,
-			cryptodev->device->name);
+	CDEV_LOG_INFO("Closing crypto device %s", cryptodev->device->name);
 
 	/* free crypto device */
 	retval = rte_cryptodev_pmd_release_device(cryptodev);
-- 
2.19.0

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

* [PATCH v5 4/7] compressdev: remove driver name from logs
  2018-10-14 20:47 ` [PATCH v5 0/7] " Thomas Monjalon
                     ` (2 preceding siblings ...)
  2018-10-14 20:47   ` [PATCH v5 3/7] cryptodev: remove driver name from logs Thomas Monjalon
@ 2018-10-14 20:47   ` Thomas Monjalon
  2018-10-15  8:51     ` Thomas Monjalon
  2018-10-14 20:47   ` [PATCH v5 5/7] drivers/bus: move driver assignment to end of probing Thomas Monjalon
                     ` (3 subsequent siblings)
  7 siblings, 1 reply; 58+ messages in thread
From: Thomas Monjalon @ 2018-10-14 20:47 UTC (permalink / raw)
  To: dev; +Cc: gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit

The logs printed by COMPRESSDEV_LOG were prefixed with the driver name.

In order to avoid assigning the driver before the end of the probing,
the driver name is removed from the compressdev library logs.

Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
---
 lib/librte_compressdev/rte_compressdev_pmd.c | 23 ++++++++------------
 1 file changed, 9 insertions(+), 14 deletions(-)

diff --git a/lib/librte_compressdev/rte_compressdev_pmd.c b/lib/librte_compressdev/rte_compressdev_pmd.c
index 7de4f339e..95beb26ab 100644
--- a/lib/librte_compressdev/rte_compressdev_pmd.c
+++ b/lib/librte_compressdev/rte_compressdev_pmd.c
@@ -92,24 +92,20 @@ rte_compressdev_pmd_create(const char *name,
 	struct rte_compressdev *compressdev;
 
 	if (params->name[0] != '\0') {
-		COMPRESSDEV_LOG(INFO, "[%s] User specified device name = %s\n",
-				device->driver->name, params->name);
+		COMPRESSDEV_LOG(INFO, "User specified device name = %s\n",
+				params->name);
 		name = params->name;
 	}
 
-	COMPRESSDEV_LOG(INFO, "[%s] - Creating compressdev %s\n",
-			device->driver->name, name);
+	COMPRESSDEV_LOG(INFO, "Creating compressdev %s\n", name);
 
-	COMPRESSDEV_LOG(INFO,
-	"[%s] - Init parameters - name: %s, socket id: %d",
-			device->driver->name, name,
-			params->socket_id);
+	COMPRESSDEV_LOG(INFO, "Init parameters - name: %s, socket id: %d",
+			name, params->socket_id);
 
 	/* allocate device structure */
 	compressdev = rte_compressdev_pmd_allocate(name, params->socket_id);
 	if (compressdev == NULL) {
-		COMPRESSDEV_LOG(ERR, "[%s] Failed to allocate comp device %s",
-				device->driver->name, name);
+		COMPRESSDEV_LOG(ERR, "Failed to allocate comp device %s", name);
 		return NULL;
 	}
 
@@ -123,8 +119,8 @@ rte_compressdev_pmd_create(const char *name,
 
 		if (compressdev->data->dev_private == NULL) {
 			COMPRESSDEV_LOG(ERR,
-		"[%s] Cannot allocate memory for compressdev %s private data",
-					device->driver->name, name);
+					"Cannot allocate memory for compressdev"
+					" %s private data", name);
 
 			rte_compressdev_pmd_release_device(compressdev);
 			return NULL;
@@ -141,8 +137,7 @@ rte_compressdev_pmd_destroy(struct rte_compressdev *compressdev)
 {
 	int retval;
 
-	COMPRESSDEV_LOG(INFO, "[%s] Closing comp device %s",
-			compressdev->device->driver->name,
+	COMPRESSDEV_LOG(INFO, "Closing comp device %s",
 			compressdev->device->name);
 
 	/* free comp device */
-- 
2.19.0

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

* [PATCH v5 5/7] drivers/bus: move driver assignment to end of probing
  2018-10-14 20:47 ` [PATCH v5 0/7] " Thomas Monjalon
                     ` (3 preceding siblings ...)
  2018-10-14 20:47   ` [PATCH v5 4/7] compressdev: " Thomas Monjalon
@ 2018-10-14 20:47   ` Thomas Monjalon
  2018-10-14 20:53     ` Thomas Monjalon
  2018-10-14 20:47   ` [PATCH v5 6/7] eal: add function to query device status Thomas Monjalon
                     ` (2 subsequent siblings)
  7 siblings, 1 reply; 58+ messages in thread
From: Thomas Monjalon @ 2018-10-14 20:47 UTC (permalink / raw)
  To: dev; +Cc: gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit

The PCI mapping requires to know the PCI driver to use,
even before the probing is done. That's why the PCI driver is
referenced early inside the PCI device structure. See
commit 1d20a073fa5e ("bus/pci: reference driver structure before mapping")

However the rte_driver does not need to be referenced in rte_device
before the device probing is done.
By moving back this assignment at the end of the device probing,
it becomes possible to make clear the status of a rte_device.

Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
Tested-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/bus/ifpga/ifpga_bus.c           | 9 ++++-----
 drivers/bus/pci/pci_common.c            | 7 +++----
 drivers/bus/pci/rte_bus_pci.h           | 2 +-
 drivers/bus/vdev/vdev.c                 | 5 ++---
 drivers/bus/vmbus/vmbus_common.c        | 5 +++--
 drivers/net/i40e/i40e_vf_representor.c  | 3 ---
 drivers/net/mlx4/mlx4.c                 | 1 -
 drivers/net/mlx5/mlx5.c                 | 1 -
 drivers/net/szedata2/rte_eth_szedata2.c | 6 +++---
 lib/librte_eal/common/include/rte_dev.h | 2 +-
 10 files changed, 17 insertions(+), 24 deletions(-)

diff --git a/drivers/bus/ifpga/ifpga_bus.c b/drivers/bus/ifpga/ifpga_bus.c
index 80663328a..fca2dbace 100644
--- a/drivers/bus/ifpga/ifpga_bus.c
+++ b/drivers/bus/ifpga/ifpga_bus.c
@@ -280,14 +280,13 @@ ifpga_probe_one_driver(struct rte_afu_driver *drv,
 
 	/* reference driver structure */
 	afu_dev->driver = drv;
-	afu_dev->device.driver = &drv->driver;
 
 	/* call the driver probe() function */
 	ret = drv->probe(afu_dev);
-	if (ret) {
+	if (ret)
 		afu_dev->driver = NULL;
-		afu_dev->device.driver = NULL;
-	}
+	else
+		afu_dev->device.driver = &drv->driver;
 
 	return ret;
 }
@@ -302,7 +301,7 @@ ifpga_probe_all_drivers(struct rte_afu_device *afu_dev)
 		return -1;
 
 	/* Check if a driver is already loaded */
-	if (afu_dev->driver != NULL)
+	if (afu_dev->device.driver != NULL)
 		return 0;
 
 	TAILQ_FOREACH(drv, &ifpga_afu_drv_list, next) {
diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
index c7695d108..d63e68045 100644
--- a/drivers/bus/pci/pci_common.c
+++ b/drivers/bus/pci/pci_common.c
@@ -160,14 +160,12 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
 	 * driver flags for adjusting configuration.
 	 */
 	dev->driver = dr;
-	dev->device.driver = &dr->driver;
 
 	if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) {
 		/* map resources for devices that use igb_uio */
 		ret = rte_pci_map_device(dev);
 		if (ret != 0) {
 			dev->driver = NULL;
-			dev->device.driver = NULL;
 			return ret;
 		}
 	}
@@ -176,7 +174,6 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
 	ret = dr->probe(dr, dev);
 	if (ret) {
 		dev->driver = NULL;
-		dev->device.driver = NULL;
 		if ((dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) &&
 			/* Don't unmap if device is unsupported and
 			 * driver needs mapped resources.
@@ -184,6 +181,8 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
 			!(ret > 0 &&
 				(dr->drv_flags & RTE_PCI_DRV_KEEP_MAPPED_RES)))
 			rte_pci_unmap_device(dev);
+	} else {
+		dev->device.driver = &dr->driver;
 	}
 
 	return ret;
@@ -244,7 +243,7 @@ pci_probe_all_drivers(struct rte_pci_device *dev)
 		return -1;
 
 	/* Check if a driver is already loaded */
-	if (dev->driver != NULL)
+	if (dev->device.driver != NULL)
 		return 0;
 
 	FOREACH_DRIVER_ON_PCIBUS(dr) {
diff --git a/drivers/bus/pci/rte_bus_pci.h b/drivers/bus/pci/rte_bus_pci.h
index 0d1955ffe..984df2b37 100644
--- a/drivers/bus/pci/rte_bus_pci.h
+++ b/drivers/bus/pci/rte_bus_pci.h
@@ -62,7 +62,7 @@ struct rte_pci_device {
 	struct rte_mem_resource mem_resource[PCI_MAX_RESOURCE];
 					    /**< PCI Memory Resource */
 	struct rte_intr_handle intr_handle; /**< Interrupt handle */
-	struct rte_pci_driver *driver;      /**< Associated driver */
+	struct rte_pci_driver *driver;      /**< PCI driver used in probing */
 	uint16_t max_vfs;                   /**< sriov enable if not zero */
 	enum rte_kernel_driver kdrv;        /**< Kernel driver passthrough */
 	char name[PCI_PRI_STR_SIZE+1];      /**< PCI location (ASCII) */
diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
index 0142fb2c8..3f27f3510 100644
--- a/drivers/bus/vdev/vdev.c
+++ b/drivers/bus/vdev/vdev.c
@@ -150,10 +150,9 @@ vdev_probe_all_drivers(struct rte_vdev_device *dev)
 
 	if (vdev_parse(name, &driver))
 		return -1;
-	dev->device.driver = &driver->driver;
 	ret = driver->probe(dev);
-	if (ret)
-		dev->device.driver = NULL;
+	if (ret == 0)
+		dev->device.driver = &driver->driver;
 	return ret;
 }
 
diff --git a/drivers/bus/vmbus/vmbus_common.c b/drivers/bus/vmbus/vmbus_common.c
index e3ceb6906..de5548aa4 100644
--- a/drivers/bus/vmbus/vmbus_common.c
+++ b/drivers/bus/vmbus/vmbus_common.c
@@ -111,7 +111,6 @@ vmbus_probe_one_driver(struct rte_vmbus_driver *dr,
 
 	/* reference driver structure */
 	dev->driver = dr;
-	dev->device.driver = &dr->driver;
 
 	if (dev->device.numa_node < 0) {
 		VMBUS_LOG(WARNING, "  Invalid NUMA socket, default to 0");
@@ -124,6 +123,8 @@ vmbus_probe_one_driver(struct rte_vmbus_driver *dr,
 	if (ret) {
 		dev->driver = NULL;
 		rte_vmbus_unmap_device(dev);
+	} else {
+		dev->device.driver = &dr->driver;
 	}
 
 	return ret;
@@ -142,7 +143,7 @@ vmbus_probe_all_drivers(struct rte_vmbus_device *dev)
 	int rc;
 
 	/* Check if a driver is already loaded */
-	if (dev->driver != NULL) {
+	if (dev->device.driver != NULL) {
 		VMBUS_LOG(DEBUG, "VMBUS driver already loaded");
 		return 0;
 	}
diff --git a/drivers/net/i40e/i40e_vf_representor.c b/drivers/net/i40e/i40e_vf_representor.c
index 0bfbb4f60..24751d13c 100644
--- a/drivers/net/i40e/i40e_vf_representor.c
+++ b/drivers/net/i40e/i40e_vf_representor.c
@@ -487,9 +487,6 @@ i40e_vf_representor_init(struct rte_eth_dev *ethdev, void *init_params)
 	if (representor->vf_id >= pf->vf_num)
 		return -ENODEV;
 
-	/** representor shares the same driver as it's PF device */
-	ethdev->device->driver = representor->adapter->eth_dev->device->driver;
-
 	/* Set representor device ops */
 	ethdev->dev_ops = &i40e_representor_dev_ops;
 
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index defc0d4b0..3de7bc53e 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -734,7 +734,6 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
 		eth_dev->data->mac_addrs = priv->mac;
 		eth_dev->device = &pci_dev->device;
 		rte_eth_copy_pci_info(eth_dev, pci_dev);
-		eth_dev->device->driver = &mlx4_driver.driver;
 		/* Initialize local interrupt handle for current port. */
 		priv->intr_handle = (struct rte_intr_handle){
 			.fd = -1,
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 795a21977..8cbfee1ba 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -1090,7 +1090,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
 	priv->dev_data = eth_dev->data;
 	eth_dev->data->mac_addrs = priv->mac;
 	eth_dev->device = dpdk_dev;
-	eth_dev->device->driver = &mlx5_driver.driver;
 	err = mlx5_uar_init_primary(eth_dev);
 	if (err) {
 		err = rte_errno;
diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
index 8f92e72f2..4e5e01cf1 100644
--- a/drivers/net/szedata2/rte_eth_szedata2.c
+++ b/drivers/net/szedata2/rte_eth_szedata2.c
@@ -1474,7 +1474,7 @@ rte_szedata2_eth_dev_init(struct rte_eth_dev *dev, struct port_info *pi)
 	PMD_INIT_FUNC_TRACE();
 
 	PMD_INIT_LOG(INFO, "Initializing eth_dev %s (driver %s)", data->name,
-			dev->device->driver->name);
+			RTE_STR(RTE_SZEDATA2_DRIVER_NAME));
 
 	/* Fill internal private structure. */
 	internals->dev = dev;
@@ -1525,7 +1525,7 @@ rte_szedata2_eth_dev_init(struct rte_eth_dev *dev, struct port_info *pi)
 	ether_addr_copy(&eth_addr, data->mac_addrs);
 
 	PMD_INIT_LOG(INFO, "%s device %s successfully initialized",
-			dev->device->driver->name, data->name);
+			RTE_STR(RTE_SZEDATA2_DRIVER_NAME), data->name);
 
 	return 0;
 }
@@ -1547,7 +1547,7 @@ rte_szedata2_eth_dev_uninit(struct rte_eth_dev *dev)
 	rte_free(dev->data->mac_addrs);
 
 	PMD_DRV_LOG(INFO, "%s device %s successfully uninitialized",
-			dev->device->driver->name, dev->data->name);
+			RTE_STR(RTE_SZEDATA2_DRIVER_NAME), dev->data->name);
 
 	return 0;
 }
diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
index 036180ff3..5084c645b 100644
--- a/lib/librte_eal/common/include/rte_dev.h
+++ b/lib/librte_eal/common/include/rte_dev.h
@@ -156,7 +156,7 @@ struct rte_driver {
 struct rte_device {
 	TAILQ_ENTRY(rte_device) next; /**< Next device */
 	const char *name;             /**< Device name */
-	const struct rte_driver *driver;/**< Associated driver */
+	const struct rte_driver *driver; /**< Driver assigned after probing */
 	const struct rte_bus *bus;    /**< Bus handle assigned on scan */
 	int numa_node;                /**< NUMA node connection */
 	struct rte_devargs *devargs;  /**< Device user arguments */
-- 
2.19.0

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

* [PATCH v5 6/7] eal: add function to query device status
  2018-10-14 20:47 ` [PATCH v5 0/7] " Thomas Monjalon
                     ` (4 preceding siblings ...)
  2018-10-14 20:47   ` [PATCH v5 5/7] drivers/bus: move driver assignment to end of probing Thomas Monjalon
@ 2018-10-14 20:47   ` Thomas Monjalon
  2018-10-14 20:47   ` [PATCH v5 7/7] eal: allow probing a device again Thomas Monjalon
  2018-10-17 11:37   ` [PATCH v5 0/7] allow hotplug to skip an already probed device Thomas Monjalon
  7 siblings, 0 replies; 58+ messages in thread
From: Thomas Monjalon @ 2018-10-14 20:47 UTC (permalink / raw)
  To: dev; +Cc: gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit

The function rte_dev_is_probed() is added in order to improve semantic
and enforce proper check of the probing status of a device.

It will answer this rte_device query:
Is it already successfully probed or not?

Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
Tested-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/bus/ifpga/ifpga_bus.c           |  4 ++--
 drivers/bus/pci/pci_common.c            |  2 +-
 drivers/bus/vdev/vdev.c                 |  2 +-
 drivers/bus/vmbus/vmbus_common.c        |  2 +-
 lib/librte_eal/common/eal_common_dev.c  |  9 ++++++++-
 lib/librte_eal/common/include/rte_dev.h | 14 ++++++++++++++
 lib/librte_eal/rte_eal_version.map      |  1 +
 7 files changed, 28 insertions(+), 6 deletions(-)

diff --git a/drivers/bus/ifpga/ifpga_bus.c b/drivers/bus/ifpga/ifpga_bus.c
index fca2dbace..2ca1efa72 100644
--- a/drivers/bus/ifpga/ifpga_bus.c
+++ b/drivers/bus/ifpga/ifpga_bus.c
@@ -301,7 +301,7 @@ ifpga_probe_all_drivers(struct rte_afu_device *afu_dev)
 		return -1;
 
 	/* Check if a driver is already loaded */
-	if (afu_dev->device.driver != NULL)
+	if (rte_dev_is_probed(&afu_dev->device))
 		return 0;
 
 	TAILQ_FOREACH(drv, &ifpga_afu_drv_list, next) {
@@ -325,7 +325,7 @@ ifpga_probe(void)
 	int ret = 0;
 
 	TAILQ_FOREACH(afu_dev, &ifpga_afu_dev_list, next) {
-		if (afu_dev->device.driver)
+		if (rte_dev_is_probed(&afu_dev->device))
 			continue;
 
 		ret = ifpga_probe_all_drivers(afu_dev);
diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
index d63e68045..62b17fba9 100644
--- a/drivers/bus/pci/pci_common.c
+++ b/drivers/bus/pci/pci_common.c
@@ -243,7 +243,7 @@ pci_probe_all_drivers(struct rte_pci_device *dev)
 		return -1;
 
 	/* Check if a driver is already loaded */
-	if (dev->device.driver != NULL)
+	if (rte_dev_is_probed(&dev->device))
 		return 0;
 
 	FOREACH_DRIVER_ON_PCIBUS(dr) {
diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
index 3f27f3510..f666099e6 100644
--- a/drivers/bus/vdev/vdev.c
+++ b/drivers/bus/vdev/vdev.c
@@ -481,7 +481,7 @@ vdev_probe(void)
 		 * we call each driver probe.
 		 */
 
-		if (dev->device.driver)
+		if (rte_dev_is_probed(&dev->device))
 			continue;
 
 		if (vdev_probe_all_drivers(dev)) {
diff --git a/drivers/bus/vmbus/vmbus_common.c b/drivers/bus/vmbus/vmbus_common.c
index de5548aa4..48a219f73 100644
--- a/drivers/bus/vmbus/vmbus_common.c
+++ b/drivers/bus/vmbus/vmbus_common.c
@@ -143,7 +143,7 @@ vmbus_probe_all_drivers(struct rte_vmbus_device *dev)
 	int rc;
 
 	/* Check if a driver is already loaded */
-	if (dev->device.driver != NULL) {
+	if (rte_dev_is_probed(&dev->device)) {
 		VMBUS_LOG(DEBUG, "VMBUS driver already loaded");
 		return 0;
 	}
diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c
index 7663eaa3f..7e8a9b260 100644
--- a/lib/librte_eal/common/eal_common_dev.c
+++ b/lib/librte_eal/common/eal_common_dev.c
@@ -74,6 +74,13 @@ static int cmp_dev_name(const struct rte_device *dev, const void *_name)
 	return strcmp(dev->name, name);
 }
 
+int __rte_experimental
+rte_dev_is_probed(const struct rte_device *dev)
+{
+	/* The field driver should be set only when the probe is successful. */
+	return dev->driver != NULL;
+}
+
 int rte_eal_dev_attach(const char *name, const char *devargs)
 {
 	struct rte_bus *bus;
@@ -189,7 +196,7 @@ rte_dev_probe(const char *devargs)
 		goto err_devarg;
 	}
 
-	if (dev->driver != NULL) {
+	if (rte_dev_is_probed(dev)) {
 		RTE_LOG(ERR, EAL, "Device is already plugged\n");
 		return -EEXIST;
 	}
diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
index 5084c645b..9f169e3b3 100644
--- a/lib/librte_eal/common/include/rte_dev.h
+++ b/lib/librte_eal/common/include/rte_dev.h
@@ -162,6 +162,20 @@ struct rte_device {
 	struct rte_devargs *devargs;  /**< Device user arguments */
 };
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change without prior notice
+ *
+ * Query status of a device.
+ *
+ * @param dev
+ *   Generic device pointer.
+ * @return
+ *   (int)true if already probed successfully, 0 otherwise.
+ */
+__rte_experimental
+int rte_dev_is_probed(const struct rte_device *dev);
+
 /**
  * Attach a device to a registered driver.
  *
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
index e968edc2e..e628c3930 100644
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -279,6 +279,7 @@ EXPERIMENTAL {
 	rte_dev_event_callback_unregister;
 	rte_dev_event_monitor_start;
 	rte_dev_event_monitor_stop;
+	rte_dev_is_probed;
 	rte_dev_iterator_init;
 	rte_dev_iterator_next;
 	rte_dev_probe;
-- 
2.19.0

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

* [PATCH v5 7/7] eal: allow probing a device again
  2018-10-14 20:47 ` [PATCH v5 0/7] " Thomas Monjalon
                     ` (5 preceding siblings ...)
  2018-10-14 20:47   ` [PATCH v5 6/7] eal: add function to query device status Thomas Monjalon
@ 2018-10-14 20:47   ` Thomas Monjalon
  2018-10-16 10:40     ` Shreyansh Jain
  2018-10-17 11:37   ` [PATCH v5 0/7] allow hotplug to skip an already probed device Thomas Monjalon
  7 siblings, 1 reply; 58+ messages in thread
From: Thomas Monjalon @ 2018-10-14 20:47 UTC (permalink / raw)
  To: dev; +Cc: gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit

In the devargs syntax for device representors, it is possible to add
several devices at once: -w dbdf,representor=[0-3]
It will become a more frequent case when introducing wildcards
and ranges in the new devargs syntax.

If a devargs string is provided for probing, and updated with a bigger
range for a new probing, then we do not want it to fail because
part of this range was already probed previously.
There can be new ports to create from an existing rte_device.

That's why the check for an already probed device
is moved as bus responsibility.
In the case of vdev, a global check is kept in insert_vdev(),
assuming that a vdev will always have only one port.
In the case of ifpga and vmbus, already probed devices are checked.
In the case of NXP buses, the probing is done only once (no hotplug),
though a check is added at bus level for consistency.
In the case of PCI, a driver flag is added to allow PMD probing again.
Only the PMD knows the ports attached to one rte_device.

As another consequence of being able to probe in several steps,
the field rte_device.devargs must not be considered as a full
representation of the rte_device, but only the latest probing args.
Anyway, the field rte_device.devargs is used only for probing.

Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
Tested-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/bus/dpaa/dpaa_bus.c             |  3 +++
 drivers/bus/fslmc/fslmc_bus.c           |  3 +++
 drivers/bus/ifpga/ifpga_bus.c           | 14 ++++++-----
 drivers/bus/pci/pci_common.c            | 33 ++++++++++++++++---------
 drivers/bus/pci/rte_bus_pci.h           |  4 ++-
 drivers/bus/vdev/vdev.c                 |  5 ++++
 lib/librte_eal/common/eal_common_dev.c  |  7 ++----
 lib/librte_eal/common/include/rte_dev.h |  2 +-
 8 files changed, 47 insertions(+), 24 deletions(-)

diff --git a/drivers/bus/dpaa/dpaa_bus.c b/drivers/bus/dpaa/dpaa_bus.c
index 138e0f98d..89d1e415d 100644
--- a/drivers/bus/dpaa/dpaa_bus.c
+++ b/drivers/bus/dpaa/dpaa_bus.c
@@ -555,6 +555,9 @@ rte_dpaa_bus_probe(void)
 			if (ret)
 				continue;
 
+			if (rte_dev_is_probed(&dev->device))
+				continue;
+
 			if (!drv->probe ||
 			    (dev->device.devargs &&
 			    dev->device.devargs->policy == RTE_DEV_BLACKLISTED))
diff --git a/drivers/bus/fslmc/fslmc_bus.c b/drivers/bus/fslmc/fslmc_bus.c
index 960f55071..7ebd980aa 100644
--- a/drivers/bus/fslmc/fslmc_bus.c
+++ b/drivers/bus/fslmc/fslmc_bus.c
@@ -386,6 +386,9 @@ rte_fslmc_probe(void)
 			if (!drv->probe)
 				continue;
 
+			if (rte_dev_is_probed(&dev->device))
+				continue;
+
 			if (dev->device.devargs &&
 			  dev->device.devargs->policy == RTE_DEV_BLACKLISTED) {
 				DPAA2_BUS_LOG(DEBUG, "%s Blacklisted, skipping",
diff --git a/drivers/bus/ifpga/ifpga_bus.c b/drivers/bus/ifpga/ifpga_bus.c
index 2ca1efa72..5f23ed8b4 100644
--- a/drivers/bus/ifpga/ifpga_bus.c
+++ b/drivers/bus/ifpga/ifpga_bus.c
@@ -301,8 +301,11 @@ ifpga_probe_all_drivers(struct rte_afu_device *afu_dev)
 		return -1;
 
 	/* Check if a driver is already loaded */
-	if (rte_dev_is_probed(&afu_dev->device))
-		return 0;
+	if (rte_dev_is_probed(&afu_dev->device)) {
+		IFPGA_BUS_DEBUG("Device %s is already probed\n",
+				rte_ifpga_device_name(afu_dev));
+		return -EEXIST;
+	}
 
 	TAILQ_FOREACH(drv, &ifpga_afu_drv_list, next) {
 		if (ifpga_probe_one_driver(drv, afu_dev)) {
@@ -325,14 +328,13 @@ ifpga_probe(void)
 	int ret = 0;
 
 	TAILQ_FOREACH(afu_dev, &ifpga_afu_dev_list, next) {
-		if (rte_dev_is_probed(&afu_dev->device))
-			continue;
-
 		ret = ifpga_probe_all_drivers(afu_dev);
+		if (ret == -EEXIST)
+			continue;
 		if (ret < 0)
 			IFPGA_BUS_ERR("failed to initialize %s device\n",
 				rte_ifpga_device_name(afu_dev));
-		}
+	}
 
 	return ret;
 }
diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
index 62b17fba9..11c5da587 100644
--- a/drivers/bus/pci/pci_common.c
+++ b/drivers/bus/pci/pci_common.c
@@ -6,6 +6,7 @@
 #include <string.h>
 #include <inttypes.h>
 #include <stdint.h>
+#include <stdbool.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <sys/queue.h>
@@ -121,6 +122,7 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
 			 struct rte_pci_device *dev)
 {
 	int ret;
+	bool already_probed;
 	struct rte_pci_addr *loc;
 
 	if ((dr == NULL) || (dev == NULL))
@@ -151,6 +153,13 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
 		dev->device.numa_node = 0;
 	}
 
+	already_probed = rte_dev_is_probed(&dev->device);
+	if (already_probed && !(dr->drv_flags & RTE_PCI_DRV_PROBE_AGAIN)) {
+		RTE_LOG(DEBUG, EAL, "Device %s is already probed\n",
+				dev->device.name);
+		return -EEXIST;
+	}
+
 	RTE_LOG(INFO, EAL, "  probe driver: %x:%x %s\n", dev->id.vendor_id,
 		dev->id.device_id, dr->driver.name);
 
@@ -159,9 +168,10 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
 	 * This needs to be before rte_pci_map_device(), as it enables to use
 	 * driver flags for adjusting configuration.
 	 */
-	dev->driver = dr;
+	if (!already_probed)
+		dev->driver = dr;
 
-	if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) {
+	if (!already_probed && (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING)) {
 		/* map resources for devices that use igb_uio */
 		ret = rte_pci_map_device(dev);
 		if (ret != 0) {
@@ -172,6 +182,8 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
 
 	/* call the driver probe() function */
 	ret = dr->probe(dr, dev);
+	if (already_probed)
+		return ret; /* no rollback if already succeeded earlier */
 	if (ret) {
 		dev->driver = NULL;
 		if ((dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) &&
@@ -242,10 +254,6 @@ pci_probe_all_drivers(struct rte_pci_device *dev)
 	if (dev == NULL)
 		return -1;
 
-	/* Check if a driver is already loaded */
-	if (rte_dev_is_probed(&dev->device))
-		return 0;
-
 	FOREACH_DRIVER_ON_PCIBUS(dr) {
 		rc = rte_pci_probe_one_driver(dr, dev);
 		if (rc < 0)
@@ -287,11 +295,14 @@ rte_pci_probe(void)
 			devargs->policy == RTE_DEV_WHITELISTED)
 			ret = pci_probe_all_drivers(dev);
 		if (ret < 0) {
-			RTE_LOG(ERR, EAL, "Requested device " PCI_PRI_FMT
-				 " cannot be used\n", dev->addr.domain, dev->addr.bus,
-				 dev->addr.devid, dev->addr.function);
-			rte_errno = errno;
-			failed++;
+			if (ret != -EEXIST) {
+				RTE_LOG(ERR, EAL, "Requested device "
+					PCI_PRI_FMT " cannot be used\n",
+					dev->addr.domain, dev->addr.bus,
+					dev->addr.devid, dev->addr.function);
+				rte_errno = errno;
+				failed++;
+			}
 			ret = 0;
 		}
 	}
diff --git a/drivers/bus/pci/rte_bus_pci.h b/drivers/bus/pci/rte_bus_pci.h
index 984df2b37..a3baa2895 100644
--- a/drivers/bus/pci/rte_bus_pci.h
+++ b/drivers/bus/pci/rte_bus_pci.h
@@ -121,7 +121,7 @@ struct rte_pci_driver {
 	pci_probe_t *probe;                /**< Device Probe function. */
 	pci_remove_t *remove;              /**< Device Remove function. */
 	const struct rte_pci_id *id_table; /**< ID table, NULL terminated. */
-	uint32_t drv_flags;                /**< Flags contolling handling of device. */
+	uint32_t drv_flags;                /**< Flags RTE_PCI_DRV_*. */
 };
 
 /**
@@ -137,6 +137,8 @@ struct rte_pci_bus {
 #define RTE_PCI_DRV_NEED_MAPPING 0x0001
 /** Device needs PCI BAR mapping with enabled write combining (wc) */
 #define RTE_PCI_DRV_WC_ACTIVATE 0x0002
+/** Device already probed can be probed again to check for new ports. */
+#define RTE_PCI_DRV_PROBE_AGAIN 0x0004
 /** Device driver supports link state interrupt */
 #define RTE_PCI_DRV_INTR_LSC	0x0008
 /** Device driver supports device removal interrupt */
diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
index f666099e6..06f314843 100644
--- a/drivers/bus/vdev/vdev.c
+++ b/drivers/bus/vdev/vdev.c
@@ -226,6 +226,11 @@ insert_vdev(const char *name, const char *args, struct rte_vdev_device **p_dev)
 	dev->device.name = devargs->name;
 
 	if (find_vdev(name)) {
+		/*
+		 * A vdev is expected to have only one port.
+		 * So there is no reason to try probing again,
+		 * even with new arguments.
+		 */
 		ret = -EEXIST;
 		goto fail;
 	}
diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c
index 7e8a9b260..e733eb779 100644
--- a/lib/librte_eal/common/eal_common_dev.c
+++ b/lib/librte_eal/common/eal_common_dev.c
@@ -196,13 +196,10 @@ rte_dev_probe(const char *devargs)
 		goto err_devarg;
 	}
 
-	if (rte_dev_is_probed(dev)) {
-		RTE_LOG(ERR, EAL, "Device is already plugged\n");
-		return -EEXIST;
-	}
-
 	ret = dev->bus->plug(dev);
 	if (ret) {
+		if (rte_dev_is_probed(dev)) /* if already succeeded earlier */
+			return ret; /* no rollback */
 		RTE_LOG(ERR, EAL, "Driver cannot attach the device (%s)\n",
 			dev->name);
 		goto err_devarg;
diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
index 9f169e3b3..a7ec8ec25 100644
--- a/lib/librte_eal/common/include/rte_dev.h
+++ b/lib/librte_eal/common/include/rte_dev.h
@@ -159,7 +159,7 @@ struct rte_device {
 	const struct rte_driver *driver; /**< Driver assigned after probing */
 	const struct rte_bus *bus;    /**< Bus handle assigned on scan */
 	int numa_node;                /**< NUMA node connection */
-	struct rte_devargs *devargs;  /**< Device user arguments */
+	struct rte_devargs *devargs;  /**< Arguments for latest probing */
 };
 
 /**
-- 
2.19.0

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

* Re: [PATCH v5 1/7] net/mlx5: remove useless driver name comparison
  2018-10-14 20:47   ` [PATCH v5 1/7] net/mlx5: remove useless driver name comparison Thomas Monjalon
@ 2018-10-14 20:49     ` Thomas Monjalon
  2018-10-15  5:53       ` Shahaf Shuler
  0 siblings, 1 reply; 58+ messages in thread
From: Thomas Monjalon @ 2018-10-14 20:49 UTC (permalink / raw)
  To: dev
  Cc: gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit, Yongseok Koh, shahafs

+Cc Yongseok and Shahaf

14/10/2018 22:47, Thomas Monjalon:
> The function mlx5_dev_to_port_id() is returning all the ports
> associated to a rte_device.
> It was comparing driver names while already comparing rte_device pointers.
> If two devices are the same, they will have the same driver.
> So the useless driver name comparison is removed.
> 
> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
> ---
>  drivers/net/mlx5/mlx5_ethdev.c | 5 +----
>  1 file changed, 1 insertion(+), 4 deletions(-)
> 
> diff --git a/drivers/net/mlx5/mlx5_ethdev.c b/drivers/net/mlx5/mlx5_ethdev.c
> index 61eda537b..cacdf8e18 100644
> --- a/drivers/net/mlx5/mlx5_ethdev.c
> +++ b/drivers/net/mlx5/mlx5_ethdev.c
> @@ -1305,10 +1305,7 @@ mlx5_dev_to_port_id(const struct rte_device *dev, uint16_t *port_list,
>  	RTE_ETH_FOREACH_DEV(id) {
>  		struct rte_eth_dev *ldev = &rte_eth_devices[id];
>  
> -		if (!ldev->device ||
> -		    !ldev->device->driver ||
> -		    strcmp(ldev->device->driver->name, MLX5_DRIVER_NAME) ||
> -		    ldev->device != dev)
> +		if (ldev->device != dev)
>  			continue;
>  		if (n < port_list_n)
>  			port_list[n] = id;
> 

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

* Re: [PATCH v5 5/7] drivers/bus: move driver assignment to end of probing
  2018-10-14 20:47   ` [PATCH v5 5/7] drivers/bus: move driver assignment to end of probing Thomas Monjalon
@ 2018-10-14 20:53     ` Thomas Monjalon
  2018-10-15  6:11       ` Xu, Rosen
  0 siblings, 1 reply; 58+ messages in thread
From: Thomas Monjalon @ 2018-10-14 20:53 UTC (permalink / raw)
  To: dev
  Cc: gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit, remes,
	beilei.xing, shahafs, yskoh, rosen.xu, stephen

+Cc vmbus, ifpga, i40e, mlx and szedata2 maintainers

14/10/2018 22:47, Thomas Monjalon:
> The PCI mapping requires to know the PCI driver to use,
> even before the probing is done. That's why the PCI driver is
> referenced early inside the PCI device structure. See
> commit 1d20a073fa5e ("bus/pci: reference driver structure before mapping")
> 
> However the rte_driver does not need to be referenced in rte_device
> before the device probing is done.
> By moving back this assignment at the end of the device probing,
> it becomes possible to make clear the status of a rte_device.
> 
> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
> Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
> Tested-by: Andrew Rybchenko <arybchenko@solarflare.com>
> ---
>  drivers/bus/ifpga/ifpga_bus.c           | 9 ++++-----
>  drivers/bus/pci/pci_common.c            | 7 +++----
>  drivers/bus/pci/rte_bus_pci.h           | 2 +-
>  drivers/bus/vdev/vdev.c                 | 5 ++---
>  drivers/bus/vmbus/vmbus_common.c        | 5 +++--
>  drivers/net/i40e/i40e_vf_representor.c  | 3 ---
>  drivers/net/mlx4/mlx4.c                 | 1 -
>  drivers/net/mlx5/mlx5.c                 | 1 -
>  drivers/net/szedata2/rte_eth_szedata2.c | 6 +++---
>  lib/librte_eal/common/include/rte_dev.h | 2 +-
>  10 files changed, 17 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/bus/ifpga/ifpga_bus.c b/drivers/bus/ifpga/ifpga_bus.c
> index 80663328a..fca2dbace 100644
> --- a/drivers/bus/ifpga/ifpga_bus.c
> +++ b/drivers/bus/ifpga/ifpga_bus.c
> @@ -280,14 +280,13 @@ ifpga_probe_one_driver(struct rte_afu_driver *drv,
>  
>  	/* reference driver structure */
>  	afu_dev->driver = drv;
> -	afu_dev->device.driver = &drv->driver;
>  
>  	/* call the driver probe() function */
>  	ret = drv->probe(afu_dev);
> -	if (ret) {
> +	if (ret)
>  		afu_dev->driver = NULL;
> -		afu_dev->device.driver = NULL;
> -	}
> +	else
> +		afu_dev->device.driver = &drv->driver;
>  
>  	return ret;
>  }
> @@ -302,7 +301,7 @@ ifpga_probe_all_drivers(struct rte_afu_device *afu_dev)
>  		return -1;
>  
>  	/* Check if a driver is already loaded */
> -	if (afu_dev->driver != NULL)
> +	if (afu_dev->device.driver != NULL)
>  		return 0;
>  
>  	TAILQ_FOREACH(drv, &ifpga_afu_drv_list, next) {
> diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c
> index c7695d108..d63e68045 100644
> --- a/drivers/bus/pci/pci_common.c
> +++ b/drivers/bus/pci/pci_common.c
> @@ -160,14 +160,12 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
>  	 * driver flags for adjusting configuration.
>  	 */
>  	dev->driver = dr;
> -	dev->device.driver = &dr->driver;
>  
>  	if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) {
>  		/* map resources for devices that use igb_uio */
>  		ret = rte_pci_map_device(dev);
>  		if (ret != 0) {
>  			dev->driver = NULL;
> -			dev->device.driver = NULL;
>  			return ret;
>  		}
>  	}
> @@ -176,7 +174,6 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
>  	ret = dr->probe(dr, dev);
>  	if (ret) {
>  		dev->driver = NULL;
> -		dev->device.driver = NULL;
>  		if ((dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) &&
>  			/* Don't unmap if device is unsupported and
>  			 * driver needs mapped resources.
> @@ -184,6 +181,8 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
>  			!(ret > 0 &&
>  				(dr->drv_flags & RTE_PCI_DRV_KEEP_MAPPED_RES)))
>  			rte_pci_unmap_device(dev);
> +	} else {
> +		dev->device.driver = &dr->driver;
>  	}
>  
>  	return ret;
> @@ -244,7 +243,7 @@ pci_probe_all_drivers(struct rte_pci_device *dev)
>  		return -1;
>  
>  	/* Check if a driver is already loaded */
> -	if (dev->driver != NULL)
> +	if (dev->device.driver != NULL)
>  		return 0;
>  
>  	FOREACH_DRIVER_ON_PCIBUS(dr) {
> diff --git a/drivers/bus/pci/rte_bus_pci.h b/drivers/bus/pci/rte_bus_pci.h
> index 0d1955ffe..984df2b37 100644
> --- a/drivers/bus/pci/rte_bus_pci.h
> +++ b/drivers/bus/pci/rte_bus_pci.h
> @@ -62,7 +62,7 @@ struct rte_pci_device {
>  	struct rte_mem_resource mem_resource[PCI_MAX_RESOURCE];
>  					    /**< PCI Memory Resource */
>  	struct rte_intr_handle intr_handle; /**< Interrupt handle */
> -	struct rte_pci_driver *driver;      /**< Associated driver */
> +	struct rte_pci_driver *driver;      /**< PCI driver used in probing */
>  	uint16_t max_vfs;                   /**< sriov enable if not zero */
>  	enum rte_kernel_driver kdrv;        /**< Kernel driver passthrough */
>  	char name[PCI_PRI_STR_SIZE+1];      /**< PCI location (ASCII) */
> diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c
> index 0142fb2c8..3f27f3510 100644
> --- a/drivers/bus/vdev/vdev.c
> +++ b/drivers/bus/vdev/vdev.c
> @@ -150,10 +150,9 @@ vdev_probe_all_drivers(struct rte_vdev_device *dev)
>  
>  	if (vdev_parse(name, &driver))
>  		return -1;
> -	dev->device.driver = &driver->driver;
>  	ret = driver->probe(dev);
> -	if (ret)
> -		dev->device.driver = NULL;
> +	if (ret == 0)
> +		dev->device.driver = &driver->driver;
>  	return ret;
>  }
>  
> diff --git a/drivers/bus/vmbus/vmbus_common.c b/drivers/bus/vmbus/vmbus_common.c
> index e3ceb6906..de5548aa4 100644
> --- a/drivers/bus/vmbus/vmbus_common.c
> +++ b/drivers/bus/vmbus/vmbus_common.c
> @@ -111,7 +111,6 @@ vmbus_probe_one_driver(struct rte_vmbus_driver *dr,
>  
>  	/* reference driver structure */
>  	dev->driver = dr;
> -	dev->device.driver = &dr->driver;
>  
>  	if (dev->device.numa_node < 0) {
>  		VMBUS_LOG(WARNING, "  Invalid NUMA socket, default to 0");
> @@ -124,6 +123,8 @@ vmbus_probe_one_driver(struct rte_vmbus_driver *dr,
>  	if (ret) {
>  		dev->driver = NULL;
>  		rte_vmbus_unmap_device(dev);
> +	} else {
> +		dev->device.driver = &dr->driver;
>  	}
>  
>  	return ret;
> @@ -142,7 +143,7 @@ vmbus_probe_all_drivers(struct rte_vmbus_device *dev)
>  	int rc;
>  
>  	/* Check if a driver is already loaded */
> -	if (dev->driver != NULL) {
> +	if (dev->device.driver != NULL) {
>  		VMBUS_LOG(DEBUG, "VMBUS driver already loaded");
>  		return 0;
>  	}
> diff --git a/drivers/net/i40e/i40e_vf_representor.c b/drivers/net/i40e/i40e_vf_representor.c
> index 0bfbb4f60..24751d13c 100644
> --- a/drivers/net/i40e/i40e_vf_representor.c
> +++ b/drivers/net/i40e/i40e_vf_representor.c
> @@ -487,9 +487,6 @@ i40e_vf_representor_init(struct rte_eth_dev *ethdev, void *init_params)
>  	if (representor->vf_id >= pf->vf_num)
>  		return -ENODEV;
>  
> -	/** representor shares the same driver as it's PF device */
> -	ethdev->device->driver = representor->adapter->eth_dev->device->driver;
> -
>  	/* Set representor device ops */
>  	ethdev->dev_ops = &i40e_representor_dev_ops;
>  
> diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
> index defc0d4b0..3de7bc53e 100644
> --- a/drivers/net/mlx4/mlx4.c
> +++ b/drivers/net/mlx4/mlx4.c
> @@ -734,7 +734,6 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv, struct rte_pci_device *pci_dev)
>  		eth_dev->data->mac_addrs = priv->mac;
>  		eth_dev->device = &pci_dev->device;
>  		rte_eth_copy_pci_info(eth_dev, pci_dev);
> -		eth_dev->device->driver = &mlx4_driver.driver;
>  		/* Initialize local interrupt handle for current port. */
>  		priv->intr_handle = (struct rte_intr_handle){
>  			.fd = -1,
> diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
> index 795a21977..8cbfee1ba 100644
> --- a/drivers/net/mlx5/mlx5.c
> +++ b/drivers/net/mlx5/mlx5.c
> @@ -1090,7 +1090,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
>  	priv->dev_data = eth_dev->data;
>  	eth_dev->data->mac_addrs = priv->mac;
>  	eth_dev->device = dpdk_dev;
> -	eth_dev->device->driver = &mlx5_driver.driver;
>  	err = mlx5_uar_init_primary(eth_dev);
>  	if (err) {
>  		err = rte_errno;
> diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
> index 8f92e72f2..4e5e01cf1 100644
> --- a/drivers/net/szedata2/rte_eth_szedata2.c
> +++ b/drivers/net/szedata2/rte_eth_szedata2.c
> @@ -1474,7 +1474,7 @@ rte_szedata2_eth_dev_init(struct rte_eth_dev *dev, struct port_info *pi)
>  	PMD_INIT_FUNC_TRACE();
>  
>  	PMD_INIT_LOG(INFO, "Initializing eth_dev %s (driver %s)", data->name,
> -			dev->device->driver->name);
> +			RTE_STR(RTE_SZEDATA2_DRIVER_NAME));
>  
>  	/* Fill internal private structure. */
>  	internals->dev = dev;
> @@ -1525,7 +1525,7 @@ rte_szedata2_eth_dev_init(struct rte_eth_dev *dev, struct port_info *pi)
>  	ether_addr_copy(&eth_addr, data->mac_addrs);
>  
>  	PMD_INIT_LOG(INFO, "%s device %s successfully initialized",
> -			dev->device->driver->name, data->name);
> +			RTE_STR(RTE_SZEDATA2_DRIVER_NAME), data->name);
>  
>  	return 0;
>  }
> @@ -1547,7 +1547,7 @@ rte_szedata2_eth_dev_uninit(struct rte_eth_dev *dev)
>  	rte_free(dev->data->mac_addrs);
>  
>  	PMD_DRV_LOG(INFO, "%s device %s successfully uninitialized",
> -			dev->device->driver->name, dev->data->name);
> +			RTE_STR(RTE_SZEDATA2_DRIVER_NAME), dev->data->name);
>  
>  	return 0;
>  }
> diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
> index 036180ff3..5084c645b 100644
> --- a/lib/librte_eal/common/include/rte_dev.h
> +++ b/lib/librte_eal/common/include/rte_dev.h
> @@ -156,7 +156,7 @@ struct rte_driver {
>  struct rte_device {
>  	TAILQ_ENTRY(rte_device) next; /**< Next device */
>  	const char *name;             /**< Device name */
> -	const struct rte_driver *driver;/**< Associated driver */
> +	const struct rte_driver *driver; /**< Driver assigned after probing */
>  	const struct rte_bus *bus;    /**< Bus handle assigned on scan */
>  	int numa_node;                /**< NUMA node connection */
>  	struct rte_devargs *devargs;  /**< Device user arguments */
> 

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

* Re: [PATCH v5 1/7] net/mlx5: remove useless driver name comparison
  2018-10-14 20:49     ` Thomas Monjalon
@ 2018-10-15  5:53       ` Shahaf Shuler
  0 siblings, 0 replies; 58+ messages in thread
From: Shahaf Shuler @ 2018-10-15  5:53 UTC (permalink / raw)
  To: Thomas Monjalon, dev
  Cc: gaetan.rivet, Ophir Munk, qi.z.zhang, ferruh.yigit, Yongseok Koh

Sunday, October 14, 2018 11:49 PM, Thomas Monjalon:
> 14/10/2018 22:47, Thomas Monjalon:
> > The function mlx5_dev_to_port_id() is returning all the ports
> > associated to a rte_device.
> > It was comparing driver names while already comparing rte_device
> pointers.
> > If two devices are the same, they will have the same driver.
> > So the useless driver name comparison is removed.
> >
> > Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
> > ---
> >  drivers/net/mlx5/mlx5_ethdev.c | 5 +----
> >  1 file changed, 1 insertion(+), 4 deletions(-)
> >
> > diff --git a/drivers/net/mlx5/mlx5_ethdev.c
> > b/drivers/net/mlx5/mlx5_ethdev.c index 61eda537b..cacdf8e18 100644
> > --- a/drivers/net/mlx5/mlx5_ethdev.c
> > +++ b/drivers/net/mlx5/mlx5_ethdev.c
> > @@ -1305,10 +1305,7 @@ mlx5_dev_to_port_id(const struct rte_device
> *dev, uint16_t *port_list,
> >  	RTE_ETH_FOREACH_DEV(id) {
> >  		struct rte_eth_dev *ldev = &rte_eth_devices[id];
> >
> > -		if (!ldev->device ||
> > -		    !ldev->device->driver ||
> > -		    strcmp(ldev->device->driver->name,
> MLX5_DRIVER_NAME) ||
> > -		    ldev->device != dev)
> > +		if (ldev->device != dev)
> >  			continue;
> >  		if (n < port_list_n)
> >  			port_list[n] = id;
> >

Acked-By: Shahaf Shuler <shahafs@mellanox.com>

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

* Re: [PATCH v5 5/7] drivers/bus: move driver assignment to end of probing
  2018-10-14 20:53     ` Thomas Monjalon
@ 2018-10-15  6:11       ` Xu, Rosen
  0 siblings, 0 replies; 58+ messages in thread
From: Xu, Rosen @ 2018-10-15  6:11 UTC (permalink / raw)
  To: Thomas Monjalon, dev
  Cc: gaetan.rivet, ophirmu, Zhang, Qi Z, Yigit, Ferruh, remes, Xing,
	Beilei, shahafs, yskoh, stephen



> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas@monjalon.net]
> Sent: Monday, October 15, 2018 4:54
> To: dev@dpdk.org
> Cc: gaetan.rivet@6wind.com; ophirmu@mellanox.com; Zhang, Qi Z
> <qi.z.zhang@intel.com>; Yigit, Ferruh <ferruh.yigit@intel.com>;
> remes@netcope.com; Xing, Beilei <beilei.xing@intel.com>;
> shahafs@mellanox.com; yskoh@mellanox.com; Xu, Rosen
> <rosen.xu@intel.com>; stephen@networkplumber.org
> Subject: Re: [dpdk-dev] [PATCH v5 5/7] drivers/bus: move driver assignment
> to end of probing
> 
> +Cc vmbus, ifpga, i40e, mlx and szedata2 maintainers
> 
> 14/10/2018 22:47, Thomas Monjalon:
> > The PCI mapping requires to know the PCI driver to use, even before
> > the probing is done. That's why the PCI driver is referenced early
> > inside the PCI device structure. See commit 1d20a073fa5e ("bus/pci:
> > reference driver structure before mapping")
> >
> > However the rte_driver does not need to be referenced in rte_device
> > before the device probing is done.
> > By moving back this assignment at the end of the device probing, it
> > becomes possible to make clear the status of a rte_device.
> >
> > Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
> > Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
> > Tested-by: Andrew Rybchenko <arybchenko@solarflare.com>
> > ---
> >  drivers/bus/ifpga/ifpga_bus.c           | 9 ++++-----
> >  drivers/bus/pci/pci_common.c            | 7 +++----
> >  drivers/bus/pci/rte_bus_pci.h           | 2 +-
> >  drivers/bus/vdev/vdev.c                 | 5 ++---
> >  drivers/bus/vmbus/vmbus_common.c        | 5 +++--
> >  drivers/net/i40e/i40e_vf_representor.c  | 3 ---
> >  drivers/net/mlx4/mlx4.c                 | 1 -
> >  drivers/net/mlx5/mlx5.c                 | 1 -
> >  drivers/net/szedata2/rte_eth_szedata2.c | 6 +++---
> > lib/librte_eal/common/include/rte_dev.h | 2 +-
> >  10 files changed, 17 insertions(+), 24 deletions(-)
> >
> > diff --git a/drivers/bus/ifpga/ifpga_bus.c
> > b/drivers/bus/ifpga/ifpga_bus.c index 80663328a..fca2dbace 100644
> > --- a/drivers/bus/ifpga/ifpga_bus.c
> > +++ b/drivers/bus/ifpga/ifpga_bus.c
> > @@ -280,14 +280,13 @@ ifpga_probe_one_driver(struct rte_afu_driver
> > *drv,
> >
> >  	/* reference driver structure */
> >  	afu_dev->driver = drv;
> > -	afu_dev->device.driver = &drv->driver;
> >
> >  	/* call the driver probe() function */
> >  	ret = drv->probe(afu_dev);
> > -	if (ret) {
> > +	if (ret)
> >  		afu_dev->driver = NULL;
> > -		afu_dev->device.driver = NULL;
> > -	}
> > +	else
> > +		afu_dev->device.driver = &drv->driver;
> >
> >  	return ret;
> >  }
> > @@ -302,7 +301,7 @@ ifpga_probe_all_drivers(struct rte_afu_device
> *afu_dev)
> >  		return -1;
> >
> >  	/* Check if a driver is already loaded */
> > -	if (afu_dev->driver != NULL)
> > +	if (afu_dev->device.driver != NULL)
> >  		return 0;
> >
> >  	TAILQ_FOREACH(drv, &ifpga_afu_drv_list, next) { diff --git

 Reviewed-by: Rosen Xu <rosen.xu@intel.com>

> > a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c index
> > c7695d108..d63e68045 100644
> > --- a/drivers/bus/pci/pci_common.c
> > +++ b/drivers/bus/pci/pci_common.c
> > @@ -160,14 +160,12 @@ rte_pci_probe_one_driver(struct rte_pci_driver
> *dr,
> >  	 * driver flags for adjusting configuration.
> >  	 */
> >  	dev->driver = dr;
> > -	dev->device.driver = &dr->driver;
> >
> >  	if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) {
> >  		/* map resources for devices that use igb_uio */
> >  		ret = rte_pci_map_device(dev);
> >  		if (ret != 0) {
> >  			dev->driver = NULL;
> > -			dev->device.driver = NULL;
> >  			return ret;
> >  		}
> >  	}
> > @@ -176,7 +174,6 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
> >  	ret = dr->probe(dr, dev);
> >  	if (ret) {
> >  		dev->driver = NULL;
> > -		dev->device.driver = NULL;
> >  		if ((dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) &&
> >  			/* Don't unmap if device is unsupported and
> >  			 * driver needs mapped resources.
> > @@ -184,6 +181,8 @@ rte_pci_probe_one_driver(struct rte_pci_driver *dr,
> >  			!(ret > 0 &&
> >  				(dr->drv_flags &
> RTE_PCI_DRV_KEEP_MAPPED_RES)))
> >  			rte_pci_unmap_device(dev);
> > +	} else {
> > +		dev->device.driver = &dr->driver;
> >  	}
> >
> >  	return ret;
> > @@ -244,7 +243,7 @@ pci_probe_all_drivers(struct rte_pci_device *dev)
> >  		return -1;
> >
> >  	/* Check if a driver is already loaded */
> > -	if (dev->driver != NULL)
> > +	if (dev->device.driver != NULL)
> >  		return 0;
> >
> >  	FOREACH_DRIVER_ON_PCIBUS(dr) {
> > diff --git a/drivers/bus/pci/rte_bus_pci.h
> > b/drivers/bus/pci/rte_bus_pci.h index 0d1955ffe..984df2b37 100644
> > --- a/drivers/bus/pci/rte_bus_pci.h
> > +++ b/drivers/bus/pci/rte_bus_pci.h
> > @@ -62,7 +62,7 @@ struct rte_pci_device {
> >  	struct rte_mem_resource mem_resource[PCI_MAX_RESOURCE];
> >  					    /**< PCI Memory Resource */
> >  	struct rte_intr_handle intr_handle; /**< Interrupt handle */
> > -	struct rte_pci_driver *driver;      /**< Associated driver */
> > +	struct rte_pci_driver *driver;      /**< PCI driver used in probing */
> >  	uint16_t max_vfs;                   /**< sriov enable if not zero */
> >  	enum rte_kernel_driver kdrv;        /**< Kernel driver passthrough */
> >  	char name[PCI_PRI_STR_SIZE+1];      /**< PCI location (ASCII) */
> > diff --git a/drivers/bus/vdev/vdev.c b/drivers/bus/vdev/vdev.c index
> > 0142fb2c8..3f27f3510 100644
> > --- a/drivers/bus/vdev/vdev.c
> > +++ b/drivers/bus/vdev/vdev.c
> > @@ -150,10 +150,9 @@ vdev_probe_all_drivers(struct rte_vdev_device
> > *dev)
> >
> >  	if (vdev_parse(name, &driver))
> >  		return -1;
> > -	dev->device.driver = &driver->driver;
> >  	ret = driver->probe(dev);
> > -	if (ret)
> > -		dev->device.driver = NULL;
> > +	if (ret == 0)
> > +		dev->device.driver = &driver->driver;
> >  	return ret;
> >  }
> >
> > diff --git a/drivers/bus/vmbus/vmbus_common.c
> > b/drivers/bus/vmbus/vmbus_common.c
> > index e3ceb6906..de5548aa4 100644
> > --- a/drivers/bus/vmbus/vmbus_common.c
> > +++ b/drivers/bus/vmbus/vmbus_common.c
> > @@ -111,7 +111,6 @@ vmbus_probe_one_driver(struct rte_vmbus_driver
> > *dr,
> >
> >  	/* reference driver structure */
> >  	dev->driver = dr;
> > -	dev->device.driver = &dr->driver;
> >
> >  	if (dev->device.numa_node < 0) {
> >  		VMBUS_LOG(WARNING, "  Invalid NUMA socket, default to
> 0"); @@
> > -124,6 +123,8 @@ vmbus_probe_one_driver(struct rte_vmbus_driver *dr,
> >  	if (ret) {
> >  		dev->driver = NULL;
> >  		rte_vmbus_unmap_device(dev);
> > +	} else {
> > +		dev->device.driver = &dr->driver;
> >  	}
> >
> >  	return ret;
> > @@ -142,7 +143,7 @@ vmbus_probe_all_drivers(struct rte_vmbus_device
> *dev)
> >  	int rc;
> >
> >  	/* Check if a driver is already loaded */
> > -	if (dev->driver != NULL) {
> > +	if (dev->device.driver != NULL) {
> >  		VMBUS_LOG(DEBUG, "VMBUS driver already loaded");
> >  		return 0;
> >  	}
> > diff --git a/drivers/net/i40e/i40e_vf_representor.c
> > b/drivers/net/i40e/i40e_vf_representor.c
> > index 0bfbb4f60..24751d13c 100644
> > --- a/drivers/net/i40e/i40e_vf_representor.c
> > +++ b/drivers/net/i40e/i40e_vf_representor.c
> > @@ -487,9 +487,6 @@ i40e_vf_representor_init(struct rte_eth_dev
> *ethdev, void *init_params)
> >  	if (representor->vf_id >= pf->vf_num)
> >  		return -ENODEV;
> >
> > -	/** representor shares the same driver as it's PF device */
> > -	ethdev->device->driver = representor->adapter->eth_dev->device-
> >driver;
> > -
> >  	/* Set representor device ops */
> >  	ethdev->dev_ops = &i40e_representor_dev_ops;
> >
> > diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c index
> > defc0d4b0..3de7bc53e 100644
> > --- a/drivers/net/mlx4/mlx4.c
> > +++ b/drivers/net/mlx4/mlx4.c
> > @@ -734,7 +734,6 @@ mlx4_pci_probe(struct rte_pci_driver *pci_drv,
> struct rte_pci_device *pci_dev)
> >  		eth_dev->data->mac_addrs = priv->mac;
> >  		eth_dev->device = &pci_dev->device;
> >  		rte_eth_copy_pci_info(eth_dev, pci_dev);
> > -		eth_dev->device->driver = &mlx4_driver.driver;
> >  		/* Initialize local interrupt handle for current port. */
> >  		priv->intr_handle = (struct rte_intr_handle){
> >  			.fd = -1,
> > diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c index
> > 795a21977..8cbfee1ba 100644
> > --- a/drivers/net/mlx5/mlx5.c
> > +++ b/drivers/net/mlx5/mlx5.c
> > @@ -1090,7 +1090,6 @@ mlx5_dev_spawn(struct rte_device *dpdk_dev,
> >  	priv->dev_data = eth_dev->data;
> >  	eth_dev->data->mac_addrs = priv->mac;
> >  	eth_dev->device = dpdk_dev;
> > -	eth_dev->device->driver = &mlx5_driver.driver;
> >  	err = mlx5_uar_init_primary(eth_dev);
> >  	if (err) {
> >  		err = rte_errno;
> > diff --git a/drivers/net/szedata2/rte_eth_szedata2.c
> > b/drivers/net/szedata2/rte_eth_szedata2.c
> > index 8f92e72f2..4e5e01cf1 100644
> > --- a/drivers/net/szedata2/rte_eth_szedata2.c
> > +++ b/drivers/net/szedata2/rte_eth_szedata2.c
> > @@ -1474,7 +1474,7 @@ rte_szedata2_eth_dev_init(struct rte_eth_dev
> *dev, struct port_info *pi)
> >  	PMD_INIT_FUNC_TRACE();
> >
> >  	PMD_INIT_LOG(INFO, "Initializing eth_dev %s (driver %s)", data-
> >name,
> > -			dev->device->driver->name);
> > +			RTE_STR(RTE_SZEDATA2_DRIVER_NAME));
> >
> >  	/* Fill internal private structure. */
> >  	internals->dev = dev;
> > @@ -1525,7 +1525,7 @@ rte_szedata2_eth_dev_init(struct rte_eth_dev
> *dev, struct port_info *pi)
> >  	ether_addr_copy(&eth_addr, data->mac_addrs);
> >
> >  	PMD_INIT_LOG(INFO, "%s device %s successfully initialized",
> > -			dev->device->driver->name, data->name);
> > +			RTE_STR(RTE_SZEDATA2_DRIVER_NAME), data-
> >name);
> >
> >  	return 0;
> >  }
> > @@ -1547,7 +1547,7 @@ rte_szedata2_eth_dev_uninit(struct rte_eth_dev
> *dev)
> >  	rte_free(dev->data->mac_addrs);
> >
> >  	PMD_DRV_LOG(INFO, "%s device %s successfully uninitialized",
> > -			dev->device->driver->name, dev->data->name);
> > +			RTE_STR(RTE_SZEDATA2_DRIVER_NAME), dev->data-
> >name);
> >
> >  	return 0;
> >  }
> > diff --git a/lib/librte_eal/common/include/rte_dev.h
> > b/lib/librte_eal/common/include/rte_dev.h
> > index 036180ff3..5084c645b 100644
> > --- a/lib/librte_eal/common/include/rte_dev.h
> > +++ b/lib/librte_eal/common/include/rte_dev.h
> > @@ -156,7 +156,7 @@ struct rte_driver {  struct rte_device {
> >  	TAILQ_ENTRY(rte_device) next; /**< Next device */
> >  	const char *name;             /**< Device name */
> > -	const struct rte_driver *driver;/**< Associated driver */
> > +	const struct rte_driver *driver; /**< Driver assigned after probing
> > +*/
> >  	const struct rte_bus *bus;    /**< Bus handle assigned on scan */
> >  	int numa_node;                /**< NUMA node connection */
> >  	struct rte_devargs *devargs;  /**< Device user arguments */
> >
> 
> 
> 
> 

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

* Re: [PATCH v5 3/7] cryptodev: remove driver name from logs
  2018-10-14 20:47   ` [PATCH v5 3/7] cryptodev: remove driver name from logs Thomas Monjalon
@ 2018-10-15  8:51     ` Thomas Monjalon
  0 siblings, 0 replies; 58+ messages in thread
From: Thomas Monjalon @ 2018-10-15  8:51 UTC (permalink / raw)
  To: dev; +Cc: gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit, Declan Doherty

+Cc Declan

14/10/2018 22:47, Thomas Monjalon:
> The logs printed by CDEV_LOG_* were prefixed with the driver name.
> 
> In order to avoid assigning the driver before the end of the probing,
> the driver name is removed from the cryptodev library logs.
> 
> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
> ---
>  lib/librte_cryptodev/rte_cryptodev_pmd.c | 23 ++++++++---------------
>  1 file changed, 8 insertions(+), 15 deletions(-)
> 
> diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.c b/lib/librte_cryptodev/rte_cryptodev_pmd.c
> index 2088ac3f3..f03bdbd5e 100644
> --- a/lib/librte_cryptodev/rte_cryptodev_pmd.c
> +++ b/lib/librte_cryptodev/rte_cryptodev_pmd.c
> @@ -93,24 +93,20 @@ rte_cryptodev_pmd_create(const char *name,
>  	struct rte_cryptodev *cryptodev;
>  
>  	if (params->name[0] != '\0') {
> -		CDEV_LOG_INFO("[%s] User specified device name = %s\n",
> -				device->driver->name, params->name);
> +		CDEV_LOG_INFO("User specified device name = %s\n", params->name);
>  		name = params->name;
>  	}
>  
> -	CDEV_LOG_INFO("[%s] - Creating cryptodev %s\n",
> -			device->driver->name, name);
> +	CDEV_LOG_INFO("Creating cryptodev %s\n", name);
>  
> -	CDEV_LOG_INFO("[%s] - Initialisation parameters - name: %s,"
> +	CDEV_LOG_INFO("Initialisation parameters - name: %s,"
>  			"socket id: %d, max queue pairs: %u",
> -			device->driver->name, name,
> -			params->socket_id, params->max_nb_queue_pairs);
> +			name, params->socket_id, params->max_nb_queue_pairs);
>  
>  	/* allocate device structure */
>  	cryptodev = rte_cryptodev_pmd_allocate(name, params->socket_id);
>  	if (cryptodev == NULL) {
> -		CDEV_LOG_ERR("[%s] Failed to allocate crypto device for %s",
> -				device->driver->name, name);
> +		CDEV_LOG_ERR("Failed to allocate crypto device for %s", name);
>  		return NULL;
>  	}
>  
> @@ -123,9 +119,8 @@ rte_cryptodev_pmd_create(const char *name,
>  						params->socket_id);
>  
>  		if (cryptodev->data->dev_private == NULL) {
> -			CDEV_LOG_ERR("[%s] Cannot allocate memory for "
> -					"cryptodev %s private data",
> -					device->driver->name, name);
> +			CDEV_LOG_ERR("Cannot allocate memory for cryptodev %s"
> +					" private data", name);
>  
>  			rte_cryptodev_pmd_release_device(cryptodev);
>  			return NULL;
> @@ -145,9 +140,7 @@ rte_cryptodev_pmd_destroy(struct rte_cryptodev *cryptodev)
>  {
>  	int retval;
>  
> -	CDEV_LOG_INFO("[%s] Closing crypto device %s",
> -			cryptodev->device->driver->name,
> -			cryptodev->device->name);
> +	CDEV_LOG_INFO("Closing crypto device %s", cryptodev->device->name);
>  
>  	/* free crypto device */
>  	retval = rte_cryptodev_pmd_release_device(cryptodev);
> 

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

* Re: [PATCH v5 4/7] compressdev: remove driver name from logs
  2018-10-14 20:47   ` [PATCH v5 4/7] compressdev: " Thomas Monjalon
@ 2018-10-15  8:51     ` Thomas Monjalon
  0 siblings, 0 replies; 58+ messages in thread
From: Thomas Monjalon @ 2018-10-15  8:51 UTC (permalink / raw)
  To: dev
  Cc: gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit, Fiona Trahe,
	Ashish Gupta

+Cc Fiona and Ashish

14/10/2018 22:47, Thomas Monjalon:
> The logs printed by COMPRESSDEV_LOG were prefixed with the driver name.
> 
> In order to avoid assigning the driver before the end of the probing,
> the driver name is removed from the compressdev library logs.
> 
> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
> ---
>  lib/librte_compressdev/rte_compressdev_pmd.c | 23 ++++++++------------
>  1 file changed, 9 insertions(+), 14 deletions(-)
> 
> diff --git a/lib/librte_compressdev/rte_compressdev_pmd.c b/lib/librte_compressdev/rte_compressdev_pmd.c
> index 7de4f339e..95beb26ab 100644
> --- a/lib/librte_compressdev/rte_compressdev_pmd.c
> +++ b/lib/librte_compressdev/rte_compressdev_pmd.c
> @@ -92,24 +92,20 @@ rte_compressdev_pmd_create(const char *name,
>  	struct rte_compressdev *compressdev;
>  
>  	if (params->name[0] != '\0') {
> -		COMPRESSDEV_LOG(INFO, "[%s] User specified device name = %s\n",
> -				device->driver->name, params->name);
> +		COMPRESSDEV_LOG(INFO, "User specified device name = %s\n",
> +				params->name);
>  		name = params->name;
>  	}
>  
> -	COMPRESSDEV_LOG(INFO, "[%s] - Creating compressdev %s\n",
> -			device->driver->name, name);
> +	COMPRESSDEV_LOG(INFO, "Creating compressdev %s\n", name);
>  
> -	COMPRESSDEV_LOG(INFO,
> -	"[%s] - Init parameters - name: %s, socket id: %d",
> -			device->driver->name, name,
> -			params->socket_id);
> +	COMPRESSDEV_LOG(INFO, "Init parameters - name: %s, socket id: %d",
> +			name, params->socket_id);
>  
>  	/* allocate device structure */
>  	compressdev = rte_compressdev_pmd_allocate(name, params->socket_id);
>  	if (compressdev == NULL) {
> -		COMPRESSDEV_LOG(ERR, "[%s] Failed to allocate comp device %s",
> -				device->driver->name, name);
> +		COMPRESSDEV_LOG(ERR, "Failed to allocate comp device %s", name);
>  		return NULL;
>  	}
>  
> @@ -123,8 +119,8 @@ rte_compressdev_pmd_create(const char *name,
>  
>  		if (compressdev->data->dev_private == NULL) {
>  			COMPRESSDEV_LOG(ERR,
> -		"[%s] Cannot allocate memory for compressdev %s private data",
> -					device->driver->name, name);
> +					"Cannot allocate memory for compressdev"
> +					" %s private data", name);
>  
>  			rte_compressdev_pmd_release_device(compressdev);
>  			return NULL;
> @@ -141,8 +137,7 @@ rte_compressdev_pmd_destroy(struct rte_compressdev *compressdev)
>  {
>  	int retval;
>  
> -	COMPRESSDEV_LOG(INFO, "[%s] Closing comp device %s",
> -			compressdev->device->driver->name,
> +	COMPRESSDEV_LOG(INFO, "Closing comp device %s",
>  			compressdev->device->name);
>  
>  	/* free comp device */
> 

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

* Re: [PATCH v5 7/7] eal: allow probing a device again
  2018-10-14 20:47   ` [PATCH v5 7/7] eal: allow probing a device again Thomas Monjalon
@ 2018-10-16 10:40     ` Shreyansh Jain
  0 siblings, 0 replies; 58+ messages in thread
From: Shreyansh Jain @ 2018-10-16 10:40 UTC (permalink / raw)
  To: Thomas Monjalon, dev; +Cc: gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit

On Monday 15 October 2018 02:17 AM, Thomas Monjalon wrote:
> In the devargs syntax for device representors, it is possible to add
> several devices at once: -w dbdf,representor=[0-3]
> It will become a more frequent case when introducing wildcards
> and ranges in the new devargs syntax.
> 
> If a devargs string is provided for probing, and updated with a bigger
> range for a new probing, then we do not want it to fail because
> part of this range was already probed previously.
> There can be new ports to create from an existing rte_device.
> 
> That's why the check for an already probed device
> is moved as bus responsibility.
> In the case of vdev, a global check is kept in insert_vdev(),
> assuming that a vdev will always have only one port.
> In the case of ifpga and vmbus, already probed devices are checked.
> In the case of NXP buses, the probing is done only once (no hotplug),
> though a check is added at bus level for consistency.
> In the case of PCI, a driver flag is added to allow PMD probing again.
> Only the PMD knows the ports attached to one rte_device.
> 
> As another consequence of being able to probe in several steps,
> the field rte_device.devargs must not be considered as a full
> representation of the rte_device, but only the latest probing args.
> Anyway, the field rte_device.devargs is used only for probing.
> 
> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
> Reviewed-by: Andrew Rybchenko <arybchenko@solarflare.com>
> Tested-by: Andrew Rybchenko <arybchenko@solarflare.com>
> ---
>   drivers/bus/dpaa/dpaa_bus.c             |  3 +++
>   drivers/bus/fslmc/fslmc_bus.c           |  3 +++
>   drivers/bus/ifpga/ifpga_bus.c           | 14 ++++++-----
>   drivers/bus/pci/pci_common.c            | 33 ++++++++++++++++---------
>   drivers/bus/pci/rte_bus_pci.h           |  4 ++-
>   drivers/bus/vdev/vdev.c                 |  5 ++++
>   lib/librte_eal/common/eal_common_dev.c  |  7 ++----
>   lib/librte_eal/common/include/rte_dev.h |  2 +-
>   8 files changed, 47 insertions(+), 24 deletions(-)
> 
> diff --git a/drivers/bus/dpaa/dpaa_bus.c b/drivers/bus/dpaa/dpaa_bus.c
> index 138e0f98d..89d1e415d 100644
> --- a/drivers/bus/dpaa/dpaa_bus.c
> +++ b/drivers/bus/dpaa/dpaa_bus.c
> @@ -555,6 +555,9 @@ rte_dpaa_bus_probe(void)
>   			if (ret)
>   				continue;
>   
> +			if (rte_dev_is_probed(&dev->device))
> +				continue;
> +
>   			if (!drv->probe ||
>   			    (dev->device.devargs &&
>   			    dev->device.devargs->policy == RTE_DEV_BLACKLISTED))
> diff --git a/drivers/bus/fslmc/fslmc_bus.c b/drivers/bus/fslmc/fslmc_bus.c
> index 960f55071..7ebd980aa 100644
> --- a/drivers/bus/fslmc/fslmc_bus.c
> +++ b/drivers/bus/fslmc/fslmc_bus.c
> @@ -386,6 +386,9 @@ rte_fslmc_probe(void)
>   			if (!drv->probe)
>   				continue;
>   
> +			if (rte_dev_is_probed(&dev->device))
> +				continue;
> +
>   			if (dev->device.devargs &&
>   			  dev->device.devargs->policy == RTE_DEV_BLACKLISTED) {
>   				DPAA2_BUS_LOG(DEBUG, "%s Blacklisted, skipping",

For the dpaa/fslmc part of this patch:

Acked-by: Shreyansh Jain <shreyansh.jain@nxp.com>

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

* Re: [PATCH v5 0/7] allow hotplug to skip an already probed device
  2018-10-14 20:47 ` [PATCH v5 0/7] " Thomas Monjalon
                     ` (6 preceding siblings ...)
  2018-10-14 20:47   ` [PATCH v5 7/7] eal: allow probing a device again Thomas Monjalon
@ 2018-10-17 11:37   ` Thomas Monjalon
  7 siblings, 0 replies; 58+ messages in thread
From: Thomas Monjalon @ 2018-10-17 11:37 UTC (permalink / raw)
  To: dev; +Cc: gaetan.rivet, ophirmu, qi.z.zhang, ferruh.yigit

14/10/2018 22:47, Thomas Monjalon:
> Thomas Monjalon (7):
>   net/mlx5: remove useless driver name comparison
>   ethdev: rename memzones allocated for DMA
>   cryptodev: remove driver name from logs
>   compressdev: remove driver name from logs
>   drivers/bus: move driver assignment to end of probing
>   eal: add function to query device status
>   eal: allow probing a device again

Applied

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

* Re: [RFC] eal: allow hotplug to skip an already probed device
@ 2018-09-12 22:50 Ophir Munk
  0 siblings, 0 replies; 58+ messages in thread
From: Ophir Munk @ 2018-09-12 22:50 UTC (permalink / raw)
  To: dev, Gaetan Rivet; +Cc: Olga Shern, Thomas Monjalon, Shahaf Shuler, Asaf Penso


> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Thomas Monjalon
> Sent: Saturday, September 08, 2018 12:10 AM
> To: dev@dpdk.org
> Cc: gaetan.rivet@6wind.com
> Subject: [dpdk-dev] [RFC] eal: allow hotplug to skip an already probed 
> device
> 
> In the devargs syntax for device representors, it is possible to add 
> several devices at once: -w dbdf,representor=[0-3] It will become a 
> more frequent case when introducing wildcards and ranges in the new devargs syntax.
> 
> If a devargs string is provided for probing, and updated with a bigger 
> range for a new probing, then we do not want it to fail because part 
> of this range was already probed previously.
> 

When having devargs with representors ("dbdf,representor=<args>") there is actually just one PCI device to probe (whose address is "dbdf", the master) while the representors themselves are net devices all using the same PCI "dbdf" address. 
The way to see it: when running "lspci": only the "dpdf" PCI device appears while when executing "ifconfig" - all representors are shown as net devices.
When calling rte_eal_hotplug_add() for the first time there is a flow which eventually calls the PMD probe callback (e.g. mlx5_pci_probe() in case of mlx5 PMD). 
When calling rte_eal_hotplug_add() for several times we should skip failures till we reach the PMD probe callback.

Skipping failures can done as follows:
1. In file ./lib/librte_eal/common/eal_common_dev.c, function: rte_eal_hotplug_add(), remove the following code:

if (dev->driver != NULL) {
	RTE_LOG(ERR, EAL, "Device is already plugged\n");
	return -EEXIST}

2. In file ./drivers/bus/pci/pci_common.cm function: pci_probe_all_drivers(), remove the following code:

/* Check if a driver is already loaded */
if (dev->driver != NULL)
	return -1;


However the substantial major changes are in each individual PMD probe callback when it is called several times with different devargs. For example it should not fail an already probed PCI device and just create new eth devices for new representors.

> On the opposite, we could require rte_eal_hotplug_add() to try to add
> all matching devices, and fail if one is already probed.
> 
> That's why a new parameter is added to specify if the function must 
> fail or not when trying to add an already probed device.
> 

Please note this new parameter ("fail_existing") will have to be propagated to all PMD probe callbacks.
Otherwise, in case (fail_existing == false) the second call to rte_eal_hotplug_add() will call the PMD probe callback, which may fail unless it is aware of "fail_existing" parameter.
Alternatively "fail_existing" may be better named "enable_multi_probe".
Anyway - if the PMD probe() callback has to be updated to return a success/failure value (for more than one probe) - maybe we do not need a new parameter and can rely on the PMD probe() callback the take the decision by returning success/failure value.

The counter part of rte_eal_hotplug_add() is rte_eal_hotplug_remove() which must be updated as well. For example when representors 1 and 2 exist - then removing just representor 1 will have to make sure that the PCI device used for both representors is not unplugged since representor 2 is not removed and it uses the same PCI device as representor 1. 

> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
> ---
> This patch contains only the change in the function itself as RFC.
> 
> This idea was presented at Dublin during the "hotplug talk".
> ---
>  lib/librte_eal/common/eal_common_dev.c  | 4 +++- 
> lib/librte_eal/common/include/rte_dev.h | 5 ++++-
>  2 files changed, 7 insertions(+), 2 deletions(-)
> 
> diff --git a/lib/librte_eal/common/eal_common_dev.c
> b/lib/librte_eal/common/eal_common_dev.c
> index 678dbcac7..17d7e9089 100644
> --- a/lib/librte_eal/common/eal_common_dev.c
> +++ b/lib/librte_eal/common/eal_common_dev.c
> @@ -128,7 +128,7 @@ int rte_eal_dev_detach(struct rte_device *dev)  }
> 
>  int __rte_experimental rte_eal_hotplug_add(const char *busname, const 
> char *devname,
> -			const char *devargs)
> +			const char *devargs, bool fail_existing)
>  {
>  	struct rte_bus *bus;
>  	struct rte_device *dev;
> @@ -173,6 +173,8 @@ int __rte_experimental rte_eal_hotplug_add(const 
> char *busname, const char *devn
>  	}
> 
>  	if (dev->driver != NULL) {
> +		if (!fail_existing)
> +			return 0;
>  		RTE_LOG(ERR, EAL, "Device is already plugged\n");
>  		return -EEXIST;
>  	}
> diff --git a/lib/librte_eal/common/include/rte_dev.h
> b/lib/librte_eal/common/include/rte_dev.h
> index b80a80598..10a1cd2b4 100644
> --- a/lib/librte_eal/common/include/rte_dev.h
> +++ b/lib/librte_eal/common/include/rte_dev.h
> @@ -201,11 +201,14 @@ int rte_eal_dev_detach(struct rte_device *dev);
>   *   capable of handling it and pass it to the driver probing function.
>   * @param devargs
>   *   Device arguments to be passed to the driver.
> + * @param fail_existing
> + *   If true and a matching device is already probed, then return -EEXIST.
> + *   If false, then skip the already probed device without returning an error.
>   * @return
>   *   0 on success, negative on error.
>   */
>  int __rte_experimental rte_eal_hotplug_add(const char *busname, const 
> char *devname,
> -			const char *devargs);
> +			const char *devargs, bool fail_existing);
> 
>  /**
>   * @warning
> --
> 2.18.0

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

end of thread, other threads:[~2018-10-17 11:37 UTC | newest]

Thread overview: 58+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-09-07 23:09 [RFC] eal: allow hotplug to skip an already probed device Thomas Monjalon
2018-09-13  6:29 ` Ophir Munk
2018-09-16 10:14   ` Ophir Munk
2018-09-28 16:40 ` [PATCH v2 0/3] " Thomas Monjalon
2018-09-28 16:40   ` [PATCH v2 1/3] drivers/bus: move driver assignment to end of probing Thomas Monjalon
2018-09-28 16:40   ` [PATCH v2 2/3] eal: add function to query device status Thomas Monjalon
2018-09-28 16:40   ` [PATCH v2 3/3] eal: allow probing a device again Thomas Monjalon
2018-10-04  9:44     ` Doherty, Declan
2018-10-04 14:25       ` Thomas Monjalon
2018-10-07 22:09 ` [PATCH v3 0/3] eal: allow hotplug to skip an already probed device Thomas Monjalon
2018-10-07 22:09   ` [PATCH v3 1/3] drivers/bus: move driver assignment to end of probing Thomas Monjalon
2018-10-08  8:05     ` Andrew Rybchenko
2018-10-11 10:53     ` Andrew Rybchenko
2018-10-11 11:45       ` Thomas Monjalon
2018-10-11 11:54         ` Andrew Rybchenko
2018-10-11 12:59           ` Thomas Monjalon
2018-10-11 13:15             ` Andrew Rybchenko
2018-10-11 15:29               ` Thomas Monjalon
2018-10-11 15:41                 ` Andrew Rybchenko
2018-10-11 16:00                   ` Thomas Monjalon
2018-10-07 22:09   ` [PATCH v3 2/3] eal: add function to query device status Thomas Monjalon
2018-10-08  8:05     ` Andrew Rybchenko
2018-10-07 22:09   ` [PATCH v3 3/3] eal: allow probing a device again Thomas Monjalon
2018-10-08  8:05     ` Andrew Rybchenko
2018-10-11 21:02 ` [PATCH v4 0/4] eal: allow hotplug to skip an already probed device Thomas Monjalon
2018-10-11 21:02   ` [PATCH v4 1/4] ethdev: rename memzones allocated for DMA Thomas Monjalon
2018-10-12  7:53     ` Andrew Rybchenko
2018-10-12 16:40       ` Thomas Monjalon
2018-10-12 16:42         ` Andrew Rybchenko
2018-10-12 16:46           ` Andrew Rybchenko
2018-10-12 17:18             ` Thomas Monjalon
2018-10-12 17:21               ` Thomas Monjalon
2018-10-12 17:51                 ` Andrew Rybchenko
2018-10-11 21:02   ` [PATCH v4 2/4] drivers/bus: move driver assignment to end of probing Thomas Monjalon
2018-10-12  7:44     ` Andrew Rybchenko
2018-10-12  8:32       ` Jan Remeš
2018-10-12 10:45         ` Thomas Monjalon
2018-10-12 15:50       ` Thomas Monjalon
2018-10-11 21:02   ` [PATCH v4 3/4] eal: add function to query device status Thomas Monjalon
2018-10-11 21:02   ` [PATCH v4 4/4] eal: allow probing a device again Thomas Monjalon
2018-10-12  9:26   ` [PATCH v4 0/4] eal: allow hotplug to skip an already probed device Andrew Rybchenko
2018-10-14 20:47 ` [PATCH v5 0/7] " Thomas Monjalon
2018-10-14 20:47   ` [PATCH v5 1/7] net/mlx5: remove useless driver name comparison Thomas Monjalon
2018-10-14 20:49     ` Thomas Monjalon
2018-10-15  5:53       ` Shahaf Shuler
2018-10-14 20:47   ` [PATCH v5 2/7] ethdev: rename memzones allocated for DMA Thomas Monjalon
2018-10-14 20:47   ` [PATCH v5 3/7] cryptodev: remove driver name from logs Thomas Monjalon
2018-10-15  8:51     ` Thomas Monjalon
2018-10-14 20:47   ` [PATCH v5 4/7] compressdev: " Thomas Monjalon
2018-10-15  8:51     ` Thomas Monjalon
2018-10-14 20:47   ` [PATCH v5 5/7] drivers/bus: move driver assignment to end of probing Thomas Monjalon
2018-10-14 20:53     ` Thomas Monjalon
2018-10-15  6:11       ` Xu, Rosen
2018-10-14 20:47   ` [PATCH v5 6/7] eal: add function to query device status Thomas Monjalon
2018-10-14 20:47   ` [PATCH v5 7/7] eal: allow probing a device again Thomas Monjalon
2018-10-16 10:40     ` Shreyansh Jain
2018-10-17 11:37   ` [PATCH v5 0/7] allow hotplug to skip an already probed device Thomas Monjalon
2018-09-12 22:50 [RFC] eal: " Ophir Munk

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.