* Re: [PATCH v2 25/32] app/testpmd: handle i40e in VF VLAN filter command
From: Ferruh Yigit @ 2016-12-13 13:40 UTC (permalink / raw)
To: Wenzhuo Lu, dev; +Cc: Bernard Iremonger
In-Reply-To: <1481081535-37448-26-git-send-email-wenzhuo.lu@intel.com>
Hi Wenzhuo,
On 12/7/2016 3:32 AM, Wenzhuo Lu wrote:
> modify set_vf_rx_vlan function to handle the i40e PMD.
>
> Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
> ---
Latest applied patches [1] conflict with some testpmd patches of this
patchset.
Can you please rebase this patchset on top of the latest next-net?
[1]
http://dpdk.org/dev/patchwork/patch/17896 - 17902
Thanks,
ferruh
> app/test-pmd/config.c | 17 ++++++++++++++++-
> 1 file changed, 16 insertions(+), 1 deletion(-)
>
> diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
> index 36c47ab..0368dc6 100644
> --- a/app/test-pmd/config.c
> +++ b/app/test-pmd/config.c
> @@ -92,6 +92,9 @@
> #include <rte_ethdev.h>
> #include <rte_string_fns.h>
> #include <rte_cycles.h>
> +#ifdef RTE_LIBRTE_I40E_PMD
> +#include <rte_pmd_i40e.h>
> +#endif
>
> #include "testpmd.h"
>
> @@ -2349,12 +2352,24 @@ struct igb_ring_desc_16_bytes {
> set_vf_rx_vlan(portid_t port_id, uint16_t vlan_id, uint64_t vf_mask, uint8_t on)
> {
> int diag;
> + struct rte_eth_dev_info dev_info;
>
> if (port_id_is_invalid(port_id, ENABLED_WARN))
> return;
> if (vlan_id_is_invalid(vlan_id))
> return;
> - diag = rte_eth_dev_set_vf_vlan_filter(port_id, vlan_id, vf_mask, on);
> +
> + rte_eth_dev_info_get(port_id, &dev_info);
> +
> +#ifdef RTE_LIBRTE_I40E_PMD
> + if (strstr(dev_info.driver_name, "i40e") != NULL)
> + diag = rte_pmd_i40e_set_vf_vlan_filter(port_id, vlan_id,
> + vf_mask, on);
> + else
> +#endif
> + diag = rte_eth_dev_set_vf_vlan_filter(port_id, vlan_id,
> + vf_mask, on);
> +
> if (diag == 0)
> return;
> printf("rte_eth_dev_set_vf_vlan_filter for port_id=%d failed "
>
^ permalink raw reply
* [PATCH] doc: fix environment variable typo
From: Baruch Siach @ 2016-12-13 13:40 UTC (permalink / raw)
To: dev; +Cc: John McNamara, Remy Horton, Baruch Siach
Signed-off-by: Baruch Siach <baruch@tkos.co.il>
---
doc/guides/sample_app_ug/ethtool.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/doc/guides/sample_app_ug/ethtool.rst b/doc/guides/sample_app_ug/ethtool.rst
index 4d1697e8a050..67797954d740 100644
--- a/doc/guides/sample_app_ug/ethtool.rst
+++ b/doc/guides/sample_app_ug/ethtool.rst
@@ -47,7 +47,7 @@ To compile the application:
.. code-block:: console
export RTE_SDK=/path/to/rte_sdk
- cd ${RTE_SD}/examples/ethtool
+ cd ${RTE_SDK}/examples/ethtool
#. Set the target (a default target is used if not specified). For example:
--
2.10.2
^ permalink raw reply related
* Re: [PATCH v4 0/7] net/ixgbe: move set VF functions.
From: Ferruh Yigit @ 2016-12-13 13:36 UTC (permalink / raw)
To: Bernard Iremonger, thomas.monjalon, dev
In-Reply-To: <1481629241-19500-1-git-send-email-bernard.iremonger@intel.com>
On 12/13/2016 11:40 AM, Bernard Iremonger wrote:
> This patchset implements the following deprecation notice:
> [PATCH v1] doc: announce API and ABI change for librte_ether
>
> Changes in V4:
> Fixed compile issues when ixgbe PMD is not present.
> Removed duplicate testpmd commands.
> Added cleanup patch for testpmd.
> Updated release note.
>
> Changes in V3:
> Updated LIBABIVER in Makefile in librte_ether patch.
> Updated rte_ethdev.h and ret_ether_version.map in librte_ether patch.
> Squashed deprecation notice patch into librte_ether patch.
> Added release_note patch.
>
> Changes in V2:
> Update testpmd set vf commands help messages.
> Updated ethtool to use the ixgbe public API's.
> Removed the ixgbe_set_pool_* and ixgbe_set_vf_rate_limit functions.
> Removed the rte_eth_dev_set_vf_* API's
> Removed the deprecation notice.
>
> Changes in V1:
> The following functions from eth_dev_ops have been moved to the ixgbe PMD
> and renamed:
>
> ixgbe_set_pool_rx_mode
> ixgbe_set_pool_rx
> ixgbe_set_pool_tx
> ixgbe_set_pool_vlan_filter
> ixgbe_set_vf_rate_limit
>
> Renamed the functions to the following:
>
> rte_pmd_ixgbe_set_vf_rxmode
> rte_pmd_ixgbe_set_vf_rx
> rte_pmd_ixgbe_set_vf_tx
> rte_pmd_ixgbe_set_vf_vlan_filter
> rte_pmd_ixgbe_set_vf_rate_limit
>
> Testpmd has been modified to use the following functions:
> rte_pmd_ixgbe_set_vf_rxmode
> rte_pmd_ixgbe_set_vf_rate_limit
>
> New testpmd commands have been added to test the following functions:
> rte_pmd_ixgbe_set_vf_rx
> rte_pmd_ixgbe_set_vf_tx
> rte_pmd_ixgbe_set_vf_vlan_filter
>
> The testpmd user guide has been updated for the new commands.
>
> Bernard Iremonger (7):
> net/ixgbe: move set VF functions from the ethdev
> app/testpmd: use ixgbe public functions
> app/testpmd: cleanup parameter checking
> examples/ethtool: use ixgbe public function
> net/ixgbe: remove static set VF functions
> librte_ether: remove the set VF API's
> doc: update release notes
>
Series applied to dpdk-next-net/master, thanks.
Last patch squashed.
^ permalink raw reply
* [PATCH v2 12/12] drivers: update PMDs to use rte_driver probe and remove
From: Shreyansh Jain @ 2016-12-13 13:37 UTC (permalink / raw)
To: dev, david.marchand
Cc: thomas.monjalon, ferruh.yigit, jianbo.liu, Shreyansh Jain
In-Reply-To: <1481636232-2300-1-git-send-email-shreyansh.jain@nxp.com>
These callbacks now act as first layer of PCI interfaces from the Bus.
Bus probe would enter the PMDs through the rte_driver->probe/remove
callbacks, falling to rte_xxx_driver->probe/remove (Currently, all the
drivers are rte_pci_driver).
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
drivers/net/bnx2x/bnx2x_ethdev.c | 8 ++++++++
drivers/net/bnxt/bnxt_ethdev.c | 4 ++++
drivers/net/cxgbe/cxgbe_ethdev.c | 4 ++++
drivers/net/e1000/em_ethdev.c | 4 ++++
drivers/net/e1000/igb_ethdev.c | 8 ++++++++
drivers/net/ena/ena_ethdev.c | 4 ++++
drivers/net/enic/enic_ethdev.c | 4 ++++
drivers/net/fm10k/fm10k_ethdev.c | 4 ++++
drivers/net/i40e/i40e_ethdev.c | 4 ++++
drivers/net/i40e/i40e_ethdev_vf.c | 4 ++++
drivers/net/ixgbe/ixgbe_ethdev.c | 8 ++++++++
drivers/net/mlx4/mlx4.c | 4 +++-
drivers/net/mlx5/mlx5.c | 1 +
drivers/net/nfp/nfp_net.c | 4 ++++
drivers/net/qede/qede_ethdev.c | 8 ++++++++
drivers/net/szedata2/rte_eth_szedata2.c | 4 ++++
drivers/net/thunderx/nicvf_ethdev.c | 4 ++++
drivers/net/virtio/virtio_ethdev.c | 2 ++
drivers/net/vmxnet3/vmxnet3_ethdev.c | 4 ++++
19 files changed, 86 insertions(+), 1 deletion(-)
diff --git a/drivers/net/bnx2x/bnx2x_ethdev.c b/drivers/net/bnx2x/bnx2x_ethdev.c
index 0eae433..9f3b3f2 100644
--- a/drivers/net/bnx2x/bnx2x_ethdev.c
+++ b/drivers/net/bnx2x/bnx2x_ethdev.c
@@ -618,6 +618,10 @@ eth_bnx2xvf_dev_init(struct rte_eth_dev *eth_dev)
static struct eth_driver rte_bnx2x_pmd = {
.pci_drv = {
+ .driver = {
+ .probe = rte_eal_pci_probe,
+ .remove = rte_eal_pci_remove,
+ },
.id_table = pci_id_bnx2x_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
.probe = rte_eth_dev_pci_probe,
@@ -632,6 +636,10 @@ static struct eth_driver rte_bnx2x_pmd = {
*/
static struct eth_driver rte_bnx2xvf_pmd = {
.pci_drv = {
+ .driver = {
+ .probe = rte_eal_pci_probe,
+ .remove = rte_eal_pci_remove,
+ },
.id_table = pci_id_bnx2xvf_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING,
.probe = rte_eth_dev_pci_probe,
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 035fe07..c8671c8 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -1160,6 +1160,10 @@ bnxt_dev_uninit(struct rte_eth_dev *eth_dev) {
static struct eth_driver bnxt_rte_pmd = {
.pci_drv = {
+ .driver = {
+ .probe = rte_eal_pci_probe,
+ .remove = rte_eal_pci_remove,
+ },
.id_table = bnxt_pci_id_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING |
RTE_PCI_DRV_DETACHABLE | RTE_PCI_DRV_INTR_LSC,
diff --git a/drivers/net/cxgbe/cxgbe_ethdev.c b/drivers/net/cxgbe/cxgbe_ethdev.c
index b7f28eb..67714fa 100644
--- a/drivers/net/cxgbe/cxgbe_ethdev.c
+++ b/drivers/net/cxgbe/cxgbe_ethdev.c
@@ -1039,6 +1039,10 @@ static int eth_cxgbe_dev_init(struct rte_eth_dev *eth_dev)
static struct eth_driver rte_cxgbe_pmd = {
.pci_drv = {
+ .driver = {
+ .probe = rte_eal_pci_probe,
+ .remove = rte_eal_pci_remove,
+ },
.id_table = cxgb4_pci_tbl,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
.probe = rte_eth_dev_pci_probe,
diff --git a/drivers/net/e1000/em_ethdev.c b/drivers/net/e1000/em_ethdev.c
index aee3d34..7be5da3 100644
--- a/drivers/net/e1000/em_ethdev.c
+++ b/drivers/net/e1000/em_ethdev.c
@@ -391,6 +391,10 @@ eth_em_dev_uninit(struct rte_eth_dev *eth_dev)
static struct eth_driver rte_em_pmd = {
.pci_drv = {
+ .driver = {
+ .probe = rte_eal_pci_probe,
+ .remove = rte_eal_pci_remove,
+ },
.id_table = pci_id_em_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC |
RTE_PCI_DRV_DETACHABLE,
diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index 2fddf0c..70dd24c 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -1078,6 +1078,10 @@ eth_igbvf_dev_uninit(struct rte_eth_dev *eth_dev)
static struct eth_driver rte_igb_pmd = {
.pci_drv = {
+ .driver = {
+ .probe = rte_eal_pci_probe,
+ .remove = rte_eal_pci_remove,
+ },
.id_table = pci_id_igb_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC |
RTE_PCI_DRV_DETACHABLE,
@@ -1094,6 +1098,10 @@ static struct eth_driver rte_igb_pmd = {
*/
static struct eth_driver rte_igbvf_pmd = {
.pci_drv = {
+ .driver = {
+ .probe = rte_eal_pci_probe,
+ .remove = rte_eal_pci_remove,
+ },
.id_table = pci_id_igbvf_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_DETACHABLE,
.probe = rte_eth_dev_pci_probe,
diff --git a/drivers/net/ena/ena_ethdev.c b/drivers/net/ena/ena_ethdev.c
index ab9a178..54fc8de 100644
--- a/drivers/net/ena/ena_ethdev.c
+++ b/drivers/net/ena/ena_ethdev.c
@@ -1705,6 +1705,10 @@ static uint16_t eth_ena_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
static struct eth_driver rte_ena_pmd = {
.pci_drv = {
+ .driver = {
+ .probe = rte_eal_pci_probe,
+ .remove = rte_eal_pci_remove,
+ },
.id_table = pci_id_ena_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING,
.probe = rte_eth_dev_pci_probe,
diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c
index 2b154ec..c2783db 100644
--- a/drivers/net/enic/enic_ethdev.c
+++ b/drivers/net/enic/enic_ethdev.c
@@ -634,6 +634,10 @@ static int eth_enicpmd_dev_init(struct rte_eth_dev *eth_dev)
static struct eth_driver rte_enic_pmd = {
.pci_drv = {
+ .driver = {
+ .probe = rte_eal_pci_probe,
+ .remove = rte_eal_pci_remove,
+ },
.id_table = pci_id_enic_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
.probe = rte_eth_dev_pci_probe,
diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index 923690c..d1a2efa 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -3061,6 +3061,10 @@ static const struct rte_pci_id pci_id_fm10k_map[] = {
static struct eth_driver rte_pmd_fm10k = {
.pci_drv = {
+ .driver = {
+ .probe = rte_eal_pci_probe,
+ .remove = rte_eal_pci_remove,
+ },
.id_table = pci_id_fm10k_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC |
RTE_PCI_DRV_DETACHABLE,
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 67778ba..9c5d50f 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -670,6 +670,10 @@ static const struct rte_i40e_xstats_name_off rte_i40e_txq_prio_strings[] = {
static struct eth_driver rte_i40e_pmd = {
.pci_drv = {
+ .driver = {
+ .probe = rte_eal_pci_probe,
+ .remove = rte_eal_pci_remove,
+ },
.id_table = pci_id_i40e_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC |
RTE_PCI_DRV_DETACHABLE,
diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c
index aa306d6..10bf6ab 100644
--- a/drivers/net/i40e/i40e_ethdev_vf.c
+++ b/drivers/net/i40e/i40e_ethdev_vf.c
@@ -1527,6 +1527,10 @@ i40evf_dev_uninit(struct rte_eth_dev *eth_dev)
*/
static struct eth_driver rte_i40evf_pmd = {
.pci_drv = {
+ .driver = {
+ .probe = rte_eal_pci_probe,
+ .remove = rte_eal_pci_remove,
+ },
.id_table = pci_id_i40evf_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_DETACHABLE,
.probe = rte_eth_dev_pci_probe,
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index edc9b22..80ee232 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -1564,6 +1564,10 @@ eth_ixgbevf_dev_uninit(struct rte_eth_dev *eth_dev)
static struct eth_driver rte_ixgbe_pmd = {
.pci_drv = {
+ .driver = {
+ .probe = rte_eal_pci_probe,
+ .remove = rte_eal_pci_remove,
+ },
.id_table = pci_id_ixgbe_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC |
RTE_PCI_DRV_DETACHABLE,
@@ -1580,6 +1584,10 @@ static struct eth_driver rte_ixgbe_pmd = {
*/
static struct eth_driver rte_ixgbevf_pmd = {
.pci_drv = {
+ .driver = {
+ .probe = rte_eal_pci_probe,
+ .remove = rte_eal_pci_remove,
+ },
.id_table = pci_id_ixgbevf_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_DETACHABLE,
.probe = rte_eth_dev_pci_probe,
diff --git a/drivers/net/mlx4/mlx4.c b/drivers/net/mlx4/mlx4.c
index da61a85..e3dcd41 100644
--- a/drivers/net/mlx4/mlx4.c
+++ b/drivers/net/mlx4/mlx4.c
@@ -5907,7 +5907,9 @@ static const struct rte_pci_id mlx4_pci_id_map[] = {
static struct eth_driver mlx4_driver = {
.pci_drv = {
.driver = {
- .name = MLX4_DRIVER_NAME
+ .name = MLX4_DRIVER_NAME,
+ .probe = rte_eal_pci_probe,
+ },
},
.id_table = mlx4_pci_id_map,
.probe = mlx4_pci_probe,
diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index 90cc35e..76dda13 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -731,6 +731,7 @@ static struct eth_driver mlx5_driver = {
.pci_drv = {
.driver = {
.name = MLX5_DRIVER_NAME
+ .probe = rte_eal_pci_probe,
},
.id_table = mlx5_pci_id_map,
.probe = mlx5_pci_probe,
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
index de80b46..125ba86 100644
--- a/drivers/net/nfp/nfp_net.c
+++ b/drivers/net/nfp/nfp_net.c
@@ -2469,6 +2469,10 @@ static struct rte_pci_id pci_id_nfp_net_map[] = {
static struct eth_driver rte_nfp_net_pmd = {
.pci_drv = {
+ .driver = {
+ .probe = rte_eal_pci_probe,
+ .remove = rte_eal_pci_remove,
+ },
.id_table = pci_id_nfp_net_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC |
RTE_PCI_DRV_DETACHABLE,
diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c
index d106dd0..31f6733 100644
--- a/drivers/net/qede/qede_ethdev.c
+++ b/drivers/net/qede/qede_ethdev.c
@@ -1642,6 +1642,10 @@ static struct rte_pci_id pci_id_qede_map[] = {
static struct eth_driver rte_qedevf_pmd = {
.pci_drv = {
+ .driver = {
+ .probe = rte_eal_pci_probe,
+ .remove = rte_eal_pci_remove,
+ },
.id_table = pci_id_qedevf_map,
.drv_flags =
RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
@@ -1655,6 +1659,10 @@ static struct eth_driver rte_qedevf_pmd = {
static struct eth_driver rte_qede_pmd = {
.pci_drv = {
+ .driver = {
+ .probe = rte_eal_pci_probe,
+ .remove = rte_eal_pci_remove,
+ },
.id_table = pci_id_qede_map,
.drv_flags =
RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
diff --git a/drivers/net/szedata2/rte_eth_szedata2.c b/drivers/net/szedata2/rte_eth_szedata2.c
index f3cd52d..a649e60 100644
--- a/drivers/net/szedata2/rte_eth_szedata2.c
+++ b/drivers/net/szedata2/rte_eth_szedata2.c
@@ -1572,6 +1572,10 @@ static const struct rte_pci_id rte_szedata2_pci_id_table[] = {
static struct eth_driver szedata2_eth_driver = {
.pci_drv = {
+ .driver = {
+ .probe = rte_eal_pci_probe,
+ .remove = rte_eal_pci_remove,
+ },
.id_table = rte_szedata2_pci_id_table,
.probe = rte_eth_dev_pci_probe,
.remove = rte_eth_dev_pci_remove,
diff --git a/drivers/net/thunderx/nicvf_ethdev.c b/drivers/net/thunderx/nicvf_ethdev.c
index 466e49c..72ac748 100644
--- a/drivers/net/thunderx/nicvf_ethdev.c
+++ b/drivers/net/thunderx/nicvf_ethdev.c
@@ -2110,6 +2110,10 @@ static const struct rte_pci_id pci_id_nicvf_map[] = {
static struct eth_driver rte_nicvf_pmd = {
.pci_drv = {
+ .driver = {
+ .probe = rte_eal_pci_probe,
+ .remove = rte_eal_pci_remove,
+ },
.id_table = pci_id_nicvf_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_INTR_LSC,
.probe = rte_eth_dev_pci_probe,
diff --git a/drivers/net/virtio/virtio_ethdev.c b/drivers/net/virtio/virtio_ethdev.c
index 079fd6c..4d5d1bb 100644
--- a/drivers/net/virtio/virtio_ethdev.c
+++ b/drivers/net/virtio/virtio_ethdev.c
@@ -1377,6 +1377,8 @@ static struct eth_driver rte_virtio_pmd = {
.pci_drv = {
.driver = {
.name = "net_virtio",
+ .probe = rte_eal_pci_probe,
+ .remove = rte_eal_pci_remove,
},
.id_table = pci_id_virtio_map,
.drv_flags = RTE_PCI_DRV_DETACHABLE,
diff --git a/drivers/net/vmxnet3/vmxnet3_ethdev.c b/drivers/net/vmxnet3/vmxnet3_ethdev.c
index 8bb13e5..57f66cb 100644
--- a/drivers/net/vmxnet3/vmxnet3_ethdev.c
+++ b/drivers/net/vmxnet3/vmxnet3_ethdev.c
@@ -335,6 +335,10 @@ eth_vmxnet3_dev_uninit(struct rte_eth_dev *eth_dev)
static struct eth_driver rte_vmxnet3_pmd = {
.pci_drv = {
+ .driver = {
+ .probe = rte_eal_pci_probe,
+ .remove = rte_eal_pci_remove,
+ },
.id_table = pci_id_vmxnet3_map,
.drv_flags = RTE_PCI_DRV_NEED_MAPPING | RTE_PCI_DRV_DETACHABLE,
.probe = rte_eth_dev_pci_probe,
--
2.7.4
^ permalink raw reply related
* [PATCH v2 11/12] eal: enable PCI bus
From: Shreyansh Jain @ 2016-12-13 13:37 UTC (permalink / raw)
To: dev, david.marchand
Cc: thomas.monjalon, ferruh.yigit, jianbo.liu, Shreyansh Jain
In-Reply-To: <1481636232-2300-1-git-send-email-shreyansh.jain@nxp.com>
Register a PCI bus with Scan/match and probe callbacks. Necessary changes
in EAL layer for enabling bus interfaces. PCI devices and drivers now
reside within the Bus object.
Now that PCI bus handles the scan/probe methods, independent calls to
PCI scan and probe can be removed from the code.
PCI device and driver list are also removed.
rte_device and rte_driver list continue to exist. As does the VDEV lists.
Note: With this patch, all PCI PMDs would cease to work because of lack
rte_driver->probe/remove implementations. Next patch would do that.
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
lib/librte_eal/bsdapp/eal/eal.c | 7 -
lib/librte_eal/bsdapp/eal/eal_pci.c | 52 ++++---
lib/librte_eal/bsdapp/eal/rte_eal_version.map | 7 +-
lib/librte_eal/common/eal_common_bus.c | 1 +
lib/librte_eal/common/eal_common_pci.c | 187 +++++++++++++++---------
lib/librte_eal/common/eal_private.h | 14 +-
lib/librte_eal/common/include/rte_pci.h | 53 ++++---
lib/librte_eal/linuxapp/eal/eal.c | 7 -
lib/librte_eal/linuxapp/eal/eal_pci.c | 54 ++++---
lib/librte_eal/linuxapp/eal/rte_eal_version.map | 7 +-
10 files changed, 220 insertions(+), 169 deletions(-)
diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
index 30afc6b..79d82d4 100644
--- a/lib/librte_eal/bsdapp/eal/eal.c
+++ b/lib/librte_eal/bsdapp/eal/eal.c
@@ -562,9 +562,6 @@ rte_eal_init(int argc, char **argv)
if (rte_eal_timer_init() < 0)
rte_panic("Cannot init HPET or TSC timers\n");
- if (rte_eal_pci_init() < 0)
- rte_panic("Cannot init PCI\n");
-
eal_check_mem_on_local_socket();
if (eal_plugins_init() < 0)
@@ -616,10 +613,6 @@ rte_eal_init(int argc, char **argv)
rte_eal_mp_remote_launch(sync_func, NULL, SKIP_MASTER);
rte_eal_mp_wait_lcore();
- /* Probe & Initialize PCI devices */
- if (rte_eal_pci_probe())
- rte_panic("Cannot probe PCI\n");
-
if (rte_eal_bus_probe())
rte_panic("Cannot probe devices\n");
diff --git a/lib/librte_eal/bsdapp/eal/eal_pci.c b/lib/librte_eal/bsdapp/eal/eal_pci.c
index 10b234e..ab9f9d2 100644
--- a/lib/librte_eal/bsdapp/eal/eal_pci.c
+++ b/lib/librte_eal/bsdapp/eal/eal_pci.c
@@ -58,6 +58,7 @@
#include <rte_interrupts.h>
#include <rte_log.h>
+#include <rte_bus.h>
#include <rte_pci.h>
#include <rte_common.h>
#include <rte_launch.h>
@@ -249,7 +250,7 @@ pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
}
static int
-pci_scan_one(int dev_pci_fd, struct pci_conf *conf)
+pci_scan_one(struct rte_bus *bus, int dev_pci_fd, struct pci_conf *conf)
{
struct rte_pci_device *dev;
struct pci_bar_io bar;
@@ -322,19 +323,23 @@ pci_scan_one(int dev_pci_fd, struct pci_conf *conf)
}
/* device is valid, add in list (sorted) */
- if (TAILQ_EMPTY(&pci_device_list)) {
- TAILQ_INSERT_TAIL(&pci_device_list, dev, next);
+ if (TAILQ_EMPTY(&bus->device_list)) {
+ rte_eal_bus_add_device(bus, &dev->device);
}
else {
struct rte_pci_device *dev2 = NULL;
+ struct rte_device *r_dev2;
int ret;
- TAILQ_FOREACH(dev2, &pci_device_list, next) {
+ TAILQ_FOREACH(r_dev2, &bus->device_list, next) {
+ dev2 = container_of(r_dev2, struct rte_pci_device,
+ device);
ret = rte_eal_compare_pci_addr(&dev->addr, &dev2->addr);
if (ret > 0)
continue;
else if (ret < 0) {
- TAILQ_INSERT_BEFORE(dev2, dev, next);
+ rte_eal_bus_insert_device(bus, &dev2->device,
+ &dev->device);
return 0;
} else { /* already registered */
dev2->kdrv = dev->kdrv;
@@ -346,7 +351,7 @@ pci_scan_one(int dev_pci_fd, struct pci_conf *conf)
return 0;
}
}
- TAILQ_INSERT_TAIL(&pci_device_list, dev, next);
+ rte_eal_bus_add_device(bus, &dev->device);
}
return 0;
@@ -361,7 +366,7 @@ pci_scan_one(int dev_pci_fd, struct pci_conf *conf)
* list. Call pci_scan_one() for each pci entry found.
*/
int
-rte_eal_pci_scan(struct rte_bus *bus __rte_unused)
+rte_eal_pci_scan(struct rte_bus *bus)
{
int fd;
unsigned dev_count = 0;
@@ -374,6 +379,10 @@ rte_eal_pci_scan(struct rte_bus *bus __rte_unused)
.matches = &matches[0],
};
+ /* for debug purposes, PCI can be disabled */
+ if (internal_config.no_pci)
+ return 0;
+
fd = open("/dev/pci", O_RDONLY);
if (fd < 0) {
RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
@@ -389,7 +398,7 @@ rte_eal_pci_scan(struct rte_bus *bus __rte_unused)
}
for (i = 0; i < conf_io.num_matches; i++)
- if (pci_scan_one(fd, &matches[i]) < 0)
+ if (pci_scan_one(bus, fd, &matches[i]) < 0)
goto error;
dev_count += conf_io.num_matches;
@@ -407,9 +416,9 @@ rte_eal_pci_scan(struct rte_bus *bus __rte_unused)
}
int
-pci_update_device(const struct rte_pci_addr *addr)
+pci_update_device(struct rte_bus *bus, const struct rte_pci_addr *addr)
{
- int fd;
+ int fd = -1;
struct pci_conf matches[2];
struct pci_match_conf match = {
.pc_sel = {
@@ -427,6 +436,9 @@ pci_update_device(const struct rte_pci_addr *addr)
.matches = &matches[0],
};
+ if (!bus)
+ goto error;
+
fd = open("/dev/pci", O_RDONLY);
if (fd < 0) {
RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
@@ -442,7 +454,7 @@ pci_update_device(const struct rte_pci_addr *addr)
if (conf_io.num_matches != 1)
goto error;
- if (pci_scan_one(fd, &matches[0]) < 0)
+ if (pci_scan_one(bus, fd, &matches[0]) < 0)
goto error;
close(fd);
@@ -668,17 +680,9 @@ rte_eal_pci_ioport_unmap(struct rte_pci_ioport *p)
return ret;
}
-/* Init the PCI EAL subsystem */
-int
-rte_eal_pci_init(void)
-{
- /* for debug purposes, PCI can be disabled */
- if (internal_config.no_pci)
- return 0;
+struct rte_bus pci_bus = {
+ .scan = rte_eal_pci_scan,
+ .match = rte_eal_pci_match,
+};
- if (rte_eal_pci_scan(NULL) < 0) {
- RTE_LOG(ERR, EAL, "%s(): Cannot scan PCI bus\n", __func__);
- return -1;
- }
- return 0;
-}
+RTE_REGISTER_BUS(pci, pci_bus);
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index 23fc1c1..3dcf439 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -6,8 +6,6 @@ DPDK_2.0 {
eal_parse_sysfs_value;
eal_timer_source;
lcore_config;
- pci_device_list;
- pci_driver_list;
per_lcore__lcore_id;
per_lcore__rte_errno;
rte_calloc;
@@ -41,7 +39,6 @@ DPDK_2.0 {
rte_eal_mp_wait_lcore;
rte_eal_parse_devargs_str;
rte_eal_pci_dump;
- rte_eal_pci_probe;
rte_eal_pci_probe_one;
rte_eal_pci_register;
rte_eal_pci_scan;
@@ -187,5 +184,9 @@ DPDK_17.02 {
rte_eal_bus_remove_device;
rte_eal_bus_remove_driver;
rte_eal_bus_unregister;
+ rte_eal_pci_match;
+ rte_eal_pci_probe;
+ rte_eal_pci_remove;
+ rte_eal_pci_scan;
} DPDK_16.11;
diff --git a/lib/librte_eal/common/eal_common_bus.c b/lib/librte_eal/common/eal_common_bus.c
index 469abac..d9ee347 100644
--- a/lib/librte_eal/common/eal_common_bus.c
+++ b/lib/librte_eal/common/eal_common_bus.c
@@ -234,6 +234,7 @@ rte_eal_bus_probe(void)
TAILQ_FOREACH(driver, &bus->driver_list, next) {
ret = bus->match(driver, device);
if (!ret) {
+ device->driver = driver;
ret = perform_probe(bus, driver,
device);
if (ret < 0)
diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c
index 562c0fd..fb4e39f 100644
--- a/lib/librte_eal/common/eal_common_pci.c
+++ b/lib/librte_eal/common/eal_common_pci.c
@@ -71,6 +71,7 @@
#include <rte_interrupts.h>
#include <rte_log.h>
+#include <rte_bus.h>
#include <rte_pci.h>
#include <rte_per_lcore.h>
#include <rte_memory.h>
@@ -82,11 +83,6 @@
#include "eal_private.h"
-struct pci_driver_list pci_driver_list =
- TAILQ_HEAD_INITIALIZER(pci_driver_list);
-struct pci_device_list pci_device_list =
- TAILQ_HEAD_INITIALIZER(pci_device_list);
-
#define SYSFS_PCI_DEVICES "/sys/bus/pci/devices"
const char *pci_get_sysfs_path(void)
@@ -206,15 +202,11 @@ rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr,
struct rte_pci_device *dev)
{
int ret;
- struct rte_driver *driver;
- struct rte_device *device;
struct rte_pci_addr *loc;
if ((dr == NULL) || (dev == NULL))
return -EINVAL;
- driver = &dr->driver;
- device = &dev->device;
loc = &dev->addr;
RTE_LOG(INFO, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
@@ -230,15 +222,6 @@ rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr,
return 1;
}
- /* The device is not blacklisted; Check if driver supports it */
- ret = rte_eal_pci_match(driver, device);
- if (ret) {
- /* Match of device and driver failed */
- RTE_LOG(DEBUG, EAL, "Driver (%s) doesn't match the device\n",
- driver->name);
- return 1;
- }
-
RTE_LOG(INFO, EAL, " probe driver: %x:%x %s\n", dev->id.vendor_id,
dev->id.device_id, dr->driver.name);
@@ -276,23 +259,11 @@ static int
rte_eal_pci_detach_dev(struct rte_pci_driver *dr,
struct rte_pci_device *dev)
{
- int ret;
- struct rte_driver *driver = NULL;
- struct rte_device *device;
struct rte_pci_addr *loc;
if ((dr == NULL) || (dev == NULL))
return -EINVAL;
- driver = &(dr->driver);
- device = &(dev->device);
-
- ret = rte_eal_pci_match(driver, device);
- if (ret) {
- /* Device and driver don't match */
- return 1;
- }
-
loc = &dev->addr;
RTE_LOG(DEBUG, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
@@ -321,9 +292,10 @@ rte_eal_pci_detach_dev(struct rte_pci_driver *dr,
* failed, return 1 if no driver is found for this device.
*/
static int
-pci_probe_all_drivers(struct rte_pci_device *dev)
+pci_probe_all_drivers(struct rte_bus *bus, struct rte_pci_device *dev)
{
struct rte_pci_driver *dr = NULL;
+ struct rte_driver *r_dr = NULL;
int rc = 0;
if (dev == NULL)
@@ -333,7 +305,8 @@ pci_probe_all_drivers(struct rte_pci_device *dev)
if (dev->driver != NULL)
return 0;
- TAILQ_FOREACH(dr, &pci_driver_list, next) {
+ TAILQ_FOREACH(r_dr, &bus->driver_list, next) {
+ dr = container_of(r_dr, struct rte_pci_driver, driver);
rc = rte_eal_pci_probe_one_driver(dr, dev);
if (rc < 0)
/* negative value is an error */
@@ -352,15 +325,17 @@ pci_probe_all_drivers(struct rte_pci_device *dev)
* failed, return 1 if no driver is found for this device.
*/
static int
-pci_detach_all_drivers(struct rte_pci_device *dev)
+pci_detach_all_drivers(struct rte_bus *bus, struct rte_pci_device *dev)
{
struct rte_pci_driver *dr = NULL;
+ struct rte_driver *r_dr = NULL;
int rc = 0;
if (dev == NULL)
return -1;
- TAILQ_FOREACH(dr, &pci_driver_list, next) {
+ TAILQ_FOREACH(r_dr, &bus->driver_list, next) {
+ dr = container_of(r_dr, struct rte_pci_driver, driver);
rc = rte_eal_pci_detach_dev(dr, dev);
if (rc < 0)
/* negative value is an error */
@@ -381,22 +356,31 @@ int
rte_eal_pci_probe_one(const struct rte_pci_addr *addr)
{
struct rte_pci_device *dev = NULL;
+ struct rte_device *r_dev = NULL;
+ struct rte_bus *bus;
int ret = 0;
if (addr == NULL)
return -1;
+ bus = rte_eal_get_bus("pci");
+ if (!bus) {
+ RTE_LOG(ERR, EAL, "PCI Bus not registered\n");
+ return -1;
+ }
+
/* update current pci device in global list, kernel bindings might have
* changed since last time we looked at it.
*/
- if (pci_update_device(addr) < 0)
+ if (pci_update_device(bus, addr) < 0)
goto err_return;
- TAILQ_FOREACH(dev, &pci_device_list, next) {
+ TAILQ_FOREACH(r_dev, &bus->device_list, next) {
+ dev = container_of(r_dev, struct rte_pci_device, device);
if (rte_eal_compare_pci_addr(&dev->addr, addr))
continue;
- ret = pci_probe_all_drivers(dev);
+ ret = pci_probe_all_drivers(bus, dev);
if (ret)
goto err_return;
return 0;
@@ -417,20 +401,29 @@ int
rte_eal_pci_detach(const struct rte_pci_addr *addr)
{
struct rte_pci_device *dev = NULL;
+ struct rte_device *r_dev = NULL;
+ struct rte_bus *bus;
int ret = 0;
if (addr == NULL)
return -1;
- TAILQ_FOREACH(dev, &pci_device_list, next) {
+ bus = rte_eal_get_bus("pci");
+ if (!bus) {
+ RTE_LOG(ERR, EAL, "PCI Bus is not registered\n");
+ return -1;
+ }
+
+ TAILQ_FOREACH(r_dev, &bus->device_list, next) {
+ dev = container_of(r_dev, struct rte_pci_device, device);
if (rte_eal_compare_pci_addr(&dev->addr, addr))
continue;
- ret = pci_detach_all_drivers(dev);
+ ret = pci_detach_all_drivers(bus, dev);
if (ret < 0)
goto err_return;
- TAILQ_REMOVE(&pci_device_list, dev, next);
+ rte_eal_bus_remove_device(r_dev);
free(dev);
return 0;
}
@@ -443,41 +436,66 @@ rte_eal_pci_detach(const struct rte_pci_addr *addr)
return -1;
}
-/*
- * Scan the content of the PCI bus, and call the probe() function for
- * all registered drivers that have a matching entry in its id_table
- * for discovered devices.
- */
int
-rte_eal_pci_probe(void)
+rte_eal_pci_probe(struct rte_driver *driver, struct rte_device *device)
{
- struct rte_pci_device *dev = NULL;
- struct rte_devargs *devargs;
- int probe_all = 0;
int ret = 0;
+ struct rte_devargs *devargs;
+ struct rte_pci_device *pci_dev;
+ struct rte_pci_driver *pci_drv;
- if (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_PCI) == 0)
- probe_all = 1;
+ if (!driver || !device)
+ return -1;
- TAILQ_FOREACH(dev, &pci_device_list, next) {
+ pci_dev = container_of(device, struct rte_pci_device, device);
+ pci_drv = container_of(driver, struct rte_pci_driver, driver);
+ ret = rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_PCI);
+ if (ret != 0) {
/* set devargs in PCI structure */
- devargs = pci_devargs_lookup(dev);
- if (devargs != NULL)
- dev->device.devargs = devargs;
-
- /* probe all or only whitelisted devices */
- if (probe_all)
- ret = pci_probe_all_drivers(dev);
- else if (devargs != NULL &&
- devargs->type == RTE_DEVTYPE_WHITELISTED_PCI)
- ret = pci_probe_all_drivers(dev);
- if (ret < 0)
- rte_exit(EXIT_FAILURE, "Requested device " PCI_PRI_FMT
- " cannot be used\n", dev->addr.domain, dev->addr.bus,
- dev->addr.devid, dev->addr.function);
+ devargs = pci_devargs_lookup(pci_dev);
+ if (devargs != NULL &&
+ devargs->type == RTE_DEVTYPE_WHITELISTED_PCI) {
+ pci_dev->device.devargs = devargs;
+ } else {
+ /* Ignore the device */
+ return 0;
+ }
+ }
+
+ ret = rte_eal_pci_probe_one_driver(pci_drv, pci_dev);
+ if (ret < 0) {
+ RTE_LOG(ERR, EAL, "Requested device " PCI_PRI_FMT
+ " cannot be used\n", pci_dev->addr.domain,
+ pci_dev->addr.bus, pci_dev->addr.devid,
+ pci_dev->addr.function);
+ return ret;
}
+ return 0;
+}
+
+int
+rte_eal_pci_remove(struct rte_device *device)
+{
+ int ret = 0;
+ struct rte_pci_device *pci_dev;
+
+ if (!device)
+ return -1;
+
+ pci_dev = container_of(device, struct rte_pci_device, device);
+ if (!pci_dev->driver)
+ return -1;
+
+ ret = rte_eal_pci_detach_dev(pci_dev->driver, pci_dev);
+ if (ret < 0) {
+ RTE_LOG(ERR, EAL, "Requested device " PCI_PRI_FMT
+ " cannot be used\n", pci_dev->addr.domain,
+ pci_dev->addr.bus, pci_dev->addr.devid,
+ pci_dev->addr.function);
+ return ret;
+ }
return 0;
}
@@ -506,8 +524,17 @@ void
rte_eal_pci_dump(FILE *f)
{
struct rte_pci_device *dev = NULL;
+ struct rte_device *r_dev = NULL;
+ struct rte_bus *bus;
- TAILQ_FOREACH(dev, &pci_device_list, next) {
+ bus = rte_eal_get_bus("pci");
+ if (!bus) {
+ RTE_LOG(ERR, EAL, "PCI Bus not registered\n");
+ return;
+ }
+
+ TAILQ_FOREACH(r_dev, &bus->device_list, next) {
+ dev = container_of(r_dev, struct rte_pci_device, device);
pci_dump_one_device(f, dev);
}
}
@@ -516,14 +543,32 @@ rte_eal_pci_dump(FILE *f)
void
rte_eal_pci_register(struct rte_pci_driver *driver)
{
- TAILQ_INSERT_TAIL(&pci_driver_list, driver, next);
- rte_eal_driver_register(&driver->driver);
+ struct rte_bus *bus;
+
+ RTE_VERIFY(driver);
+
+ bus = rte_eal_get_bus("pci");
+ if (!bus) {
+ RTE_LOG(ERR, EAL, "PCI Bus not registered\n");
+ return;
+ }
+
+ rte_eal_bus_add_driver(bus, &driver->driver);
}
/* unregister a driver */
void
rte_eal_pci_unregister(struct rte_pci_driver *driver)
{
- rte_eal_driver_unregister(&driver->driver);
- TAILQ_REMOVE(&pci_driver_list, driver, next);
+ struct rte_bus *bus;
+
+ RTE_VERIFY(driver);
+
+ bus = driver->driver.bus;
+ if (!bus) {
+ RTE_LOG(ERR, EAL, "PCI Bus not registered\n");
+ return;
+ }
+
+ rte_eal_bus_remove_driver(&driver->driver);
}
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index 9e7d8f6..06ec172 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -108,16 +108,6 @@ int rte_eal_timer_init(void);
*/
int rte_eal_log_init(const char *id, int facility);
-/**
- * Init the PCI infrastructure
- *
- * This function is private to EAL.
- *
- * @return
- * 0 on success, negative on error
- */
-int rte_eal_pci_init(void);
-
struct rte_pci_driver;
struct rte_pci_device;
@@ -126,13 +116,15 @@ struct rte_pci_device;
*
* This function is private to EAL.
*
+ * @param bus
+ * The PCI bus on which device is connected
* @param addr
* The PCI Bus-Device-Function address to look for
* @return
* - 0 on success.
* - negative on error.
*/
-int pci_update_device(const struct rte_pci_addr *addr);
+int pci_update_device(struct rte_bus *bus, const struct rte_pci_addr *addr);
/**
* Unbind kernel driver for this device
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
index 10108a4..ec8f672 100644
--- a/lib/librte_eal/common/include/rte_pci.h
+++ b/lib/librte_eal/common/include/rte_pci.h
@@ -86,12 +86,6 @@ extern "C" {
#include <rte_interrupts.h>
#include <rte_dev.h>
-TAILQ_HEAD(pci_device_list, rte_pci_device); /**< PCI devices in D-linked Q. */
-TAILQ_HEAD(pci_driver_list, rte_pci_driver); /**< PCI drivers in D-linked Q. */
-
-extern struct pci_driver_list pci_driver_list; /**< Global list of PCI drivers. */
-extern struct pci_device_list pci_device_list; /**< Global list of PCI devices. */
-
/** Pathname of PCI devices directory. */
const char *pci_get_sysfs_path(void);
@@ -372,6 +366,40 @@ rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
int rte_eal_pci_scan(struct rte_bus *bus);
/**
+ * Probe callback for the PCI bus
+ *
+ * For each matched pair of PCI device and driver on PCI bus, perform devargs
+ * check, and call a series of callbacks to allocate ethdev/cryptodev instances
+ * and intializing them.
+ *
+ * @param driver
+ * Generic driver object matched with the device
+ * @param device
+ * Generic device object to initialize
+ * @return
+ * - 0 on success.
+ * - !0 on error.
+ */
+int
+rte_eal_pci_probe(struct rte_driver *driver, struct rte_device *device);
+
+/**
+ * Remove callback for the PCI bus
+ *
+ * Called when a device needs to be removed from a bus; wraps around the
+ * PCI specific implementation layered over rte_pci_driver->remove. Default
+ * handler used by PCI PMDs
+ *
+ * @param device
+ * rte_device object referring to device to be removed
+ * @return
+ * - 0 for successful removal
+ * - !0 for failure in removal of device
+ */
+int
+rte_eal_pci_remove(struct rte_device *device);
+
+/**
* Match the PCI Driver and Device using the ID Table
*
* @param drv
@@ -387,19 +415,6 @@ rte_eal_pci_match(struct rte_driver *drv,
struct rte_device *dev);
/**
- * Probe the PCI bus for registered drivers.
- *
- * Scan the content of the PCI bus, and call the probe() function for
- * all registered drivers that have a matching entry in its id_table
- * for discovered devices.
- *
- * @return
- * - 0 on success.
- * - Negative on error.
- */
-int rte_eal_pci_probe(void);
-
-/**
* Map the PCI device resources in user space virtual memory address
*
* Note that driver should not call this function when flag
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 01d0cee..ff92de2 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -803,9 +803,6 @@ rte_eal_init(int argc, char **argv)
if (rte_eal_log_init(logid, internal_config.syslog_facility) < 0)
rte_panic("Cannot init logs\n");
- if (rte_eal_pci_init() < 0)
- rte_panic("Cannot init PCI\n");
-
#ifdef VFIO_PRESENT
if (rte_eal_vfio_setup() < 0)
rte_panic("Cannot init VFIO\n");
@@ -887,10 +884,6 @@ rte_eal_init(int argc, char **argv)
rte_eal_mp_remote_launch(sync_func, NULL, SKIP_MASTER);
rte_eal_mp_wait_lcore();
- /* Probe & Initialize PCI devices */
- if (rte_eal_pci_probe())
- rte_panic("Cannot probe PCI\n");
-
if (rte_eal_bus_probe())
rte_panic("Cannot probe devices\n");
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
index cbd25df..5cc89c5 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
@@ -35,6 +35,7 @@
#include <dirent.h>
#include <rte_log.h>
+#include <rte_bus.h>
#include <rte_pci.h>
#include <rte_eal_memconfig.h>
#include <rte_malloc.h>
@@ -267,7 +268,8 @@ pci_parse_sysfs_resource(const char *filename, struct rte_pci_device *dev)
/* Scan one pci sysfs entry, and fill the devices list from it. */
static int
-pci_scan_one(const char *dirname, const struct rte_pci_addr *addr)
+pci_scan_one(struct rte_bus *bus, const char *dirname,
+ const struct rte_pci_addr *addr)
{
char filename[PATH_MAX];
unsigned long tmp;
@@ -385,20 +387,24 @@ pci_scan_one(const char *dirname, const struct rte_pci_addr *addr)
dev->kdrv = RTE_KDRV_NONE;
/* device is valid, add in list (sorted) */
- if (TAILQ_EMPTY(&pci_device_list)) {
+ if (TAILQ_EMPTY(&bus->device_list)) {
rte_eal_device_insert(&dev->device);
- TAILQ_INSERT_TAIL(&pci_device_list, dev, next);
+ rte_eal_bus_add_device(bus, &dev->device);
} else {
struct rte_pci_device *dev2;
+ struct rte_device *r_dev2;
int ret;
- TAILQ_FOREACH(dev2, &pci_device_list, next) {
+ TAILQ_FOREACH(r_dev2, &bus->device_list, next) {
+ dev2 = container_of(r_dev2, struct rte_pci_device,
+ device);
ret = rte_eal_compare_pci_addr(&dev->addr, &dev2->addr);
if (ret > 0)
continue;
if (ret < 0) {
- TAILQ_INSERT_BEFORE(dev2, dev, next);
+ rte_eal_bus_insert_device(bus, &dev2->device,
+ &dev->device);
rte_eal_device_insert(&dev->device);
} else { /* already registered */
dev2->kdrv = dev->kdrv;
@@ -410,14 +416,14 @@ pci_scan_one(const char *dirname, const struct rte_pci_addr *addr)
return 0;
}
rte_eal_device_insert(&dev->device);
- TAILQ_INSERT_TAIL(&pci_device_list, dev, next);
+ rte_eal_bus_add_device(bus, &dev->device);
}
return 0;
}
int
-pci_update_device(const struct rte_pci_addr *addr)
+pci_update_device(struct rte_bus *bus, const struct rte_pci_addr *addr)
{
char filename[PATH_MAX];
@@ -425,7 +431,7 @@ pci_update_device(const struct rte_pci_addr *addr)
pci_get_sysfs_path(), addr->domain, addr->bus, addr->devid,
addr->function);
- return pci_scan_one(filename, addr);
+ return pci_scan_one(bus, filename, addr);
}
/*
@@ -479,13 +485,22 @@ parse_pci_addr_format(const char *buf, int bufsize, struct rte_pci_addr *addr)
* list
*/
int
-rte_eal_pci_scan(struct rte_bus *bus_p __rte_unused)
+rte_eal_pci_scan(struct rte_bus *bus_p)
{
struct dirent *e;
DIR *dir;
char dirname[PATH_MAX];
struct rte_pci_addr addr;
+ if (!bus_p) {
+ RTE_LOG(ERR, EAL, "PCI Bus is not registered\n");
+ return -1;
+ }
+
+ /* for debug purposes, PCI can be disabled */
+ if (internal_config.no_pci)
+ return 0;
+
dir = opendir(pci_get_sysfs_path());
if (dir == NULL) {
RTE_LOG(ERR, EAL, "%s(): opendir failed: %s\n",
@@ -504,7 +519,7 @@ rte_eal_pci_scan(struct rte_bus *bus_p __rte_unused)
snprintf(dirname, sizeof(dirname), "%s/%s",
pci_get_sysfs_path(), e->d_name);
- if (pci_scan_one(dirname, &addr) < 0)
+ if (pci_scan_one(bus_p, dirname, &addr) < 0)
goto error;
}
closedir(dir);
@@ -750,18 +765,9 @@ rte_eal_pci_ioport_unmap(struct rte_pci_ioport *p)
return ret;
}
-/* Init the PCI EAL subsystem */
-int
-rte_eal_pci_init(void)
-{
- /* for debug purposes, PCI can be disabled */
- if (internal_config.no_pci)
- return 0;
-
- if (rte_eal_pci_scan(NULL) < 0) {
- RTE_LOG(ERR, EAL, "%s(): Cannot scan PCI bus\n", __func__);
- return -1;
- }
+struct rte_bus pci_bus = {
+ .scan = rte_eal_pci_scan,
+ .match = rte_eal_pci_match,
+};
- return 0;
-}
+RTE_REGISTER_BUS(pci, pci_bus);
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index c873a7f..6e0ec51 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -6,8 +6,6 @@ DPDK_2.0 {
eal_parse_sysfs_value;
eal_timer_source;
lcore_config;
- pci_device_list;
- pci_driver_list;
per_lcore__lcore_id;
per_lcore__rte_errno;
rte_calloc;
@@ -41,7 +39,6 @@ DPDK_2.0 {
rte_eal_mp_wait_lcore;
rte_eal_parse_devargs_str;
rte_eal_pci_dump;
- rte_eal_pci_probe;
rte_eal_pci_probe_one;
rte_eal_pci_register;
rte_eal_pci_scan;
@@ -191,5 +188,9 @@ DPDK_17.02 {
rte_eal_bus_remove_device;
rte_eal_bus_remove_driver;
rte_eal_bus_unregister;
+ rte_eal_pci_match;
+ rte_eal_pci_probe;
+ rte_eal_pci_remove;
+ rte_eal_pci_scan;
} DPDK_16.11;
--
2.7.4
^ permalink raw reply related
* [PATCH v2 10/12] pci: Pass rte_pci_addr to functions instead of separate args
From: Shreyansh Jain @ 2016-12-13 13:37 UTC (permalink / raw)
To: dev, david.marchand
Cc: thomas.monjalon, ferruh.yigit, jianbo.liu, Ben Walker,
Shreyansh Jain
In-Reply-To: <1481636232-2300-1-git-send-email-shreyansh.jain@nxp.com>
From: Ben Walker <benjamin.walker@intel.com>
Instead of passing domain, bus, devid, func, just pass
an rte_pci_addr.
Signed-off-by: Ben Walker <benjamin.walker@intel.com>
[Shreyansh: Checkpatch error fix]
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
lib/librte_eal/linuxapp/eal/eal_pci.c | 33 ++++++++++++++-------------------
1 file changed, 14 insertions(+), 19 deletions(-)
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
index bafb7fb..cbd25df 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
@@ -267,8 +267,7 @@ pci_parse_sysfs_resource(const char *filename, struct rte_pci_device *dev)
/* Scan one pci sysfs entry, and fill the devices list from it. */
static int
-pci_scan_one(const char *dirname, uint16_t domain, uint8_t bus,
- uint8_t devid, uint8_t function)
+pci_scan_one(const char *dirname, const struct rte_pci_addr *addr)
{
char filename[PATH_MAX];
unsigned long tmp;
@@ -281,10 +280,7 @@ pci_scan_one(const char *dirname, uint16_t domain, uint8_t bus,
return -1;
memset(dev, 0, sizeof(*dev));
- dev->addr.domain = domain;
- dev->addr.bus = bus;
- dev->addr.devid = devid;
- dev->addr.function = function;
+ dev->addr = *addr;
/* get vendor id */
snprintf(filename, sizeof(filename), "%s/vendor", dirname);
@@ -429,16 +425,14 @@ pci_update_device(const struct rte_pci_addr *addr)
pci_get_sysfs_path(), addr->domain, addr->bus, addr->devid,
addr->function);
- return pci_scan_one(filename, addr->domain, addr->bus, addr->devid,
- addr->function);
+ return pci_scan_one(filename, addr);
}
/*
* split up a pci address into its constituent parts.
*/
static int
-parse_pci_addr_format(const char *buf, int bufsize, uint16_t *domain,
- uint8_t *bus, uint8_t *devid, uint8_t *function)
+parse_pci_addr_format(const char *buf, int bufsize, struct rte_pci_addr *addr)
{
/* first split on ':' */
union splitaddr {
@@ -466,10 +460,10 @@ parse_pci_addr_format(const char *buf, int bufsize, uint16_t *domain,
/* now convert to int values */
errno = 0;
- *domain = (uint16_t)strtoul(splitaddr.domain, NULL, 16);
- *bus = (uint8_t)strtoul(splitaddr.bus, NULL, 16);
- *devid = (uint8_t)strtoul(splitaddr.devid, NULL, 16);
- *function = (uint8_t)strtoul(splitaddr.function, NULL, 10);
+ addr->domain = (uint16_t)strtoul(splitaddr.domain, NULL, 16);
+ addr->bus = (uint8_t)strtoul(splitaddr.bus, NULL, 16);
+ addr->devid = (uint8_t)strtoul(splitaddr.devid, NULL, 16);
+ addr->function = (uint8_t)strtoul(splitaddr.function, NULL, 10);
if (errno != 0)
goto error;
@@ -490,8 +484,7 @@ rte_eal_pci_scan(struct rte_bus *bus_p __rte_unused)
struct dirent *e;
DIR *dir;
char dirname[PATH_MAX];
- uint16_t domain;
- uint8_t bus, devid, function;
+ struct rte_pci_addr addr;
dir = opendir(pci_get_sysfs_path());
if (dir == NULL) {
@@ -500,20 +493,22 @@ rte_eal_pci_scan(struct rte_bus *bus_p __rte_unused)
return -1;
}
+
while ((e = readdir(dir)) != NULL) {
if (e->d_name[0] == '.')
continue;
- if (parse_pci_addr_format(e->d_name, sizeof(e->d_name), &domain,
- &bus, &devid, &function) != 0)
+ if (parse_pci_addr_format(e->d_name,
+ sizeof(e->d_name), &addr) != 0)
continue;
snprintf(dirname, sizeof(dirname), "%s/%s",
pci_get_sysfs_path(), e->d_name);
- if (pci_scan_one(dirname, domain, bus, devid, function) < 0)
+ if (pci_scan_one(dirname, &addr) < 0)
goto error;
}
closedir(dir);
+
return 0;
error:
--
2.7.4
^ permalink raw reply related
* [PATCH v2 09/12] eal/pci: generalize args of PCI scan/match towards RTE device/driver
From: Shreyansh Jain @ 2016-12-13 13:37 UTC (permalink / raw)
To: dev, david.marchand
Cc: thomas.monjalon, ferruh.yigit, jianbo.liu, Shreyansh Jain
In-Reply-To: <1481636232-2300-1-git-send-email-shreyansh.jain@nxp.com>
PCI scan and match now work on rte_device/rte_driver rather than PCI
specific objects. These functions can now be plugged to the generic
bus callbacks for scanning and matching devices/drivers.
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
app/test/test_pci.c | 2 +-
lib/librte_eal/bsdapp/eal/eal_pci.c | 4 ++--
lib/librte_eal/common/eal_common_pci.c | 28 +++++++++++++++++++++-------
lib/librte_eal/common/include/rte_pci.h | 17 ++++++++++-------
lib/librte_eal/linuxapp/eal/eal_pci.c | 4 ++--
5 files changed, 36 insertions(+), 19 deletions(-)
diff --git a/app/test/test_pci.c b/app/test/test_pci.c
index cda186d..f9b84db 100644
--- a/app/test/test_pci.c
+++ b/app/test/test_pci.c
@@ -180,7 +180,7 @@ test_pci_setup(void)
TAILQ_INSERT_TAIL(&real_pci_device_list, dev, next);
}
- ret = rte_eal_pci_scan();
+ ret = rte_eal_pci_scan(NULL);
TEST_ASSERT_SUCCESS(ret, "failed to scan PCI bus");
rte_eal_pci_dump(stdout);
diff --git a/lib/librte_eal/bsdapp/eal/eal_pci.c b/lib/librte_eal/bsdapp/eal/eal_pci.c
index 8b3ed88..10b234e 100644
--- a/lib/librte_eal/bsdapp/eal/eal_pci.c
+++ b/lib/librte_eal/bsdapp/eal/eal_pci.c
@@ -361,7 +361,7 @@ pci_scan_one(int dev_pci_fd, struct pci_conf *conf)
* list. Call pci_scan_one() for each pci entry found.
*/
int
-rte_eal_pci_scan(void)
+rte_eal_pci_scan(struct rte_bus *bus __rte_unused)
{
int fd;
unsigned dev_count = 0;
@@ -676,7 +676,7 @@ rte_eal_pci_init(void)
if (internal_config.no_pci)
return 0;
- if (rte_eal_pci_scan() < 0) {
+ if (rte_eal_pci_scan(NULL) < 0) {
RTE_LOG(ERR, EAL, "%s(): Cannot scan PCI bus\n", __func__);
return -1;
}
diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c
index 706f91c..562c0fd 100644
--- a/lib/librte_eal/common/eal_common_pci.c
+++ b/lib/librte_eal/common/eal_common_pci.c
@@ -153,17 +153,22 @@ pci_unmap_resource(void *requested_addr, size_t size)
}
int
-rte_eal_pci_match(struct rte_pci_driver *pci_drv,
- struct rte_pci_device *pci_dev)
+rte_eal_pci_match(struct rte_driver *drv,
+ struct rte_device *dev)
{
int match = 1;
const struct rte_pci_id *id_table;
+ struct rte_pci_driver *pci_drv;
+ struct rte_pci_device *pci_dev;
- if (!pci_drv || !pci_dev || !pci_drv->id_table) {
- RTE_LOG(DEBUG, EAL, "Invalid PCI Driver object\n");
+ if (!drv || !dev) {
+ RTE_LOG(DEBUG, EAL, "Invalid Device/Driver\n");
return -1;
}
+ pci_drv = container_of(drv, struct rte_pci_driver, driver);
+ pci_dev = container_of(dev, struct rte_pci_device, device);
+
for (id_table = pci_drv->id_table; id_table->vendor_id != 0;
id_table++) {
/* check if device's identifiers match the driver's ones */
@@ -201,11 +206,15 @@ rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr,
struct rte_pci_device *dev)
{
int ret;
+ struct rte_driver *driver;
+ struct rte_device *device;
struct rte_pci_addr *loc;
if ((dr == NULL) || (dev == NULL))
return -EINVAL;
+ driver = &dr->driver;
+ device = &dev->device;
loc = &dev->addr;
RTE_LOG(INFO, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
@@ -222,11 +231,11 @@ rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr,
}
/* The device is not blacklisted; Check if driver supports it */
- ret = rte_eal_pci_match(dr, dev);
+ ret = rte_eal_pci_match(driver, device);
if (ret) {
/* Match of device and driver failed */
RTE_LOG(DEBUG, EAL, "Driver (%s) doesn't match the device\n",
- dr->driver.name);
+ driver->name);
return 1;
}
@@ -268,12 +277,17 @@ rte_eal_pci_detach_dev(struct rte_pci_driver *dr,
struct rte_pci_device *dev)
{
int ret;
+ struct rte_driver *driver = NULL;
+ struct rte_device *device;
struct rte_pci_addr *loc;
if ((dr == NULL) || (dev == NULL))
return -EINVAL;
- ret = rte_eal_pci_match(dr, dev);
+ driver = &(dr->driver);
+ device = &(dev->device);
+
+ ret = rte_eal_pci_match(driver, device);
if (ret) {
/* Device and driver don't match */
return 1;
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
index c9b113d..10108a4 100644
--- a/lib/librte_eal/common/include/rte_pci.h
+++ b/lib/librte_eal/common/include/rte_pci.h
@@ -363,25 +363,28 @@ rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
* Scan the content of the PCI bus, and the devices in the devices
* list
*
+ * @param bus
+ * Reference to the PCI bus
+ *
* @return
* 0 on success, negative on error
*/
-int rte_eal_pci_scan(void);
+int rte_eal_pci_scan(struct rte_bus *bus);
/**
* Match the PCI Driver and Device using the ID Table
*
- * @param pci_drv
- * PCI driver from which ID table would be extracted
- * @param pci_dev
- * PCI device to match against the driver
+ * @param drv
+ * driver from which ID table would be extracted
+ * @param dev
+ * device to match against the driver
* @return
* 0 for successful match
* !0 for unsuccessful match
*/
int
-rte_eal_pci_match(struct rte_pci_driver *pci_drv,
- struct rte_pci_device *pci_dev);
+rte_eal_pci_match(struct rte_driver *drv,
+ struct rte_device *dev);
/**
* Probe the PCI bus for registered drivers.
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
index 876ba38..bafb7fb 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
@@ -485,7 +485,7 @@ parse_pci_addr_format(const char *buf, int bufsize, uint16_t *domain,
* list
*/
int
-rte_eal_pci_scan(void)
+rte_eal_pci_scan(struct rte_bus *bus_p __rte_unused)
{
struct dirent *e;
DIR *dir;
@@ -763,7 +763,7 @@ rte_eal_pci_init(void)
if (internal_config.no_pci)
return 0;
- if (rte_eal_pci_scan() < 0) {
+ if (rte_eal_pci_scan(NULL) < 0) {
RTE_LOG(ERR, EAL, "%s(): Cannot scan PCI bus\n", __func__);
return -1;
}
--
2.7.4
^ permalink raw reply related
* [PATCH v2 08/12] pci: split match and probe function
From: Shreyansh Jain @ 2016-12-13 13:37 UTC (permalink / raw)
To: dev, david.marchand
Cc: thomas.monjalon, ferruh.yigit, jianbo.liu, Shreyansh Jain
In-Reply-To: <1481636232-2300-1-git-send-email-shreyansh.jain@nxp.com>
Matching of PCI device address and driver ID table is being done at two
discreet locations duplicating the code. (rte_eal_pci_probe_one_driver
and rte_eal_pci_detach_dev).
Splitting the matching function into rte_eal_pci_match.
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
--
v2:
- Change default return in match function
---
lib/librte_eal/common/eal_common_pci.c | 198 ++++++++++++++++++--------------
lib/librte_eal/common/include/rte_pci.h | 15 +++
2 files changed, 125 insertions(+), 88 deletions(-)
diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c
index 6bff675..706f91c 100644
--- a/lib/librte_eal/common/eal_common_pci.c
+++ b/lib/librte_eal/common/eal_common_pci.c
@@ -152,131 +152,153 @@ pci_unmap_resource(void *requested_addr, size_t size)
requested_addr);
}
-/*
- * If vendor/device ID match, call the probe() function of the
- * driver.
- */
-static int
-rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr, struct rte_pci_device *dev)
+int
+rte_eal_pci_match(struct rte_pci_driver *pci_drv,
+ struct rte_pci_device *pci_dev)
{
- int ret;
+ int match = 1;
const struct rte_pci_id *id_table;
- for (id_table = dr->id_table; id_table->vendor_id != 0; id_table++) {
+ if (!pci_drv || !pci_dev || !pci_drv->id_table) {
+ RTE_LOG(DEBUG, EAL, "Invalid PCI Driver object\n");
+ return -1;
+ }
+ for (id_table = pci_drv->id_table; id_table->vendor_id != 0;
+ id_table++) {
/* check if device's identifiers match the driver's ones */
- if (id_table->vendor_id != dev->id.vendor_id &&
+ if (id_table->vendor_id != pci_dev->id.vendor_id &&
id_table->vendor_id != PCI_ANY_ID)
continue;
- if (id_table->device_id != dev->id.device_id &&
+ if (id_table->device_id != pci_dev->id.device_id &&
id_table->device_id != PCI_ANY_ID)
continue;
- if (id_table->subsystem_vendor_id != dev->id.subsystem_vendor_id &&
- id_table->subsystem_vendor_id != PCI_ANY_ID)
+ if (id_table->subsystem_vendor_id !=
+ pci_dev->id.subsystem_vendor_id &&
+ id_table->subsystem_vendor_id != PCI_ANY_ID)
continue;
- if (id_table->subsystem_device_id != dev->id.subsystem_device_id &&
- id_table->subsystem_device_id != PCI_ANY_ID)
+ if (id_table->subsystem_device_id !=
+ pci_dev->id.subsystem_device_id &&
+ id_table->subsystem_device_id != PCI_ANY_ID)
continue;
- if (id_table->class_id != dev->id.class_id &&
+ if (id_table->class_id != pci_dev->id.class_id &&
id_table->class_id != RTE_CLASS_ANY_ID)
continue;
- struct rte_pci_addr *loc = &dev->addr;
-
- RTE_LOG(INFO, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
- loc->domain, loc->bus, loc->devid, loc->function,
- dev->device.numa_node);
-
- /* no initialization when blacklisted, return without error */
- if (dev->device.devargs != NULL &&
- dev->device.devargs->type ==
- RTE_DEVTYPE_BLACKLISTED_PCI) {
- RTE_LOG(INFO, EAL, " Device is blacklisted, not initializing\n");
- return 1;
- }
-
- RTE_LOG(INFO, EAL, " probe driver: %x:%x %s\n", dev->id.vendor_id,
- dev->id.device_id, dr->driver.name);
-
- if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) {
- /* map resources for devices that use igb_uio */
- ret = rte_eal_pci_map_device(dev);
- if (ret != 0)
- return ret;
- } else if (dr->drv_flags & RTE_PCI_DRV_FORCE_UNBIND &&
- rte_eal_process_type() == RTE_PROC_PRIMARY) {
- /* unbind current driver */
- if (pci_unbind_kernel_driver(dev) < 0)
- return -1;
- }
-
- /* reference driver structure */
- dev->driver = dr;
-
- /* call the driver probe() function */
- ret = dr->probe(dr, dev);
- if (ret)
- dev->driver = NULL;
-
- return ret;
+ match = 0;
+ break;
}
- /* return positive value if driver doesn't support this device */
- return 1;
+
+ return match;
}
/*
- * If vendor/device ID match, call the remove() function of the
+ * If vendor/device ID match, call the probe() function of the
* driver.
*/
static int
-rte_eal_pci_detach_dev(struct rte_pci_driver *dr,
- struct rte_pci_device *dev)
+rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr,
+ struct rte_pci_device *dev)
{
- const struct rte_pci_id *id_table;
+ int ret;
+ struct rte_pci_addr *loc;
if ((dr == NULL) || (dev == NULL))
return -EINVAL;
- for (id_table = dr->id_table; id_table->vendor_id != 0; id_table++) {
+ loc = &dev->addr;
- /* check if device's identifiers match the driver's ones */
- if (id_table->vendor_id != dev->id.vendor_id &&
- id_table->vendor_id != PCI_ANY_ID)
- continue;
- if (id_table->device_id != dev->id.device_id &&
- id_table->device_id != PCI_ANY_ID)
- continue;
- if (id_table->subsystem_vendor_id != dev->id.subsystem_vendor_id &&
- id_table->subsystem_vendor_id != PCI_ANY_ID)
- continue;
- if (id_table->subsystem_device_id != dev->id.subsystem_device_id &&
- id_table->subsystem_device_id != PCI_ANY_ID)
- continue;
+ RTE_LOG(INFO, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
+ loc->domain, loc->bus, loc->devid, loc->function,
+ dev->device.numa_node);
- struct rte_pci_addr *loc = &dev->addr;
+ /* no initialization when blacklisted, return without error */
+ if (dev->device.devargs != NULL &&
+ dev->device.devargs->type ==
+ RTE_DEVTYPE_BLACKLISTED_PCI) {
+ RTE_LOG(INFO, EAL, " Device is blacklisted, not"
+ " initializing\n");
+ return 1;
+ }
- RTE_LOG(DEBUG, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
- loc->domain, loc->bus, loc->devid,
- loc->function, dev->device.numa_node);
+ /* The device is not blacklisted; Check if driver supports it */
+ ret = rte_eal_pci_match(dr, dev);
+ if (ret) {
+ /* Match of device and driver failed */
+ RTE_LOG(DEBUG, EAL, "Driver (%s) doesn't match the device\n",
+ dr->driver.name);
+ return 1;
+ }
- RTE_LOG(DEBUG, EAL, " remove driver: %x:%x %s\n", dev->id.vendor_id,
- dev->id.device_id, dr->driver.name);
+ RTE_LOG(INFO, EAL, " probe driver: %x:%x %s\n", dev->id.vendor_id,
+ dev->id.device_id, dr->driver.name);
+
+ if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING) {
+ /* map resources for devices that use igb_uio */
+ ret = rte_eal_pci_map_device(dev);
+ if (ret != 0)
+ return ret;
+ } else if (dr->drv_flags & RTE_PCI_DRV_FORCE_UNBIND &&
+ rte_eal_process_type() == RTE_PROC_PRIMARY) {
+ /* unbind current driver */
+ if (pci_unbind_kernel_driver(dev) < 0)
+ return -1;
+ }
- if (dr->remove && (dr->remove(dev) < 0))
- return -1; /* negative value is an error */
+ /* reference driver structure */
+ dev->driver = dr;
- /* clear driver structure */
+ /* call the driver probe() function */
+ ret = dr->probe(dr, dev);
+ if (ret) {
+ RTE_LOG(DEBUG, EAL, "Driver (%s) probe failed.\n",
+ dr->driver.name);
dev->driver = NULL;
+ }
- if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING)
- /* unmap resources for devices that use igb_uio */
- rte_eal_pci_unmap_device(dev);
+ return ret;
+}
- return 0;
+/*
+ * If vendor/device ID match, call the remove() function of the
+ * driver.
+ */
+static int
+rte_eal_pci_detach_dev(struct rte_pci_driver *dr,
+ struct rte_pci_device *dev)
+{
+ int ret;
+ struct rte_pci_addr *loc;
+
+ if ((dr == NULL) || (dev == NULL))
+ return -EINVAL;
+
+ ret = rte_eal_pci_match(dr, dev);
+ if (ret) {
+ /* Device and driver don't match */
+ return 1;
}
- /* return positive value if driver doesn't support this device */
- return 1;
+ loc = &dev->addr;
+
+ RTE_LOG(DEBUG, EAL, "PCI device "PCI_PRI_FMT" on NUMA socket %i\n",
+ loc->domain, loc->bus, loc->devid,
+ loc->function, dev->device.numa_node);
+
+ RTE_LOG(DEBUG, EAL, " remove driver: %x:%x %s\n", dev->id.vendor_id,
+ dev->id.device_id, dr->driver.name);
+
+ if (dr->remove && (dr->remove(dev) < 0))
+ return -1; /* negative value is an error */
+
+ /* clear driver structure */
+ dev->driver = NULL;
+
+ if (dr->drv_flags & RTE_PCI_DRV_NEED_MAPPING)
+ /* unmap resources for devices that use igb_uio */
+ rte_eal_pci_unmap_device(dev);
+
+ return 0;
}
/*
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
index 9ce8847..c9b113d 100644
--- a/lib/librte_eal/common/include/rte_pci.h
+++ b/lib/librte_eal/common/include/rte_pci.h
@@ -369,6 +369,21 @@ rte_eal_compare_pci_addr(const struct rte_pci_addr *addr,
int rte_eal_pci_scan(void);
/**
+ * Match the PCI Driver and Device using the ID Table
+ *
+ * @param pci_drv
+ * PCI driver from which ID table would be extracted
+ * @param pci_dev
+ * PCI device to match against the driver
+ * @return
+ * 0 for successful match
+ * !0 for unsuccessful match
+ */
+int
+rte_eal_pci_match(struct rte_pci_driver *pci_drv,
+ struct rte_pci_device *pci_dev);
+
+/**
* Probe the PCI bus for registered drivers.
*
* Scan the content of the PCI bus, and call the probe() function for
--
2.7.4
^ permalink raw reply related
* [PATCH v2 07/12] eal: enable probe from bus infrastructure
From: Shreyansh Jain @ 2016-12-13 13:37 UTC (permalink / raw)
To: dev, david.marchand
Cc: thomas.monjalon, ferruh.yigit, jianbo.liu, Shreyansh Jain
In-Reply-To: <1481636232-2300-1-git-send-email-shreyansh.jain@nxp.com>
The model is:
rte_eal_init
`--> calls rte_eal_bus_probe()
This iterates over all the drivers and devices and matches them. For
matched bus specific device-driver and calls:
`-> rte_driver->probe()
for all matched device/drivers (rte_bus->match() successful)
This would be responsible for devargs related checks, eventually
calling:
`-> rte_xxx_driver->probe()
which does all the work from eth_dev allocation to init.
(Currently, eth_dev init is done by eth_driver->eth_dev_init,
which would be removed soon)
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
--
v2:
- No more bus->probe call
---
lib/librte_eal/common/eal_common_bus.c | 50 +++++++++++++++++++++++++++++++++-
1 file changed, 49 insertions(+), 1 deletion(-)
diff --git a/lib/librte_eal/common/eal_common_bus.c b/lib/librte_eal/common/eal_common_bus.c
index 67b808b..469abac 100644
--- a/lib/librte_eal/common/eal_common_bus.c
+++ b/lib/librte_eal/common/eal_common_bus.c
@@ -195,11 +195,59 @@ rte_eal_bus_scan(void)
return 0;
}
+static int
+perform_probe(struct rte_bus *bus __rte_unused, struct rte_driver *driver,
+ struct rte_device *device)
+{
+ int ret;
+
+ if (!driver->probe) {
+ RTE_LOG(ERR, EAL, "Driver (%s) doesn't support probe.\n",
+ driver->name);
+ /* This is not an error - just a badly implemented PMD */
+ return 0;
+ }
+
+ ret = driver->probe(driver, device);
+ if (ret < 0)
+ /* One of the probes failed */
+ RTE_LOG(ERR, EAL, "Probe failed for (%s).\n", driver->name);
+
+ /* In either case, ret <0 (error), ret > 0 (not supported) and ret = 0
+ * success, return ret
+ */
+ return ret;
+}
+
/* Match driver<->device and call driver->probe() */
int
rte_eal_bus_probe(void)
{
- /* Until driver->probe is available, this is dummy implementation */
+ int ret;
+ struct rte_bus *bus;
+ struct rte_device *device;
+ struct rte_driver *driver;
+
+ /* For each bus registered with EAL */
+ TAILQ_FOREACH(bus, &rte_bus_list, next) {
+ TAILQ_FOREACH(device, &bus->device_list, next) {
+ TAILQ_FOREACH(driver, &bus->driver_list, next) {
+ ret = bus->match(driver, device);
+ if (!ret) {
+ ret = perform_probe(bus, driver,
+ device);
+ if (ret < 0)
+ return ret;
+
+ /* ret == 0 is success; ret >0 implies
+ * driver doesn't support the device.
+ * in either case, continue
+ */
+ }
+ }
+ }
+ }
+
return 0;
}
--
2.7.4
^ permalink raw reply related
* [PATCH v2 06/12] eal: add probe and remove support for rte_driver
From: Shreyansh Jain @ 2016-12-13 13:37 UTC (permalink / raw)
To: dev, david.marchand
Cc: thomas.monjalon, ferruh.yigit, jianbo.liu, Shreyansh Jain
In-Reply-To: <1481636232-2300-1-git-send-email-shreyansh.jain@nxp.com>
rte_driver now supports probe and remove. These would be used for generic
device type (PCI, etc) probe and remove.
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
lib/librte_eal/common/include/rte_dev.h | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
index 4004f9a..7d2ab16 100644
--- a/lib/librte_eal/common/include/rte_dev.h
+++ b/lib/librte_eal/common/include/rte_dev.h
@@ -145,6 +145,16 @@ void rte_eal_device_insert(struct rte_device *dev);
void rte_eal_device_remove(struct rte_device *dev);
/**
+ * Initialisation function for the driver called during probing.
+ */
+typedef int (driver_probe_t)(struct rte_driver *, struct rte_device *);
+
+/**
+ * Uninitialisation function for the driver called during hotplugging.
+ */
+typedef int (driver_remove_t)(struct rte_device *);
+
+/**
* A structure describing a device driver.
*/
struct rte_driver {
@@ -152,6 +162,8 @@ struct rte_driver {
struct rte_bus *bus; /**< Bus serviced by this driver */
const char *name; /**< Driver name. */
const char *alias; /**< Driver alias. */
+ driver_probe_t *probe; /**< Probe the device */
+ driver_remove_t *remove; /**< Remove/hotplugging the device */
};
/**
--
2.7.4
^ permalink raw reply related
* [PATCH v2 05/12] eal: integrate bus scan and probe with EAL
From: Shreyansh Jain @ 2016-12-13 13:37 UTC (permalink / raw)
To: dev, david.marchand
Cc: thomas.monjalon, ferruh.yigit, jianbo.liu, Shreyansh Jain
In-Reply-To: <1481636232-2300-1-git-send-email-shreyansh.jain@nxp.com>
Still a dummy implementation as no real bus driver exists. This adds calls
from EAL to bus specific scan, match functions.
Once driver->probe is in place, and a bus handler has been installed,
the code would become effective.
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
lib/librte_eal/bsdapp/eal/eal.c | 7 +++++++
lib/librte_eal/common/eal_common_bus.c | 30 ++++++++++++++++++++++++++++++
lib/librte_eal/common/include/rte_bus.h | 19 +++++++++++++++++++
lib/librte_eal/linuxapp/eal/eal.c | 7 +++++++
4 files changed, 63 insertions(+)
diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
index 35e3117..30afc6b 100644
--- a/lib/librte_eal/bsdapp/eal/eal.c
+++ b/lib/librte_eal/bsdapp/eal/eal.c
@@ -64,6 +64,7 @@
#include <rte_string_fns.h>
#include <rte_cpuflags.h>
#include <rte_interrupts.h>
+#include <rte_bus.h>
#include <rte_pci.h>
#include <rte_dev.h>
#include <rte_devargs.h>
@@ -580,6 +581,9 @@ rte_eal_init(int argc, char **argv)
if (rte_eal_dev_init() < 0)
rte_panic("Cannot init pmd devices\n");
+ if (rte_eal_bus_scan())
+ rte_panic("Cannot scan the buses for devices\n");
+
RTE_LCORE_FOREACH_SLAVE(i) {
/*
@@ -616,6 +620,9 @@ rte_eal_init(int argc, char **argv)
if (rte_eal_pci_probe())
rte_panic("Cannot probe PCI\n");
+ if (rte_eal_bus_probe())
+ rte_panic("Cannot probe devices\n");
+
rte_eal_mcfg_complete();
return fctret;
diff --git a/lib/librte_eal/common/eal_common_bus.c b/lib/librte_eal/common/eal_common_bus.c
index 3be9c77..67b808b 100644
--- a/lib/librte_eal/common/eal_common_bus.c
+++ b/lib/librte_eal/common/eal_common_bus.c
@@ -173,6 +173,36 @@ rte_eal_bus_unregister(struct rte_bus *bus)
RTE_LOG(INFO, EAL, "Unregistered [%s] bus.\n", bus->name);
}
+/* Scan all the buses for registering devices */
+int
+rte_eal_bus_scan(void)
+{
+ int ret;
+ struct rte_bus *bus = NULL;
+
+ TAILQ_FOREACH(bus, &rte_bus_list, next) {
+ ret = bus->scan(bus);
+ if (ret) {
+ RTE_LOG(ERR, EAL, "Scan for (%s) bus failed.\n",
+ bus->name);
+ /* TODO: Should error on a particular bus block scan
+ * for all others?
+ */
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+/* Match driver<->device and call driver->probe() */
+int
+rte_eal_bus_probe(void)
+{
+ /* Until driver->probe is available, this is dummy implementation */
+ return 0;
+}
+
/* dump one bus info */
static int
bus_dump_one(FILE *f, struct rte_bus *bus)
diff --git a/lib/librte_eal/common/include/rte_bus.h b/lib/librte_eal/common/include/rte_bus.h
index d1bd2e8..9bd8650 100644
--- a/lib/librte_eal/common/include/rte_bus.h
+++ b/lib/librte_eal/common/include/rte_bus.h
@@ -209,6 +209,25 @@ void rte_eal_bus_unregister(struct rte_bus *bus);
*/
struct rte_bus *rte_eal_get_bus(const char *bus_name);
+/** @internal
+ * Scan all the buses attached to the framework.
+ *
+ * @param void
+ * @return void
+ */
+int rte_eal_bus_scan(void);
+
+/** @internal
+ * For each device on the bus, perform a driver 'match' and call the
+ * driver's probe for device initialization.
+ *
+ * @param void
+ * @return
+ * 0 for successful match/probe
+ * !0 otherwise
+ */
+int rte_eal_bus_probe(void);
+
/**
* Dump information of all the buses registered with EAL.
*
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 2075282..01d0cee 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -69,6 +69,7 @@
#include <rte_string_fns.h>
#include <rte_cpuflags.h>
#include <rte_interrupts.h>
+#include <rte_bus.h>
#include <rte_pci.h>
#include <rte_dev.h>
#include <rte_devargs.h>
@@ -847,6 +848,9 @@ rte_eal_init(int argc, char **argv)
if (rte_eal_intr_init() < 0)
rte_panic("Cannot init interrupt-handling thread\n");
+ if (rte_eal_bus_scan())
+ rte_panic("Cannot scan the buses for devices\n");
+
RTE_LCORE_FOREACH_SLAVE(i) {
/*
@@ -887,6 +891,9 @@ rte_eal_init(int argc, char **argv)
if (rte_eal_pci_probe())
rte_panic("Cannot probe PCI\n");
+ if (rte_eal_bus_probe())
+ rte_panic("Cannot probe devices\n");
+
rte_eal_mcfg_complete();
return fctret;
--
2.7.4
^ permalink raw reply related
* [PATCH v2 04/12] eal/bus: add scan, match and insert support
From: Shreyansh Jain @ 2016-12-13 13:37 UTC (permalink / raw)
To: dev, david.marchand
Cc: thomas.monjalon, ferruh.yigit, jianbo.liu, Shreyansh Jain
In-Reply-To: <1481636232-2300-1-git-send-email-shreyansh.jain@nxp.com>
When a PMD is registred, it will associate itself with a bus.
A bus is responsible for 'scan' of all the devices attached to it.
All the scanned devices are attached to bus specific device_list.
During the probe operation, 'match' of the drivers and devices would
be done.
Also, rather than adding a device to tail, a new device might be added to
the list (pivoted on bus) at a predefined position, for example, adding it
in order of addressing. Support for this is added as '*bus_insert'.
This patch also adds necessary test framework to test the scan and
match callbacks.
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
app/test/test_bus.c | 265 ++++++++++++++++++++++++++++++++
lib/librte_eal/common/eal_common_bus.c | 14 ++
lib/librte_eal/common/include/rte_bus.h | 64 ++++++++
3 files changed, 343 insertions(+)
diff --git a/app/test/test_bus.c b/app/test/test_bus.c
index 760d40a..ed95479 100644
--- a/app/test/test_bus.c
+++ b/app/test/test_bus.c
@@ -80,12 +80,32 @@ struct dummy_bus {
struct rte_bus_list orig_bus_list =
TAILQ_HEAD_INITIALIZER(orig_bus_list);
+/* Forward declarations for callbacks from bus */
+
+/* Bus A
+ * Scan would register devA1 and devA2 to bus
+ */
+int scan_fn_for_busA(struct rte_bus *bus);
+
+/* Bus B
+ * Scan would register devB1 and devB2 to bus
+ */
+int scan_fn_for_busB(struct rte_bus *bus);
+
+/* generic implementations wrapped around by above declarations */
+static int generic_scan_fn(struct rte_bus *bus);
+static int generic_match_fn(struct rte_driver *drv, struct rte_device *dev);
+
struct rte_bus busA = {
.name = "busA", /* "busA" */
+ .scan = scan_fn_for_busA,
+ .match = generic_match_fn,
};
struct rte_bus busB = {
.name = "busB", /* "busB */
+ .scan = scan_fn_for_busB,
+ .match = generic_match_fn,
};
struct rte_driver driverA = {
@@ -184,6 +204,92 @@ dump_device_tree(void)
printf("------>8-------\n");
}
+/* @internal
+ * Move over the dummy_buses and find the entry matching the bus object
+ * passed as argument.
+ * For each device in that dummy_buses list, register.
+ *
+ * @param bus
+ * bus to scan againt test entry
+ * @return
+ * 0 for successful scan, even if no devices are found
+ * !0 for any error in scanning (like, invalid bus)
+ */
+static int
+generic_scan_fn(struct rte_bus *bus)
+{
+ int i = 0;
+ struct rte_device *dev = NULL;
+ struct dummy_bus *db = NULL;
+
+ if (!bus)
+ return -1;
+
+ /* Extract the device tree node using the bus passed */
+ for (i = 0; dummy_buses[i].name; i++) {
+ if (!strcmp(dummy_buses[i].name, bus->name)) {
+ db = &dummy_buses[i];
+ break;
+ }
+ }
+
+ if (!db)
+ return -1;
+
+ /* For all the devices in the device tree (dummy_buses), add device */
+ for (i = 0; db->devices[i]; i++) {
+ dev = &(db->devices[i]->dev);
+ rte_eal_bus_add_device(bus, dev);
+ }
+
+ return 0;
+}
+
+/* @internal
+ * Obtain bus from driver object. Match the address of rte_device object
+ * with all the devices associated with that bus.
+ *
+ * Being a test function, all this does is validate that device object
+ * provided is available on the same bus to which driver is registered.
+ *
+ * @param drv
+ * driver to which matching is to be performed
+ * @param dev
+ * device object to match with driver
+ * @return
+ * 0 for successful match
+ * !0 for failed match
+ */
+static int
+generic_match_fn(struct rte_driver *drv, struct rte_device *dev)
+{
+ struct rte_bus *bus;
+ struct rte_device *dev_p = NULL;
+
+ /* Match is based entirely on address of 'dev' and 'dev_p' extracted
+ * from bus->device_list.
+ */
+
+ /* a driver is registered with the bus *before* the scan. */
+ bus = drv->bus;
+ TAILQ_FOREACH(dev_p, &bus->device_list, next) {
+ if (dev == dev_p)
+ return 0;
+ }
+
+ return 1;
+}
+
+int
+scan_fn_for_busA(struct rte_bus *bus) {
+ return generic_scan_fn(bus);
+}
+
+int
+scan_fn_for_busB(struct rte_bus *bus) {
+ return generic_scan_fn(bus);
+}
+
static int
test_bus_setup(void)
{
@@ -391,6 +497,155 @@ test_driver_unregistration_on_bus(void)
}
+static int
+test_device_unregistration_on_bus(void)
+{
+ int i;
+ struct rte_bus *bus = NULL;
+ struct rte_device *dev;
+
+ for (i = 0; dummy_buses[i].name; i++) {
+ bus = rte_eal_get_bus(dummy_buses[i].name);
+ if (!bus) {
+ printf("Unable to find bus (%s)\n",
+ dummy_buses[i].name);
+ return -1;
+ }
+
+ /* For bus 'bus', unregister all devices */
+ TAILQ_FOREACH(dev, &bus->device_list, next) {
+ rte_eal_bus_remove_device(dev);
+ }
+ }
+
+ for (i = 0; dummy_buses[i].name; i++) {
+ bus = rte_eal_get_bus(dummy_buses[i].name);
+
+ if (!TAILQ_EMPTY(&bus->device_list)) {
+ printf("Unable to remove all devices on bus (%s)\n",
+ bus->name);
+ return -1;
+ }
+ }
+
+ /* All devices from all buses have been removed */
+ printf("All devices on all buses unregistered.\n");
+ dump_device_tree();
+
+ return 0;
+}
+
+/* @internal
+ * For each bus registered, call the scan function to identify devices
+ * on the bus.
+ *
+ * @param void
+ * @return
+ * 0 for successful scan
+ * !0 for unsuccessful scan
+ *
+ */
+static int
+test_bus_scan(void)
+{
+ int ret;
+ struct rte_bus *bus;
+
+ TAILQ_FOREACH(bus, &rte_bus_list, next) {
+ /* Call the scan function for each bus */
+ ret = bus->scan(bus);
+ if (ret) {
+ printf("Scan of buses failed.\n");
+ return -1;
+ }
+ }
+
+ printf("Scan of all buses completed.\n");
+ dump_device_tree();
+
+ return 0;
+}
+
+/* @internal
+ * Function to perform 'probe' and link devices and drivers on a bus.
+ * This would work over all the buses registered, and all devices and drivers
+ * registered with it - call match on each pair.
+ * Aim is to test the match_fn for each bus.
+ *
+ * @param void
+ * @return
+ * 0 for successful probe
+ * !0 for failure in probe
+ *
+ */
+static int
+test_probe_on_bus(void)
+{
+ int ret = 0;
+ int i, j;
+ struct rte_bus *bus = NULL;
+ struct rte_device *dev = NULL;
+ struct rte_driver *drv = NULL;
+
+ /* In case of this test:
+ * 1. for each bus in rte_bus_list
+ * 2. for each device in bus->device_list
+ * 3. for each driver in bus->driver_list
+ * 4. call match
+ * 5. link driver and device
+ * 6. Verify the linkage.
+ */
+ for (i = 0; dummy_buses[i].name; i++) {
+ /* get bus pointer from dummy_buses itself rather than
+ * rte_eal_get_bus
+ */
+ bus = dummy_buses[i].bus;
+
+ TAILQ_FOREACH(dev, &bus->device_list, next) {
+ TAILQ_FOREACH(drv, &bus->driver_list, next) {
+ if (!bus->match) {
+ printf("Incorrect bus without match "
+ "fn: (%s).\n", bus->name);
+ return -1;
+ }
+
+ ret = bus->match(drv, dev);
+ if (ret) {
+ printf("Device and driver don't "
+ "belong to same bus.\n");
+ return -1;
+ }
+ dev->driver = drv;
+
+ /* As match is generic, it always results in
+ * dev->drv pointing to first driver entry in
+ * dummy_buses[i]
+ */
+ }
+ }
+ }
+
+ /* Verify the linkage. All devices belonging to a dummy_buses[i]
+ * should have same driver (first driver entry of dummy_buses[i])
+ */
+ for (i = 0; dummy_buses[i].name; i++) {
+ drv = dummy_buses[i].drivers[0];
+
+ for (j = 0; dummy_buses[i].devices[j]; j++) {
+ dev = &(dummy_buses[i].devices[j]->dev);
+ if (dev->driver != drv) {
+ printf("Incorrect driver<->device linkage.\n");
+ return -1;
+ }
+ }
+ }
+
+ printf("Probe on all buses successful.\n");
+ dump_device_tree();
+
+ return 0;
+}
+
int
test_bus(void)
{
@@ -407,6 +662,16 @@ test_bus(void)
if (test_driver_registration_on_bus())
return -1;
+ if (test_bus_scan())
+ return -1;
+
+ /* Now that the devices and drivers are registered, perform probe */
+ if (test_probe_on_bus())
+ return -1;
+
+ if (test_device_unregistration_on_bus())
+ return -1;
+
if (test_driver_unregistration_on_bus())
return -1;
diff --git a/lib/librte_eal/common/eal_common_bus.c b/lib/librte_eal/common/eal_common_bus.c
index 612f64e..3be9c77 100644
--- a/lib/librte_eal/common/eal_common_bus.c
+++ b/lib/librte_eal/common/eal_common_bus.c
@@ -58,6 +58,17 @@ rte_eal_bus_add_device(struct rte_bus *bus, struct rte_device *dev)
dev->bus = bus;
}
+void
+rte_eal_bus_insert_device(struct rte_bus *bus, struct rte_device *old_dev,
+ struct rte_device *new_dev)
+{
+ RTE_VERIFY(bus);
+ RTE_VERIFY(old_dev);
+ RTE_VERIFY(new_dev);
+
+ TAILQ_INSERT_BEFORE(old_dev, new_dev, next);
+}
+
/** @internal
* Remove a device from its bus.
*/
@@ -132,6 +143,9 @@ rte_eal_bus_register(struct rte_bus *bus)
{
RTE_VERIFY(bus);
RTE_VERIFY(bus->name && strlen(bus->name));
+ /* A bus should mandatorily have the scan and match implemented */
+ RTE_VERIFY(bus->scan);
+ RTE_VERIFY(bus->match);
/* Initialize the driver and device list associated with the bus */
TAILQ_INIT(&(bus->driver_list));
diff --git a/lib/librte_eal/common/include/rte_bus.h b/lib/librte_eal/common/include/rte_bus.h
index f0297a9..d1bd2e8 100644
--- a/lib/librte_eal/common/include/rte_bus.h
+++ b/lib/librte_eal/common/include/rte_bus.h
@@ -59,6 +59,49 @@ TAILQ_HEAD(rte_bus_list, rte_bus);
/* Global Bus list */
extern struct rte_bus_list rte_bus_list;
+/**
+ * Bus specific scan for devices attached on the bus.
+ * For each bus object, the scan would be reponsible for finding devices and
+ * adding them to its private device list.
+ *
+ * Successful detection of a device results in rte_device object which is
+ * embedded within the respective device type (rte_pci_device, for example).
+ * Thereafter, PCI specific bus would need to perform
+ * container_of(rte_pci_device) to obtain PCI device object.
+ *
+ * Scan failure of a bus is not treated as exit criteria for application. Scan
+ * for all other buses would still continue.
+ *
+ * A bus should mandatorily implement this method.
+ *
+ * @param bus
+ * Reference to the bus on which device is added
+ * @return
+ * 0 for successful scan
+ * !0 (<0) for unsuccessful scan with error value
+ */
+typedef int (*bus_scan_t)(struct rte_bus *bus);
+
+/**
+ * Bus specific match for devices and drivers which can service them.
+ * For each scanned device, rte_driver->probe would be called for driver
+ * specific initialization of the device.
+ *
+ * It is the work of each bus handler to obtain the specific device object
+ * using container_of (or typecasting, as a less preferred way).
+ *
+ * A bus should mandatorily implement this method.
+ *
+ * @param drv
+ * Driver object attached to the bus
+ * @param dev
+ * Device object which is being probed.
+ * @return
+ * 0 for successful match
+ * !0 for unsuccessful match
+ */
+typedef int (*bus_match_t)(struct rte_driver *drv, struct rte_device *dev);
+
struct rte_bus {
TAILQ_ENTRY(rte_bus) next; /**< Next bus object in linked list */
struct rte_driver_list driver_list;
@@ -66,6 +109,9 @@ struct rte_bus {
struct rte_device_list device_list;
/**< List of all devices on bus */
const char *name; /**< Name of the bus */
+ bus_scan_t scan; /**< Scan for devices attached to bus */
+ bus_match_t match;
+ /**< Match device with drivers associated with the bus */
};
/** @internal
@@ -82,6 +128,24 @@ void
rte_eal_bus_add_device(struct rte_bus *bus, struct rte_device *dev);
/** @internal
+ * Rather than adding a device to tail, insert at a predefined location.
+ * This is specifically useful for update device cases, or where addition
+ * of devices in the list needs to be ordered (addressing, for example).
+ *
+ * @param bus
+ * Handle for bus on which device is to be added
+ * @param old_dev
+ * Existing rte_device object before which new device needs to be added
+ * @param new_dev
+ * Object for device to be added before old_dev
+ * @return
+ * void
+ */
+void
+rte_eal_bus_insert_device(struct rte_bus *bus, struct rte_device *old_device,
+ struct rte_device *new_device);
+
+/** @internal
* Remove a device from its bus.
*
* @param dev
--
2.7.4
^ permalink raw reply related
* [PATCH v2 03/12] test: add basic bus infrastructure tests
From: Shreyansh Jain @ 2016-12-13 13:37 UTC (permalink / raw)
To: dev, david.marchand
Cc: thomas.monjalon, ferruh.yigit, jianbo.liu, Shreyansh Jain
In-Reply-To: <1481636232-2300-1-git-send-email-shreyansh.jain@nxp.com>
Verification of bus registration, driver registration on a bus.
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
app/test/Makefile | 2 +-
app/test/test.h | 2 +
app/test/test_bus.c | 423 ++++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 426 insertions(+), 1 deletion(-)
create mode 100644 app/test/test_bus.c
diff --git a/app/test/Makefile b/app/test/Makefile
index 5be023a..ca0f106 100644
--- a/app/test/Makefile
+++ b/app/test/Makefile
@@ -94,7 +94,7 @@ SRCS-y += test_cycles.c
SRCS-y += test_spinlock.c
SRCS-y += test_memory.c
SRCS-y += test_memzone.c
-
+SRCS-y += test_bus.c
SRCS-y += test_ring.c
SRCS-y += test_ring_perf.c
SRCS-y += test_pmd_perf.c
diff --git a/app/test/test.h b/app/test/test.h
index 82831f4..c8ec43f 100644
--- a/app/test/test.h
+++ b/app/test/test.h
@@ -236,6 +236,8 @@ int commands_init(void);
int test_pci(void);
int test_pci_run;
+int test_bus(void);
+
int test_mp_secondary(void);
int test_set_rxtx_conf(cmdline_fixed_string_t mode);
diff --git a/app/test/test_bus.c b/app/test/test_bus.c
new file mode 100644
index 0000000..760d40a
--- /dev/null
+++ b/app/test/test_bus.c
@@ -0,0 +1,423 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2016 NXP.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of NXP nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <sys/queue.h>
+
+#include <rte_bus.h>
+#include <rte_devargs.h>
+
+#include "test.h"
+#include "resource.h"
+
+/* Visualizing following bus-device-driver model for test
+ *
+ * ===.===========.===========.=========,= busA
+ * | | . |
+ * devA1 devA2 . '____CPU_
+ * `-----------`-------> driverA |
+ * '
+ * ===.===========.===========.=========|= busB
+ * | | .
+ * devB1 devB2 .
+ * `-----------`-------> driverB
+ *
+ */
+
+#define MAX_DEVICES_ON_BUS 10
+#define MAX_DRIVERS_ON_BUS 10
+
+/* A structure representing a ethernet/crypto device, embedding
+ * the rte_device.
+ */
+struct dummy_device {
+ const char *name;
+ struct rte_device dev;
+};
+
+/* Structure representing a Bus with devices attached to it, and drivers
+ * for those devices
+ */
+struct dummy_bus {
+ const char *name;
+ struct rte_bus *bus;
+ struct rte_driver *drivers[MAX_DRIVERS_ON_BUS];
+ struct dummy_device *devices[MAX_DEVICES_ON_BUS];
+};
+
+struct rte_bus_list orig_bus_list =
+ TAILQ_HEAD_INITIALIZER(orig_bus_list);
+
+struct rte_bus busA = {
+ .name = "busA", /* "busA" */
+};
+
+struct rte_bus busB = {
+ .name = "busB", /* "busB */
+};
+
+struct rte_driver driverA = {
+ .name = "driverA",
+};
+
+struct dummy_device devA1 = {
+ .name = "devA1",
+ .dev = {
+ .bus = NULL,
+ .driver = NULL,
+ }
+};
+
+struct dummy_device devA2 = {
+ .name = "devA2",
+ .dev = {
+ .bus = NULL,
+ .driver = NULL,
+ }
+};
+
+struct rte_driver driverB = {
+ .name = "driverB",
+};
+
+struct dummy_device devB1 = {
+ .name = "devB1",
+ .dev = {
+ .bus = NULL,
+ .driver = NULL,
+ }
+};
+
+struct dummy_device devB2 = {
+ .name = "devB2",
+ .dev = {
+ .bus = NULL,
+ .driver = NULL,
+ }
+};
+
+struct dummy_bus dummy_buses[] = {
+ {
+ .name = "busA",
+ .bus = &busA,
+ .drivers = {&driverA, NULL},
+ .devices = {&devA1, &devA2, NULL},
+ },
+ {
+ .name = "busB",
+ .bus = &busB,
+ .drivers = {&driverB, NULL},
+ .devices = {&devB1, &devB2, NULL},
+ },
+ {NULL, NULL, {NULL,}, {NULL,}, },
+};
+
+/* @internal
+ * Dump the device tree
+ */
+static void
+dump_device_tree(void)
+{
+ int i;
+ struct dummy_bus *db;
+ struct rte_bus *bus;
+ struct rte_driver *drv;
+ struct rte_device *dev;
+
+ printf("------>8-------\n");
+ printf("Device Tree:\n");
+ for (i = 0; dummy_buses[i].name; i++) {
+ db = &dummy_buses[i];
+
+ bus = rte_eal_get_bus(db->name);
+ if (!bus)
+ return;
+
+ printf(" Bus: %s\n", bus->name);
+
+ printf(" Drivers on bus:\n");
+ TAILQ_FOREACH(drv, &bus->driver_list, next) {
+ printf(" %s\n", drv->name);
+ }
+
+ printf(" Devices on bus:\n");
+ TAILQ_FOREACH(dev, &bus->device_list, next) {
+ printf(" Addr: %p\n", dev);
+ if (dev->driver)
+ printf(" Driver = %s\n", dev->driver->name);
+ else
+ printf(" Driver = None\n");
+ }
+ }
+ printf("------>8-------\n");
+}
+
+static int
+test_bus_setup(void)
+{
+ struct rte_bus *bus_p = NULL;
+
+ /* Preserve the original bus list before executing test */
+ while (!TAILQ_EMPTY(&rte_bus_list)) {
+ bus_p = TAILQ_FIRST(&rte_bus_list);
+ rte_eal_bus_unregister(bus_p);
+ TAILQ_INSERT_TAIL(&orig_bus_list, bus_p, next);
+ }
+
+ return 0;
+}
+
+static int
+test_bus_cleanup(void)
+{
+ struct rte_bus *bus_p = NULL;
+
+ /* Cleanup rte_bus_list before restoring entries */
+ while (!TAILQ_EMPTY(&rte_bus_list)) {
+ bus_p = TAILQ_FIRST(&rte_bus_list);
+ rte_eal_bus_unregister(bus_p);
+ }
+
+ bus_p = NULL;
+ /* Restore original entries */
+ while (!TAILQ_EMPTY(&orig_bus_list)) {
+ bus_p = TAILQ_FIRST(&orig_bus_list);
+ TAILQ_REMOVE(&orig_bus_list, bus_p, next);
+ rte_eal_bus_register(bus_p);
+ }
+
+ dump_device_tree();
+ return 0;
+}
+
+
+static int
+test_bus_registration(void)
+{
+ int i;
+ int ret;
+ struct rte_bus *bus = NULL;
+
+ for (i = 0; dummy_buses[i].name != NULL; i++) {
+ bus = dummy_buses[i].bus;
+ rte_eal_bus_register(bus);
+ printf("Registered Bus %s\n", dummy_buses[i].name);
+ }
+
+ /* Verify that all buses have been successfully registered */
+ i = 0;
+ TAILQ_FOREACH(bus, &rte_bus_list, next) {
+ /* Or, if the name of the bus is NULL */
+ if (!bus->name) {
+ /* Incorrect entry in list */
+ printf("Incorrect bus registered.\n");
+ return -1;
+ }
+
+ /* Or, if the bus name doesn't match that of dummy_buses */
+ ret = strcmp(bus->name, dummy_buses[i].name);
+ if (ret) {
+ /* Bus name doesn't match */
+ printf("Unable to correctly register bus (%s).\n",
+ dummy_buses[i].name);
+ return -1;
+ }
+ i++;
+ }
+
+ /* Current value of dummy_buses[i] should be the NULL entry */
+ if (dummy_buses[i].name != NULL) {
+ printf("Not all buses were registered. For e.g. (%s)\n",
+ dummy_buses[i].name);
+ return -1;
+ }
+
+ printf("Buses registered are:\n");
+ rte_eal_bus_dump(stdout);
+
+ return 0;
+}
+
+static int
+test_bus_unregistration(void)
+{
+ int i;
+ struct rte_bus *bus = NULL;
+
+ for (i = 0; dummy_buses[i].name != NULL; i++) {
+ bus = rte_eal_get_bus(dummy_buses[i].name);
+ if (bus) {
+ printf("Unregistering bus: '%s'\n", bus->name);
+ rte_eal_bus_unregister(bus);
+ }
+ }
+
+ if (!TAILQ_EMPTY(&rte_bus_list)) {
+ /* Unable to unregister all dummy buses */
+ printf("Unable to unregister all buses\n");
+ return -1;
+ }
+
+ printf("All buses have been unregistered.\n");
+ dump_device_tree();
+ return 0;
+}
+
+/* Positive case: For each driver in dummy_buses, perform
+ * registration
+ */
+static int
+test_driver_registration_on_bus(void)
+{
+ int i, j;
+ struct rte_bus *bus = NULL;
+ struct rte_driver *drv, *drv2;
+
+ /* For each bus on the dummy_buses list:
+ * 1. get the bus reference
+ * 2. register all drivers from dummy_buses
+ */
+ for (i = 0; dummy_buses[i].name; i++) {
+ bus = rte_eal_get_bus(dummy_buses[i].name);
+ if (!bus) {
+ printf("Unable to find bus (%s)\n",
+ dummy_buses[i].name);
+ return -1;
+ }
+
+ /* For bus 'bus', register all drivers */
+ for (j = 0; dummy_buses[i].drivers[j]; j++) {
+ drv = dummy_buses[i].drivers[j];
+ rte_eal_bus_add_driver(bus, drv);
+ }
+ }
+
+ /* Drivers have been registered. Verify by parsing the list */
+ drv = NULL;
+ for (i = 0; dummy_buses[i].name; i++) {
+ bus = rte_eal_get_bus(dummy_buses[i].name);
+ if (!bus) {
+ printf("Unable to find bus (%s)\n",
+ dummy_buses[i].name);
+ return -1;
+ }
+
+ j = 0;
+ TAILQ_FOREACH(drv, &bus->driver_list, next) {
+ drv2 = dummy_buses[i].drivers[j++];
+ if (strcmp(drv2->name, drv->name)) {
+ printf("Incorrectly registered drivers."
+ " Expected: %s; Available: %s\n",
+ drv2->name, drv->name);
+ return -1;
+ }
+ }
+ }
+
+ printf("Driver registration test successful.\n");
+ dump_device_tree();
+
+ return 0;
+}
+
+static int
+test_driver_unregistration_on_bus(void)
+{
+ int i;
+ struct rte_bus *bus = NULL;
+ struct rte_driver *drv;
+
+ for (i = 0; dummy_buses[i].name; i++) {
+ bus = rte_eal_get_bus(dummy_buses[i].name);
+ if (!bus) {
+ printf("Unable to find bus (%s)\n",
+ dummy_buses[i].name);
+ return -1;
+ }
+
+ /* For bus 'bus', unregister all drivers */
+ TAILQ_FOREACH(drv, &bus->driver_list, next) {
+ rte_eal_bus_remove_driver(drv);
+ }
+ }
+
+ /* Verifying that all drivers have been removed */
+ for (i = 0; dummy_buses[i].name; i++) {
+ bus = rte_eal_get_bus(dummy_buses[i].name);
+
+ if (!TAILQ_EMPTY(&bus->driver_list)) {
+ printf("Unable to remove all drivers on bus (%s)\n",
+ bus->name);
+ return -1;
+ }
+ }
+
+ printf("Unregistration of drivers on all buses is successful.\n");
+ /* All devices from all buses have been removed */
+ dump_device_tree();
+ return 0;
+
+}
+
+int
+test_bus(void)
+{
+ /* Make necessary arrangements before starting test */
+ if (test_bus_setup())
+ return -1;
+
+ if (test_bus_registration())
+ return -1;
+
+ /* Assuming that buses are already registered, register drivers
+ * with them.
+ */
+ if (test_driver_registration_on_bus())
+ return -1;
+
+ if (test_driver_unregistration_on_bus())
+ return -1;
+
+ if (test_bus_unregistration())
+ return -1;
+
+ /* Restore the original environment/settings */
+ if (test_bus_cleanup())
+ return -1;
+
+ return 0;
+}
+
+REGISTER_TEST_COMMAND(bus_autotest, test_bus);
--
2.7.4
^ permalink raw reply related
* [PATCH v2 02/12] eal/bus: introduce bus abstraction
From: Shreyansh Jain @ 2016-12-13 13:37 UTC (permalink / raw)
To: dev, david.marchand
Cc: thomas.monjalon, ferruh.yigit, jianbo.liu, Shreyansh Jain
In-Reply-To: <1481636232-2300-1-git-send-email-shreyansh.jain@nxp.com>
This patch introduces the rte_bus abstraction for devices and drivers in
EAL framework. The model is:
- One or more buses are connected to a CPU (or core)
- One or more devices are conneted to a Bus
- Drivers are running instances which manage one or more devices
- Bus is responsible for identifying devices (and interrupt propogation)
- Driver is responsible for initializing the device
This patch adds a 'rte_bus' class which rte_driver and rte_device refer.
This way, each device (rte_xxx_device) would have reference to the bus
it is based on. As well as, each driver (rte_xxx_driver) would have link
to the bus and devices on it for servicing.
__ rte_bus_list
/
+----------'---+
|rte_bus |
| driver_list------> List of rte_bus specific
| device_list---- devices
| | `-> List of rte_bus associated
| | drivers
+--|------|----+
_________/ \_________
+--------/----+ +-\---------------+
|rte_device | |rte_driver |
| rte_bus | | rte_bus |
| rte_driver | | ... |
| ... | +---------...-----+
| | |||
+---||--------+ |||
|| |||
| \ \\\
| \_____________ \\\
| \ |||
+------|---------+ +----|----------+ |||
|rte_pci_device | |rte_xxx_device | |||
| .... | | .... | |||
+----------------+ +---------------+ / | \
/ | \
_____________________/ / \
/ ___/ \
+-------------'--+ +------------'---+ +--'------------+
|rte_pci_driver | |rte_vdev_driver | |rte_xxx_driver |
| .... | | .... | | .... |
+----------------+ +----------------+ +---------------+
This patch only enables the bus references on rte_driver and rte_driver.
EAL wide global device and driver list continue to exist until an instance
of bus is added in subsequent patches.
This patch also introduces RTE_REGISTER_BUS macro on the lines of
RTE_PMD_REGISTER_XXX. Key difference is that the constructor priority has
been explicitly set to 101 so as to execute bus registration before PMD.
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
--
v2:
- fix bsdapp compilation issue because of missing export symbols in map
file
---
lib/librte_eal/bsdapp/eal/Makefile | 1 +
lib/librte_eal/bsdapp/eal/rte_eal_version.map | 15 ++
lib/librte_eal/common/Makefile | 2 +-
lib/librte_eal/common/eal_common_bus.c | 192 ++++++++++++++++++++++++
lib/librte_eal/common/include/rte_bus.h | 174 +++++++++++++++++++++
lib/librte_eal/common/include/rte_dev.h | 2 +
lib/librte_eal/linuxapp/eal/Makefile | 1 +
lib/librte_eal/linuxapp/eal/rte_eal_version.map | 15 ++
8 files changed, 401 insertions(+), 1 deletion(-)
create mode 100644 lib/librte_eal/common/eal_common_bus.c
create mode 100644 lib/librte_eal/common/include/rte_bus.h
diff --git a/lib/librte_eal/bsdapp/eal/Makefile b/lib/librte_eal/bsdapp/eal/Makefile
index a15b762..cce99f7 100644
--- a/lib/librte_eal/bsdapp/eal/Makefile
+++ b/lib/librte_eal/bsdapp/eal/Makefile
@@ -78,6 +78,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_cpuflags.c
SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_string_fns.c
SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_hexdump.c
SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_devargs.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_bus.c
SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_dev.c
SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_options.c
SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_common_thread.c
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index 2f81f7c..23fc1c1 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -174,3 +174,18 @@ DPDK_16.11 {
rte_eal_vdrv_unregister;
} DPDK_16.07;
+
+DPDK_17.02 {
+ global:
+
+ rte_bus_list;
+ rte_eal_bus_add_device;
+ rte_eal_bus_add_driver;
+ rte_eal_get_bus;
+ rte_eal_bus_dump;
+ rte_eal_bus_register;
+ rte_eal_bus_remove_device;
+ rte_eal_bus_remove_driver;
+ rte_eal_bus_unregister;
+
+} DPDK_16.11;
diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index a92c984..0c39414 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -38,7 +38,7 @@ INC += rte_per_lcore.h rte_random.h
INC += rte_tailq.h rte_interrupts.h rte_alarm.h
INC += rte_string_fns.h rte_version.h
INC += rte_eal_memconfig.h rte_malloc_heap.h
-INC += rte_hexdump.h rte_devargs.h rte_dev.h rte_vdev.h
+INC += rte_hexdump.h rte_devargs.h rte_bus.h rte_dev.h rte_vdev.h
INC += rte_pci_dev_feature_defs.h rte_pci_dev_features.h
INC += rte_malloc.h rte_keepalive.h rte_time.h
diff --git a/lib/librte_eal/common/eal_common_bus.c b/lib/librte_eal/common/eal_common_bus.c
new file mode 100644
index 0000000..612f64e
--- /dev/null
+++ b/lib/librte_eal/common/eal_common_bus.c
@@ -0,0 +1,192 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2016 NXP
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of NXP nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <inttypes.h>
+#include <sys/queue.h>
+
+#include <rte_bus.h>
+#include <rte_devargs.h>
+#include <rte_debug.h>
+
+#include "eal_private.h"
+
+struct rte_bus_list rte_bus_list =
+ TAILQ_HEAD_INITIALIZER(rte_bus_list);
+
+/** @internal
+ * Add a device to a bus.
+ */
+void
+rte_eal_bus_add_device(struct rte_bus *bus, struct rte_device *dev)
+{
+ RTE_VERIFY(bus);
+ RTE_VERIFY(dev);
+
+ TAILQ_INSERT_TAIL(&bus->device_list, dev, next);
+ dev->bus = bus;
+}
+
+/** @internal
+ * Remove a device from its bus.
+ */
+void
+rte_eal_bus_remove_device(struct rte_device *dev)
+{
+ struct rte_bus *bus;
+
+ RTE_VERIFY(dev);
+ RTE_VERIFY(dev->bus);
+
+ bus = dev->bus;
+ TAILQ_REMOVE(&bus->device_list, dev, next);
+ dev->bus = NULL;
+}
+
+/** @internal
+ * Associate a driver with a bus.
+ */
+void
+rte_eal_bus_add_driver(struct rte_bus *bus, struct rte_driver *drv)
+{
+ RTE_VERIFY(bus);
+ RTE_VERIFY(drv);
+
+ TAILQ_INSERT_TAIL(&bus->driver_list, drv, next);
+ drv->bus = bus;
+}
+
+/** @internal
+ * Disassociate a driver from bus.
+ */
+void
+rte_eal_bus_remove_driver(struct rte_driver *drv)
+{
+ struct rte_bus *bus;
+
+ RTE_VERIFY(drv);
+ RTE_VERIFY(drv->bus);
+
+ bus = drv->bus;
+ TAILQ_REMOVE(&bus->driver_list, drv, next);
+ drv->bus = NULL;
+}
+
+/**
+ * Get the bus handle using its name
+ */
+struct rte_bus *
+rte_eal_get_bus(const char *bus_name)
+{
+ struct rte_bus *bus;
+
+ RTE_VERIFY(bus_name);
+
+ TAILQ_FOREACH(bus, &rte_bus_list, next) {
+ RTE_VERIFY(bus->name);
+
+ if (!strcmp(bus_name, bus->name)) {
+ RTE_LOG(DEBUG, EAL, "Returning Bus object %p\n", bus);
+ return bus;
+ }
+ }
+
+ /* Unable to find bus requested */
+ return NULL;
+}
+
+/* register a bus */
+void
+rte_eal_bus_register(struct rte_bus *bus)
+{
+ RTE_VERIFY(bus);
+ RTE_VERIFY(bus->name && strlen(bus->name));
+
+ /* Initialize the driver and device list associated with the bus */
+ TAILQ_INIT(&(bus->driver_list));
+ TAILQ_INIT(&(bus->device_list));
+
+ TAILQ_INSERT_TAIL(&rte_bus_list, bus, next);
+ RTE_LOG(INFO, EAL, "Registered [%s] bus.\n", bus->name);
+}
+
+/* unregister a bus */
+void
+rte_eal_bus_unregister(struct rte_bus *bus)
+{
+ /* All devices and drivers associated with the bus should have been
+ * 'device->uninit' and 'driver->remove()' already.
+ */
+ RTE_VERIFY(TAILQ_EMPTY(&(bus->driver_list)));
+ RTE_VERIFY(TAILQ_EMPTY(&(bus->device_list)));
+
+ /* TODO: For each device, call its rte_device->driver->remove()
+ * and rte_eal_bus_remove_driver()
+ */
+
+ TAILQ_REMOVE(&rte_bus_list, bus, next);
+ RTE_LOG(INFO, EAL, "Unregistered [%s] bus.\n", bus->name);
+}
+
+/* dump one bus info */
+static int
+bus_dump_one(FILE *f, struct rte_bus *bus)
+{
+ int ret;
+
+ /* For now, dump only the bus name */
+ ret = fprintf(f, " %s\n", bus->name);
+
+ /* Error in case of inability in writing to stream */
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
+void
+rte_eal_bus_dump(FILE *f)
+{
+ int ret;
+ struct rte_bus *bus;
+
+ TAILQ_FOREACH(bus, &rte_bus_list, next) {
+ ret = bus_dump_one(f, bus);
+ if (ret) {
+ RTE_LOG(ERR, EAL, "Unable to write to stream (%d)\n",
+ ret);
+ break;
+ }
+ }
+}
diff --git a/lib/librte_eal/common/include/rte_bus.h b/lib/librte_eal/common/include/rte_bus.h
new file mode 100644
index 0000000..f0297a9
--- /dev/null
+++ b/lib/librte_eal/common/include/rte_bus.h
@@ -0,0 +1,174 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2016 NXP
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of NXP nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _RTE_BUS_H_
+#define _RTE_BUS_H_
+
+/**
+ * @file
+ *
+ * RTE PMD Bus Abstraction interfaces
+ *
+ * This file exposes APIs and Interfaces for Bus Abstraction over the devices
+ * drivers in EAL.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <sys/queue.h>
+
+#include <rte_log.h>
+#include <rte_dev.h>
+
+/** Double linked list of buses */
+TAILQ_HEAD(rte_bus_list, rte_bus);
+
+/* Global Bus list */
+extern struct rte_bus_list rte_bus_list;
+
+struct rte_bus {
+ TAILQ_ENTRY(rte_bus) next; /**< Next bus object in linked list */
+ struct rte_driver_list driver_list;
+ /**< List of all drivers on bus */
+ struct rte_device_list device_list;
+ /**< List of all devices on bus */
+ const char *name; /**< Name of the bus */
+};
+
+/** @internal
+ * Add a device to a bus.
+ *
+ * @param bus
+ * Bus on which device is to be added
+ * @param dev
+ * Device handle
+ * @return
+ * None
+ */
+void
+rte_eal_bus_add_device(struct rte_bus *bus, struct rte_device *dev);
+
+/** @internal
+ * Remove a device from its bus.
+ *
+ * @param dev
+ * Device handle to remove
+ * @return
+ * None
+ */
+void
+rte_eal_bus_remove_device(struct rte_device *dev);
+
+/** @internal
+ * Associate a driver with a bus.
+ *
+ * @param bus
+ * Bus on which driver is to be added
+ * @param dev
+ * Driver handle
+ * @return
+ * None
+ */
+void
+rte_eal_bus_add_driver(struct rte_bus *bus, struct rte_driver *drv);
+
+/** @internal
+ * Disassociate a driver from its bus.
+ *
+ * @param dev
+ * Driver handle to remove
+ * @return
+ * None
+ */
+void
+rte_eal_bus_remove_driver(struct rte_driver *drv);
+
+/**
+ * Register a Bus handler.
+ *
+ * @param driver
+ * A pointer to a rte_bus structure describing the bus
+ * to be registered.
+ */
+void rte_eal_bus_register(struct rte_bus *bus);
+
+/**
+ * Unregister a Bus handler.
+ *
+ * @param driver
+ * A pointer to a rte_bus structure describing the bus
+ * to be unregistered.
+ */
+void rte_eal_bus_unregister(struct rte_bus *bus);
+
+/**
+ * Obtain handle for bus given its name.
+ *
+ * @param bus_name
+ * Name of the bus handle to search
+ * @return
+ * Pointer to Bus object if name matches any registered bus object
+ * NULL, if no matching bus found
+ */
+struct rte_bus *rte_eal_get_bus(const char *bus_name);
+
+/**
+ * Dump information of all the buses registered with EAL.
+ *
+ * @param f
+ * A valid and open output stream handle
+ *
+ * @return
+ * 0 in case of success
+ * !0 in case there is error in opening the output stream
+ */
+void rte_eal_bus_dump(FILE *f);
+
+/** Helper for Bus registration. The constructor has higher priority than
+ * PMD constructors
+ */
+#define RTE_REGISTER_BUS(nm, bus) \
+static void __attribute__((constructor(101), used)) businitfn_ ##nm(void) \
+{\
+ (bus).name = RTE_STR(nm);\
+ rte_eal_bus_register(&bus); \
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_BUS_H */
diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
index 8840380..4004f9a 100644
--- a/lib/librte_eal/common/include/rte_dev.h
+++ b/lib/librte_eal/common/include/rte_dev.h
@@ -122,6 +122,7 @@ struct rte_driver;
*/
struct rte_device {
TAILQ_ENTRY(rte_device) next; /**< Next device */
+ struct rte_bus *bus; /**< Device connected to this bus */
struct rte_driver *driver; /**< Associated driver */
int numa_node; /**< NUMA node connection */
struct rte_devargs *devargs; /**< Device user arguments */
@@ -148,6 +149,7 @@ void rte_eal_device_remove(struct rte_device *dev);
*/
struct rte_driver {
TAILQ_ENTRY(rte_driver) next; /**< Next in list. */
+ struct rte_bus *bus; /**< Bus serviced by this driver */
const char *name; /**< Driver name. */
const char *alias; /**< Driver alias. */
};
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index 4e206f0..aa874a5 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -87,6 +87,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_cpuflags.c
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_string_fns.c
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_hexdump.c
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_devargs.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_bus.c
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_dev.c
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_options.c
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_thread.c
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index 83721ba..c873a7f 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -178,3 +178,18 @@ DPDK_16.11 {
rte_eal_vdrv_unregister;
} DPDK_16.07;
+
+DPDK_17.02 {
+ global:
+
+ rte_bus_list;
+ rte_eal_bus_add_device;
+ rte_eal_bus_add_driver;
+ rte_eal_get_bus;
+ rte_eal_bus_dump;
+ rte_eal_bus_register;
+ rte_eal_bus_remove_device;
+ rte_eal_bus_remove_driver;
+ rte_eal_bus_unregister;
+
+} DPDK_16.11;
--
2.7.4
^ permalink raw reply related
* [PATCH v2 01/12] eal: define container_of macro
From: Shreyansh Jain @ 2016-12-13 13:37 UTC (permalink / raw)
To: dev, david.marchand
Cc: thomas.monjalon, ferruh.yigit, jianbo.liu, Jan Blunck,
Jan Viktorin, Shreyansh Jain
In-Reply-To: <1481636232-2300-1-git-send-email-shreyansh.jain@nxp.com>
From: Jan Blunck <jblunck@infradead.org>
This macro is based on Jan Viktorin's original patch but also checks the
type of the passed pointer against the type of the member.
Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
[shreyansh.jain@nxp.com: Fix checkpatch error]
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
[jblunck@infradead.org: add type checking and __extension__]
Signed-off-by: Jan Blunck <jblunck@infradead.org>
--
v2:
- fix checkpatch error
---
lib/librte_eal/common/include/rte_common.h | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/lib/librte_eal/common/include/rte_common.h b/lib/librte_eal/common/include/rte_common.h
index db5ac91..3eb8d11 100644
--- a/lib/librte_eal/common/include/rte_common.h
+++ b/lib/librte_eal/common/include/rte_common.h
@@ -331,6 +331,27 @@ rte_bsf32(uint32_t v)
#define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER)
#endif
+/**
+ * Return pointer to the wrapping struct instance.
+ *
+ * Example:
+ *
+ * struct wrapper {
+ * ...
+ * struct child c;
+ * ...
+ * };
+ *
+ * struct child *x = obtain(...);
+ * struct wrapper *w = container_of(x, struct wrapper, c);
+ */
+#ifndef container_of
+#define container_of(ptr, type, member) (__extension__ ({ \
+ typeof(((type *)0)->member) * _ptr = (ptr); \
+ (type *)(((char *)_ptr) - offsetof(type, member));\
+ }))
+#endif
+
#define _RTE_STR(x) #x
/** Take a macro value and get a string version of it */
#define RTE_STR(x) _RTE_STR(x)
--
2.7.4
^ permalink raw reply related
* [PATCH v2 00/12] Introducing EAL Bus-Device-Driver Model
From: Shreyansh Jain @ 2016-12-13 13:37 UTC (permalink / raw)
To: dev, david.marchand
Cc: thomas.monjalon, ferruh.yigit, jianbo.liu, Shreyansh Jain
In-Reply-To: <1480846288-2517-1-git-send-email-shreyansh.jain@nxp.com>
Link to v1: [10]
:: Introduction ::
DPDK has been inherently a PCI inclined framework. Because of this, the
design of device tree (or list) within DPDK is also PCI inclined. A
non-PCI device doesn't have a way of being expressed without using hooks
started from EAL to PMD.
(Check 'Version Changes' section for changes)
:: Overview of the Proposed Changes ::
Assuming the below graph for a computing node:
device A1
|
+==.===='==============.============+ Bus A.
| `--> driver A11 \
device A2 `-> driver A12 \______
|CPU |
/`````
device B1 /
| /
+==.===='==============.============+ Bus B`
| `--> driver B11
device B2 `-> driver B12
- One or more buses are connected to a CPU (or core)
- One or more devices are conneted to a Bus
- Drivers are running instances which manage one or more devices
- Bus is responsible for identifying devices (and interrupt propogation)
- Driver is responsible for initializing the device
In context of DPDK EAL:
- rte_bus, represents a Bus. An implementation of a physical bus would
instantiate this class.
- Buses are registered just like a PMD - RTE_REGISTER_BUS()
`- Thus, implementation for PCI would instantiate a rte_bus, give it a
name and provide scan/match hooks.
- Currently, priority of RTE_REGISTER_BUS constructor has been set to
101 to make sure bus is registered *before* drivers are.
- Each registered bus is part of a doubly list.
-- Each device refers to rte_bus on which it belongs
-- Each driver refers to rte_bus with which it is associated
-- Device and Drivers lists are part of rte_bus
-- NO global device/driver list would exist
- When a PMD wants to register itself, it would 'add' itself to an
existing bus. Which essentially converts to adding the driver to
a bus specific driver_list.
- Bus would perform a scan and 'add' devices scanned to its list.
- Bus would perform a probe and link devices and drivers on each bus and
invoking a series of probes
`-- There are some parallel work for combining scan/probe in EAL [5]
and also for doing away with a independent scan function all
together [6].
The view would be almost like:
__ rte_bus_list
/
+----------'---+
|rte_bus |
| driver_list------> device_list for this bus
| device_list----
| scan() | `-> driver_list for this bus
| match() |
| probe() |
| |
+--|------|----+
_________/ \_________
+--------/----+ +-\---------------+
|rte_device | |rte_driver |
| *rte_bus | | *rte_bus |
| rte_driver | | probe() |
| | | remove() |
| devargs | | |
+---||--------+ +---------|||-----+
|| '''
| \ \\\
| \_____________ \\\
| \ |||
+------|---------+ +----|----------+ |||
|rte_pci_device | |rte_xxx_device | |||
| PCI specific | | xxx device | |||
| info (mem,) | | specific fns | / | \
+----------------+ +---------------+ / | \
_____________________/ / \
/ ___/ \
+-------------'--+ +------------'---+ +--'------------+
|rte_pci_driver | |rte_vdev_driver | |rte_xxx_driver |
| PCI id table, | | <probably, | | .... |
| other driver | | nothing> | +---------------+
| data | | ... |
| probe() | +----------------+
| remove() |
+----------------+
In continuation to the RFC posted on 17/Nov [9],
A series of patches is being posted which attempts to create:
1. A basic bus model
`- define rte_bus and associated methods/helpers
`- test infrastructure to test the Bus infra
2. Changes in EAL to support PCI as a bus
`- a "pci" bus is registered
`- existing scan/match/probe are modified to allow for bus integration
`- PCI Device and Driver list, which were global entities, have been
moved to rte_bus->[device/driver]_list
For v2 as well, I have sanity tested this patch over a XeonD X552 available
with me, as well as part of PoC for verifying NXP's DPAA2 PMD (being pushed
out in a separate series). Exhaustive testing is still pending.
-> Please help in MLX & BSD related changes.
:: Brief about Patch Layout ::
0001: Container_of patch from [3]
0002~0003: Introducing the basic Bus model and associated test case
0004~0005: Add scan, match and insert support for devices on bus
0006: Add probe and remove for rte_driver
0007: Enable probing of PCI Bus (devices) from EAL
0008: Split the existing PCI probe into match and probe
0009: Make PCI probe/match work on rte_driver/device rather than
rte_pci_device/rte_pci_driver
0010: Patch from Ben [8], part of series [2]
0011: Enable Scan/Match/probe on Bus from EAL and remove unused
functions and lists. PMDs still don't work (in fact, PCI PMD
don't work after this patch - but without any compilation
issues).
0012: Change PMDs to integrate with PCI bus
:: Pending Changes/Caveats ::
0. eth_dev still contains rte_pci_device. I am banking on Jan's patches [1]
for conversion to a macro (ETH_DEV_PCI_DEV) and subsequent replacement
of all pci_dev usage in eth_dev.
1. One of the major changes pending, as against proposed in RFC, is the
removal of eth_driver.
Being a large change, and independent one, this would be done in a
separate series of patches. []
2. app/test/test_pci.c is still not modified. It is rendered uncompilable
as most of the APIs it was calling don't exist anymore. I will push a
v2 which would include a complete re-write of test_pci (or, if someone
can help me that, it would be awesome).
3. This patchset only moves the PCI into a bus. And, that movement is also
currently part of the EAL (lib/librte_eal/linux)
- there was an open question in RFC about where to place the PCI bus
instance - whether in drivers/bus/... or in lib/librte_bus/... or
lib/librte_eal/...; This patch uses the last option. But, movement
only impacts placement of Makefiles. Please convey your reservations
for current placement.
- It also impacts the point (8) about priority use in constructor
4. Though the implementation for bus is common for Linux and BSD, the PCI
bus implementation has been done/tested only for Linux.
5. There was a suggestion from Jan Blunk about a helper iterator within the
rte_bus. I will send this out in v3.
6. Cyptodev and VDEV changes are still pending. Jan has already conveyed
that he would be working on the VDEV part. I will work on the Crypto
part and target that for v3.
7. The overall layout for driver probing has changed a little.
earlier, it was:
rte_eal_init()
`-> rte_eal_pci_probe() (and parallel for VDEV)
`-> rte_pci_driver->probe()
`-> eth_driver->eth_dev_init()
now, it would be:
rte_eal_init()
`-> rte_eal_bus_probe() <- Iterator for PCI device/driver
`-> rte_driver->probe() <- devargs handling
| old rte_eal_pci_probe()
`-> rte_xxx_driver->probe() <- eth_dev allocation
`-> eth_driver->eth_dev_init <- eth_dev init
Open Questions:
Also, rte_driver->probe() creating eth_dev certainly sounds a little
wrong - but, I would like to get your opinion on how to lay this
order of which layer ethernet device corresponds to.
1) Which layer should allocate eth_dev?
`-> My take: rte_driver->probe()
2) which layer should fill the eth_dev?
`-> My take: rte_xxx_driver->probe()
3) Is init/uninit better name for rte_xxx_driver()->probe() if all
they do is initialize the ethernet device?
8. RTE_REGISTER_BUS has been declared with contructor priority of 101
It is important that Bus is registered *before* drivers are registered.
Only way I could find to assure that was via
__attribute(contructor(priority)) of GCC. I am not sure how it would
behave on other compilers. Any suggestions?
- One suggestion from David Marchand was to use global bus object
handles, which I have not implemented for now. If that is common
choice, I will change in v3.
:: ToDo list ::
- app/test/test_pci.c compilation is failing, if enabled.
- Bump to librte_eal version
- Documentation continues to have references to some _old_ PCI symbols
- vdev changes
- eth_device, eth_driver changes
:: References ::
[1] http://dpdk.org/ml/archives/dev/2016-November/050186.html
[2] http://dpdk.org/ml/archives/dev/2016-November/050622.html
[3] http://dpdk.org/ml/archives/dev/2016-November/050416.html
[4] http://dpdk.org/ml/archives/dev/2016-November/050567.html
[5] http://dpdk.org/ml/archives/dev/2016-November/050628.html
[6] http://dpdk.org/ml/archives/dev/2016-November/050415.html
[7] http://dpdk.org/ml/archives/dev/2016-November/050443.html
[8] http://dpdk.org/ml/archives/dev/2016-November/050624.html
[9] http://dpdk.org/ml/archives/dev/2016-November/050296.html
[10] http://dpdk.org/ml/archives/dev/2016-December/051349.html
:: Version Changes ::
v2:
- No more bus->probe()
Now, rte_eal_bus_probe() calls rte_driver->probe based on match output
- new functions, rte_eal_pci_probe and rte_eal_pci_remove have been
added as glue code between PCI PMDs and PCI Bus
`-> PMDs are updated to use these new functions as callbacks for
rte_driver
- 'default' keyword has been removed from match and scan
- Fix for incorrect changes in mlx* and nicvf*
- Checkpatch fixes
- Some variable checks have been removed from internal functions;
functions which are externally visible continue to have such checks
- Some rearrangement of patches:
-- changes to drivers have been separated from EAL changes (but this
does make PCI PMDs non-working for a particular patch)
Ben Walker (1):
pci: Pass rte_pci_addr to functions instead of separate args
Jan Blunck (1):
eal: define container_of macro
Shreyansh Jain (10):
eal/bus: introduce bus abstraction
test: add basic bus infrastructure tests
eal/bus: add scan, match and insert support
eal: integrate bus scan and probe with EAL
eal: add probe and remove support for rte_driver
eal: enable probe from bus infrastructure
pci: split match and probe function
eal/pci: generalize args of PCI scan/match towards RTE device/driver
eal: enable PCI bus
drivers: update PMDs to use rte_driver probe and remove
app/test/Makefile | 2 +-
app/test/test.h | 2 +
app/test/test_bus.c | 688 ++++++++++++++++++++++++
app/test/test_pci.c | 2 +-
drivers/net/bnx2x/bnx2x_ethdev.c | 8 +
drivers/net/bnxt/bnxt_ethdev.c | 4 +
drivers/net/cxgbe/cxgbe_ethdev.c | 4 +
drivers/net/e1000/em_ethdev.c | 4 +
drivers/net/e1000/igb_ethdev.c | 8 +
drivers/net/ena/ena_ethdev.c | 4 +
drivers/net/enic/enic_ethdev.c | 4 +
drivers/net/fm10k/fm10k_ethdev.c | 4 +
drivers/net/i40e/i40e_ethdev.c | 4 +
drivers/net/i40e/i40e_ethdev_vf.c | 4 +
drivers/net/ixgbe/ixgbe_ethdev.c | 8 +
drivers/net/mlx4/mlx4.c | 4 +-
drivers/net/mlx5/mlx5.c | 1 +
drivers/net/nfp/nfp_net.c | 4 +
drivers/net/qede/qede_ethdev.c | 8 +
drivers/net/szedata2/rte_eth_szedata2.c | 4 +
drivers/net/thunderx/nicvf_ethdev.c | 4 +
drivers/net/virtio/virtio_ethdev.c | 2 +
drivers/net/vmxnet3/vmxnet3_ethdev.c | 4 +
lib/librte_eal/bsdapp/eal/Makefile | 1 +
lib/librte_eal/bsdapp/eal/eal.c | 12 +-
lib/librte_eal/bsdapp/eal/eal_pci.c | 52 +-
lib/librte_eal/bsdapp/eal/rte_eal_version.map | 22 +-
lib/librte_eal/common/Makefile | 2 +-
lib/librte_eal/common/eal_common_bus.c | 285 ++++++++++
lib/librte_eal/common/eal_common_pci.c | 341 +++++++-----
lib/librte_eal/common/eal_private.h | 14 +-
lib/librte_eal/common/include/rte_bus.h | 257 +++++++++
lib/librte_eal/common/include/rte_common.h | 21 +
lib/librte_eal/common/include/rte_dev.h | 14 +
lib/librte_eal/common/include/rte_pci.h | 59 +-
lib/librte_eal/linuxapp/eal/Makefile | 1 +
lib/librte_eal/linuxapp/eal/eal.c | 12 +-
lib/librte_eal/linuxapp/eal/eal_pci.c | 81 +--
lib/librte_eal/linuxapp/eal/rte_eal_version.map | 22 +-
39 files changed, 1737 insertions(+), 240 deletions(-)
create mode 100644 app/test/test_bus.c
create mode 100644 lib/librte_eal/common/eal_common_bus.c
create mode 100644 lib/librte_eal/common/include/rte_bus.h
--
2.7.4
^ permalink raw reply
* [PATCH v4] vhost: allow for many vhost user ports
From: Jan Wickbom @ 2016-12-13 13:19 UTC (permalink / raw)
To: yuanhan.liu; +Cc: dev, patrik.r.andersson, Jan Wickbom
In-Reply-To: <1480606010-6132-1-git-send-email-jan.wickbom@ericsson.com>
Currently select() is used to monitor file descriptors for vhostuser
ports. This limits the number of ports possible to create since the
fd number is used as index in the fd_set and we have seen fds > 1023.
This patch changes select() to poll(). This way we can keep an
packed (pollfd) array for the fds, e.g. as many fds as the size of
the array.
Also see:
http://dpdk.org/ml/archives/dev/2016-April/037024.html
Signed-off-by: Jan Wickbom <jan.wickbom@ericsson.com>
Reported-by: Patrik Andersson <patrik.r.andersson@ericsson.com>
---
v4:
* fdset_del can not shrink the array. Took care of that in sveral places
* Moved rwfds[] into struct fdset
v3:
* removed unnecessary include
* removed fdset_fill, made it functionally part of poll loop
v2:
* removed unnecessary casts
* static array replacing allocated memory
lib/librte_vhost/fd_man.c | 226 ++++++++++++++++++++++++++--------------------
lib/librte_vhost/fd_man.h | 4 +-
2 files changed, 131 insertions(+), 99 deletions(-)
diff --git a/lib/librte_vhost/fd_man.c b/lib/librte_vhost/fd_man.c
index 2d3eeb7..d7c775d 100644
--- a/lib/librte_vhost/fd_man.c
+++ b/lib/librte_vhost/fd_man.c
@@ -35,16 +35,38 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
-#include <sys/select.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
+#include <string.h>
#include <rte_common.h>
#include <rte_log.h>
#include "fd_man.h"
+#define FDPOLLERR (POLLERR | POLLHUP | POLLNVAL)
+
+/**
+ * Adjusts the highest index populated in the array of fds
+ * @return
+ * The new size of fdset.
+ */
+static int
+fdset_shrink(struct fdset *pfdset)
+{
+ int idx;
+
+ for (idx = pfdset->num - 1;
+ idx >= 0 && pfdset->fd[idx].fd == -1;
+ idx--)
+ ;
+
+ pfdset->num = idx + 1;
+
+ return pfdset->num;
+}
+
/**
* Returns the index in the fdset for a given fd.
* If fd is -1, it means to search for a free entry.
@@ -56,72 +78,28 @@
{
int i;
- if (pfdset == NULL)
- return -1;
-
- for (i = 0; i < MAX_FDS && pfdset->fd[i].fd != fd; i++)
+ for (i = 0; i < pfdset->num && pfdset->fd[i].fd != fd; i++)
;
- return i == MAX_FDS ? -1 : i;
-}
-
-static int
-fdset_find_free_slot(struct fdset *pfdset)
-{
- return fdset_find_fd(pfdset, -1);
+ return i == pfdset->num ? -1 : i;
}
-static int
-fdset_add_fd(struct fdset *pfdset, int idx, int fd,
+static void
+fdset_add_fd(struct fdset *pfdset, int idx, int fd,
fd_cb rcb, fd_cb wcb, void *dat)
{
- struct fdentry *pfdentry;
-
- if (pfdset == NULL || idx >= MAX_FDS || fd >= FD_SETSIZE)
- return -1;
+ struct fdentry *pfdentry = &pfdset->fd[idx];
+ struct pollfd *pfd = &pfdset->rwfds[idx];
- pfdentry = &pfdset->fd[idx];
pfdentry->fd = fd;
pfdentry->rcb = rcb;
pfdentry->wcb = wcb;
pfdentry->dat = dat;
- return 0;
-}
-
-/**
- * Fill the read/write fd_set with the fds in the fdset.
- * @return
- * the maximum fds filled in the read/write fd_set.
- */
-static int
-fdset_fill(fd_set *rfset, fd_set *wfset, struct fdset *pfdset)
-{
- struct fdentry *pfdentry;
- int i, maxfds = -1;
- int num = MAX_FDS;
-
- if (pfdset == NULL)
- return -1;
-
- for (i = 0; i < num; i++) {
- pfdentry = &pfdset->fd[i];
- if (pfdentry->fd != -1) {
- int added = 0;
- if (pfdentry->rcb && rfset) {
- FD_SET(pfdentry->fd, rfset);
- added = 1;
- }
- if (pfdentry->wcb && wfset) {
- FD_SET(pfdentry->fd, wfset);
- added = 1;
- }
- if (added)
- maxfds = pfdentry->fd < maxfds ?
- maxfds : pfdentry->fd;
- }
- }
- return maxfds;
+ pfd->fd = fd;
+ pfd->events = rcb ? POLLIN : 0;
+ pfd->events |= wcb ? POLLOUT : 0;
+ pfd->revents = 0;
}
void
@@ -132,11 +110,15 @@
if (pfdset == NULL)
return;
+ pthread_mutex_init(&pfdset->fd_mutex, NULL);
+
for (i = 0; i < MAX_FDS; i++) {
pfdset->fd[i].fd = -1;
pfdset->fd[i].dat = NULL;
}
pfdset->num = 0;
+
+ memset(pfdset->rwfds, 0, sizeof(pfdset->rwfds));
}
/**
@@ -152,14 +134,14 @@
pthread_mutex_lock(&pfdset->fd_mutex);
- /* Find a free slot in the list. */
- i = fdset_find_free_slot(pfdset);
- if (i == -1 || fdset_add_fd(pfdset, i, fd, rcb, wcb, dat) < 0) {
+ i = pfdset->num < MAX_FDS ? pfdset->num++ : -1;
+
+ if (i == -1) {
pthread_mutex_unlock(&pfdset->fd_mutex);
return -2;
}
- pfdset->num++;
+ fdset_add_fd(pfdset, i, fd, rcb, wcb, dat);
pthread_mutex_unlock(&pfdset->fd_mutex);
@@ -189,7 +171,6 @@
pfdset->fd[i].fd = -1;
pfdset->fd[i].rcb = pfdset->fd[i].wcb = NULL;
pfdset->fd[i].dat = NULL;
- pfdset->num--;
i = -1;
}
pthread_mutex_unlock(&pfdset->fd_mutex);
@@ -198,25 +179,26 @@
return dat;
}
+
/**
- * Unregister the fd at the specified slot from the fdset.
+ * Moves the fd from last slot to specified slot, including
+ * corresponding pollfd
*/
static void
-fdset_del_slot(struct fdset *pfdset, int index)
+fdset_move_last(struct fdset *pfdset, int idx)
{
- if (pfdset == NULL || index < 0 || index >= MAX_FDS)
- return;
-
- pthread_mutex_lock(&pfdset->fd_mutex);
+ int last_idx = pfdset->num - 1;
- pfdset->fd[index].fd = -1;
- pfdset->fd[index].rcb = pfdset->fd[index].wcb = NULL;
- pfdset->fd[index].dat = NULL;
- pfdset->num--;
+ if (idx < last_idx) {
+ pfdset->fd[idx] = pfdset->fd[last_idx];
+ pfdset->fd[last_idx].fd = -1;
- pthread_mutex_unlock(&pfdset->fd_mutex);
+ pfdset->rwfds[idx] = pfdset->rwfds[last_idx];
+ pfdset->rwfds[last_idx].revents = 0;
+ }
}
+
/**
* This functions runs in infinite blocking loop until there is no fd in
* pfdset. It calls corresponding r/w handler if there is event on the fd.
@@ -229,55 +211,75 @@
void
fdset_event_dispatch(struct fdset *pfdset)
{
- fd_set rfds, wfds;
- int i, maxfds;
+ int i;
+ struct pollfd *pfd;
struct fdentry *pfdentry;
- int num = MAX_FDS;
fd_cb rcb, wcb;
void *dat;
- int fd;
+ int fd, numfds;
int remove1, remove2;
- int ret;
if (pfdset == NULL)
return;
while (1) {
- struct timeval tv;
- tv.tv_sec = 1;
- tv.tv_usec = 0;
- FD_ZERO(&rfds);
- FD_ZERO(&wfds);
- pthread_mutex_lock(&pfdset->fd_mutex);
-
- maxfds = fdset_fill(&rfds, &wfds, pfdset);
-
- pthread_mutex_unlock(&pfdset->fd_mutex);
-
/*
- * When select is blocked, other threads might unregister
+ * When poll is blocked, other threads might unregister
* listenfds from and register new listenfds into fdset.
- * When select returns, the entries for listenfds in the fdset
+ * When poll returns, the entries for listenfds in the fdset
* might have been updated. It is ok if there is unwanted call
* for new listenfds.
*/
- ret = select(maxfds + 1, &rfds, &wfds, NULL, &tv);
- if (ret <= 0)
- continue;
+ pthread_mutex_lock(&pfdset->fd_mutex);
- for (i = 0; i < num; i++) {
- remove1 = remove2 = 0;
+ numfds = pfdset->num;
+
+ pthread_mutex_unlock(&pfdset->fd_mutex);
+
+ poll(pfdset->rwfds, numfds, 1000 /* millisecs */);
+
+ for (i = 0; i < numfds; ) {
pthread_mutex_lock(&pfdset->fd_mutex);
+
pfdentry = &pfdset->fd[i];
fd = pfdentry->fd;
+ pfd = &pfdset->rwfds[i];
+
+ if (fd < 0) {
+ /* Removed during poll */
+ /* shrink first, last migth be deleted*/
+
+ fdset_shrink(pfdset);
+ fdset_move_last(pfdset, i);
+ fdset_shrink(pfdset);
+
+ pthread_mutex_unlock(&pfdset->fd_mutex);
+
+ continue;
+ }
+
+ if (!pfd->revents) {
+
+ pthread_mutex_unlock(&pfdset->fd_mutex);
+
+ i++;
+ continue;
+ }
+
+ /* Valid fd, and at least one revent ... */
+
+ remove1 = remove2 = 0;
+
rcb = pfdentry->rcb;
wcb = pfdentry->wcb;
dat = pfdentry->dat;
pfdentry->busy = 1;
+
pthread_mutex_unlock(&pfdset->fd_mutex);
- if (fd >= 0 && FD_ISSET(fd, &rfds) && rcb)
+
+ if (rcb && pfd->revents & (POLLIN | FDPOLLERR))
rcb(fd, dat, &remove1);
- if (fd >= 0 && FD_ISSET(fd, &wfds) && wcb)
+ if (wcb && pfd->revents & (POLLOUT | FDPOLLERR))
wcb(fd, dat, &remove2);
pfdentry->busy = 0;
/*
@@ -292,8 +294,36 @@
* listen fd in another thread, we couldn't call
* fd_set_del.
*/
- if (remove1 || remove2)
- fdset_del_slot(pfdset, i);
+ if (remove1 || remove2) {
+ pthread_mutex_lock(&pfdset->fd_mutex);
+
+ /* shrink first, last migth be deleted*/
+ fdset_shrink(pfdset);
+ fdset_move_last(pfdset, i);
+ fdset_shrink(pfdset);
+
+ pthread_mutex_unlock(&pfdset->fd_mutex);
+
+ continue;
+ }
+
+ i++;
}
+
+ /* fdset_del do not shrink, pack eventual remainings of array */
+ pthread_mutex_lock(&pfdset->fd_mutex);
+
+ fdset_shrink(pfdset);
+
+ for ( ; i < pfdset->num; i++) {
+ pfdentry = &pfdset->fd[i];
+
+ if (pfdentry->fd < 0) {
+ fdset_move_last(pfdset, i);
+ fdset_shrink(pfdset);
+ }
+ }
+
+ pthread_mutex_unlock(&pfdset->fd_mutex);
}
}
diff --git a/lib/librte_vhost/fd_man.h b/lib/librte_vhost/fd_man.h
index bd66ed1..03e7881 100644
--- a/lib/librte_vhost/fd_man.h
+++ b/lib/librte_vhost/fd_man.h
@@ -35,6 +35,7 @@
#define _FD_MAN_H_
#include <stdint.h>
#include <pthread.h>
+#include <poll.h>
#define MAX_FDS 1024
@@ -49,9 +50,10 @@ struct fdentry {
};
struct fdset {
+ struct pollfd rwfds[MAX_FDS];
struct fdentry fd[MAX_FDS];
pthread_mutex_t fd_mutex;
- int num; /* current fd number of this fdset */
+ int num; /* highest index occupied in fd array + 1 */
};
--
1.9.1
^ permalink raw reply related
* Re: [PATCH v3] vhost: allow for many vhost user ports
From: Jan Wickbom @ 2016-12-13 13:15 UTC (permalink / raw)
To: Yuanhan Liu; +Cc: dev@dpdk.org, Patrik Andersson R
In-Reply-To: <20161213091454.GB18991@yliu-dev.sh.intel.com>
> -----Original Message-----
> From: Yuanhan Liu [mailto:yuanhan.liu@linux.intel.com]
> Sent: den 13 december 2016 10:15
> To: Jan Wickbom <jan.wickbom@ericsson.com>
> Cc: dev@dpdk.org; Patrik Andersson R <patrik.r.andersson@ericsson.com>
> Subject: Re: [PATCH v3] vhost: allow for many vhost user ports
>
> On Mon, Dec 12, 2016 at 05:50:34PM +0100, Jan Wickbom wrote:
> > Currently select() is used to monitor file descriptors for vhostuser
> > ports. This limits the number of ports possible to create since the
> > fd number is used as index in the fd_set and we have seen fds > 1023.
> > This patch changes select() to poll(). This way we can keep an
> > packed (pollfd) array for the fds, e.g. as many fds as the size of
> > the array.
> >
> > Also see:
> > http://dpdk.org/ml/archives/dev/2016-April/037024.html
> >
> > Signed-off-by: Jan Wickbom <jan.wickbom@ericsson.com>
> > Reported-by: Patrik Andersson <patrik.r.andersson@ericsson.com>
> ...
> > +static struct pollfd rwfds[MAX_FDS];
>
> Though it's unlikely, but just assume we have multiple instance of
> fdset_event_dispatch(pfdset), a global rwfds will not work.
>
> Thought twice, and it's better to put it into the fdset struct:
>
> struct fdset {
> struct fdentry fd[MAX_FDS];
> struct pollfd rwfds[MAX_FDS];
> ...
>
Done
> > /**
> > * This functions runs in infinite blocking loop until there is no fd in
> > * pfdset. It calls corresponding r/w handler if there is event on the fd.
> > @@ -229,55 +217,71 @@
> > void
> > fdset_event_dispatch(struct fdset *pfdset)
> > {
> > - fd_set rfds, wfds;
> > - int i, maxfds;
> > + int i;
> > struct fdentry *pfdentry;
> > - int num = MAX_FDS;
> > fd_cb rcb, wcb;
> > void *dat;
> > int fd;
> > int remove1, remove2;
> > - int ret;
> >
> > if (pfdset == NULL)
> > return;
> >
> > - while (1) {
> > - struct timeval tv;
> > - tv.tv_sec = 1;
> > - tv.tv_usec = 0;
> > - FD_ZERO(&rfds);
> > - FD_ZERO(&wfds);
> > - pthread_mutex_lock(&pfdset->fd_mutex);
> > -
> > - maxfds = fdset_fill(&rfds, &wfds, pfdset);
> > -
> > - pthread_mutex_unlock(&pfdset->fd_mutex);
> > + memset(rwfds, 0, sizeof(rwfds));
> >
> > + while (1) {
> > /*
> > - * When select is blocked, other threads might
> unregister
> > + * When poll is blocked, other threads might
> unregister
> > * listenfds from and register new listenfds into
> fdset.
> > - * When select returns, the entries for listenfds
> in the fdset
> > + * When poll returns, the entries for listenfds in
> the fdset
> > * might have been updated. It is ok if there is
> unwanted call
> > * for new listenfds.
> > */
> > - ret = select(maxfds + 1, &rfds, &wfds, NULL,
> &tv);
> > - if (ret <= 0)
> > - continue;
> > + poll(rwfds, pfdset->num, 1000 /* millisecs */);
> >
> > - for (i = 0; i < num; i++) {
> > - remove1 = remove2 = 0;
> > + for (i = 0; i < pfdset->num; ) {
> > pthread_mutex_lock(&pfdset-
> >fd_mutex);
> > +
> > pfdentry = &pfdset->fd[i];
> > fd = pfdentry->fd;
> > +
> > + if (fd < 0) {
> > + /* Removed during
> poll */
> > +
> > +
> fdset_move_last(pfdset, i);
> > +
> fdset_shrink(pfdset);
> > +
> > +
> pthread_mutex_unlock(&pfdset->fd_mutex);
> > +
> > + continue;
> > + }
> > +
> > + if (!rwfds[i].revents) {
> > + /* No revents,
> maybe added during poll */
> > +
> > + rwfds[i].fd = fd;
> > + rwfds[i].events =
> pfdentry->rcb ? POLLIN : 0;
> > + rwfds[i].events |=
> pfdentry->wcb ? POLLOUT : 0;
> > +
> pthread_mutex_unlock(&pfdset->fd_mutex);
> > +
> > + i++;
> > + continue;
>
> I think it's error-prone to manipulate the rwfds here. Besides, it
> registers an fd repeatedly.
>
> The way I think of is:
>
> - set rwfds[i] at fdset_add().
>
> This also simply makes sure that pfdset->rwfds[i] and pfdset->fd[i] is
> correctly bond.
>
> fdset_add(fdset, fd, ...) {
> lock();
>
> i = fdset_find_free_slot(..);
>
> pfdset->fd[i]->fd = fd;
> pfdset->fd[i]->rcb = rcb;
> pfdset->fd[i]->...;
>
> pfdset->rwfds[i]->fd = fd;
> pfdset->rwfds[i]->events = ...;
> pfdset->rwfds[i]->revents = 0;
> }
>
>
> - set pfdset->fd[i]->fd = -1 on fdset_del. Note we should not decrease
> 'num' here, as we may be at poll.
>
> fdset_del(fdset, fd) {
> lock();
>
> i = fdset_find_fd(pfdset, fd);
> pfdset->fd[i]->fd = -1;
>
> ...
> }
>
>
>
> - log down pfdset->num before poll, because 'num' may increase during poll.
>
> I think it's optional, since even 'num' is increased during poll, it just
> leads to few more rwfds entries will be accessed. But it's not tracked by
> kernel, and revents is initiated with 0, that there is no issue.
>
>
> - shrink the fdset and rwfds (together) for those removed entries,
> __outside__
> the for loop after poll.
>
> Works to you?
I did quite of a rework of this yesterday before reading your mail. I think
That should work, please have a look.
V4 coming in a minute
>
> --yliu
^ permalink raw reply
* Re: [PATCH] gitignore: ignore top level build/ directory
From: Ferruh Yigit @ 2016-12-13 12:02 UTC (permalink / raw)
To: Baruch Siach, dev; +Cc: Thomas Monjalon
In-Reply-To: <2dfce93f986deb95eb5ac4773e020005d45f0c48.1481629710.git.baruch@tkos.co.il>
On 12/13/2016 11:48 AM, Baruch Siach wrote:
> RTE_OUTPUT defaults to build/.
>
> Signed-off-by: Baruch Siach <baruch@tkos.co.il>
There is a similar patch:
http://dpdk.org/dev/patchwork/patch/11637/
If you want you can review/comment that one too.
> ---
> .gitignore | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/.gitignore b/.gitignore
> index a722abea21fe..7b462d3a0455 100644
> --- a/.gitignore
> +++ b/.gitignore
> @@ -1 +1,2 @@
> doc/guides/nics/overview_table.txt
> +/build/
>
^ permalink raw reply
* Re: [PATCH v12 0/6] add Tx preparation
From: Ferruh Yigit @ 2016-12-13 11:59 UTC (permalink / raw)
To: Thomas Monjalon, dev, Jan Medala, Jakub Palider, Netanel Belgazal,
Evgeny Schemeilin, Yong Wang, Hemant Agrawal
Cc: Tomasz Kulasek, konstantin.ananyev
In-Reply-To: <2dfc10d2-bb19-1385-aa01-97e44a3db139@intel.com>
On 12/6/2016 3:53 PM, Ferruh Yigit wrote:
> On 11/28/2016 11:03 AM, Thomas Monjalon wrote:
>> We need attention of every PMD developers on this thread.
>>
>> Reminder of what Konstantin suggested:
>> "
>> - if the PMD supports TX offloads AND
>> - if to be able use any of these offloads the upper layer SW would have to:
>> * modify the contents of the packet OR
>> * obey HW specific restrictions
>> then it is a PMD developer responsibility to provide tx_prep() that would implement
>> expected modifications of the packet contents and restriction checks.
>> Otherwise, tx_prep() implementation is not required and can be safely set to NULL.
>> "
>>
>> I copy/paste also my previous conclusion:
>>
>> Before txprep, there is only one API: the application must prepare the
>> packets checksum itself (get_psd_sum in testpmd).
>> With txprep, the application have 2 choices: keep doing the job itself
>> or call txprep which calls a PMD-specific function.
>> The question is: does non-Intel drivers need a checksum preparation for TSO?
>> Will it behave well if txprep does nothing in these drivers?
>>
>> When looking at the code, most of drivers handle the TSO flags.
>> But it is hard to know whether they rely on the pseudo checksum or not.
>>
>> git grep -l 'PKT_TX_UDP_CKSUM\|PKT_TX_TCP_CKSUM\|PKT_TX_TCP_SEG' drivers/net/
>>
>> drivers/net/bnxt/bnxt_txr.c
>> drivers/net/cxgbe/sge.c
>> drivers/net/e1000/em_rxtx.c
>> drivers/net/e1000/igb_rxtx.c
>> drivers/net/ena/ena_ethdev.c
>> drivers/net/enic/enic_rxtx.c
>> drivers/net/fm10k/fm10k_rxtx.c
>> drivers/net/i40e/i40e_rxtx.c
>> drivers/net/ixgbe/ixgbe_rxtx.c
>> drivers/net/mlx4/mlx4.c
>> drivers/net/mlx5/mlx5_rxtx.c
>> drivers/net/nfp/nfp_net.c
>> drivers/net/qede/qede_rxtx.c
>> drivers/net/thunderx/nicvf_rxtx.c
>> drivers/net/virtio/virtio_rxtx.c
>> drivers/net/vmxnet3/vmxnet3_rxtx.c
>>
>> Please, we need a comment for each driver saying
>> "it is OK, we do not need any checksum preparation for TSO"
>> or
>> "yes we have to implement tx_prepare or TSO will not work in this mode"
>>
>
> Still waiting response from PMDs:
> - ena
> - nfp
> - virtio
>
> Waiting clarification for preparation requirements:
> - vmxnet3
>
> Also including new PMDs to the thread:
> - sfc
> - dpaa2
Thanks all for responses, now only remaining ones are following:
Waiting clarification for preparation requirements: (it would be great
if details can be provided before next version of the patch)
- ena
Will support review/testing of the patch:
- vmxnet3
new PMD (still not in repo, so response is good to have)
- dpaa2
^ permalink raw reply
* Re: [PATCH] net/qede: fix resource leak
From: Ferruh Yigit @ 2016-12-13 11:52 UTC (permalink / raw)
To: Yong Wang, harish.patil; +Cc: dpdk stable, DPDK
In-Reply-To: <1480509129-27623-1-git-send-email-wang.yong19@zte.com.cn>
On 11/30/2016 12:32 PM, Yong Wang wrote:
> Current code does not close 'fd' on function exit, leaking resources.
>
> Signed-off-by: Yong Wang <wang.yong19@zte.com.cn>
CC: stable@dpdk.org
> ---
> drivers/net/qede/qede_main.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/drivers/net/qede/qede_main.c b/drivers/net/qede/qede_main.c
> index ab22409..b666e1c 100644
> --- a/drivers/net/qede/qede_main.c
> +++ b/drivers/net/qede/qede_main.c
> @@ -137,6 +137,7 @@ static int qed_load_firmware_data(struct ecore_dev *edev)
>
> if (fstat(fd, &st) < 0) {
> DP_NOTICE(edev, false, "Can't stat firmware file\n");
> + close(fd);
> return -1;
> }
>
> @@ -158,9 +159,11 @@ static int qed_load_firmware_data(struct ecore_dev *edev)
> if (edev->fw_len < 104) {
> DP_NOTICE(edev, false, "Invalid fw size: %" PRIu64 "\n",
> edev->fw_len);
> + close(fd);
> return -EINVAL;
> }
>
> + close(fd);
> return 0;
> }
> #endif
>
^ permalink raw reply
* Re: [PATCH] net/qede: fix resource leak
From: Ferruh Yigit @ 2016-12-13 11:51 UTC (permalink / raw)
To: Harish Patil, Yong Wang; +Cc: dev@dpdk.org
In-Reply-To: <D4743B07.C053C%Harish.Patil@cavium.com>
On 12/12/2016 7:32 PM, Harish Patil wrote:
>
>> On 11/30/2016 12:32 PM, Yong Wang wrote:
>>> Current code does not close 'fd' on function exit, leaking resources.
>>>
>>> Signed-off-by: Yong Wang <wang.yong19@zte.com.cn>
>>> ---
>>
>> Add new mail address of the maintainer.
>>
>> CC: Harish Patil <harish.patil@cavium.com>
>>
>> <...>
>>
>
> Acked-by: Harish Patil <harish.patil@qlogic.com>
>
Applied to dpdk-next-net/master, thanks.
^ permalink raw reply
* [PATCH] gitignore: ignore top level build/ directory
From: Baruch Siach @ 2016-12-13 11:48 UTC (permalink / raw)
To: dev; +Cc: Thomas Monjalon, Baruch Siach
RTE_OUTPUT defaults to build/.
Signed-off-by: Baruch Siach <baruch@tkos.co.il>
---
.gitignore | 1 +
1 file changed, 1 insertion(+)
diff --git a/.gitignore b/.gitignore
index a722abea21fe..7b462d3a0455 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
doc/guides/nics/overview_table.txt
+/build/
--
2.10.2
^ permalink raw reply related
* [PATCH v4 7/7] doc: update release notes
From: Bernard Iremonger @ 2016-12-13 11:40 UTC (permalink / raw)
To: thomas.monjalon, dev; +Cc: Bernard Iremonger
In-Reply-To: <1481550626-14539-1-git-send-email-bernard.iremonger@intel.com>
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 1871 bytes --]
Add release note for removing set VF API's from the ethdev,
renaming the API's and moving them to the ixgbe PMD.
Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
doc/guides/rel_notes/release_17_02.rst | 23 +++++++++++++++++++++--
1 file changed, 21 insertions(+), 2 deletions(-)
diff --git a/doc/guides/rel_notes/release_17_02.rst b/doc/guides/rel_notes/release_17_02.rst
index 3b65038..7a40057 100644
--- a/doc/guides/rel_notes/release_17_02.rst
+++ b/doc/guides/rel_notes/release_17_02.rst
@@ -38,7 +38,6 @@ New Features
Also, make sure to start the actual text at the margin.
=========================================================
-
Resolved Issues
---------------
@@ -102,6 +101,26 @@ API Changes
Also, make sure to start the actual text at the margin.
=========================================================
+* **Moved five APIs for VF management from the ethdev to the ixgbe PMD.**
+
+ The following five APIs for VF management from the PF have been removed from the ethdev,
+ renamed and added to the ixgbe PMD::
+
+ rte_eth_dev_set_vf_rate_limit
+ rte_eth_dev_set_vf_rx
+ rte_eth_dev_set_vf_rxmode
+ rte_eth_dev_set_vf_tx
+ rte_eth_dev_set_vf_vlan_filter
+
+ The API's have been renamed to the following::
+
+ rte_pmd_ixgbe_set_vf_rate_limit
+ rte_pmd_ixgbe_set_vf_rx
+ rte_pmd_ixgbe_set_vf_rxmode
+ rte_pmd_ixgbe_set_vf_tx
+ rte_pmd_ixgbe_set_vf_vlan_filter
+
+ The declarations for the API’s can be found in ``rte_pmd_ixgbe.h``.
ABI Changes
-----------
@@ -142,7 +161,7 @@ The libraries prepended with a plus sign were incremented in this version.
librte_cryptodev.so.2
librte_distributor.so.1
librte_eal.so.3
- librte_ethdev.so.5
+ +librte_ethdev.so.6
librte_hash.so.2
librte_ip_frag.so.1
librte_jobstats.so.1
--
2.10.1
^ permalink raw reply related
* [PATCH v4 6/7] librte_ether: remove the set VF API's
From: Bernard Iremonger @ 2016-12-13 11:40 UTC (permalink / raw)
To: thomas.monjalon, dev; +Cc: Bernard Iremonger
In-Reply-To: <1481550626-14539-1-git-send-email-bernard.iremonger@intel.com>
remove the following API's:
rte_eth_dev_set_vf_rxmode
rte_eth_dev_set_vf_rx
rte_eth_dev_set_vf_tx
rte_eth_dev_set_vf_vlan_filter
rte_eth_dev_set_vf_rate_limit
Increment LIBABIVER in Makefile
Remove deprecation notice for removing rte_eth_dev_set_vf_* API's.
Signed-off-by: Bernard Iremonger <bernard.iremonger@intel.com>
---
doc/guides/rel_notes/deprecation.rst | 13 ---
lib/librte_ether/Makefile | 4 +-
lib/librte_ether/rte_ethdev.c | 129 ------------------------------
lib/librte_ether/rte_ethdev.h | 140 ---------------------------------
lib/librte_ether/rte_ether_version.map | 7 +-
5 files changed, 3 insertions(+), 290 deletions(-)
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 2d17bc6..c897c18 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -38,19 +38,6 @@ Deprecation Notices
``_rte_eth_dev_callback_process``. In 17.02 the function will return an ``int``
instead of ``void`` and a fourth parameter ``void *ret_param`` will be added.
-* ethdev: for 17.02 it is planned to deprecate the following five functions
- and move them in ixgbe:
-
- ``rte_eth_dev_set_vf_rxmode``
-
- ``rte_eth_dev_set_vf_rx``
-
- ``rte_eth_dev_set_vf_tx``
-
- ``rte_eth_dev_set_vf_vlan_filter``
-
- ``rte_eth_set_vf_rate_limit``
-
* ABI changes are planned for 17.02 in the ``rte_mbuf`` structure: some fields
may be reordered to facilitate the writing of ``data_off``, ``refcnt``, and
``nb_segs`` in one operation, because some platforms have an overhead if the
diff --git a/lib/librte_ether/Makefile b/lib/librte_ether/Makefile
index efe1e5f..d23015c 100644
--- a/lib/librte_ether/Makefile
+++ b/lib/librte_ether/Makefile
@@ -1,6 +1,6 @@
# BSD LICENSE
#
-# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+# Copyright(c) 2010-2016 Intel Corporation. All rights reserved.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -41,7 +41,7 @@ CFLAGS += $(WERROR_FLAGS)
EXPORT_MAP := rte_ether_version.map
-LIBABIVER := 5
+LIBABIVER := 6
SRCS-y += rte_ethdev.c
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 1e0f206..6a93014 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -2137,32 +2137,6 @@ rte_eth_dev_default_mac_addr_set(uint8_t port_id, struct ether_addr *addr)
return 0;
}
-int
-rte_eth_dev_set_vf_rxmode(uint8_t port_id, uint16_t vf,
- uint16_t rx_mode, uint8_t on)
-{
- uint16_t num_vfs;
- struct rte_eth_dev *dev;
- struct rte_eth_dev_info dev_info;
-
- RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
- dev = &rte_eth_devices[port_id];
- rte_eth_dev_info_get(port_id, &dev_info);
-
- num_vfs = dev_info.max_vfs;
- if (vf > num_vfs) {
- RTE_PMD_DEBUG_TRACE("set VF RX mode:invalid VF id %d\n", vf);
- return -EINVAL;
- }
-
- if (rx_mode == 0) {
- RTE_PMD_DEBUG_TRACE("set VF RX mode:mode mask ca not be zero\n");
- return -EINVAL;
- }
- RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_vf_rx_mode, -ENOTSUP);
- return (*dev->dev_ops->set_vf_rx_mode)(dev, vf, rx_mode, on);
-}
/*
* Returns index into MAC address array of addr. Use 00:00:00:00:00:00 to find
@@ -2252,76 +2226,6 @@ rte_eth_dev_uc_all_hash_table_set(uint8_t port_id, uint8_t on)
return (*dev->dev_ops->uc_all_hash_table_set)(dev, on);
}
-int
-rte_eth_dev_set_vf_rx(uint8_t port_id, uint16_t vf, uint8_t on)
-{
- uint16_t num_vfs;
- struct rte_eth_dev *dev;
- struct rte_eth_dev_info dev_info;
-
- RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
- dev = &rte_eth_devices[port_id];
- rte_eth_dev_info_get(port_id, &dev_info);
-
- num_vfs = dev_info.max_vfs;
- if (vf > num_vfs) {
- RTE_PMD_DEBUG_TRACE("port %d: invalid vf id\n", port_id);
- return -EINVAL;
- }
-
- RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_vf_rx, -ENOTSUP);
- return (*dev->dev_ops->set_vf_rx)(dev, vf, on);
-}
-
-int
-rte_eth_dev_set_vf_tx(uint8_t port_id, uint16_t vf, uint8_t on)
-{
- uint16_t num_vfs;
- struct rte_eth_dev *dev;
- struct rte_eth_dev_info dev_info;
-
- RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
- dev = &rte_eth_devices[port_id];
- rte_eth_dev_info_get(port_id, &dev_info);
-
- num_vfs = dev_info.max_vfs;
- if (vf > num_vfs) {
- RTE_PMD_DEBUG_TRACE("set pool tx:invalid pool id=%d\n", vf);
- return -EINVAL;
- }
-
- RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_vf_tx, -ENOTSUP);
- return (*dev->dev_ops->set_vf_tx)(dev, vf, on);
-}
-
-int
-rte_eth_dev_set_vf_vlan_filter(uint8_t port_id, uint16_t vlan_id,
- uint64_t vf_mask, uint8_t vlan_on)
-{
- struct rte_eth_dev *dev;
-
- RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
- dev = &rte_eth_devices[port_id];
-
- if (vlan_id > ETHER_MAX_VLAN_ID) {
- RTE_PMD_DEBUG_TRACE("VF VLAN filter:invalid VLAN id=%d\n",
- vlan_id);
- return -EINVAL;
- }
-
- if (vf_mask == 0) {
- RTE_PMD_DEBUG_TRACE("VF VLAN filter:pool_mask can not be 0\n");
- return -EINVAL;
- }
-
- RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_vf_vlan_filter, -ENOTSUP);
- return (*dev->dev_ops->set_vf_vlan_filter)(dev, vlan_id,
- vf_mask, vlan_on);
-}
-
int rte_eth_set_queue_rate_limit(uint8_t port_id, uint16_t queue_idx,
uint16_t tx_rate)
{
@@ -2352,39 +2256,6 @@ int rte_eth_set_queue_rate_limit(uint8_t port_id, uint16_t queue_idx,
return (*dev->dev_ops->set_queue_rate_limit)(dev, queue_idx, tx_rate);
}
-int rte_eth_set_vf_rate_limit(uint8_t port_id, uint16_t vf, uint16_t tx_rate,
- uint64_t q_msk)
-{
- struct rte_eth_dev *dev;
- struct rte_eth_dev_info dev_info;
- struct rte_eth_link link;
-
- if (q_msk == 0)
- return 0;
-
- RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
-
- dev = &rte_eth_devices[port_id];
- rte_eth_dev_info_get(port_id, &dev_info);
- link = dev->data->dev_link;
-
- if (vf > dev_info.max_vfs) {
- RTE_PMD_DEBUG_TRACE("set VF rate limit:port %d: "
- "invalid vf id=%d\n", port_id, vf);
- return -EINVAL;
- }
-
- if (tx_rate > link.link_speed) {
- RTE_PMD_DEBUG_TRACE("set VF rate limit:invalid tx_rate=%d, "
- "bigger than link speed= %d\n",
- tx_rate, link.link_speed);
- return -EINVAL;
- }
-
- RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->set_vf_rate_limit, -ENOTSUP);
- return (*dev->dev_ops->set_vf_rate_limit)(dev, vf, tx_rate, q_msk);
-}
-
int
rte_eth_mirror_rule_set(uint8_t port_id,
struct rte_eth_mirror_conf *mirror_conf,
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 9678179..c602d7d 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1249,39 +1249,11 @@ typedef int (*eth_uc_all_hash_table_set_t)(struct rte_eth_dev *dev,
uint8_t on);
/**< @internal Set all Unicast Hash bitmap */
-typedef int (*eth_set_vf_rx_mode_t)(struct rte_eth_dev *dev,
- uint16_t vf,
- uint16_t rx_mode,
- uint8_t on);
-/**< @internal Set a VF receive mode */
-
-typedef int (*eth_set_vf_rx_t)(struct rte_eth_dev *dev,
- uint16_t vf,
- uint8_t on);
-/**< @internal Set a VF receive mode */
-
-typedef int (*eth_set_vf_tx_t)(struct rte_eth_dev *dev,
- uint16_t vf,
- uint8_t on);
-/**< @internal Enable or disable a VF transmit */
-
-typedef int (*eth_set_vf_vlan_filter_t)(struct rte_eth_dev *dev,
- uint16_t vlan,
- uint64_t vf_mask,
- uint8_t vlan_on);
-/**< @internal Set VF VLAN pool filter */
-
typedef int (*eth_set_queue_rate_limit_t)(struct rte_eth_dev *dev,
uint16_t queue_idx,
uint16_t tx_rate);
/**< @internal Set queue TX rate */
-typedef int (*eth_set_vf_rate_limit_t)(struct rte_eth_dev *dev,
- uint16_t vf,
- uint16_t tx_rate,
- uint64_t q_msk);
-/**< @internal Set VF TX rate */
-
typedef int (*eth_mirror_rule_set_t)(struct rte_eth_dev *dev,
struct rte_eth_mirror_conf *mirror_conf,
uint8_t rule_id,
@@ -1479,16 +1451,11 @@ struct eth_dev_ops {
eth_uc_all_hash_table_set_t uc_all_hash_table_set; /**< Set Unicast hash bitmap */
eth_mirror_rule_set_t mirror_rule_set; /**< Add a traffic mirror rule.*/
eth_mirror_rule_reset_t mirror_rule_reset; /**< reset a traffic mirror rule.*/
- eth_set_vf_rx_mode_t set_vf_rx_mode; /**< Set VF RX mode */
- eth_set_vf_rx_t set_vf_rx; /**< enable/disable a VF receive */
- eth_set_vf_tx_t set_vf_tx; /**< enable/disable a VF transmit */
- eth_set_vf_vlan_filter_t set_vf_vlan_filter; /**< Set VF VLAN filter */
/** Add UDP tunnel port. */
eth_udp_tunnel_port_add_t udp_tunnel_port_add;
/** Del UDP tunnel port. */
eth_udp_tunnel_port_del_t udp_tunnel_port_del;
eth_set_queue_rate_limit_t set_queue_rate_limit; /**< Set queue rate limit */
- eth_set_vf_rate_limit_t set_vf_rate_limit; /**< Set VF rate limit */
/** Update redirection table. */
reta_update_t reta_update;
/** Query redirection table. */
@@ -3403,93 +3370,6 @@ int rte_eth_dev_uc_hash_table_set(uint8_t port,struct ether_addr *addr,
*/
int rte_eth_dev_uc_all_hash_table_set(uint8_t port,uint8_t on);
- /**
- * Set RX L2 Filtering mode of a VF of an Ethernet device.
- *
- * @param port
- * The port identifier of the Ethernet device.
- * @param vf
- * VF id.
- * @param rx_mode
- * The RX mode mask, which is one or more of accepting Untagged Packets,
- * packets that match the PFUTA table, Broadcast and Multicast Promiscuous.
- * ETH_VMDQ_ACCEPT_UNTAG,ETH_VMDQ_ACCEPT_HASH_UC,
- * ETH_VMDQ_ACCEPT_BROADCAST and ETH_VMDQ_ACCEPT_MULTICAST will be used
- * in rx_mode.
- * @param on
- * 1 - Enable a VF RX mode.
- * 0 - Disable a VF RX mode.
- * @return
- * - (0) if successful.
- * - (-ENOTSUP) if hardware doesn't support.
- * - (-ENOTSUP) if hardware doesn't support.
- * - (-EINVAL) if bad parameter.
- */
-int rte_eth_dev_set_vf_rxmode(uint8_t port, uint16_t vf, uint16_t rx_mode,
- uint8_t on);
-
-/**
-* Enable or disable a VF traffic transmit of the Ethernet device.
-*
-* @param port
-* The port identifier of the Ethernet device.
-* @param vf
-* VF id.
-* @param on
-* 1 - Enable a VF traffic transmit.
-* 0 - Disable a VF traffic transmit.
-* @return
-* - (0) if successful.
-* - (-ENODEV) if *port_id* invalid.
-* - (-ENOTSUP) if hardware doesn't support.
-* - (-EINVAL) if bad parameter.
-*/
-int
-rte_eth_dev_set_vf_tx(uint8_t port,uint16_t vf, uint8_t on);
-
-/**
-* Enable or disable a VF traffic receive of an Ethernet device.
-*
-* @param port
-* The port identifier of the Ethernet device.
-* @param vf
-* VF id.
-* @param on
-* 1 - Enable a VF traffic receive.
-* 0 - Disable a VF traffic receive.
-* @return
-* - (0) if successful.
-* - (-ENOTSUP) if hardware doesn't support.
-* - (-ENODEV) if *port_id* invalid.
-* - (-EINVAL) if bad parameter.
-*/
-int
-rte_eth_dev_set_vf_rx(uint8_t port,uint16_t vf, uint8_t on);
-
-/**
-* Enable/Disable hardware VF VLAN filtering by an Ethernet device of
-* received VLAN packets tagged with a given VLAN Tag Identifier.
-*
-* @param port id
-* The port identifier of the Ethernet device.
-* @param vlan_id
-* The VLAN Tag Identifier whose filtering must be enabled or disabled.
-* @param vf_mask
-* Bitmap listing which VFs participate in the VLAN filtering.
-* @param vlan_on
-* 1 - Enable VFs VLAN filtering.
-* 0 - Disable VFs VLAN filtering.
-* @return
-* - (0) if successful.
-* - (-ENOTSUP) if hardware doesn't support.
-* - (-ENODEV) if *port_id* invalid.
-* - (-EINVAL) if bad parameter.
-*/
-int
-rte_eth_dev_set_vf_vlan_filter(uint8_t port, uint16_t vlan_id,
- uint64_t vf_mask,
- uint8_t vlan_on);
-
/**
* Set a traffic mirroring rule on an Ethernet device
*
@@ -3551,26 +3431,6 @@ int rte_eth_set_queue_rate_limit(uint8_t port_id, uint16_t queue_idx,
uint16_t tx_rate);
/**
- * Set the rate limitation for a vf on an Ethernet device.
- *
- * @param port_id
- * The port identifier of the Ethernet device.
- * @param vf
- * VF id.
- * @param tx_rate
- * The tx rate allocated from the total link speed for this VF id.
- * @param q_msk
- * The queue mask which need to set the rate.
- * @return
- * - (0) if successful.
- * - (-ENOTSUP) if hardware doesn't support this feature.
- * - (-ENODEV) if *port_id* invalid.
- * - (-EINVAL) if bad parameter.
- */
-int rte_eth_set_vf_rate_limit(uint8_t port_id, uint16_t vf,
- uint16_t tx_rate, uint64_t q_msk);
-
-/**
* Initialize bypass logic. This function needs to be called before
* executing any other bypass API.
*
diff --git a/lib/librte_ether/rte_ether_version.map b/lib/librte_ether/rte_ether_version.map
index 72be66d..7594416 100644
--- a/lib/librte_ether/rte_ether_version.map
+++ b/lib/librte_ether/rte_ether_version.map
@@ -61,10 +61,6 @@ DPDK_2.2 {
rte_eth_dev_set_mtu;
rte_eth_dev_set_rx_queue_stats_mapping;
rte_eth_dev_set_tx_queue_stats_mapping;
- rte_eth_dev_set_vf_rx;
- rte_eth_dev_set_vf_rxmode;
- rte_eth_dev_set_vf_tx;
- rte_eth_dev_set_vf_vlan_filter;
rte_eth_dev_set_vlan_offload;
rte_eth_dev_set_vlan_pvid;
rte_eth_dev_set_vlan_strip_on_queue;
@@ -94,7 +90,6 @@ DPDK_2.2 {
rte_eth_rx_queue_info_get;
rte_eth_rx_queue_setup;
rte_eth_set_queue_rate_limit;
- rte_eth_set_vf_rate_limit;
rte_eth_stats;
rte_eth_stats_get;
rte_eth_stats_reset;
@@ -146,4 +141,4 @@ DPDK_16.11 {
rte_eth_dev_pci_probe;
rte_eth_dev_pci_remove;
-} DPDK_16.07;
+} DPDK_16.07;
\ No newline at end of file
--
2.10.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox