[dpdk-dev,3/9] drivers: no more pdev drivers

Message ID 1454076516-21591-4-git-send-email-david.marchand@6wind.com (mailing list archive)
State Changes Requested, archived
Headers

Commit Message

David Marchand Jan. 29, 2016, 2:08 p.m. UTC
  Now that pdev drivers have been converted to pci drivers, there is nothing
left in their init functions that can't go in a constructor.
pdev / vdev drivers init order is changed by this commit, but I can't see
why we would need to preserve it.

Signed-off-by: David Marchand <david.marchand@6wind.com>
---
 drivers/crypto/qat/rte_qat_cryptodev.c | 13 +++---------
 drivers/net/bnx2x/bnx2x_ethdev.c       | 26 +++---------------------
 drivers/net/cxgbe/cxgbe_ethdev.c       | 19 +++---------------
 drivers/net/e1000/em_ethdev.c          | 13 +++---------
 drivers/net/e1000/igb_ethdev.c         | 34 ++++----------------------------
 drivers/net/enic/enic_ethdev.c         | 18 +++--------------
 drivers/net/fm10k/fm10k_ethdev.c       | 19 +++---------------
 drivers/net/i40e/i40e_ethdev.c         | 19 +++---------------
 drivers/net/i40e/i40e_ethdev_vf.c      | 19 +++---------------
 drivers/net/ixgbe/ixgbe_ethdev.c       | 36 +++-------------------------------
 drivers/net/mlx4/mlx4.c                | 19 +++---------------
 drivers/net/mlx5/mlx5.c                | 19 +++---------------
 drivers/net/nfp/nfp_net.c              | 14 +++----------
 drivers/net/virtio/virtio_ethdev.c     | 22 ++++-----------------
 drivers/net/vmxnet3/vmxnet3_ethdev.c   | 18 +++--------------
 15 files changed, 47 insertions(+), 261 deletions(-)
  

Comments

Jan Viktorin Feb. 9, 2016, 5:05 p.m. UTC | #1
Maybe, a better subject?

drivers: init pdev drivers in constructors

On Fri, 29 Jan 2016 15:08:30 +0100
David Marchand <david.marchand@6wind.com> wrote:

> Now that pdev drivers have been converted to pci drivers, there is nothing
> left in their init functions that can't go in a constructor.
> pdev / vdev drivers init order is changed by this commit, but I can't see
> why we would need to preserve it.
> 
> Signed-off-by: David Marchand <david.marchand@6wind.com>
> ---
>  drivers/crypto/qat/rte_qat_cryptodev.c | 13 +++---------
>  drivers/net/bnx2x/bnx2x_ethdev.c       | 26 +++---------------------
>  drivers/net/cxgbe/cxgbe_ethdev.c       | 19 +++---------------
>  drivers/net/e1000/em_ethdev.c          | 13 +++---------
>  drivers/net/e1000/igb_ethdev.c         | 34 ++++----------------------------
>  drivers/net/enic/enic_ethdev.c         | 18 +++--------------
>  drivers/net/fm10k/fm10k_ethdev.c       | 19 +++---------------
>  drivers/net/i40e/i40e_ethdev.c         | 19 +++---------------
>  drivers/net/i40e/i40e_ethdev_vf.c      | 19 +++---------------
>  drivers/net/ixgbe/ixgbe_ethdev.c       | 36 +++-------------------------------
>  drivers/net/mlx4/mlx4.c                | 19 +++---------------
>  drivers/net/mlx5/mlx5.c                | 19 +++---------------
>  drivers/net/nfp/nfp_net.c              | 14 +++----------
>  drivers/net/virtio/virtio_ethdev.c     | 22 ++++-----------------
>  drivers/net/vmxnet3/vmxnet3_ethdev.c   | 18 +++--------------
>  15 files changed, 47 insertions(+), 261 deletions(-)
> 
> diff --git a/drivers/crypto/qat/rte_qat_cryptodev.c b/drivers/crypto/qat/rte_qat_cryptodev.c
> index 6853aee..ded5d60 100644
> --- a/drivers/crypto/qat/rte_qat_cryptodev.c
> +++ b/drivers/crypto/qat/rte_qat_cryptodev.c
> @@ -124,17 +124,10 @@ static struct rte_cryptodev_driver rte_qat_pmd = {
>  	.dev_private_size = sizeof(struct qat_pmd_private),
>  };
>  
> -static int
> -rte_qat_pmd_init(const char *name __rte_unused, const char *params __rte_unused)
> +/* Driver registration */
> +static void __attribute__((constructor, used))
> +rte_qat_pmd_init(void)
>  {
>  	PMD_INIT_FUNC_TRACE();
>  	rte_eal_pci_register(&rte_qat_pmd.pci_drv);
> -	return 0;
>  }
> -
> -static struct rte_driver pmd_qat_drv = {
> -	.type = PMD_PDEV,
> -	.init = rte_qat_pmd_init,
> -};
> -
> -PMD_REGISTER_DRIVER(pmd_qat_drv);

What about introducing a macro for this?

RTE_REGISTER_PCI_DRIVER(rte_qad_pmd);

Regards
Jan
  
David Marchand Feb. 10, 2016, 8:51 a.m. UTC | #2
On Tue, Feb 9, 2016 at 6:05 PM, Jan Viktorin <viktorin@rehivetech.com> wrote:
> Maybe, a better subject?
>
> drivers: init pdev drivers in constructors

Why not, I will try to find a best one, and if I can't, I will go with this.

> On Fri, 29 Jan 2016 15:08:30 +0100
> David Marchand <david.marchand@6wind.com> wrote:
>> -static int
>> -rte_qat_pmd_init(const char *name __rte_unused, const char *params __rte_unused)
>> +/* Driver registration */
>> +static void __attribute__((constructor, used))
>> +rte_qat_pmd_init(void)
>>  {
>>       PMD_INIT_FUNC_TRACE();
>>       rte_eal_pci_register(&rte_qat_pmd.pci_drv);
>> -     return 0;
>>  }
>> -
>> -static struct rte_driver pmd_qat_drv = {
>> -     .type = PMD_PDEV,
>> -     .init = rte_qat_pmd_init,
>> -};
>> -
>> -PMD_REGISTER_DRIVER(pmd_qat_drv);
>
> What about introducing a macro for this?
>
> RTE_REGISTER_PCI_DRIVER(rte_qad_pmd);

Yes.
  
David Marchand Feb. 10, 2016, 9:27 a.m. UTC | #3
On Wed, Feb 10, 2016 at 9:51 AM, David Marchand
<david.marchand@6wind.com> wrote:
> On Tue, Feb 9, 2016 at 6:05 PM, Jan Viktorin <viktorin@rehivetech.com> wrote:
>> What about introducing a macro for this?
>>
>> RTE_REGISTER_PCI_DRIVER(rte_qad_pmd);
>
> Yes.

The only problem here, is that rte_qad_pmd is a crypto structure (same
problem with ethdev), so I can't just pass it to eal.
I can't just pass the pci driver, for the cases where multiple drivers
are registered in a single file (look at ixgbe driver).

So, how about :

In rte_pci.h :

#define RTE_EAL_PCI_REGISTER(name, d)\
void pciinitfn_ ##name(void);\
void __attribute__((constructor, used)) pciinitfn_ ##name(void)\
{\
        rte_eal_pci_register(d);\
}

Then, in qat driver :
RTE_EAL_PCI_REGISTER(qat, &rte_qat_pmd.pci_drv);
  
Jan Viktorin Feb. 10, 2016, 10:20 a.m. UTC | #4
On Wed, 10 Feb 2016 10:27:14 +0100
David Marchand <david.marchand@6wind.com> wrote:

> On Wed, Feb 10, 2016 at 9:51 AM, David Marchand
> <david.marchand@6wind.com> wrote:
> > On Tue, Feb 9, 2016 at 6:05 PM, Jan Viktorin <viktorin@rehivetech.com> wrote:  
> >> What about introducing a macro for this?
> >>
> >> RTE_REGISTER_PCI_DRIVER(rte_qad_pmd);  
> >
> > Yes.  
> 
> The only problem here, is that rte_qad_pmd is a crypto structure (same
> problem with ethdev), so I can't just pass it to eal.
> I can't just pass the pci driver, for the cases where multiple drivers
> are registered in a single file (look at ixgbe driver).
> 
> So, how about :
> 
> In rte_pci.h :
> 
> #define RTE_EAL_PCI_REGISTER(name, d)\
> void pciinitfn_ ##name(void);\
> void __attribute__((constructor, used)) pciinitfn_ ##name(void)\
> {\
>         rte_eal_pci_register(d);\

I meant
	rte_eal_pci_register(&(d)->pci_drv);\

Perhaps, my assumption that a PCI driver is always referred as pci_drv is wrong...

> }
> 
> Then, in qat driver :
> RTE_EAL_PCI_REGISTER(qat, &rte_qat_pmd.pci_drv);
> 

However, I think that this is a detail. Passing rte_pci_driver is good.

Regards
Jan
  
David Marchand Feb. 10, 2016, 11:38 a.m. UTC | #5
On Wed, Feb 10, 2016 at 11:20 AM, Jan Viktorin <viktorin@rehivetech.com> wrote:
> On Wed, 10 Feb 2016 10:27:14 +0100
> David Marchand <david.marchand@6wind.com> wrote:
>> #define RTE_EAL_PCI_REGISTER(name, d)\
>> void pciinitfn_ ##name(void);\
>> void __attribute__((constructor, used)) pciinitfn_ ##name(void)\
>> {\
>>         rte_eal_pci_register(d);\
>
> I meant
>         rte_eal_pci_register(&(d)->pci_drv);\
>
> Perhaps, my assumption that a PCI driver is always referred as pci_drv is wrong...

Well, I suppose we will always have a pci driver embedded in some
other internal pmd structure.
So we can always expect it to be called pci_drv ...

Btw, for drivers like mlx or virtio that need to do some more stuff in
their constructor (the iopl stuff for virtio is the most interesting
case, since the pci register happens only if iopl succeeded), we might
need some RTE_MODULE_INIT for those.

But in such a case, I think having RTE_MODULE_INIT in all pmds would
make more sense, and RTE_EAL_PCI_REGISTER looks unneeded ?
  
Jan Viktorin Feb. 10, 2016, 12:29 p.m. UTC | #6
On Wed, 10 Feb 2016 12:38:20 +0100
David Marchand <david.marchand@6wind.com> wrote:

> On Wed, Feb 10, 2016 at 11:20 AM, Jan Viktorin <viktorin@rehivetech.com> wrote:
> > On Wed, 10 Feb 2016 10:27:14 +0100
> > David Marchand <david.marchand@6wind.com> wrote:  
> >> #define RTE_EAL_PCI_REGISTER(name, d)\
> >> void pciinitfn_ ##name(void);\
> >> void __attribute__((constructor, used)) pciinitfn_ ##name(void)\
> >> {\
> >>         rte_eal_pci_register(d);\  
> >
> > I meant
> >         rte_eal_pci_register(&(d)->pci_drv);\
> >
> > Perhaps, my assumption that a PCI driver is always referred as pci_drv is wrong...  
> 
> Well, I suppose we will always have a pci driver embedded in some
> other internal pmd structure.
> So we can always expect it to be called pci_drv ...
> 
> Btw, for drivers like mlx or virtio that need to do some more stuff in
> their constructor (the iopl stuff for virtio is the most interesting
> case, since the pci register happens only if iopl succeeded), we might
> need some RTE_MODULE_INIT for those.
> 
> But in such a case, I think having RTE_MODULE_INIT in all pmds would
> make more sense, and RTE_EAL_PCI_REGISTER looks unneeded ?
> 

The Linux Kernel solves this by allowing both ways. You can do it by
hand and for most cases you can use just a simple oneliner.

So, we can have the RTE_(EAL_)MODULE_INIT for the general case. And then
eg. RTE_EAL_PCI_MODULE_INIT that makes the most common glue code to
register a single driver and who finally calls the RTE_EAL_MODULE_INIT.

Regards
Jan
  

Patch

diff --git a/drivers/crypto/qat/rte_qat_cryptodev.c b/drivers/crypto/qat/rte_qat_cryptodev.c
index 6853aee..ded5d60 100644
--- a/drivers/crypto/qat/rte_qat_cryptodev.c
+++ b/drivers/crypto/qat/rte_qat_cryptodev.c
@@ -124,17 +124,10 @@  static struct rte_cryptodev_driver rte_qat_pmd = {
 	.dev_private_size = sizeof(struct qat_pmd_private),
 };
 
-static int
-rte_qat_pmd_init(const char *name __rte_unused, const char *params __rte_unused)
+/* Driver registration */
+static void __attribute__((constructor, used))
+rte_qat_pmd_init(void)
 {
 	PMD_INIT_FUNC_TRACE();
 	rte_eal_pci_register(&rte_qat_pmd.pci_drv);
-	return 0;
 }
-
-static struct rte_driver pmd_qat_drv = {
-	.type = PMD_PDEV,
-	.init = rte_qat_pmd_init,
-};
-
-PMD_REGISTER_DRIVER(pmd_qat_drv);
diff --git a/drivers/net/bnx2x/bnx2x_ethdev.c b/drivers/net/bnx2x/bnx2x_ethdev.c
index 916b9da..a4b1599 100644
--- a/drivers/net/bnx2x/bnx2x_ethdev.c
+++ b/drivers/net/bnx2x/bnx2x_ethdev.c
@@ -523,31 +523,11 @@  static struct eth_driver rte_bnx2xvf_pmd = {
 	.dev_private_size = sizeof(struct bnx2x_softc),
 };
 
-static int rte_bnx2x_pmd_init(const char *name __rte_unused,
-			      const char *params __rte_unused)
+/* Driver registration */
+static void __attribute__((constructor, used))
+rte_bnx2x_pmd_init(void)
 {
 	PMD_INIT_FUNC_TRACE();
 	rte_eal_pci_register(&rte_bnx2x_pmd.pci_drv);
-	return 0;
-}
-
-static int rte_bnx2xvf_pmd_init(const char *name __rte_unused,
-				const char *params __rte_unused)
-{
-	PMD_INIT_FUNC_TRACE();
 	rte_eal_pci_register(&rte_bnx2xvf_pmd.pci_drv);
-	return 0;
 }
-
-static struct rte_driver rte_bnx2x_driver = {
-	.type = PMD_PDEV,
-	.init = rte_bnx2x_pmd_init,
-};
-
-static struct rte_driver rte_bnx2xvf_driver = {
-	.type = PMD_PDEV,
-	.init = rte_bnx2xvf_pmd_init,
-};
-
-PMD_REGISTER_DRIVER(rte_bnx2x_driver);
-PMD_REGISTER_DRIVER(rte_bnx2xvf_driver);
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index e425ef2..9654ced 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -858,23 +858,10 @@  static struct eth_driver rte_cxgbe_pmd = {
 	.dev_private_size = sizeof(struct port_info),
 };
 
-/*
- * Driver initialization routine.
- * Invoked once at EAL init time.
- * Register itself as the [Poll Mode] Driver of PCI CXGBE devices.
- */
-static int rte_cxgbe_pmd_init(const char *name __rte_unused,
-			      const char *params __rte_unused)
+/* Driver registration */
+static void __attribute__((constructor, used))
+rte_cxgbe_pmd_init(void)
 {
 	CXGBE_FUNC_TRACE();
 	rte_eal_pci_register(&rte_cxgbe_pmd.pci_drv);
-	return 0;
 }
-
-static struct rte_driver rte_cxgbe_driver = {
-	.name = "cxgbe_driver",
-	.type = PMD_PDEV,
-	.init = rte_cxgbe_pmd_init,
-};
-
-PMD_REGISTER_DRIVER(rte_cxgbe_driver);
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index 973ec97..19b2645 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -348,11 +348,11 @@  static struct eth_driver rte_em_pmd = {
 	.dev_private_size = sizeof(struct e1000_adapter),
 };
 
-static int
-rte_em_pmd_init(const char *name __rte_unused, const char *params __rte_unused)
+/* Driver registration */
+static void __attribute__((constructor, used))
+rte_em_pmd_init(void)
 {
 	rte_eal_pci_register(&rte_em_pmd.pci_drv);
-	return 0;
 }
 
 static int
@@ -1738,10 +1738,3 @@  eth_em_set_mc_addr_list(struct rte_eth_dev *dev,
 	e1000_update_mc_addr_list(hw, (u8 *)mc_addr_set, nb_mc_addr);
 	return 0;
 }
-
-struct rte_driver em_pmd_drv = {
-	.type = PMD_PDEV,
-	.init = rte_em_pmd_init,
-};
-
-PMD_REGISTER_DRIVER(em_pmd_drv);
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index a8d94a4..da63365 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -985,11 +985,12 @@  static struct eth_driver rte_igbvf_pmd = {
 	.dev_private_size = sizeof(struct e1000_adapter),
 };
 
-static int
-rte_igb_pmd_init(const char *name __rte_unused, const char *params __rte_unused)
+/* Driver registration */
+static void __attribute__((constructor, used))
+rte_igb_pmd_init(void)
 {
 	rte_eal_pci_register(&rte_igb_pmd.pci_drv);
-	return 0;
+	rte_eal_pci_register(&rte_igbvf_pmd.pci_drv);
 }
 
 static void
@@ -1003,20 +1004,6 @@  igb_vmdq_vlan_hw_filter_enable(struct rte_eth_dev *dev)
 	E1000_WRITE_REG(hw, E1000_RCTL, rctl);
 }
 
-/*
- * VF Driver initialization routine.
- * Invoked one at EAL init time.
- * Register itself as the [Virtual Poll Mode] Driver of PCI IGB devices.
- */
-static int
-rte_igbvf_pmd_init(const char *name __rte_unused,
-		   const char *params __rte_unused)
-{
-	PMD_INIT_FUNC_TRACE();
-	rte_eal_pci_register(&rte_igbvf_pmd.pci_drv);
-	return 0;
-}
-
 static int
 igb_check_mq_mode(struct rte_eth_dev *dev)
 {
@@ -4696,16 +4683,6 @@  eth_igb_set_eeprom(struct rte_eth_dev *dev,
 	return nvm->ops.write(hw,  first, length, data);
 }
 
-static struct rte_driver pmd_igb_drv = {
-	.type = PMD_PDEV,
-	.init = rte_igb_pmd_init,
-};
-
-static struct rte_driver pmd_igbvf_drv = {
-	.type = PMD_PDEV,
-	.init = rte_igbvf_pmd_init,
-};
-
 static int
 eth_igb_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id)
 {
@@ -4866,6 +4843,3 @@  eth_igb_configure_msix_intr(struct rte_eth_dev *dev)
 
 	E1000_WRITE_FLUSH(hw);
 }
-
-PMD_REGISTER_DRIVER(pmd_igb_drv);
-PMD_REGISTER_DRIVER(pmd_igbvf_drv);
diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index 7678c0a..9f997b1 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -632,22 +632,10 @@  static struct eth_driver rte_enic_pmd = {
 	.dev_private_size = sizeof(struct enic),
 };
 
-/* Driver initialization routine.
- * Invoked once at EAL init time.
- * Register as the [Poll Mode] Driver of Cisco ENIC device.
- */
-static int
-rte_enic_pmd_init(const char *name __rte_unused,
-	const char *params __rte_unused)
+/* Driver registration */
+static void __attribute__((constructor, used))
+rte_enic_pmd_init(void)
 {
 	ENICPMD_FUNC_TRACE();
 	rte_eal_pci_register(&rte_enic_pmd.pci_drv);
-	return 0;
 }
-
-static struct rte_driver rte_enic_driver = {
-	.type = PMD_PDEV,
-	.init = rte_enic_pmd_init,
-};
-
-PMD_REGISTER_DRIVER(rte_enic_driver);
diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index 75537e0..b69fc22 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -2760,23 +2760,10 @@  static struct eth_driver rte_pmd_fm10k = {
 	.dev_private_size = sizeof(struct fm10k_adapter),
 };
 
-/*
- * Driver initialization routine.
- * Invoked once at EAL init time.
- * Register itself as the [Poll Mode] Driver of PCI FM10K devices.
- */
-static int
-rte_pmd_fm10k_init(__rte_unused const char *name,
-	__rte_unused const char *params)
+/* Driver registration */
+static void __attribute__((constructor, used))
+rte_pmd_fm10k_init(void)
 {
 	PMD_INIT_FUNC_TRACE();
 	rte_eal_pci_register(&rte_pmd_fm10k.pci_drv);
-	return 0;
 }
-
-static struct rte_driver rte_fm10k_driver = {
-	.type = PMD_PDEV,
-	.init = rte_pmd_fm10k_init,
-};
-
-PMD_REGISTER_DRIVER(rte_fm10k_driver);
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index ab24115..f47bb4b 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -639,27 +639,14 @@  rte_i40e_dev_atomic_write_link_status(struct rte_eth_dev *dev,
 	return 0;
 }
 
-/*
- * Driver initialization routine.
- * Invoked once at EAL init time.
- * Register itself as the [Poll Mode] Driver of PCI IXGBE devices.
- */
-static int
-rte_i40e_pmd_init(const char *name __rte_unused,
-		  const char *params __rte_unused)
+/* Driver registration */
+static void __attribute__((constructor, used))
+rte_i40e_pmd_init(void)
 {
 	PMD_INIT_FUNC_TRACE();
 	rte_eal_pci_register(&rte_i40e_pmd.pci_drv);
-	return 0;
 }
 
-static struct rte_driver rte_i40e_driver = {
-	.type = PMD_PDEV,
-	.init = rte_i40e_pmd_init,
-};
-
-PMD_REGISTER_DRIVER(rte_i40e_driver);
-
 /*
  * Initialize registers for flexible payload, which should be set by NVM.
  * This should be removed from code once it is fixed in NVM.
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index 050d7ea..2e11ff9 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -1374,27 +1374,14 @@  static struct eth_driver rte_i40evf_pmd = {
 	.dev_private_size = sizeof(struct i40e_adapter),
 };
 
-/*
- * VF Driver initialization routine.
- * Invoked one at EAL init time.
- * Register itself as the [Virtual Poll Mode] Driver of PCI Fortville devices.
- */
-static int
-rte_i40evf_pmd_init(const char *name __rte_unused,
-		    const char *params __rte_unused)
+/* Driver registration */
+static void __attribute__((constructor, used))
+rte_i40evf_pmd_init(void)
 {
 	PMD_INIT_FUNC_TRACE();
 	rte_eal_pci_register(&rte_i40evf_pmd.pci_drv);
-	return 0;
 }
 
-static struct rte_driver rte_i40evf_driver = {
-	.type = PMD_PDEV,
-	.init = rte_i40evf_pmd_init,
-};
-
-PMD_REGISTER_DRIVER(rte_i40evf_driver);
-
 static int
 i40evf_dev_configure(struct rte_eth_dev *dev)
 {
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index 970528e..9f29525 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -1457,30 +1457,13 @@  static struct eth_driver rte_ixgbevf_pmd = {
 	.dev_private_size = sizeof(struct ixgbe_adapter),
 };
 
-/*
- * Driver initialization routine.
- * Invoked once at EAL init time.
- * Register itself as the [Poll Mode] Driver of PCI IXGBE devices.
- */
-static int
-rte_ixgbe_pmd_init(const char *name __rte_unused, const char *params __rte_unused)
+/* Driver registration */
+static void __attribute__((constructor, used))
+rte_ixgbe_pmd_init(void)
 {
 	PMD_INIT_FUNC_TRACE();
 	rte_eal_pci_register(&rte_ixgbe_pmd.pci_drv);
-	return 0;
-}
-
-/*
- * VF Driver initialization routine.
- * Invoked one at EAL init time.
- * Register itself as the [Virtual Poll Mode] Driver of PCI niantic devices.
- */
-static int
-rte_ixgbevf_pmd_init(const char *name __rte_unused, const char *param __rte_unused)
-{
-	PMD_INIT_FUNC_TRACE();
 	rte_eal_pci_register(&rte_ixgbevf_pmd.pci_drv);
-	return (0);
 }
 
 static int
@@ -6192,16 +6175,3 @@  ixgbe_dev_get_dcb_info(struct rte_eth_dev *dev,
 	}
 	return 0;
 }
-
-static struct rte_driver rte_ixgbe_driver = {
-	.type = PMD_PDEV,
-	.init = rte_ixgbe_pmd_init,
-};
-
-static struct rte_driver rte_ixgbevf_driver = {
-	.type = PMD_PDEV,
-	.init = rte_ixgbevf_pmd_init,
-};
-
-PMD_REGISTER_DRIVER(rte_ixgbe_driver);
-PMD_REGISTER_DRIVER(rte_ixgbevf_driver);
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index 207bfe2..bd223c0 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -5677,14 +5677,10 @@  static struct eth_driver mlx4_driver = {
 	.dev_private_size = sizeof(struct priv)
 };
 
-/**
- * Driver initialization routine.
- */
-static int
-rte_mlx4_pmd_init(const char *name, const char *args)
+/* Driver registration */
+static void __attribute__((constructor, used))
+rte_mlx4_pmd_init(void)
 {
-	(void)name;
-	(void)args;
 	/*
 	 * RDMAV_HUGEPAGES_SAFE tells ibv_fork_init() we intend to use
 	 * huge pages. Calling ibv_fork_init() during init allows
@@ -5694,13 +5690,4 @@  rte_mlx4_pmd_init(const char *name, const char *args)
 	setenv("RDMAV_HUGEPAGES_SAFE", "1", 1);
 	ibv_fork_init();
 	rte_eal_pci_register(&mlx4_driver.pci_drv);
-	return 0;
 }
-
-static struct rte_driver rte_mlx4_driver = {
-	.type = PMD_PDEV,
-	.name = MLX4_DRIVER_NAME,
-	.init = rte_mlx4_pmd_init,
-};
-
-PMD_REGISTER_DRIVER(rte_mlx4_driver)
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 821ee0f..8d23068 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -542,14 +542,10 @@  static struct eth_driver mlx5_driver = {
 	.dev_private_size = sizeof(struct priv)
 };
 
-/**
- * Driver initialization routine.
- */
-static int
-rte_mlx5_pmd_init(const char *name, const char *args)
+/* Driver registration */
+static void __attribute__((constructor, used))
+rte_mlx5_pmd_init(void)
 {
-	(void)name;
-	(void)args;
 	/*
 	 * RDMAV_HUGEPAGES_SAFE tells ibv_fork_init() we intend to use
 	 * huge pages. Calling ibv_fork_init() during init allows
@@ -559,13 +555,4 @@  rte_mlx5_pmd_init(const char *name, const char *args)
 	setenv("RDMAV_HUGEPAGES_SAFE", "1", 1);
 	ibv_fork_init();
 	rte_eal_pci_register(&mlx5_driver.pci_drv);
-	return 0;
 }
-
-static struct rte_driver rte_mlx5_driver = {
-	.type = PMD_PDEV,
-	.name = MLX5_DRIVER_NAME,
-	.init = rte_mlx5_pmd_init,
-};
-
-PMD_REGISTER_DRIVER(rte_mlx5_driver)
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index 89ba703..6e4bc16 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -2474,24 +2474,16 @@  static struct eth_driver rte_nfp_net_pmd = {
 	.dev_private_size = sizeof(struct nfp_net_adapter),
 };
 
-static int
-nfp_net_pmd_init(const char *name __rte_unused,
-		 const char *params __rte_unused)
+/* Driver registration */
+static void __attribute__((constructor, used))
+nfp_net_pmd_init(void)
 {
 	PMD_INIT_FUNC_TRACE();
 	PMD_INIT_LOG(INFO, "librte_pmd_nfp_net version %s\n",
 		     NFP_NET_PMD_VERSION);
 	rte_eal_pci_register(&rte_nfp_net_pmd.pci_drv);
-	return 0;
 }
 
-static struct rte_driver rte_nfp_net_driver = {
-	.type = PMD_PDEV,
-	.init = nfp_net_pmd_init,
-};
-
-PMD_REGISTER_DRIVER(rte_nfp_net_driver);
-
 /*
  * Local variables:
  * c-file-style: "Linux"
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 08f386a..e44411e 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1447,23 +1447,16 @@  static struct eth_driver rte_virtio_pmd = {
 	.dev_private_size = sizeof(struct virtio_hw),
 };
 
-/*
- * Driver initialization routine.
- * Invoked once at EAL init time.
- * Register itself as the [Poll Mode] Driver of PCI virtio devices.
- * Returns 0 on success.
- */
-static int
-rte_virtio_pmd_init(const char *name __rte_unused,
-		    const char *param __rte_unused)
+/* Driver registration */
+static void __attribute__((constructor, used))
+rte_virtio_pmd_init(void)
 {
 	if (rte_eal_iopl_init() != 0) {
 		PMD_INIT_LOG(ERR, "IOPL call failed - cannot use virtio PMD");
-		return -1;
+		return;
 	}
 
 	rte_eal_pci_register(&rte_virtio_pmd.pci_drv);
-	return 0;
 }
 
 /*
@@ -1684,10 +1677,3 @@  __rte_unused uint8_t is_rx)
 {
 	return 0;
 }
-
-static struct rte_driver rte_virtio_driver = {
-	.type = PMD_PDEV,
-	.init = rte_virtio_pmd_init,
-};
-
-PMD_REGISTER_DRIVER(rte_virtio_driver);
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index 1a3bc66..a065610 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -333,17 +333,12 @@  static struct eth_driver rte_vmxnet3_pmd = {
 	.dev_private_size = sizeof(struct vmxnet3_hw),
 };
 
-/*
- * Driver initialization routine.
- * Invoked once at EAL init time.
- * Register itself as the [Poll Mode] Driver of Virtual PCI VMXNET3 devices.
- */
-static int
-rte_vmxnet3_pmd_init(const char *name __rte_unused, const char *param __rte_unused)
+/* Driver registration */
+static void __attribute__((constructor, used))
+rte_vmxnet3_pmd_init(void)
 {
 	PMD_INIT_FUNC_TRACE();
 	rte_eal_pci_register(&rte_vmxnet3_pmd.pci_drv);
-	return 0;
 }
 
 static int
@@ -922,10 +917,3 @@  vmxnet3_process_events(struct vmxnet3_hw *hw)
 
 }
 #endif
-
-static struct rte_driver rte_vmxnet3_driver = {
-	.type = PMD_PDEV,
-	.init = rte_vmxnet3_pmd_init,
-};
-
-PMD_REGISTER_DRIVER(rte_vmxnet3_driver);