* Re: [PATCH] net/mlx5: fix handling of small mbuf sizes
From: Adrien Mazarguil @ 2016-10-28 12:19 UTC (permalink / raw)
To: Raslan Darawsheh; +Cc: dev
In-Reply-To: <937aac679e571c4fff8ab720f4dd910fe10a283e.1477296585.git.rasland@mellanox.com>
On Mon, Oct 24, 2016 at 11:10:59AM +0300, Raslan Darawsheh wrote:
> When mbufs are smaller than MRU, multi-segment support must be enabled to
> default set when not in promiscuous or allmulticast modes.
>
> Fixes: 9964b965ad69 ("net/mlx5: re-add Rx scatter support")
>
> Signed-off-by: Raslan Darawsheh <rasland@mellanox.com>
> ---
> drivers/net/mlx5/mlx5_rxq.c | 6 ++++++
> 1 file changed, 6 insertions(+)
>
> diff --git a/drivers/net/mlx5/mlx5_rxq.c b/drivers/net/mlx5/mlx5_rxq.c
> index 4dc5cc3..62253ed 100644
> --- a/drivers/net/mlx5/mlx5_rxq.c
> +++ b/drivers/net/mlx5/mlx5_rxq.c
> @@ -946,6 +946,12 @@ rxq_ctrl_setup(struct rte_eth_dev *dev, struct rxq_ctrl *rxq_ctrl,
> (void)conf; /* Thresholds configuration (ignored). */
> /* Enable scattered packets support for this queue if necessary. */
> assert(mb_len >= RTE_PKTMBUF_HEADROOM);
> + /* If smaller than MRU, multi-segment support must be enabled. */
> + if (mb_len < (priv->mtu > dev->data->dev_conf.rxmode.max_rx_pkt_len ?
> + dev->data->dev_conf.rxmode.max_rx_pkt_len :
> + priv->mtu
> + ))
Let's move poor "))" to the end of the previous line.
> + dev->data->dev_conf.rxmode.jumbo_frame = 1;
> if ((dev->data->dev_conf.rxmode.jumbo_frame) &&
> (dev->data->dev_conf.rxmode.max_rx_pkt_len >
> (mb_len - RTE_PKTMBUF_HEADROOM))) {
> --
> 1.9.1
Besides the above comment:
Acked-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
--
Adrien Mazarguil
6WIND
^ permalink raw reply
* Re: [PATCH v11 1/6] ethdev: add Tx preparation
From: Thomas Monjalon @ 2016-10-28 12:23 UTC (permalink / raw)
To: Ananyev, Konstantin; +Cc: dev
In-Reply-To: <2601191342CEEE43887BDE71AB9772583F0CEC6E@irsmsx105.ger.corp.intel.com>
2016-10-28 11:34, Ananyev, Konstantin:
> > > 2016-10-27 16:24, Ananyev, Konstantin:
> > > > From: Thomas Monjalon [mailto:thomas.monjalon@6wind.com]
> > > > > 2016-10-27 15:52, Ananyev, Konstantin:
> > > > > > > 2016-10-26 14:56, Tomasz Kulasek:
> > > > > > > > --- a/config/common_base
> > > > > > > > +++ b/config/common_base
> > > > > > > > +CONFIG_RTE_ETHDEV_TX_PREP=y
> > > > > > >
> > > > > > > We cannot enable it until it is implemented in every drivers.
> > > > > >
> > > > > > Not sure why?
> > > > > > If tx_pkt_prep == NULL, then rte_eth_tx_prep() would just act as noop.
> > > > > > Right now it is not mandatory for the PMD to implement it.
> > > > >
> > > > > If it is not implemented, the application must do the preparation by itself.
> > > > > From patch 6:
> > > > > "
> > > > > Removed pseudo header calculation for udp/tcp/tso packets from
> > > > > application and used Tx preparation API for packet preparation and
> > > > > verification.
> > > > > "
> > > > > So how does it behave with other drivers?
> > > >
> > > > Hmm so it seems that we broke testpmd csumonly mode for non-intel drivers..
> > > > My bad, missed that part completely.
> > > > Yes, then I suppose for now we'll need to support both (with and without) code paths for testpmd.
> > > > Probably a new fwd mode or just extra parameter for the existing one?
> > > > Any other suggestions?
> > >
> > > Please think how we can use it in every applications.
> > > It is not ready.
> > > Either we introduce the API without enabling it, or we implement it
> > > in every drivers.
> >
> > I understand your position here, but just like to point that:
> > 1) It is a new functionality optional to use.
> > The app is free not to use that functionality and still do the preparation itself
> > (as it has to do it now).
> > All existing apps would keep working as expected without using that function.
> > Though if the app developer knows that for all HW models he plans to run on
> > tx_prep is implemented - he is free to use it.
> > 2) It would be difficult for Tomasz (and other Intel guys) to implement tx_prep()
> > for all non-Intel HW that DPDK supports right now.
> > We just don't have all the actual HW in stock and probably adequate knowledge of it.
> > So we depend here on the good will of other PMD mainaners/developers to implement
> > tx_prep() for these devices.
> > From other side, if it will be disabled by default, then, I think,
> > PMD developers just wouldn't be motivated to implement it.
> > So it will be left untested and unused forever.
>
> Actually as another thought:
> Can we have it enabled by default, but mark it as experimental or so?
> If memory serves me right, we've done that for cryptodev in the past, no?
Cryptodev was a whole new library.
We won't play the game "find which function is experimental or not".
We should not enable a function until it is fully implemented.
If the user really understands that it will work only with few drivers
then he can change the build configuration himself.
Enabling in the default configuration is a message to say that it works
everywhere without any risk.
It's so simple that I don't even understand why I must argue for.
And by the way, it is late for 16.11.
I suggest to integrate it in the beginning of 17.02 cycle, with the hope
that you can convince other developers to implement it in other drivers,
so we could finally enable it in the default config.
Oh, and I don't trust that nobody were thinking that it would break testpmd
for non-Intel drivers.
^ permalink raw reply
* [PATCH v7 00/21] Introduce SoC device/driver framework for EAL
From: Shreyansh Jain @ 2016-10-28 12:26 UTC (permalink / raw)
To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin
In-Reply-To: <1477581467-12588-1-git-send-email-shreyansh.jain@nxp.com>
Introduction:
=============
This patch set is direct derivative of Jan's original series [1],[2].
- This version is based on master HEAD (ca41215)
- In this, I am merging the series [11] back. It was initially part
of this set but I had split considering that those changes in PCI
were good standalone as well. But, 1) not much feedback was avail-
able and 2) this patchset is a use-case for those patches making
it easier to review. Just like what Jan had intended in original
series.
- SoC support is not enabled by default. It needs the 'enable-soc' toggle
on command line. This is primarily because this patchset is still
experimental and we would like to keep it isolated from non-SoC ops.
Though, it does impact the ABI.
Aim:
====
As of now EAL is primarly focused on PCI initialization/probing.
rte_eal_init()
|- rte_eal_pci_init(): Find PCI devices from sysfs
|- ...
|- rte_eal_memzone_init()
|- ...
`- rte_eal_pci_probe(): Driver<=>Device initialization
This patchset introduces SoC framework which would enable SoC drivers and
drivers to be plugged into EAL, very similar to how PCI drivers/devices are
done today.
This is a stripped down version of PCI framework which allows the SoC PMDs
to implement their own routines for detecting devices and linking devices to
drivers.
1) Changes to EAL
rte_eal_init()
|- rte_eal_pci_init(): Find PCI devices from sysfs
|- rte_eal_soc_init(): Calls PMDs->scan_fn
|- ...
|- rte_eal_memzone_init()
|- ...
|- rte_eal_pci_probe(): Driver<=>Device initialization, PMD->devinit()
`- rte_eal_soc_probe(): Calls PMDs->match_fn and PMDs->devinit();
2) New device/driver structures:
- rte_soc_driver (inheriting rte_driver)
- rte_soc_device (inheriting rte_device)
- rte_eth_dev and eth_driver embedded rte_soc_device and rte_soc_driver,
respectively.
3) The SoC PMDs need to:
- define rte_soc_driver with necessary scan and match callbacks
- Register themselves using DRIVER_REGISTER_SOC()
- Implement respective bus scanning in the scan callbacks to add necessary
devices to SoC device list
- Implement necessary eth_dev_init/uninint for ethernet instances
4) Design considerations that are same as PCI:
- SoC initialization is being done through rte_eal_init(), just after PCI
initialization is done.
- As in case of PCI, probe is done after rte_eal_pci_probe() to link the
devices detected with the drivers registered.
- Device attach/detach functions are available and have been designed on
the lines of PCI framework.
- PMDs register using DRIVER_REGISTER_SOC, very similar to
DRIVER_REGISTER_PCI for PCI devices.
- Linked list of SoC driver and devices exists independent of the other
driver/device list, but inheriting rte_driver/rte_driver, these are
also part of a global list.
5) Design considerations that are different from PCI:
- Each driver implements its own scan and match function. PCI uses the BDF
format to read the device from sysfs, but this _may_not_ be a case for a
SoC ethernet device.
= This is an important change from initial proposal by Jan in [2].
Unlike his attempt to use /sys/bus/platform, this patch relies on the
PMD to detect the devices. This is because SoC may require specific or
additional info for device detection. Further, SoC may have embedded
devices/MACs which require initialization which cannot be covered
through sysfs parsing.
`-> Point (6) below is a side note to above.
= PCI based PMDs rely on EAL's capability to detect devices. This
proposal puts the onus on PMD to detect devices, add to soc_device_list
and wait for Probe. Matching, of device<=>driver is again PMD's
callback.
6) Adding default scan and match helpers for PMDs
- The design warrrants the PMDs implement their own scan of devices
on bus, and match routines for probe implementation.
This patch introduces helpers which can be used by PMDs for scan of
the platform bus and matching devices against the compatible string
extracted from the scan.
- Intention is to make it easier to integrate known SoC which expose
platform bus compliant information (compat, sys/bus/platform...).
- PMDs which have deviations from this standard model can implement and
hook their bus scanning and probe match callbacks while registering
driver.
Patchset Overview:
==================
- Patches 0001~0004 are from [11] - moving some PCI specific functions
and definitions to non-PCI area.
- Patches 0005~0008 introduce the base infrastructure and test case
- Patch 0009 is for command line support for no-soc, on lines of no-pci
- Patch 0010 enables EAL to handle SoC type devices
- Patch 0011 adds support for scan and probe callbacks and updates the test
framework with relevant test case.
- Patch 0012~0014 enable device argument, driver specific flags and
interrupt handling related basic infra. Subsequent patches build up on
them.
- Patch 0015~0016 add support for default function which PMDs can use for
scanning platform bus. These functions are optional and need to be hooked
to by PMDs.
- Patch 0017~0019 makes changes to PCI as well as ethdev code to remove
assumption that eth_driver is a PCI driver.
- Patch 0020 adds necessary ethdev probe/remove functions for PMDs to use
- Patch 0021 adds support for SoC driver/devices, along with probe/remove
functions for Cryptodev devices.
Future/Pending Changes:
=======================
- Device whitelisting/blacklist still relies on command line '-b' and '-c'
which are internally implemented using OPT_PCI_BLACKLIST/OPT_PCI_WHITELIST.
This needs to be changed to a generic form - OPT_DEV_*LIST - probably.
- No cryptodriver currently uses SoC framework - probably a example driver
can be created to demonstrate usage.
- test case for enable-soc command line parameter
- This patch impacts a couple of ABIs (rte_device/driver) and thus require
a patch for bump of libraries (if need be) and documentation.
[1] http://dpdk.org/ml/archives/dev/2016-January/030915.html
[2] http://www.dpdk.org/ml/archives/dev/2016-May/038486.html
[3] http://dpdk.org/ml/archives/dev/2016-August/045707.html
[4] http://dpdk.org/ml/archives/dev/2016-May/038948.html
[5] http://dpdk.org/ml/archives/dev/2016-May/038953.html
[6] http://dpdk.org/ml/archives/dev/2016-May/038487.html
[7] http://dpdk.org/ml/archives/dev/2016-May/038488.html
[8] http://dpdk.org/ml/archives/dev/2016-May/038489.html
[9] http://dpdk.org/ml/archives/dev/2016-May/038491.html
[10] http://dpdk.org/ml/archives/dev/2016-September/046256.html
[11] http://dpdk.org/ml/archives/dev/2016-October/048915.html
Changes since v6;
- Fix patch rebase over HEAD (ca41215)
Changes since v5:
- fix devinit/devuninit name change; it was in wrong patch
- rebased over HEAD (ca41215)
- Update to pending section of coverletter
Changes since v4:
- change name of rte_eal_soc_scan function name to
rte_eal_soc_scan_platform_bus. This still remains a helper function.
- Fix comments over scan and match functions
Changes since v3:
- rebasing over HEAD (fed622df tag: v16.11-rc1)
- Add support for default scan function; PMD can use this for
scanning on platform bus.
- Support for kernel driver bind/unbind, numa and DMA from
Jan's original patches.
- SoC is disabled by default. '--enable-soc' command line parameter
enables it. doc updated.
- Updated testcase function names and comments
- Map file addition alphabetically ordered
- Patch author corrected
Changes since v2:
- Rebasing over rte_driver/device patchset v9 [10]
- Added cryptodev support for SoC
- Default match function for SoC device<=>Driver
- Some variables renamed to reflect 'drv' rather than 'dr'
Change since v1 [2]:
- Removed patch 1-5 which were for generalizing some PCI specific routines
into EAL. These patches are good-to-have but not directly linked to SoC
and hence would be proposed separately.
- Removed support for sysfs parsing (patches 6~9)
- Rebasing over the recent (v8) version of rte_driver/device patchset
- Rebasing over master (16.07)
- Changes to various map file to change API intro to 16.11 from 16.07
Jan Viktorin (19):
eal: generalize PCI kernel driver enum to EAL
eal: generalize PCI map/unmap resource to EAL
eal/linux: generalize PCI kernel unbinding driver to EAL
eal/linux: generalize PCI kernel driver extraction to EAL
eal: define container macro
eal/soc: introduce very essential SoC infra definitions
eal/soc: add SoC PMD register/unregister logic
eal/soc: implement SoC device list and dump
eal: introduce command line enable SoC option
eal/soc: init SoC infra from EAL
eal/soc: extend and utilize devargs
eal/soc: add drv_flags
eal/soc: add intr_handle
eal/soc: add default scan for Soc devices
eal/soc: additional features for SoC
ether: utilize container_of for pci_drv
ether: verify we copy info from a PCI device
ether: extract function eth_dev_get_intr_handle
ether: introduce ethernet dev probe remove
Shreyansh Jain (2):
eal/soc: implement probing of drivers
eal/crypto: Support rte_soc_driver/device for cryptodev
app/test/Makefile | 1 +
app/test/test_soc.c | 404 +++++++++++++++++++
doc/guides/testpmd_app_ug/run_app.rst | 4 +
lib/librte_cryptodev/rte_cryptodev.c | 122 +++++-
lib/librte_cryptodev/rte_cryptodev.h | 3 +
lib/librte_cryptodev/rte_cryptodev_pmd.h | 18 +-
lib/librte_cryptodev/rte_cryptodev_version.map | 2 +
lib/librte_eal/bsdapp/eal/Makefile | 1 +
lib/librte_eal/bsdapp/eal/eal.c | 18 +
lib/librte_eal/bsdapp/eal/eal_pci.c | 6 +-
lib/librte_eal/bsdapp/eal/eal_soc.c | 46 +++
lib/librte_eal/bsdapp/eal/rte_eal_version.map | 11 +
lib/librte_eal/common/Makefile | 2 +-
lib/librte_eal/common/eal_common_dev.c | 66 ++-
lib/librte_eal/common/eal_common_devargs.c | 17 +
lib/librte_eal/common/eal_common_options.c | 5 +
lib/librte_eal/common/eal_common_pci.c | 39 --
lib/librte_eal/common/eal_common_pci_uio.c | 16 +-
lib/librte_eal/common/eal_common_soc.c | 368 +++++++++++++++++
lib/librte_eal/common/eal_internal_cfg.h | 1 +
lib/librte_eal/common/eal_options.h | 2 +
lib/librte_eal/common/eal_private.h | 64 +++
lib/librte_eal/common/include/rte_common.h | 18 +
lib/librte_eal/common/include/rte_dev.h | 44 ++
lib/librte_eal/common/include/rte_devargs.h | 8 +
lib/librte_eal/common/include/rte_pci.h | 41 --
lib/librte_eal/common/include/rte_soc.h | 322 +++++++++++++++
lib/librte_eal/linuxapp/eal/Makefile | 2 +
lib/librte_eal/linuxapp/eal/eal.c | 63 +++
lib/librte_eal/linuxapp/eal/eal_pci.c | 62 +--
lib/librte_eal/linuxapp/eal/eal_pci_uio.c | 2 +-
lib/librte_eal/linuxapp/eal/eal_pci_vfio.c | 5 +-
lib/librte_eal/linuxapp/eal/eal_soc.c | 515 ++++++++++++++++++++++++
lib/librte_eal/linuxapp/eal/rte_eal_version.map | 11 +
lib/librte_ether/rte_ethdev.c | 166 +++++++-
lib/librte_ether/rte_ethdev.h | 33 +-
36 files changed, 2343 insertions(+), 165 deletions(-)
create mode 100644 app/test/test_soc.c
create mode 100644 lib/librte_eal/bsdapp/eal/eal_soc.c
create mode 100644 lib/librte_eal/common/eal_common_soc.c
create mode 100644 lib/librte_eal/common/include/rte_soc.h
create mode 100644 lib/librte_eal/linuxapp/eal/eal_soc.c
--
2.7.4
^ permalink raw reply
* [PATCH v7 01/21] eal: generalize PCI kernel driver enum to EAL
From: Shreyansh Jain @ 2016-10-28 12:26 UTC (permalink / raw)
To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin
In-Reply-To: <1477657598-826-1-git-send-email-shreyansh.jain@nxp.com>
From: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
--
Changes since v0:
- fix compilation error due to missing include
---
lib/librte_eal/common/include/rte_dev.h | 12 ++++++++++++
lib/librte_eal/common/include/rte_pci.h | 9 ---------
2 files changed, 12 insertions(+), 9 deletions(-)
diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
index 8840380..6975b9f 100644
--- a/lib/librte_eal/common/include/rte_dev.h
+++ b/lib/librte_eal/common/include/rte_dev.h
@@ -109,6 +109,18 @@ struct rte_mem_resource {
void *addr; /**< Virtual address, NULL when not mapped. */
};
+/**
+ * Kernel driver passthrough type
+ */
+enum rte_kernel_driver {
+ RTE_KDRV_UNKNOWN = 0,
+ RTE_KDRV_IGB_UIO,
+ RTE_KDRV_VFIO,
+ RTE_KDRV_UIO_GENERIC,
+ RTE_KDRV_NIC_UIO,
+ RTE_KDRV_NONE,
+};
+
/** Double linked list of device drivers. */
TAILQ_HEAD(rte_driver_list, rte_driver);
/** Double linked list of devices. */
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
index 9ce8847..2c7046f 100644
--- a/lib/librte_eal/common/include/rte_pci.h
+++ b/lib/librte_eal/common/include/rte_pci.h
@@ -135,15 +135,6 @@ struct rte_pci_addr {
struct rte_devargs;
-enum rte_kernel_driver {
- RTE_KDRV_UNKNOWN = 0,
- RTE_KDRV_IGB_UIO,
- RTE_KDRV_VFIO,
- RTE_KDRV_UIO_GENERIC,
- RTE_KDRV_NIC_UIO,
- RTE_KDRV_NONE,
-};
-
/**
* A structure describing a PCI device.
*/
--
2.7.4
^ permalink raw reply related
* [PATCH v7 02/21] eal: generalize PCI map/unmap resource to EAL
From: Shreyansh Jain @ 2016-10-28 12:26 UTC (permalink / raw)
To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin
In-Reply-To: <1477657598-826-1-git-send-email-shreyansh.jain@nxp.com>
From: Jan Viktorin <viktorin@rehivetech.com>
The functions pci_map_resource, pci_unmap_resource are generic so the
pci_* prefix can be omitted. The functions are moved to the
eal_common_dev.c so they can be reused by other infrastructure.
Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
lib/librte_eal/bsdapp/eal/eal_pci.c | 2 +-
lib/librte_eal/bsdapp/eal/rte_eal_version.map | 2 ++
lib/librte_eal/common/eal_common_dev.c | 39 +++++++++++++++++++++++++
lib/librte_eal/common/eal_common_pci.c | 39 -------------------------
lib/librte_eal/common/eal_common_pci_uio.c | 16 +++++-----
lib/librte_eal/common/include/rte_dev.h | 32 ++++++++++++++++++++
lib/librte_eal/common/include/rte_pci.h | 32 --------------------
lib/librte_eal/linuxapp/eal/eal_pci_uio.c | 2 +-
lib/librte_eal/linuxapp/eal/eal_pci_vfio.c | 5 ++--
lib/librte_eal/linuxapp/eal/rte_eal_version.map | 2 ++
10 files changed, 89 insertions(+), 82 deletions(-)
diff --git a/lib/librte_eal/bsdapp/eal/eal_pci.c b/lib/librte_eal/bsdapp/eal/eal_pci.c
index 8b3ed88..7ed0115 100644
--- a/lib/librte_eal/bsdapp/eal/eal_pci.c
+++ b/lib/librte_eal/bsdapp/eal/eal_pci.c
@@ -228,7 +228,7 @@ pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
/* if matching map is found, then use it */
offset = res_idx * pagesz;
- mapaddr = pci_map_resource(NULL, fd, (off_t)offset,
+ mapaddr = rte_eal_map_resource(NULL, fd, (off_t)offset,
(size_t)dev->mem_resource[res_idx].len, 0);
close(fd);
if (mapaddr == MAP_FAILED)
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index 2f81f7c..11d9f59 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -170,6 +170,8 @@ DPDK_16.11 {
rte_delay_us_callback_register;
rte_eal_dev_attach;
rte_eal_dev_detach;
+ rte_eal_map_resource;
+ rte_eal_unmap_resource;
rte_eal_vdrv_register;
rte_eal_vdrv_unregister;
diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c
index 4f3b493..457d227 100644
--- a/lib/librte_eal/common/eal_common_dev.c
+++ b/lib/librte_eal/common/eal_common_dev.c
@@ -36,6 +36,7 @@
#include <string.h>
#include <inttypes.h>
#include <sys/queue.h>
+#include <sys/mman.h>
#include <rte_dev.h>
#include <rte_devargs.h>
@@ -151,3 +152,41 @@ err:
RTE_LOG(ERR, EAL, "Driver cannot detach the device (%s)\n", name);
return -EINVAL;
}
+
+/* map a particular resource from a file */
+void *
+rte_eal_map_resource(void *requested_addr, int fd, off_t offset, size_t size,
+ int additional_flags)
+{
+ void *mapaddr;
+
+ /* Map the Memory resource of device */
+ mapaddr = mmap(requested_addr, size, PROT_READ | PROT_WRITE,
+ MAP_SHARED | additional_flags, fd, offset);
+ if (mapaddr == MAP_FAILED) {
+ RTE_LOG(ERR, EAL, "%s(): cannot mmap(%d, %p, 0x%lx, 0x%lx): %s"
+ " (%p)\n", __func__, fd, requested_addr,
+ (unsigned long)size, (unsigned long)offset,
+ strerror(errno), mapaddr);
+ } else
+ RTE_LOG(DEBUG, EAL, " Device memory mapped at %p\n", mapaddr);
+
+ return mapaddr;
+}
+
+/* unmap a particular resource */
+void
+rte_eal_unmap_resource(void *requested_addr, size_t size)
+{
+ if (requested_addr == NULL)
+ return;
+
+ /* Unmap the Memory resource of device */
+ if (munmap(requested_addr, size)) {
+ RTE_LOG(ERR, EAL, "%s(): cannot munmap(%p, 0x%lx): %s\n",
+ __func__, requested_addr, (unsigned long)size,
+ strerror(errno));
+ } else
+ RTE_LOG(DEBUG, EAL, " Device memory unmapped at %p\n",
+ requested_addr);
+}
diff --git a/lib/librte_eal/common/eal_common_pci.c b/lib/librte_eal/common/eal_common_pci.c
index 638cd86..464acc1 100644
--- a/lib/librte_eal/common/eal_common_pci.c
+++ b/lib/librte_eal/common/eal_common_pci.c
@@ -67,7 +67,6 @@
#include <stdlib.h>
#include <stdio.h>
#include <sys/queue.h>
-#include <sys/mman.h>
#include <rte_interrupts.h>
#include <rte_log.h>
@@ -114,44 +113,6 @@ static struct rte_devargs *pci_devargs_lookup(struct rte_pci_device *dev)
return NULL;
}
-/* map a particular resource from a file */
-void *
-pci_map_resource(void *requested_addr, int fd, off_t offset, size_t size,
- int additional_flags)
-{
- void *mapaddr;
-
- /* Map the PCI memory resource of device */
- mapaddr = mmap(requested_addr, size, PROT_READ | PROT_WRITE,
- MAP_SHARED | additional_flags, fd, offset);
- if (mapaddr == MAP_FAILED) {
- RTE_LOG(ERR, EAL, "%s(): cannot mmap(%d, %p, 0x%lx, 0x%lx): %s (%p)\n",
- __func__, fd, requested_addr,
- (unsigned long)size, (unsigned long)offset,
- strerror(errno), mapaddr);
- } else
- RTE_LOG(DEBUG, EAL, " PCI memory mapped at %p\n", mapaddr);
-
- return mapaddr;
-}
-
-/* unmap a particular resource */
-void
-pci_unmap_resource(void *requested_addr, size_t size)
-{
- if (requested_addr == NULL)
- return;
-
- /* Unmap the PCI memory resource of device */
- if (munmap(requested_addr, size)) {
- RTE_LOG(ERR, EAL, "%s(): cannot munmap(%p, 0x%lx): %s\n",
- __func__, requested_addr, (unsigned long)size,
- strerror(errno));
- } else
- RTE_LOG(DEBUG, EAL, " PCI memory unmapped at %p\n",
- requested_addr);
-}
-
/*
* If vendor/device ID match, call the probe() function of the
* driver.
diff --git a/lib/librte_eal/common/eal_common_pci_uio.c b/lib/librte_eal/common/eal_common_pci_uio.c
index 367a681..3402518 100644
--- a/lib/librte_eal/common/eal_common_pci_uio.c
+++ b/lib/librte_eal/common/eal_common_pci_uio.c
@@ -75,9 +75,11 @@ pci_uio_map_secondary(struct rte_pci_device *dev)
return -1;
}
- void *mapaddr = pci_map_resource(uio_res->maps[i].addr,
- fd, (off_t)uio_res->maps[i].offset,
- (size_t)uio_res->maps[i].size, 0);
+ void *mapaddr = rte_eal_map_resource(
+ uio_res->maps[i].addr, fd,
+ (off_t)uio_res->maps[i].offset,
+ (size_t)uio_res->maps[i].size,
+ 0);
/* fd is not needed in slave process, close it */
close(fd);
if (mapaddr != uio_res->maps[i].addr) {
@@ -88,11 +90,11 @@ pci_uio_map_secondary(struct rte_pci_device *dev)
if (mapaddr != MAP_FAILED) {
/* unmap addrs correctly mapped */
for (j = 0; j < i; j++)
- pci_unmap_resource(
+ rte_eal_unmap_resource(
uio_res->maps[j].addr,
(size_t)uio_res->maps[j].size);
/* unmap addr wrongly mapped */
- pci_unmap_resource(mapaddr,
+ rte_eal_unmap_resource(mapaddr,
(size_t)uio_res->maps[i].size);
}
return -1;
@@ -150,7 +152,7 @@ pci_uio_map_resource(struct rte_pci_device *dev)
return 0;
error:
for (i = 0; i < map_idx; i++) {
- pci_unmap_resource(uio_res->maps[i].addr,
+ rte_eal_unmap_resource(uio_res->maps[i].addr,
(size_t)uio_res->maps[i].size);
rte_free(uio_res->maps[i].path);
}
@@ -167,7 +169,7 @@ pci_uio_unmap(struct mapped_pci_resource *uio_res)
return;
for (i = 0; i != uio_res->nb_maps; i++) {
- pci_unmap_resource(uio_res->maps[i].addr,
+ rte_eal_unmap_resource(uio_res->maps[i].addr,
(size_t)uio_res->maps[i].size);
if (rte_eal_process_type() == RTE_PROC_PRIMARY)
rte_free(uio_res->maps[i].path);
diff --git a/lib/librte_eal/common/include/rte_dev.h b/lib/librte_eal/common/include/rte_dev.h
index 6975b9f..5be6326 100644
--- a/lib/librte_eal/common/include/rte_dev.h
+++ b/lib/librte_eal/common/include/rte_dev.h
@@ -235,6 +235,38 @@ int rte_eal_dev_attach(const char *name, const char *devargs);
*/
int rte_eal_dev_detach(const char *name);
+/*
+ * @internal
+ * Map a particular resource from a file.
+ *
+ * @param requested_addr
+ * The starting address for the new mapping range.
+ * @param fd
+ * The file descriptor.
+ * @param offset
+ * The offset for the mapping range.
+ * @param size
+ * The size for the mapping range.
+ * @param additional_flags
+ * The additional flags for the mapping range.
+ * @return
+ * - On success, the function returns a pointer to the mapped area.
+ * - On error, the value MAP_FAILED is returned.
+ */
+void *rte_eal_map_resource(void *requested_addr, int fd, off_t offset,
+ size_t size, int additional_flags);
+
+/**
+ * @internal
+ * Unmap a particular resource.
+ *
+ * @param requested_addr
+ * The address for the unmapping range.
+ * @param size
+ * The size for the unmapping range.
+ */
+void rte_eal_unmap_resource(void *requested_addr, size_t size);
+
#define RTE_PMD_EXPORT_NAME_ARRAY(n, idx) n##idx[]
#define RTE_PMD_EXPORT_NAME(name, idx) \
diff --git a/lib/librte_eal/common/include/rte_pci.h b/lib/librte_eal/common/include/rte_pci.h
index 2c7046f..7d6eef5 100644
--- a/lib/librte_eal/common/include/rte_pci.h
+++ b/lib/librte_eal/common/include/rte_pci.h
@@ -399,38 +399,6 @@ int rte_eal_pci_map_device(struct rte_pci_device *dev);
void rte_eal_pci_unmap_device(struct rte_pci_device *dev);
/**
- * @internal
- * Map a particular resource from a file.
- *
- * @param requested_addr
- * The starting address for the new mapping range.
- * @param fd
- * The file descriptor.
- * @param offset
- * The offset for the mapping range.
- * @param size
- * The size for the mapping range.
- * @param additional_flags
- * The additional flags for the mapping range.
- * @return
- * - On success, the function returns a pointer to the mapped area.
- * - On error, the value MAP_FAILED is returned.
- */
-void *pci_map_resource(void *requested_addr, int fd, off_t offset,
- size_t size, int additional_flags);
-
-/**
- * @internal
- * Unmap a particular resource.
- *
- * @param requested_addr
- * The address for the unmapping range.
- * @param size
- * The size for the unmapping range.
- */
-void pci_unmap_resource(void *requested_addr, size_t size);
-
-/**
* Probe the single PCI device.
*
* Scan the content of the PCI bus, and find the pci device specified by pci
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
index 1786b75..5c34421 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci_uio.c
@@ -347,7 +347,7 @@ pci_uio_map_resource_by_index(struct rte_pci_device *dev, int res_idx,
if (pci_map_addr == NULL)
pci_map_addr = pci_find_max_end_va();
- mapaddr = pci_map_resource(pci_map_addr, fd, 0,
+ mapaddr = rte_eal_map_resource(pci_map_addr, fd, 0,
(size_t)dev->mem_resource[res_idx].len, 0);
close(fd);
if (mapaddr == MAP_FAILED)
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
index 5f478c5..5ad8cbe 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci_vfio.c
@@ -465,7 +465,8 @@ pci_vfio_map_resource(struct rte_pci_device *dev)
void *map_addr = NULL;
if (memreg[0].size) {
/* actual map of first part */
- map_addr = pci_map_resource(bar_addr, vfio_dev_fd,
+ map_addr = rte_eal_map_resource(bar_addr,
+ vfio_dev_fd,
memreg[0].offset,
memreg[0].size,
MAP_FIXED);
@@ -477,7 +478,7 @@ pci_vfio_map_resource(struct rte_pci_device *dev)
void *second_addr = RTE_PTR_ADD(bar_addr,
memreg[1].offset -
(uintptr_t)reg.offset);
- map_addr = pci_map_resource(second_addr,
+ map_addr = rte_eal_map_resource(second_addr,
vfio_dev_fd, memreg[1].offset,
memreg[1].size,
MAP_FIXED);
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index 83721ba..22b5b59 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -174,6 +174,8 @@ DPDK_16.11 {
rte_delay_us_callback_register;
rte_eal_dev_attach;
rte_eal_dev_detach;
+ rte_eal_map_resource;
+ rte_eal_unmap_resource;
rte_eal_vdrv_register;
rte_eal_vdrv_unregister;
--
2.7.4
^ permalink raw reply related
* [PATCH v7 03/21] eal/linux: generalize PCI kernel unbinding driver to EAL
From: Shreyansh Jain @ 2016-10-28 12:26 UTC (permalink / raw)
To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin
In-Reply-To: <1477657598-826-1-git-send-email-shreyansh.jain@nxp.com>
From: Jan Viktorin <viktorin@rehivetech.com>
Generalize the PCI-specific pci_unbind_kernel_driver. It is now divided
into two parts. First, determination of the path and string identification
of the device to be unbound. Second, the actual unbind operation which is
generic.
BSD implementation updated as ENOTSUP
Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
--
Changes since v2:
- update BSD support for unbind kernel driver
---
lib/librte_eal/bsdapp/eal/eal.c | 7 +++++++
lib/librte_eal/bsdapp/eal/eal_pci.c | 4 ++--
lib/librte_eal/common/eal_private.h | 13 +++++++++++++
lib/librte_eal/linuxapp/eal/eal.c | 26 ++++++++++++++++++++++++++
lib/librte_eal/linuxapp/eal/eal_pci.c | 33 +++++++++------------------------
5 files changed, 57 insertions(+), 26 deletions(-)
diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
index 35e3117..5271fc2 100644
--- a/lib/librte_eal/bsdapp/eal/eal.c
+++ b/lib/librte_eal/bsdapp/eal/eal.c
@@ -633,3 +633,10 @@ rte_eal_process_type(void)
{
return rte_config.process_type;
}
+
+int
+rte_eal_unbind_kernel_driver(const char *devpath __rte_unused,
+ const char *devid __rte_unused)
+{
+ return -ENOTSUP;
+}
diff --git a/lib/librte_eal/bsdapp/eal/eal_pci.c b/lib/librte_eal/bsdapp/eal/eal_pci.c
index 7ed0115..703f034 100644
--- a/lib/librte_eal/bsdapp/eal/eal_pci.c
+++ b/lib/librte_eal/bsdapp/eal/eal_pci.c
@@ -89,11 +89,11 @@
/* unbind kernel driver for this device */
int
-pci_unbind_kernel_driver(struct rte_pci_device *dev __rte_unused)
+pci_unbind_kernel_driver(struct rte_pci_device *dev)
{
RTE_LOG(ERR, EAL, "RTE_PCI_DRV_FORCE_UNBIND flag is not implemented "
"for BSD\n");
- return -ENOTSUP;
+ return rte_eal_unbind_kernel_driver(dev);
}
/* Map pci device */
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index 9e7d8f6..b0c208a 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -256,6 +256,19 @@ int rte_eal_alarm_init(void);
int rte_eal_check_module(const char *module_name);
/**
+ * Unbind kernel driver bound to the device specified by the given devpath,
+ * and its string identification.
+ *
+ * @param devpath path to the device directory ("/sys/.../devices/<name>")
+ * @param devid identification of the device (<name>)
+ *
+ * @return
+ * -1 unbind has failed
+ * 0 module has been unbound
+ */
+int rte_eal_unbind_kernel_driver(const char *devpath, const char *devid);
+
+/**
* Get cpu core_id.
*
* This function is private to the EAL.
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 2075282..5f6676d 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -943,3 +943,29 @@ rte_eal_check_module(const char *module_name)
/* Module has been found */
return 1;
}
+
+int
+rte_eal_unbind_kernel_driver(const char *devpath, const char *devid)
+{
+ char filename[PATH_MAX];
+ FILE *f;
+
+ snprintf(filename, sizeof(filename),
+ "%s/driver/unbind", devpath);
+
+ f = fopen(filename, "w");
+ if (f == NULL) /* device was not bound */
+ return 0;
+
+ if (fwrite(devid, strlen(devid), 1, f) == 0) {
+ RTE_LOG(ERR, EAL, "%s(): could not write to %s\n", __func__,
+ filename);
+ goto error;
+ }
+
+ fclose(f);
+ return 0;
+error:
+ fclose(f);
+ return -1;
+}
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
index 876ba38..a03553f 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
@@ -59,38 +59,23 @@ int
pci_unbind_kernel_driver(struct rte_pci_device *dev)
{
int n;
- FILE *f;
- char filename[PATH_MAX];
- char buf[BUFSIZ];
+ char devpath[PATH_MAX];
+ char devid[BUFSIZ];
struct rte_pci_addr *loc = &dev->addr;
- /* open /sys/bus/pci/devices/AAAA:BB:CC.D/driver */
- snprintf(filename, sizeof(filename),
- "%s/" PCI_PRI_FMT "/driver/unbind", pci_get_sysfs_path(),
+ /* devpath /sys/bus/pci/devices/AAAA:BB:CC.D */
+ snprintf(devpath, sizeof(devpath),
+ "%s/" PCI_PRI_FMT, pci_get_sysfs_path(),
loc->domain, loc->bus, loc->devid, loc->function);
- f = fopen(filename, "w");
- if (f == NULL) /* device was not bound */
- return 0;
-
- n = snprintf(buf, sizeof(buf), PCI_PRI_FMT "\n",
+ n = snprintf(devid, sizeof(devid), PCI_PRI_FMT "\n",
loc->domain, loc->bus, loc->devid, loc->function);
- if ((n < 0) || (n >= (int)sizeof(buf))) {
+ if ((n < 0) || (n >= (int)sizeof(devid))) {
RTE_LOG(ERR, EAL, "%s(): snprintf failed\n", __func__);
- goto error;
- }
- if (fwrite(buf, n, 1, f) == 0) {
- RTE_LOG(ERR, EAL, "%s(): could not write to %s\n", __func__,
- filename);
- goto error;
+ return -1;
}
- fclose(f);
- return 0;
-
-error:
- fclose(f);
- return -1;
+ return rte_eal_unbind_kernel_driver(devpath, devid);
}
static int
--
2.7.4
^ permalink raw reply related
* [PATCH v7 04/21] eal/linux: generalize PCI kernel driver extraction to EAL
From: Shreyansh Jain @ 2016-10-28 12:26 UTC (permalink / raw)
To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin
In-Reply-To: <1477657598-826-1-git-send-email-shreyansh.jain@nxp.com>
From: Jan Viktorin <viktorin@rehivetech.com>
Generalize the PCI-specific pci_get_kernel_driver_by_path. The function
is general enough, we have just moved it to eal.c, changed the prefix to
rte_eal and provided it privately to other parts of EAL.
Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
lib/librte_eal/bsdapp/eal/eal.c | 7 +++++++
lib/librte_eal/common/eal_private.h | 14 ++++++++++++++
lib/librte_eal/linuxapp/eal/eal.c | 29 +++++++++++++++++++++++++++++
lib/librte_eal/linuxapp/eal/eal_pci.c | 31 +------------------------------
4 files changed, 51 insertions(+), 30 deletions(-)
diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
index 5271fc2..9b93da3 100644
--- a/lib/librte_eal/bsdapp/eal/eal.c
+++ b/lib/librte_eal/bsdapp/eal/eal.c
@@ -640,3 +640,10 @@ rte_eal_unbind_kernel_driver(const char *devpath __rte_unused,
{
return -ENOTSUP;
}
+
+int
+rte_eal_get_kernel_driver_by_path(const char *filename __rte_unused,
+ char *dri_name __rte_unused)
+{
+ return -ENOTSUP;
+}
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index b0c208a..c8c2131 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -269,6 +269,20 @@ int rte_eal_check_module(const char *module_name);
int rte_eal_unbind_kernel_driver(const char *devpath, const char *devid);
/**
+ * Extract the kernel driver name from the absolute path to the driver.
+ *
+ * @param filename path to the driver ("<path-to-device>/driver")
+ * @path dri_name target buffer where to place the driver name
+ * (should be at least PATH_MAX long)
+ *
+ * @return
+ * -1 on failure
+ * 0 when successful
+ * 1 when there is no such driver
+ */
+int rte_eal_get_kernel_driver_by_path(const char *filename, char *dri_name);
+
+/**
* Get cpu core_id.
*
* This function is private to the EAL.
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 5f6676d..00af21c 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -969,3 +969,32 @@ error:
fclose(f);
return -1;
}
+
+int
+rte_eal_get_kernel_driver_by_path(const char *filename, char *dri_name)
+{
+ int count;
+ char path[PATH_MAX];
+ char *name;
+
+ if (!filename || !dri_name)
+ return -1;
+
+ count = readlink(filename, path, PATH_MAX);
+ if (count >= PATH_MAX)
+ return -1;
+
+ /* For device does not have a driver */
+ if (count < 0)
+ return 1;
+
+ path[count] = '\0';
+
+ name = strrchr(path, '/');
+ if (name) {
+ strncpy(dri_name, name + 1, strlen(name + 1) + 1);
+ return 0;
+ }
+
+ return -1;
+}
diff --git a/lib/librte_eal/linuxapp/eal/eal_pci.c b/lib/librte_eal/linuxapp/eal/eal_pci.c
index a03553f..e1cf9e8 100644
--- a/lib/librte_eal/linuxapp/eal/eal_pci.c
+++ b/lib/librte_eal/linuxapp/eal/eal_pci.c
@@ -78,35 +78,6 @@ pci_unbind_kernel_driver(struct rte_pci_device *dev)
return rte_eal_unbind_kernel_driver(devpath, devid);
}
-static int
-pci_get_kernel_driver_by_path(const char *filename, char *dri_name)
-{
- int count;
- char path[PATH_MAX];
- char *name;
-
- if (!filename || !dri_name)
- return -1;
-
- count = readlink(filename, path, PATH_MAX);
- if (count >= PATH_MAX)
- return -1;
-
- /* For device does not have a driver */
- if (count < 0)
- return 1;
-
- path[count] = '\0';
-
- name = strrchr(path, '/');
- if (name) {
- strncpy(dri_name, name + 1, strlen(name + 1) + 1);
- return 0;
- }
-
- return -1;
-}
-
/* Map pci device */
int
rte_eal_pci_map_device(struct rte_pci_device *dev)
@@ -354,7 +325,7 @@ pci_scan_one(const char *dirname, uint16_t domain, uint8_t bus,
/* parse driver */
snprintf(filename, sizeof(filename), "%s/driver", dirname);
- ret = pci_get_kernel_driver_by_path(filename, driver);
+ ret = rte_eal_get_kernel_driver_by_path(filename, driver);
if (ret < 0) {
RTE_LOG(ERR, EAL, "Fail to get kernel driver\n");
free(dev);
--
2.7.4
^ permalink raw reply related
* [PATCH v7 05/21] eal: define container macro
From: Shreyansh Jain @ 2016-10-28 12:26 UTC (permalink / raw)
To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin
In-Reply-To: <1477657598-826-1-git-send-email-shreyansh.jain@nxp.com>
From: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
lib/librte_eal/common/include/rte_common.h | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/lib/librte_eal/common/include/rte_common.h b/lib/librte_eal/common/include/rte_common.h
index db5ac91..8152bd9 100644
--- a/lib/librte_eal/common/include/rte_common.h
+++ b/lib/librte_eal/common/include/rte_common.h
@@ -331,6 +331,24 @@ 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(p, type, member) \
+ ((type *) (((char *) (p)) - 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 v7 06/21] eal/soc: introduce very essential SoC infra definitions
From: Shreyansh Jain @ 2016-10-28 12:26 UTC (permalink / raw)
To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin
In-Reply-To: <1477657598-826-1-git-send-email-shreyansh.jain@nxp.com>
From: Jan Viktorin <viktorin@rehivetech.com>
Define initial structures and functions for the SoC infrastructure.
This patch supports only a very minimal functions for now.
More features will be added in the following commits.
Includes rte_device/rte_driver inheritance of
rte_soc_device/rte_soc_driver.
Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
app/test/Makefile | 1 +
app/test/test_soc.c | 90 +++++++++++++++++++++
lib/librte_eal/common/Makefile | 2 +-
lib/librte_eal/common/eal_private.h | 4 +
lib/librte_eal/common/include/rte_soc.h | 138 ++++++++++++++++++++++++++++++++
5 files changed, 234 insertions(+), 1 deletion(-)
create mode 100644 app/test/test_soc.c
create mode 100644 lib/librte_eal/common/include/rte_soc.h
diff --git a/app/test/Makefile b/app/test/Makefile
index 5be023a..30295af 100644
--- a/app/test/Makefile
+++ b/app/test/Makefile
@@ -77,6 +77,7 @@ APP = test
#
SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) := commands.c
SRCS-y += test.c
+SRCS-y += test_soc.c
SRCS-y += resource.c
SRCS-y += test_resource.c
test_resource.res: test_resource.c
diff --git a/app/test/test_soc.c b/app/test/test_soc.c
new file mode 100644
index 0000000..916a863
--- /dev/null
+++ b/app/test/test_soc.c
@@ -0,0 +1,90 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2016 RehiveTech. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of RehiveTech 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_soc.h>
+#include <rte_devargs.h>
+#include <rte_debug.h>
+
+#include "test.h"
+
+static char *safe_strdup(const char *s)
+{
+ char *c = strdup(s);
+
+ if (c == NULL)
+ rte_panic("failed to strdup '%s'\n", s);
+
+ return c;
+}
+
+static int test_compare_addr(void)
+{
+ struct rte_soc_addr a0;
+ struct rte_soc_addr a1;
+ struct rte_soc_addr a2;
+
+ a0.name = safe_strdup("ethernet0");
+ a0.fdt_path = NULL;
+
+ a1.name = safe_strdup("ethernet0");
+ a1.fdt_path = NULL;
+
+ a2.name = safe_strdup("ethernet1");
+ a2.fdt_path = NULL;
+
+ TEST_ASSERT(!rte_eal_compare_soc_addr(&a0, &a1),
+ "Failed to compare two soc addresses that equal");
+ TEST_ASSERT(rte_eal_compare_soc_addr(&a0, &a2),
+ "Failed to compare two soc addresses that differs");
+
+ free(a2.name);
+ free(a1.name);
+ free(a0.name);
+ return 0;
+}
+
+static int
+test_soc(void)
+{
+ if (test_compare_addr())
+ return -1;
+
+ return 0;
+}
+
+REGISTER_TEST_COMMAND(soc_autotest, test_soc);
diff --git a/lib/librte_eal/common/Makefile b/lib/librte_eal/common/Makefile
index dfd64aa..b414008 100644
--- a/lib/librte_eal/common/Makefile
+++ b/lib/librte_eal/common/Makefile
@@ -33,7 +33,7 @@ include $(RTE_SDK)/mk/rte.vars.mk
INC := rte_branch_prediction.h rte_common.h
INC += rte_debug.h rte_eal.h rte_errno.h rte_launch.h rte_lcore.h
-INC += rte_log.h rte_memory.h rte_memzone.h rte_pci.h
+INC += rte_log.h rte_memory.h rte_memzone.h rte_soc.h rte_pci.h
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
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index c8c2131..0e8d6f7 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -36,6 +36,7 @@
#include <stdio.h>
#include <rte_pci.h>
+#include <rte_soc.h>
/**
* Initialize the memzone subsystem (private to eal).
@@ -118,6 +119,9 @@ int rte_eal_log_init(const char *id, int facility);
*/
int rte_eal_pci_init(void);
+struct rte_soc_driver;
+struct rte_soc_device;
+
struct rte_pci_driver;
struct rte_pci_device;
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
new file mode 100644
index 0000000..5c32737
--- /dev/null
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -0,0 +1,138 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2016 RehiveTech. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of RehiveTech 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_SOC_H_
+#define _RTE_SOC_H_
+
+/**
+ * @file
+ *
+ * RTE SoC Interface
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <inttypes.h>
+#include <string.h>
+
+#include <rte_dev.h>
+#include <rte_debug.h>
+
+struct rte_soc_id {
+ const char *compatible; /**< OF compatible specification */
+ uint64_t priv_data; /**< SoC Driver specific data */
+};
+
+struct rte_soc_addr {
+ char *name; /**< name used in sysfs */
+ char *fdt_path; /**< path to the associated node in FDT */
+};
+
+/**
+ * A structure describing a SoC device.
+ */
+struct rte_soc_device {
+ TAILQ_ENTRY(rte_soc_device) next; /**< Next probed SoC device */
+ struct rte_device device; /**< Inherit code device */
+ struct rte_soc_addr addr; /**< SoC device Location */
+ struct rte_soc_id *id; /**< SoC device ID list */
+ struct rte_soc_driver *driver; /**< Associated driver */
+};
+
+struct rte_soc_driver;
+
+/**
+ * Probe function for the driver called during SoC probing.
+ */
+typedef int (soc_probe_t)(struct rte_soc_driver *, struct rte_soc_device *);
+
+/**
+ * Remove function for the driver called during hotplugging.
+ */
+typedef int (soc_remove_t)(struct rte_soc_device *);
+
+/**
+ * A structure describing a SoC driver.
+ */
+struct rte_soc_driver {
+ TAILQ_ENTRY(rte_soc_driver) next; /**< Next in list */
+ struct rte_driver driver; /**< Inherit core driver. */
+ soc_probe_t *probe; /**< Device probe */
+ soc_remove_t *remove; /**< Device remove */
+ const struct rte_soc_id *id_table; /**< ID table, NULL terminated */
+};
+
+/**
+ * Utility function to write a SoC device name, this device name can later be
+ * used to retrieve the corresponding rte_soc_addr using above functions.
+ *
+ * @param addr
+ * The SoC address
+ * @param output
+ * The output buffer string
+ * @param size
+ * The output buffer size
+ * @return
+ * 0 on success, negative on error.
+ */
+static inline void
+rte_eal_soc_device_name(const struct rte_soc_addr *addr,
+ char *output, size_t size)
+{
+ int ret;
+
+ RTE_VERIFY(addr != NULL);
+ RTE_VERIFY(size >= strlen(addr->name));
+ ret = snprintf(output, size, "%s", addr->name);
+ RTE_VERIFY(ret >= 0);
+}
+
+static inline int
+rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
+ const struct rte_soc_addr *a1)
+{
+ if (a0 == NULL || a1 == NULL)
+ return -1;
+
+ RTE_VERIFY(a0->name != NULL);
+ RTE_VERIFY(a1->name != NULL);
+
+ return strcmp(a0->name, a1->name);
+}
+
+#endif
--
2.7.4
^ permalink raw reply related
* [PATCH v7 07/21] eal/soc: add SoC PMD register/unregister logic
From: Shreyansh Jain @ 2016-10-28 12:26 UTC (permalink / raw)
To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin
In-Reply-To: <1477657598-826-1-git-send-email-shreyansh.jain@nxp.com>
From: Jan Viktorin <viktorin@rehivetech.com>
Registeration of a SoC driver through a helper RTE_PMD_REGISTER_SOC
(on the lines of RTE_PMD_REGISTER_PCI). soc_driver_list stores all the
registered drivers.
Test case has been introduced to verify the registration and
deregistration.
Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
[Shreyansh: update PMD registration method]
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
app/test/test_soc.c | 111 ++++++++++++++++++++++++
lib/librte_eal/bsdapp/eal/rte_eal_version.map | 3 +
lib/librte_eal/common/eal_common_soc.c | 56 ++++++++++++
lib/librte_eal/common/include/rte_soc.h | 26 ++++++
lib/librte_eal/linuxapp/eal/Makefile | 1 +
lib/librte_eal/linuxapp/eal/rte_eal_version.map | 3 +
6 files changed, 200 insertions(+)
create mode 100644 lib/librte_eal/common/eal_common_soc.c
diff --git a/app/test/test_soc.c b/app/test/test_soc.c
index 916a863..ac03e64 100644
--- a/app/test/test_soc.c
+++ b/app/test/test_soc.c
@@ -75,6 +75,108 @@ static int test_compare_addr(void)
free(a2.name);
free(a1.name);
free(a0.name);
+
+ return 0;
+}
+
+/**
+ * Empty PMD driver based on the SoC infra.
+ *
+ * The rte_soc_device is usually wrapped in some higher-level struct
+ * (eth_driver). We simulate such a wrapper with an anonymous struct here.
+ */
+struct test_wrapper {
+ struct rte_soc_driver soc_drv;
+};
+
+struct test_wrapper empty_pmd0 = {
+ .soc_drv = {
+ .driver = {
+ .name = "empty_pmd0"
+ },
+ },
+};
+
+struct test_wrapper empty_pmd1 = {
+ .soc_drv = {
+ .driver = {
+ .name = "empty_pmd1"
+ },
+ },
+};
+
+static int
+count_registered_socdrvs(void)
+{
+ int i;
+ struct rte_soc_driver *drv;
+
+ i = 0;
+ TAILQ_FOREACH(drv, &soc_driver_list, next)
+ i += 1;
+
+ return i;
+}
+
+static int
+test_register_unregister(void)
+{
+ struct rte_soc_driver *drv;
+ int count;
+
+ rte_eal_soc_register(&empty_pmd0.soc_drv);
+
+ TEST_ASSERT(!TAILQ_EMPTY(&soc_driver_list),
+ "No PMD is present but the empty_pmd0 should be there");
+ drv = TAILQ_FIRST(&soc_driver_list);
+ TEST_ASSERT(!strcmp(drv->driver.name, "empty_pmd0"),
+ "The registered PMD is not empty_pmd0 but '%s'",
+ drv->driver.name);
+
+ rte_eal_soc_register(&empty_pmd1.soc_drv);
+
+ count = count_registered_socdrvs();
+ TEST_ASSERT_EQUAL(count, 2, "Expected 2 PMDs but detected %d", count);
+
+ rte_eal_soc_unregister(&empty_pmd0.soc_drv);
+ count = count_registered_socdrvs();
+ TEST_ASSERT_EQUAL(count, 1, "Expected 1 PMDs but detected %d", count);
+
+ rte_eal_soc_unregister(&empty_pmd1.soc_drv);
+
+ printf("%s has been successful\n", __func__);
+ return 0;
+}
+
+/* save real devices and drivers until the tests finishes */
+struct soc_driver_list real_soc_driver_list =
+ TAILQ_HEAD_INITIALIZER(real_soc_driver_list);
+
+static int test_soc_setup(void)
+{
+ struct rte_soc_driver *drv;
+
+ /* no real drivers for the test */
+ while (!TAILQ_EMPTY(&soc_driver_list)) {
+ drv = TAILQ_FIRST(&soc_driver_list);
+ rte_eal_soc_unregister(drv);
+ TAILQ_INSERT_TAIL(&real_soc_driver_list, drv, next);
+ }
+
+ return 0;
+}
+
+static int test_soc_cleanup(void)
+{
+ struct rte_soc_driver *drv;
+
+ /* bring back real drivers after the test */
+ while (!TAILQ_EMPTY(&real_soc_driver_list)) {
+ drv = TAILQ_FIRST(&real_soc_driver_list);
+ TAILQ_REMOVE(&real_soc_driver_list, drv, next);
+ rte_eal_soc_register(drv);
+ }
+
return 0;
}
@@ -84,6 +186,15 @@ test_soc(void)
if (test_compare_addr())
return -1;
+ if (test_soc_setup())
+ return -1;
+
+ if (test_register_unregister())
+ return -1;
+
+ if (test_soc_cleanup())
+ return -1;
+
return 0;
}
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index 11d9f59..cf6fb8e 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -171,8 +171,11 @@ DPDK_16.11 {
rte_eal_dev_attach;
rte_eal_dev_detach;
rte_eal_map_resource;
+ rte_eal_soc_register;
+ rte_eal_soc_unregister;
rte_eal_unmap_resource;
rte_eal_vdrv_register;
rte_eal_vdrv_unregister;
+ soc_driver_list;
} DPDK_16.07;
diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
new file mode 100644
index 0000000..56135ed
--- /dev/null
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -0,0 +1,56 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2016 RehiveTech. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of RehiveTech 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 <sys/queue.h>
+
+#include <rte_log.h>
+
+#include "eal_private.h"
+
+/* Global SoC driver list */
+struct soc_driver_list soc_driver_list =
+ TAILQ_HEAD_INITIALIZER(soc_driver_list);
+
+/* register a driver */
+void
+rte_eal_soc_register(struct rte_soc_driver *driver)
+{
+ TAILQ_INSERT_TAIL(&soc_driver_list, driver, next);
+}
+
+/* unregister a driver */
+void
+rte_eal_soc_unregister(struct rte_soc_driver *driver)
+{
+ TAILQ_REMOVE(&soc_driver_list, driver, next);
+}
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 5c32737..23b06a9 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -51,8 +51,14 @@ extern "C" {
#include <string.h>
#include <rte_dev.h>
+#include <rte_eal.h>
#include <rte_debug.h>
+extern struct soc_driver_list soc_driver_list;
+/**< Global list of SoC Drivers */
+
+TAILQ_HEAD(soc_driver_list, rte_soc_driver); /**< SoC drivers in D-linked Q. */
+
struct rte_soc_id {
const char *compatible; /**< OF compatible specification */
uint64_t priv_data; /**< SoC Driver specific data */
@@ -135,4 +141,24 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
return strcmp(a0->name, a1->name);
}
+/**
+ * Register a SoC driver.
+ */
+void rte_eal_soc_register(struct rte_soc_driver *driver);
+
+/** Helper for SoC device registeration from PMD Drivers */
+#define RTE_PMD_REGISTER_SOC(nm, soc_drv) \
+RTE_INIT(socinitfn_ ##name); \
+static void socinitfn_ ##name(void) \
+{\
+ (soc_drv).driver.name = RTE_STR(nm);\
+ rte_eal_soc_register(&soc_drv); \
+} \
+RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
+
+/**
+ * Unregister a SoC driver.
+ */
+void rte_eal_soc_unregister(struct rte_soc_driver *driver);
+
#endif
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index 4e206f0..a520477 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -77,6 +77,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_timer.c
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_memzone.c
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_log.c
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_launch.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_soc.c
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_vdev.c
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci.c
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_common_pci_uio.c
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index 22b5b59..ab6b985 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -175,8 +175,11 @@ DPDK_16.11 {
rte_eal_dev_attach;
rte_eal_dev_detach;
rte_eal_map_resource;
+ rte_eal_soc_register;
+ rte_eal_soc_unregister;
rte_eal_unmap_resource;
rte_eal_vdrv_register;
rte_eal_vdrv_unregister;
+ soc_driver_list;
} DPDK_16.07;
--
2.7.4
^ permalink raw reply related
* [PATCH v7 08/21] eal/soc: implement SoC device list and dump
From: Shreyansh Jain @ 2016-10-28 12:26 UTC (permalink / raw)
To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin
In-Reply-To: <1477657598-826-1-git-send-email-shreyansh.jain@nxp.com>
From: Jan Viktorin <viktorin@rehivetech.com>
SoC devices would be linked in a separate list (from PCI). This is used for
probe function.
A helper for dumping the device list is added.
Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
lib/librte_eal/bsdapp/eal/rte_eal_version.map | 2 ++
lib/librte_eal/common/eal_common_soc.c | 34 +++++++++++++++++++++++++
lib/librte_eal/common/include/rte_soc.h | 9 +++++++
lib/librte_eal/linuxapp/eal/rte_eal_version.map | 2 ++
4 files changed, 47 insertions(+)
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index cf6fb8e..86e3cfd 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -171,11 +171,13 @@ DPDK_16.11 {
rte_eal_dev_attach;
rte_eal_dev_detach;
rte_eal_map_resource;
+ rte_eal_soc_dump;
rte_eal_soc_register;
rte_eal_soc_unregister;
rte_eal_unmap_resource;
rte_eal_vdrv_register;
rte_eal_vdrv_unregister;
+ soc_device_list;
soc_driver_list;
} DPDK_16.07;
diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
index 56135ed..5dcddc5 100644
--- a/lib/librte_eal/common/eal_common_soc.c
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -31,6 +31,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <stddef.h>
+#include <stdio.h>
#include <sys/queue.h>
#include <rte_log.h>
@@ -40,6 +42,38 @@
/* Global SoC driver list */
struct soc_driver_list soc_driver_list =
TAILQ_HEAD_INITIALIZER(soc_driver_list);
+struct soc_device_list soc_device_list =
+ TAILQ_HEAD_INITIALIZER(soc_device_list);
+
+/* dump one device */
+static int
+soc_dump_one_device(FILE *f, struct rte_soc_device *dev)
+{
+ int i;
+
+ fprintf(f, "%s", dev->addr.name);
+ fprintf(f, " - fdt_path: %s\n",
+ dev->addr.fdt_path ? dev->addr.fdt_path : "(none)");
+
+ for (i = 0; dev->id && dev->id[i].compatible; ++i)
+ fprintf(f, " %s\n", dev->id[i].compatible);
+
+ return 0;
+}
+
+/* dump devices on the bus to an output stream */
+void
+rte_eal_soc_dump(FILE *f)
+{
+ struct rte_soc_device *dev = NULL;
+
+ if (!f)
+ return;
+
+ TAILQ_FOREACH(dev, &soc_device_list, next) {
+ soc_dump_one_device(f, dev);
+ }
+}
/* register a driver */
void
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 23b06a9..347e611 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -56,8 +56,12 @@ extern "C" {
extern struct soc_driver_list soc_driver_list;
/**< Global list of SoC Drivers */
+extern struct soc_device_list soc_device_list;
+/**< Global list of SoC Devices */
TAILQ_HEAD(soc_driver_list, rte_soc_driver); /**< SoC drivers in D-linked Q. */
+TAILQ_HEAD(soc_device_list, rte_soc_device); /**< SoC devices in D-linked Q. */
+
struct rte_soc_id {
const char *compatible; /**< OF compatible specification */
@@ -142,6 +146,11 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
}
/**
+ * Dump discovered SoC devices.
+ */
+void rte_eal_soc_dump(FILE *f);
+
+/**
* Register a SoC driver.
*/
void rte_eal_soc_register(struct rte_soc_driver *driver);
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index ab6b985..0155025 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -175,11 +175,13 @@ DPDK_16.11 {
rte_eal_dev_attach;
rte_eal_dev_detach;
rte_eal_map_resource;
+ rte_eal_soc_dump;
rte_eal_soc_register;
rte_eal_soc_unregister;
rte_eal_unmap_resource;
rte_eal_vdrv_register;
rte_eal_vdrv_unregister;
+ soc_device_list;
soc_driver_list;
} DPDK_16.07;
--
2.7.4
^ permalink raw reply related
* [PATCH v7 09/21] eal: introduce command line enable SoC option
From: Shreyansh Jain @ 2016-10-28 12:26 UTC (permalink / raw)
To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin
In-Reply-To: <1477657598-826-1-git-send-email-shreyansh.jain@nxp.com>
From: Jan Viktorin <viktorin@rehivetech.com>
Support --enable-soc. SoC support is disabled by default.
Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
[Shreyansh: Change --no-soc to --enable-soc; disabled by default]
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
doc/guides/testpmd_app_ug/run_app.rst | 4 ++++
lib/librte_eal/common/eal_common_options.c | 5 +++++
lib/librte_eal/common/eal_internal_cfg.h | 1 +
lib/librte_eal/common/eal_options.h | 2 ++
4 files changed, 12 insertions(+)
diff --git a/doc/guides/testpmd_app_ug/run_app.rst b/doc/guides/testpmd_app_ug/run_app.rst
index d7c5120..4dafe5f 100644
--- a/doc/guides/testpmd_app_ug/run_app.rst
+++ b/doc/guides/testpmd_app_ug/run_app.rst
@@ -156,6 +156,10 @@ See the DPDK Getting Started Guides for more information on these options.
Use malloc instead of hugetlbfs.
+* ``--enable-soc``
+
+ Enable SoC framework support
+
Testpmd Command-line Options
----------------------------
diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
index 6ca8af1..2156ab3 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -75,6 +75,7 @@ const struct option
eal_long_options[] = {
{OPT_BASE_VIRTADDR, 1, NULL, OPT_BASE_VIRTADDR_NUM },
{OPT_CREATE_UIO_DEV, 0, NULL, OPT_CREATE_UIO_DEV_NUM },
+ {OPT_ENABLE_SOC, 0, NULL, OPT_ENABLE_SOC_NUM },
{OPT_FILE_PREFIX, 1, NULL, OPT_FILE_PREFIX_NUM },
{OPT_HELP, 0, NULL, OPT_HELP_NUM },
{OPT_HUGE_DIR, 1, NULL, OPT_HUGE_DIR_NUM },
@@ -843,6 +844,10 @@ eal_parse_common_option(int opt, const char *optarg,
break;
/* long options */
+ case OPT_ENABLE_SOC_NUM:
+ conf->enable_soc = 1;
+ break;
+
case OPT_HUGE_UNLINK_NUM:
conf->hugepage_unlink = 1;
break;
diff --git a/lib/librte_eal/common/eal_internal_cfg.h b/lib/librte_eal/common/eal_internal_cfg.h
index 5f1367e..2a6e3ea 100644
--- a/lib/librte_eal/common/eal_internal_cfg.h
+++ b/lib/librte_eal/common/eal_internal_cfg.h
@@ -67,6 +67,7 @@ struct internal_config {
unsigned hugepage_unlink; /**< true to unlink backing files */
volatile unsigned xen_dom0_support; /**< support app running on Xen Dom0*/
volatile unsigned no_pci; /**< true to disable PCI */
+ volatile unsigned enable_soc; /**< true to enable SoC */
volatile unsigned no_hpet; /**< true to disable HPET */
volatile unsigned vmware_tsc_map; /**< true to use VMware TSC mapping
* instead of native TSC */
diff --git a/lib/librte_eal/common/eal_options.h b/lib/librte_eal/common/eal_options.h
index a881c62..6e679c3 100644
--- a/lib/librte_eal/common/eal_options.h
+++ b/lib/librte_eal/common/eal_options.h
@@ -49,6 +49,8 @@ enum {
OPT_BASE_VIRTADDR_NUM,
#define OPT_CREATE_UIO_DEV "create-uio-dev"
OPT_CREATE_UIO_DEV_NUM,
+#define OPT_ENABLE_SOC "enable-soc"
+ OPT_ENABLE_SOC_NUM,
#define OPT_FILE_PREFIX "file-prefix"
OPT_FILE_PREFIX_NUM,
#define OPT_HUGE_DIR "huge-dir"
--
2.7.4
^ permalink raw reply related
* [PATCH v7 10/21] eal/soc: init SoC infra from EAL
From: Shreyansh Jain @ 2016-10-28 12:26 UTC (permalink / raw)
To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin
In-Reply-To: <1477657598-826-1-git-send-email-shreyansh.jain@nxp.com>
From: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
lib/librte_eal/bsdapp/eal/Makefile | 1 +
lib/librte_eal/bsdapp/eal/eal.c | 4 +++
lib/librte_eal/bsdapp/eal/eal_soc.c | 46 ++++++++++++++++++++++++++++
lib/librte_eal/common/eal_private.h | 10 +++++++
lib/librte_eal/linuxapp/eal/Makefile | 1 +
lib/librte_eal/linuxapp/eal/eal.c | 3 ++
lib/librte_eal/linuxapp/eal/eal_soc.c | 56 +++++++++++++++++++++++++++++++++++
7 files changed, 121 insertions(+)
create mode 100644 lib/librte_eal/bsdapp/eal/eal_soc.c
create mode 100644 lib/librte_eal/linuxapp/eal/eal_soc.c
diff --git a/lib/librte_eal/bsdapp/eal/Makefile b/lib/librte_eal/bsdapp/eal/Makefile
index a15b762..42b3a2b 100644
--- a/lib/librte_eal/bsdapp/eal/Makefile
+++ b/lib/librte_eal/bsdapp/eal/Makefile
@@ -56,6 +56,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_memory.c
SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_hugepage_info.c
SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_thread.c
SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_pci.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_soc.c
SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_debug.c
SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_lcore.c
SRCS-$(CONFIG_RTE_EXEC_ENV_BSDAPP) += eal_timer.c
diff --git a/lib/librte_eal/bsdapp/eal/eal.c b/lib/librte_eal/bsdapp/eal/eal.c
index 9b93da3..2d62b9d 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_soc.h>
#include <rte_pci.h>
#include <rte_dev.h>
#include <rte_devargs.h>
@@ -564,6 +565,9 @@ rte_eal_init(int argc, char **argv)
if (rte_eal_pci_init() < 0)
rte_panic("Cannot init PCI\n");
+ if (rte_eal_soc_init() < 0)
+ rte_panic("Cannot init SoC\n");
+
eal_check_mem_on_local_socket();
if (eal_plugins_init() < 0)
diff --git a/lib/librte_eal/bsdapp/eal/eal_soc.c b/lib/librte_eal/bsdapp/eal/eal_soc.c
new file mode 100644
index 0000000..cb297ff
--- /dev/null
+++ b/lib/librte_eal/bsdapp/eal/eal_soc.c
@@ -0,0 +1,46 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2016 RehiveTech. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of RehiveTech nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <rte_common.h>
+#include <rte_log.h>
+
+#include <eal_private.h>
+
+/* Init the SoC EAL subsystem */
+int
+rte_eal_soc_init(void)
+{
+ return 0;
+}
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index 0e8d6f7..d810f9f 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -122,6 +122,16 @@ int rte_eal_pci_init(void);
struct rte_soc_driver;
struct rte_soc_device;
+/**
+ * Init the SoC infra.
+ *
+ * This function is private to EAL.
+ *
+ * @return
+ * 0 on success, negative on error
+ */
+int rte_eal_soc_init(void);
+
struct rte_pci_driver;
struct rte_pci_device;
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index a520477..59e30fa 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -65,6 +65,7 @@ SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_vfio_mp_sync.c
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci.c
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci_uio.c
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_pci_vfio.c
+SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_soc.c
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_debug.c
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_lcore.c
SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_timer.c
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 00af21c..098ba02 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -810,6 +810,9 @@ rte_eal_init(int argc, char **argv)
rte_panic("Cannot init VFIO\n");
#endif
+ if (rte_eal_soc_init() < 0)
+ rte_panic("Cannot init SoC\n");
+
if (rte_eal_memory_init() < 0)
rte_panic("Cannot init memory\n");
diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c
new file mode 100644
index 0000000..04848b9
--- /dev/null
+++ b/lib/librte_eal/linuxapp/eal/eal_soc.c
@@ -0,0 +1,56 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2016 RehiveTech. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of RehiveTech nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <dirent.h>
+#include <limits.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <rte_log.h>
+#include <rte_soc.h>
+
+#include "eal_internal_cfg.h"
+#include "eal_filesystem.h"
+#include "eal_private.h"
+
+/* Init the SoC EAL subsystem */
+int
+rte_eal_soc_init(void)
+{
+ return 0;
+}
--
2.7.4
^ permalink raw reply related
* [PATCH v7 11/21] eal/soc: implement probing of drivers
From: Shreyansh Jain @ 2016-10-28 12:26 UTC (permalink / raw)
To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin
In-Reply-To: <1477657598-826-1-git-send-email-shreyansh.jain@nxp.com>
Each SoC PMD registers a set of callback for scanning its own bus/infra and
matching devices to drivers when probe is called.
This patch introduces the infra for calls to SoC scan on rte_eal_soc_init()
and match on rte_eal_soc_probe().
Patch also adds test case for scan and probe.
Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
--
v4:
- Update test_soc for descriptive test function names
- Comments over test functions
- devinit and devuninint --> probe/remove
- RTE_VERIFY at some places
---
app/test/test_soc.c | 205 ++++++++++++++++++++++-
lib/librte_eal/bsdapp/eal/rte_eal_version.map | 4 +
lib/librte_eal/common/eal_common_soc.c | 213 +++++++++++++++++++++++-
lib/librte_eal/common/include/rte_soc.h | 75 ++++++++-
lib/librte_eal/linuxapp/eal/eal.c | 5 +
lib/librte_eal/linuxapp/eal/eal_soc.c | 21 ++-
lib/librte_eal/linuxapp/eal/rte_eal_version.map | 4 +
7 files changed, 519 insertions(+), 8 deletions(-)
diff --git a/app/test/test_soc.c b/app/test/test_soc.c
index ac03e64..b587d5e 100644
--- a/app/test/test_soc.c
+++ b/app/test/test_soc.c
@@ -87,14 +87,65 @@ static int test_compare_addr(void)
*/
struct test_wrapper {
struct rte_soc_driver soc_drv;
+ struct rte_soc_device soc_dev;
};
+static int empty_pmd0_probe(struct rte_soc_driver *drv,
+ struct rte_soc_device *dev);
+static int empty_pmd0_remove(struct rte_soc_device *dev);
+
+static void always_find_dev0_cb(void);
+static int match_dev0_by_name(struct rte_soc_driver *drv,
+ struct rte_soc_device *dev);
+
+static void always_find_dev1_cb(void);
+static int match_dev1_by_name(struct rte_soc_driver *drv,
+ struct rte_soc_device *dev);
+
+/**
+ * Dummy probe handler for PMD driver 'pmd0'.
+ *
+ * @param drv
+ * driver object
+ * @param dev
+ * device object
+ * @return
+ * 0 on success
+ */
+static int
+empty_pmd0_probe(struct rte_soc_driver *drv __rte_unused,
+ struct rte_soc_device *dev __rte_unused)
+{
+ return 0;
+}
+
+/**
+ * Remove handler for PMD driver 'pmd0'.
+ *
+ * @param dev
+ * device to remove
+ * @return
+ * 0 on success
+ */
+static int
+empty_pmd0_remove(struct rte_soc_device *dev)
+{
+ /* Release the memory associated with dev->addr.name */
+ free(dev->addr.name);
+
+ return 0;
+}
+
struct test_wrapper empty_pmd0 = {
.soc_drv = {
.driver = {
.name = "empty_pmd0"
},
- },
+ .probe = empty_pmd0_probe,
+ .remove = empty_pmd0_remove,
+ .scan_fn = always_find_dev0_cb,
+ .match_fn = match_dev0_by_name,
+ }
};
struct test_wrapper empty_pmd1 = {
@@ -102,9 +153,87 @@ struct test_wrapper empty_pmd1 = {
.driver = {
.name = "empty_pmd1"
},
+ .scan_fn = always_find_dev1_cb,
+ .match_fn = match_dev1_by_name,
},
};
+/**
+ * Bus scan by PMD 'pmd0' for adding device 'dev0'
+ *
+ * @param void
+ * @return void
+ */
+static void
+always_find_dev0_cb(void)
+{
+ /* SoC's scan would scan devices on its bus and add to
+ * soc_device_list
+ */
+ empty_pmd0.soc_dev.addr.name = strdup("empty_pmd0_dev");
+
+ TAILQ_INSERT_TAIL(&soc_device_list, &empty_pmd0.soc_dev, next);
+}
+
+/**
+ * Match device 'dev0' with driver PMD pmd0
+ *
+ * @param drv
+ * Driver with this matching needs to be done; unused here
+ * @param dev
+ * device to be matched against driver
+ * @return
+ * 0 on successful matched
+ * 1 if driver<=>device don't match
+ */
+static int
+match_dev0_by_name(struct rte_soc_driver *drv __rte_unused,
+ struct rte_soc_device *dev)
+{
+ if (!dev->addr.name || strcmp(dev->addr.name, "empty_pmd0_dev"))
+ return 0;
+
+ return 1;
+}
+
+/**
+ * Bus scan by PMD 'pmd0' for adding device 'dev1'
+ *
+ * @param void
+ * @return void
+ */
+static void
+always_find_dev1_cb(void)
+{
+ /* SoC's scan would scan devices on its bus and add to
+ * soc_device_list
+ */
+ empty_pmd0.soc_dev.addr.name = strdup("empty_pmd1_dev");
+
+ TAILQ_INSERT_TAIL(&soc_device_list, &empty_pmd1.soc_dev, next);
+}
+
+/**
+ * Match device 'dev1' with driver PMD pmd0
+ *
+ * @param drv
+ * Driver with this matching needs to be done; unused here
+ * @param dev
+ * device to be matched against driver
+ * @return
+ * 0 on successful matched
+ * 1 if driver<=>device don't match
+ */
+static int
+match_dev1_by_name(struct rte_soc_driver *drv __rte_unused,
+ struct rte_soc_device *dev)
+{
+ if (!dev->addr.name || strcmp(dev->addr.name, "empty_pmd1_dev"))
+ return 0;
+
+ return 1;
+}
+
static int
count_registered_socdrvs(void)
{
@@ -148,13 +277,68 @@ test_register_unregister(void)
return 0;
}
+/* Test Probe (scan and match) functionality */
+static int
+test_soc_scan_and_match(void)
+{
+ int drv_count = 0;
+ struct rte_soc_driver *drv;
+
+ /* Registering dummy drivers */
+ rte_eal_soc_register(&empty_pmd0.soc_drv);
+ rte_eal_soc_register(&empty_pmd1.soc_drv);
+ /* Assuming that test_register_unregister is working, not verifying
+ * that drivers are indeed registered
+ */
+
+ /* rte_eal_soc_init is called by rte_eal_init, which in turn calls the
+ * scan_fn of each driver.
+ */
+ TAILQ_FOREACH(drv, &soc_driver_list, next) {
+ if (drv && drv->scan_fn)
+ drv->scan_fn();
+ drv_count++;
+ }
+
+ /* rte_eal_init() would perform other inits here */
+
+ /* Probe would link the SoC devices<=>drivers */
+ rte_eal_soc_probe();
+
+ /* Unregistering dummy drivers */
+ rte_eal_soc_unregister(&empty_pmd0.soc_drv);
+ rte_eal_soc_unregister(&empty_pmd1.soc_drv);
+
+ /* Verify the Unregistering has removed the driver from list */
+ TAILQ_FOREACH(drv, &soc_driver_list, next) {
+ if (drv)
+ drv_count--;
+ }
+
+ free(empty_pmd0.soc_dev.addr.name);
+
+ /* If drv_count is anything other than 0, Unregistering failed */
+ if (drv_count) {
+ printf("%s has failed\n", __func__);
+ return 1;
+ }
+
+ printf("%s has been successful\n", __func__);
+ return 0;
+}
+
/* save real devices and drivers until the tests finishes */
struct soc_driver_list real_soc_driver_list =
TAILQ_HEAD_INITIALIZER(real_soc_driver_list);
+/* save real devices and drivers until the tests finishes */
+struct soc_device_list real_soc_device_list =
+ TAILQ_HEAD_INITIALIZER(real_soc_device_list);
+
static int test_soc_setup(void)
{
struct rte_soc_driver *drv;
+ struct rte_soc_device *dev;
/* no real drivers for the test */
while (!TAILQ_EMPTY(&soc_driver_list)) {
@@ -163,12 +347,20 @@ static int test_soc_setup(void)
TAILQ_INSERT_TAIL(&real_soc_driver_list, drv, next);
}
+ /* And, no real devices for the test */
+ while (!TAILQ_EMPTY(&soc_device_list)) {
+ dev = TAILQ_FIRST(&soc_device_list);
+ TAILQ_REMOVE(&soc_device_list, dev, next);
+ TAILQ_INSERT_TAIL(&real_soc_device_list, dev, next);
+ }
+
return 0;
}
static int test_soc_cleanup(void)
{
struct rte_soc_driver *drv;
+ struct rte_soc_device *dev;
/* bring back real drivers after the test */
while (!TAILQ_EMPTY(&real_soc_driver_list)) {
@@ -177,6 +369,13 @@ static int test_soc_cleanup(void)
rte_eal_soc_register(drv);
}
+ /* And, bring back real devices after the test */
+ while (!TAILQ_EMPTY(&real_soc_device_list)) {
+ dev = TAILQ_FIRST(&real_soc_device_list);
+ TAILQ_REMOVE(&real_soc_device_list, dev, next);
+ TAILQ_INSERT_TAIL(&soc_device_list, dev, next);
+ }
+
return 0;
}
@@ -192,6 +391,10 @@ test_soc(void)
if (test_register_unregister())
return -1;
+ /* Assuming test_register_unregister has succeeded */
+ if (test_soc_scan_and_match())
+ return -1;
+
if (test_soc_cleanup())
return -1;
diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
index 86e3cfd..dfbb1ac 100644
--- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/bsdapp/eal/rte_eal_version.map
@@ -171,7 +171,11 @@ DPDK_16.11 {
rte_eal_dev_attach;
rte_eal_dev_detach;
rte_eal_map_resource;
+ rte_eal_soc_detach;
rte_eal_soc_dump;
+ rte_eal_soc_match;
+ rte_eal_soc_probe;
+ rte_eal_soc_probe_one;
rte_eal_soc_register;
rte_eal_soc_unregister;
rte_eal_unmap_resource;
diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
index 5dcddc5..256cef8 100644
--- a/lib/librte_eal/common/eal_common_soc.c
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -36,6 +36,8 @@
#include <sys/queue.h>
#include <rte_log.h>
+#include <rte_common.h>
+#include <rte_soc.h>
#include "eal_private.h"
@@ -45,6 +47,208 @@ struct soc_driver_list soc_driver_list =
struct soc_device_list soc_device_list =
TAILQ_HEAD_INITIALIZER(soc_device_list);
+int
+rte_eal_soc_match_compat(struct rte_soc_driver *drv,
+ struct rte_soc_device *dev)
+{
+ int i, j;
+
+ RTE_VERIFY(drv != NULL && drv->id_table != NULL);
+ RTE_VERIFY(dev != NULL && dev->id != NULL);
+
+ for (i = 0; drv->id_table[i].compatible; ++i) {
+ const char *drv_compat = drv->id_table[i].compatible;
+
+ for (j = 0; dev->id[j].compatible; ++j) {
+ const char *dev_compat = dev->id[j].compatible;
+
+ if (!strcmp(drv_compat, dev_compat))
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+static int
+rte_eal_soc_probe_one_driver(struct rte_soc_driver *drv,
+ struct rte_soc_device *dev)
+{
+ int ret = 1;
+
+ RTE_VERIFY(drv->match_fn);
+
+ ret = drv->match_fn(drv, dev);
+ if (ret) {
+ RTE_LOG(DEBUG, EAL,
+ " match function failed, skipping\n");
+ return ret;
+ }
+
+ dev->driver = drv;
+ RTE_VERIFY(drv->probe != NULL);
+ return drv->probe(drv, dev);
+}
+
+static int
+soc_probe_all_drivers(struct rte_soc_device *dev)
+{
+ struct rte_soc_driver *drv = NULL;
+ int rc = 0;
+
+ if (dev == NULL)
+ return -1;
+
+ TAILQ_FOREACH(drv, &soc_driver_list, next) {
+ rc = rte_eal_soc_probe_one_driver(drv, dev);
+ if (rc < 0)
+ /* negative value is an error */
+ return -1;
+ if (rc > 0)
+ /* positive value means driver doesn't support it */
+ continue;
+ return 0;
+ }
+ return 1;
+}
+
+/* If the IDs match, call the remove() function of the driver. */
+static int
+rte_eal_soc_detach_dev(struct rte_soc_driver *drv,
+ struct rte_soc_device *dev)
+{
+ int ret;
+
+ if ((drv == NULL) || (dev == NULL))
+ return -EINVAL;
+
+ ret = drv->match_fn(drv, dev);
+ if (ret) {
+ RTE_LOG(DEBUG, EAL, " driver (%s) didn't match device (%s)\n",
+ drv->driver.name, dev->addr.name);
+ return ret;
+ }
+
+ RTE_LOG(DEBUG, EAL, "SoC device %s\n",
+ dev->addr.name);
+
+ RTE_LOG(DEBUG, EAL, " remove driver: %s\n", drv->driver.name);
+
+ if (drv->remove && (drv->remove(dev) < 0))
+ return -1; /* negative value is an error */
+
+ /* clear driver structure */
+ dev->driver = NULL;
+
+ return 0;
+}
+
+/*
+ * Call the remove() function of all registered drivers for the device.
+ *
+ * @param dev
+ * Device for which detach is to be performed
+ * @return
+ * 0 when successful
+ * -1 if deinitialization fails
+ * 1 if no driver is found for this device.
+ */
+static int
+soc_detach_all_drivers(struct rte_soc_device *dev)
+{
+ struct rte_soc_driver *dr = NULL;
+ int rc = 0;
+
+ if (dev == NULL)
+ return -1;
+
+ TAILQ_FOREACH(dr, &soc_driver_list, next) {
+ rc = rte_eal_soc_detach_dev(dr, dev);
+ if (rc < 0)
+ /* negative value is an error */
+ return -1;
+ if (rc > 0)
+ /* positive value means driver doesn't support it */
+ continue;
+ return 0;
+ }
+ return 1;
+}
+
+int
+rte_eal_soc_detach(const struct rte_soc_addr *addr)
+{
+ struct rte_soc_device *dev = NULL;
+ int ret = 0;
+
+ if (addr == NULL)
+ return -1;
+
+ TAILQ_FOREACH(dev, &soc_device_list, next) {
+ if (rte_eal_compare_soc_addr(&dev->addr, addr))
+ continue;
+
+ ret = soc_detach_all_drivers(dev);
+ if (ret < 0)
+ goto err_return;
+
+ TAILQ_REMOVE(&soc_device_list, dev, next);
+ return 0;
+ }
+ return -1;
+
+err_return:
+ RTE_LOG(WARNING, EAL, "Requested device %s cannot be used\n",
+ dev->addr.name);
+ return -1;
+}
+
+int
+rte_eal_soc_probe_one(const struct rte_soc_addr *addr)
+{
+ struct rte_soc_device *dev = NULL;
+ int ret = 0;
+
+ if (addr == NULL)
+ return -1;
+
+ TAILQ_FOREACH(dev, &soc_device_list, next) {
+ if (rte_eal_compare_soc_addr(&dev->addr, addr))
+ continue;
+
+ ret = soc_probe_all_drivers(dev);
+ if (ret < 0)
+ goto err_return;
+ return 0;
+ }
+ return -1;
+
+err_return:
+ RTE_LOG(WARNING, EAL,
+ "Requested device %s cannot be used\n", addr->name);
+ return -1;
+}
+
+int
+rte_eal_soc_probe(void)
+{
+ struct rte_soc_device *dev = NULL;
+ int ret = 0;
+
+ TAILQ_FOREACH(dev, &soc_device_list, next) {
+ ret = soc_probe_all_drivers(dev);
+ if (ret < 0) {
+ RTE_LOG(DEBUG, EAL, "Requested device %s"
+ " cannot be used\n", dev->addr.name);
+ /* Failure for a particular device is logged and
+ * ignored
+ */
+ }
+ }
+
+ return ret;
+}
+
/* dump one device */
static int
soc_dump_one_device(FILE *f, struct rte_soc_device *dev)
@@ -61,7 +265,6 @@ soc_dump_one_device(FILE *f, struct rte_soc_device *dev)
return 0;
}
-/* dump devices on the bus to an output stream */
void
rte_eal_soc_dump(FILE *f)
{
@@ -75,14 +278,18 @@ rte_eal_soc_dump(FILE *f)
}
}
-/* register a driver */
void
rte_eal_soc_register(struct rte_soc_driver *driver)
{
+ /* For a valid soc driver, match and scan function
+ * should be provided.
+ */
+ RTE_VERIFY(driver != NULL);
+ RTE_VERIFY(driver->match_fn != NULL);
+ RTE_VERIFY(driver->scan_fn != NULL);
TAILQ_INSERT_TAIL(&soc_driver_list, driver, next);
}
-/* unregister a driver */
void
rte_eal_soc_unregister(struct rte_soc_driver *driver)
{
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 347e611..53a321b 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -62,7 +62,6 @@ extern struct soc_device_list soc_device_list;
TAILQ_HEAD(soc_driver_list, rte_soc_driver); /**< SoC drivers in D-linked Q. */
TAILQ_HEAD(soc_device_list, rte_soc_device); /**< SoC devices in D-linked Q. */
-
struct rte_soc_id {
const char *compatible; /**< OF compatible specification */
uint64_t priv_data; /**< SoC Driver specific data */
@@ -97,6 +96,23 @@ typedef int (soc_probe_t)(struct rte_soc_driver *, struct rte_soc_device *);
typedef int (soc_remove_t)(struct rte_soc_device *);
/**
+ * SoC device scan callback, called from rte_eal_soc_init.
+ * For various SoC, the bus on which devices are attached maynot be compliant
+ * to a standard platform (or platform bus itself). In which case, extra
+ * steps are implemented by PMD to scan over the bus and add devices to SoC
+ * device list.
+ */
+typedef void (soc_scan_t)(void);
+
+/**
+ * Custom device<=>driver match callback for SoC
+ * Unlike PCI, SoC devices don't have a fixed definition of device
+ * identification. PMDs can implement a specific matching function in which
+ * driver and device objects are provided to perform custom match.
+ */
+typedef int (soc_match_t)(struct rte_soc_driver *, struct rte_soc_device *);
+
+/**
* A structure describing a SoC driver.
*/
struct rte_soc_driver {
@@ -104,6 +120,8 @@ struct rte_soc_driver {
struct rte_driver driver; /**< Inherit core driver. */
soc_probe_t *probe; /**< Device probe */
soc_remove_t *remove; /**< Device remove */
+ soc_scan_t *scan_fn; /**< Callback for scanning SoC bus*/
+ soc_match_t *match_fn; /**< Callback to match dev<->drv */
const struct rte_soc_id *id_table; /**< ID table, NULL terminated */
};
@@ -146,12 +164,63 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
}
/**
+ * Default function for matching the Soc driver with device. Each driver can
+ * either use this function or define their own soc matching function.
+ * This function relies on the compatible string extracted from sysfs. But,
+ * a SoC might have different way of identifying its devices. Such SoC can
+ * override match_fn.
+ *
+ * @return
+ * 0 on success
+ * -1 when no match found
+ */
+int
+rte_eal_soc_match_compat(struct rte_soc_driver *drv,
+ struct rte_soc_device *dev);
+
+/**
+ * Probe SoC devices for registered drivers.
+ *
+ * @return
+ * 0 on success
+ * !0 in case of any failure in probe
+ */
+int rte_eal_soc_probe(void);
+
+/**
+ * Probe the single SoC device.
+ */
+int rte_eal_soc_probe_one(const struct rte_soc_addr *addr);
+
+/**
+ * Close the single SoC device.
+ *
+ * Scan the SoC devices and find the SoC device specified by the SoC
+ * address, then call the remove() function for registered driver
+ * that has a matching entry in its id_table for discovered device.
+ *
+ * @param addr
+ * The SoC address to close.
+ * @return
+ * - 0 on success.
+ * - Negative on error.
+ */
+int rte_eal_soc_detach(const struct rte_soc_addr *addr);
+
+/**
* Dump discovered SoC devices.
+ *
+ * @param f
+ * File to dump device info in.
*/
void rte_eal_soc_dump(FILE *f);
/**
* Register a SoC driver.
+ *
+ * @param driver
+ * Object for SoC driver to register
+ * @return void
*/
void rte_eal_soc_register(struct rte_soc_driver *driver);
@@ -167,6 +236,10 @@ RTE_PMD_EXPORT_NAME(nm, __COUNTER__)
/**
* Unregister a SoC driver.
+ *
+ * @param driver
+ * Object for SoC driver to unregister
+ * @return void
*/
void rte_eal_soc_unregister(struct rte_soc_driver *driver);
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 098ba02..bd775f3 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -70,6 +70,7 @@
#include <rte_cpuflags.h>
#include <rte_interrupts.h>
#include <rte_pci.h>
+#include <rte_soc.h>
#include <rte_dev.h>
#include <rte_devargs.h>
#include <rte_common.h>
@@ -890,6 +891,10 @@ rte_eal_init(int argc, char **argv)
if (rte_eal_pci_probe())
rte_panic("Cannot probe PCI\n");
+ /* Probe & Initialize SoC devices */
+ if (rte_eal_soc_probe())
+ rte_panic("Cannot probe SoC\n");
+
rte_eal_mcfg_complete();
return fctret;
diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c
index 04848b9..3929a76 100644
--- a/lib/librte_eal/linuxapp/eal/eal_soc.c
+++ b/lib/librte_eal/linuxapp/eal/eal_soc.c
@@ -44,13 +44,28 @@
#include <rte_log.h>
#include <rte_soc.h>
-#include "eal_internal_cfg.h"
-#include "eal_filesystem.h"
-#include "eal_private.h"
+#include <eal_internal_cfg.h>
+#include <eal_filesystem.h>
+#include <eal_private.h>
/* Init the SoC EAL subsystem */
int
rte_eal_soc_init(void)
{
+ struct rte_soc_driver *drv;
+
+ /* SoC is disabled by default */
+ if (!internal_config.enable_soc)
+ return 0;
+
+ /* For each registered driver, call their scan routine to perform any
+ * custom scan for devices (for example, custom buses)
+ */
+ TAILQ_FOREACH(drv, &soc_driver_list, next) {
+ RTE_VERIFY(drv->scan_fn);
+ drv->scan_fn();
+ /* Ignore all errors from this */
+ }
+
return 0;
}
diff --git a/lib/librte_eal/linuxapp/eal/rte_eal_version.map b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
index 0155025..c28e093 100644
--- a/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+++ b/lib/librte_eal/linuxapp/eal/rte_eal_version.map
@@ -175,7 +175,11 @@ DPDK_16.11 {
rte_eal_dev_attach;
rte_eal_dev_detach;
rte_eal_map_resource;
+ rte_eal_soc_detach;
rte_eal_soc_dump;
+ rte_eal_soc_match;
+ rte_eal_soc_probe;
+ rte_eal_soc_probe_one;
rte_eal_soc_register;
rte_eal_soc_unregister;
rte_eal_unmap_resource;
--
2.7.4
^ permalink raw reply related
* [PATCH v7 12/21] eal/soc: extend and utilize devargs
From: Shreyansh Jain @ 2016-10-28 12:26 UTC (permalink / raw)
To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin
In-Reply-To: <1477657598-826-1-git-send-email-shreyansh.jain@nxp.com>
From: Jan Viktorin <viktorin@rehivetech.com>
It is assumed that SoC Devices provided on command line are prefixed with
"soc:". This patch adds parse and attach support for such devices.
Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
lib/librte_eal/common/eal_common_dev.c | 27 +++++++++----
lib/librte_eal/common/eal_common_devargs.c | 17 ++++++++
lib/librte_eal/common/eal_common_soc.c | 61 ++++++++++++++++++++++++-----
lib/librte_eal/common/include/rte_devargs.h | 8 ++++
lib/librte_eal/common/include/rte_soc.h | 24 ++++++++++++
5 files changed, 120 insertions(+), 17 deletions(-)
diff --git a/lib/librte_eal/common/eal_common_dev.c b/lib/librte_eal/common/eal_common_dev.c
index 457d227..ebbcf47 100644
--- a/lib/librte_eal/common/eal_common_dev.c
+++ b/lib/librte_eal/common/eal_common_dev.c
@@ -107,17 +107,23 @@ rte_eal_dev_init(void)
int rte_eal_dev_attach(const char *name, const char *devargs)
{
- struct rte_pci_addr addr;
+ struct rte_soc_addr soc_addr;
+ struct rte_pci_addr pci_addr;
if (name == NULL || devargs == NULL) {
RTE_LOG(ERR, EAL, "Invalid device or arguments provided\n");
return -EINVAL;
}
- if (eal_parse_pci_DomBDF(name, &addr) == 0) {
- if (rte_eal_pci_probe_one(&addr) < 0)
+ memset(&soc_addr, 0, sizeof(soc_addr));
+ if (rte_eal_parse_soc_spec(name, &soc_addr) == 0) {
+ if (rte_eal_soc_probe_one(&soc_addr) < 0) {
+ free(soc_addr.name);
+ goto err;
+ }
+ } else if (eal_parse_pci_DomBDF(name, &pci_addr) == 0) {
+ if (rte_eal_pci_probe_one(&pci_addr) < 0)
goto err;
-
} else {
if (rte_eal_vdev_init(name, devargs))
goto err;
@@ -132,15 +138,22 @@ err:
int rte_eal_dev_detach(const char *name)
{
- struct rte_pci_addr addr;
+ struct rte_soc_addr soc_addr;
+ struct rte_pci_addr pci_addr;
if (name == NULL) {
RTE_LOG(ERR, EAL, "Invalid device provided.\n");
return -EINVAL;
}
- if (eal_parse_pci_DomBDF(name, &addr) == 0) {
- if (rte_eal_pci_detach(&addr) < 0)
+ memset(&soc_addr, 0, sizeof(soc_addr));
+ if (rte_eal_parse_soc_spec(name, &soc_addr) == 0) {
+ if (rte_eal_soc_detach(&soc_addr) < 0) {
+ free(soc_addr.name);
+ goto err;
+ }
+ } else if (eal_parse_pci_DomBDF(name, &pci_addr) == 0) {
+ if (rte_eal_pci_detach(&pci_addr) < 0)
goto err;
} else {
if (rte_eal_vdev_uninit(name))
diff --git a/lib/librte_eal/common/eal_common_devargs.c b/lib/librte_eal/common/eal_common_devargs.c
index e403717..e1dae1a 100644
--- a/lib/librte_eal/common/eal_common_devargs.c
+++ b/lib/librte_eal/common/eal_common_devargs.c
@@ -41,6 +41,7 @@
#include <string.h>
#include <rte_pci.h>
+#include <rte_soc.h>
#include <rte_devargs.h>
#include "eal_private.h"
@@ -105,6 +106,14 @@ rte_eal_devargs_add(enum rte_devtype devtype, const char *devargs_str)
goto fail;
break;
+
+ case RTE_DEVTYPE_WHITELISTED_SOC:
+ case RTE_DEVTYPE_BLACKLISTED_SOC:
+ /* try to parse soc device with prefix "soc:" */
+ if (rte_eal_parse_soc_spec(buf, &devargs->soc.addr) != 0)
+ goto fail;
+ break;
+
case RTE_DEVTYPE_VIRTUAL:
/* save driver name */
ret = snprintf(devargs->virt.drv_name,
@@ -166,6 +175,14 @@ rte_eal_devargs_dump(FILE *f)
devargs->pci.addr.devid,
devargs->pci.addr.function,
devargs->args);
+ else if (devargs->type == RTE_DEVTYPE_WHITELISTED_SOC)
+ fprintf(f, " SoC whitelist %s %s\n",
+ devargs->soc.addr.name,
+ devargs->soc.addr.fdt_path);
+ else if (devargs->type == RTE_DEVTYPE_BLACKLISTED_SOC)
+ fprintf(f, " SoC blacklist %s %s\n",
+ devargs->soc.addr.name,
+ devargs->soc.addr.fdt_path);
else if (devargs->type == RTE_DEVTYPE_VIRTUAL)
fprintf(f, " VIRTUAL %s %s\n",
devargs->virt.drv_name,
diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
index 256cef8..44f5559 100644
--- a/lib/librte_eal/common/eal_common_soc.c
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -37,6 +37,8 @@
#include <rte_log.h>
#include <rte_common.h>
+#include <rte_devargs.h>
+#include <rte_eal.h>
#include <rte_soc.h>
#include "eal_private.h"
@@ -70,6 +72,21 @@ rte_eal_soc_match_compat(struct rte_soc_driver *drv,
return 1;
}
+static struct rte_devargs *soc_devargs_lookup(struct rte_soc_device *dev)
+{
+ struct rte_devargs *devargs;
+
+ TAILQ_FOREACH(devargs, &devargs_list, next) {
+ if (devargs->type != RTE_DEVTYPE_BLACKLISTED_SOC &&
+ devargs->type != RTE_DEVTYPE_WHITELISTED_SOC)
+ continue;
+ if (!rte_eal_compare_soc_addr(&dev->addr, &devargs->soc.addr))
+ return devargs;
+ }
+
+ return NULL;
+}
+
static int
rte_eal_soc_probe_one_driver(struct rte_soc_driver *drv,
struct rte_soc_device *dev)
@@ -85,6 +102,18 @@ rte_eal_soc_probe_one_driver(struct rte_soc_driver *drv,
return ret;
}
+ RTE_LOG(DEBUG, EAL, "SoC device %s on NUMA socket %d\n",
+ dev->addr.name, dev->device.numa_node);
+ RTE_LOG(DEBUG, EAL, " probe driver %s\n", drv->driver.name);
+
+ /* no initialization when blacklisted, return without error */
+ if (dev->device.devargs != NULL
+ && dev->device.devargs->type == RTE_DEVTYPE_BLACKLISTED_SOC) {
+ RTE_LOG(DEBUG, EAL,
+ " device is blacklisted, skipping\n");
+ return ret;
+ }
+
dev->driver = drv;
RTE_VERIFY(drv->probe != NULL);
return drv->probe(drv, dev);
@@ -129,8 +158,8 @@ rte_eal_soc_detach_dev(struct rte_soc_driver *drv,
return ret;
}
- RTE_LOG(DEBUG, EAL, "SoC device %s\n",
- dev->addr.name);
+ RTE_LOG(DEBUG, EAL, "SoC device %s on NUMA socket %i\n",
+ dev->addr.name, dev->device.numa_node);
RTE_LOG(DEBUG, EAL, " remove driver: %s\n", drv->driver.name);
@@ -233,17 +262,29 @@ int
rte_eal_soc_probe(void)
{
struct rte_soc_device *dev = NULL;
+ struct rte_devargs *devargs = NULL;
int ret = 0;
+ int probe_all = 0;
+
+ if (rte_eal_devargs_type_count(RTE_DEVTYPE_WHITELISTED_SOC) == 0)
+ probe_all = 1;
TAILQ_FOREACH(dev, &soc_device_list, next) {
- ret = soc_probe_all_drivers(dev);
- if (ret < 0) {
- RTE_LOG(DEBUG, EAL, "Requested device %s"
- " cannot be used\n", dev->addr.name);
- /* Failure for a particular device is logged and
- * ignored
- */
- }
+
+ /* set devargs in SoC structure */
+ devargs = soc_devargs_lookup(dev);
+ if (devargs != NULL)
+ dev->device.devargs = devargs;
+
+ /* probe all or only whitelisted devices */
+ if (probe_all)
+ ret = soc_probe_all_drivers(dev);
+ else if (devargs != NULL &&
+ devargs->type == RTE_DEVTYPE_WHITELISTED_SOC)
+ ret = soc_probe_all_drivers(dev);
+ if (ret < 0)
+ rte_exit(EXIT_FAILURE, "Requested device %s "
+ "cannot be used\n", dev->addr.name);
}
return ret;
diff --git a/lib/librte_eal/common/include/rte_devargs.h b/lib/librte_eal/common/include/rte_devargs.h
index 88120a1..b5dd436 100644
--- a/lib/librte_eal/common/include/rte_devargs.h
+++ b/lib/librte_eal/common/include/rte_devargs.h
@@ -51,6 +51,7 @@ extern "C" {
#include <stdio.h>
#include <sys/queue.h>
#include <rte_pci.h>
+#include <rte_soc.h>
/**
* Type of generic device
@@ -58,6 +59,8 @@ extern "C" {
enum rte_devtype {
RTE_DEVTYPE_WHITELISTED_PCI,
RTE_DEVTYPE_BLACKLISTED_PCI,
+ RTE_DEVTYPE_WHITELISTED_SOC,
+ RTE_DEVTYPE_BLACKLISTED_SOC,
RTE_DEVTYPE_VIRTUAL,
};
@@ -83,6 +86,11 @@ struct rte_devargs {
/** PCI location. */
struct rte_pci_addr addr;
} pci;
+ /** Used if type is RTE_DEVTYPE_*_SOC. */
+ struct {
+ /** SoC location. */
+ struct rte_soc_addr addr;
+ } soc;
/** Used if type is RTE_DEVTYPE_VIRTUAL. */
struct {
/** Driver name. */
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 53a321b..fb5ea7b 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -164,6 +164,30 @@ rte_eal_compare_soc_addr(const struct rte_soc_addr *a0,
}
/**
+ * Parse a specification of a soc device. The specification must differentiate
+ * a SoC device specification from the PCI bus and virtual devices. We assume
+ * a SoC specification starts with "soc:". The function allocates the name
+ * entry of the given addr.
+ *
+ * @return
+ * - 0 on success
+ * - 1 when not a SoC spec
+ * - -1 on failure
+ */
+static inline int
+rte_eal_parse_soc_spec(const char *spec, struct rte_soc_addr *addr)
+{
+ if (strstr(spec, "soc:") == spec) {
+ addr->name = strdup(spec + 4);
+ if (addr->name == NULL)
+ return -1;
+ return 0;
+ }
+
+ return 1;
+}
+
+/**
* Default function for matching the Soc driver with device. Each driver can
* either use this function or define their own soc matching function.
* This function relies on the compatible string extracted from sysfs. But,
--
2.7.4
^ permalink raw reply related
* [PATCH v7 14/21] eal/soc: add intr_handle
From: Shreyansh Jain @ 2016-10-28 12:26 UTC (permalink / raw)
To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin
In-Reply-To: <1477657598-826-1-git-send-email-shreyansh.jain@nxp.com>
From: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
lib/librte_eal/common/include/rte_soc.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 40490b9..38f897d 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -53,6 +53,7 @@ extern "C" {
#include <rte_dev.h>
#include <rte_eal.h>
#include <rte_debug.h>
+#include <rte_interrupts.h>
extern struct soc_driver_list soc_driver_list;
/**< Global list of SoC Drivers */
@@ -80,6 +81,7 @@ struct rte_soc_device {
struct rte_device device; /**< Inherit code device */
struct rte_soc_addr addr; /**< SoC device Location */
struct rte_soc_id *id; /**< SoC device ID list */
+ struct rte_intr_handle intr_handle; /**< Interrupt handle */
struct rte_soc_driver *driver; /**< Associated driver */
};
--
2.7.4
^ permalink raw reply related
* [PATCH v7 13/21] eal/soc: add drv_flags
From: Shreyansh Jain @ 2016-10-28 12:26 UTC (permalink / raw)
To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin
In-Reply-To: <1477657598-826-1-git-send-email-shreyansh.jain@nxp.com>
From: Jan Viktorin <viktorin@rehivetech.com>
The flags are copied from the PCI ones. They should be refactorized into a
general set of flags in the future.
Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
lib/librte_eal/common/include/rte_soc.h | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index fb5ea7b..40490b9 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -123,8 +123,18 @@ struct rte_soc_driver {
soc_scan_t *scan_fn; /**< Callback for scanning SoC bus*/
soc_match_t *match_fn; /**< Callback to match dev<->drv */
const struct rte_soc_id *id_table; /**< ID table, NULL terminated */
+ uint32_t drv_flags; /**< Control handling of device */
};
+/** Device needs to map its resources by EAL */
+#define RTE_SOC_DRV_NEED_MAPPING 0x0001
+/** Device needs to be unbound even if no module is provieded */
+#define RTE_SOC_DRV_FORCE_UNBIND 0x0004
+/** Device driver supports link state interrupt */
+#define RTE_SOC_DRV_INTR_LSC 0x0008
+/** Device driver supports detaching capability */
+#define RTE_SOC_DRV_DETACHABLE 0x0010
+
/**
* Utility function to write a SoC device name, this device name can later be
* used to retrieve the corresponding rte_soc_addr using above functions.
--
2.7.4
^ permalink raw reply related
* [PATCH v7 15/21] eal/soc: add default scan for Soc devices
From: Shreyansh Jain @ 2016-10-28 12:26 UTC (permalink / raw)
To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin
In-Reply-To: <1477657598-826-1-git-send-email-shreyansh.jain@nxp.com>
From: Jan Viktorin <viktorin@rehivetech.com>
Default implementation which scans the sysfs platform devices hierarchy.
For each device, extract the ueven and convert into rte_soc_device.
The information populated can then be used in probe to match against
the drivers registered.
Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
[Shreyansh: restructure commit to be an optional implementation]
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
--
v5:
- Update rte_eal_soc_scan to rte_eal_soc_scan_platform_bus
- Fix comments over scan and match functions
---
lib/librte_eal/common/include/rte_soc.h | 16 +-
lib/librte_eal/linuxapp/eal/eal_soc.c | 315 ++++++++++++++++++++++++++++++++
2 files changed, 329 insertions(+), 2 deletions(-)
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 38f897d..8be3db7 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -64,7 +64,10 @@ TAILQ_HEAD(soc_driver_list, rte_soc_driver); /**< SoC drivers in D-linked Q. */
TAILQ_HEAD(soc_device_list, rte_soc_device); /**< SoC devices in D-linked Q. */
struct rte_soc_id {
- const char *compatible; /**< OF compatible specification */
+ union {
+ const char *compatible; /**< OF compatible specification */
+ char *_compatible;
+ };
uint64_t priv_data; /**< SoC Driver specific data */
};
@@ -200,7 +203,16 @@ rte_eal_parse_soc_spec(const char *spec, struct rte_soc_addr *addr)
}
/**
- * Default function for matching the Soc driver with device. Each driver can
+ * Helper function for scanning for new SoC devices on platform bus.
+ *
+ * @return
+ * 0 on success
+ * !0 on failure to scan
+ */
+int rte_eal_soc_scan_platform_bus(void);
+
+/**
+ * Helper function for matching the Soc driver with device. Each driver can
* either use this function or define their own soc matching function.
* This function relies on the compatible string extracted from sysfs. But,
* a SoC might have different way of identifying its devices. Such SoC can
diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c
index 3929a76..d8dfe97 100644
--- a/lib/librte_eal/linuxapp/eal/eal_soc.c
+++ b/lib/librte_eal/linuxapp/eal/eal_soc.c
@@ -48,6 +48,321 @@
#include <eal_filesystem.h>
#include <eal_private.h>
+/** Pathname of SoC devices directory. */
+#define SYSFS_SOC_DEVICES "/sys/bus/platform/devices"
+
+static const char *
+soc_get_sysfs_path(void)
+{
+ const char *path = NULL;
+
+ path = getenv("SYSFS_SOC_DEVICES");
+ if (path == NULL)
+ return SYSFS_SOC_DEVICES;
+
+ return path;
+}
+
+static char *
+dev_read_uevent(const char *dirname)
+{
+ char filename[PATH_MAX];
+ struct stat st;
+ char *buf;
+ ssize_t total = 0;
+ int fd;
+
+ snprintf(filename, sizeof(filename), "%s/uevent", dirname);
+ fd = open(filename, O_RDONLY);
+ if (fd < 0) {
+ RTE_LOG(WARNING, EAL, "Failed to open file %s\n", filename);
+ return strdup("");
+ }
+
+ if (fstat(fd, &st) < 0) {
+ RTE_LOG(ERR, EAL, "Failed to stat file %s\n", filename);
+ close(fd);
+ return NULL;
+ }
+
+ if (st.st_size == 0) {
+ close(fd);
+ return strdup("");
+ }
+
+ buf = malloc(st.st_size + 1);
+ if (buf == NULL) {
+ RTE_LOG(ERR, EAL, "Failed to alloc memory to read %s\n",
+ filename);
+ close(fd);
+ return NULL;
+ }
+
+ while (total < st.st_size) {
+ ssize_t rlen = read(fd, buf + total, st.st_size - total);
+ if (rlen < 0) {
+ if (errno == EINTR)
+ continue;
+
+ RTE_LOG(ERR, EAL, "Failed to read file %s\n", filename);
+
+ free(buf);
+ close(fd);
+ return NULL;
+ }
+ if (rlen == 0) /* EOF */
+ break;
+
+ total += rlen;
+ }
+
+ buf[total] = '\0';
+ close(fd);
+
+ return buf;
+}
+
+static const char *
+dev_uevent_find(const char *uevent, const char *key)
+{
+ const size_t keylen = strlen(key);
+ const size_t total = strlen(uevent);
+ const char *p = uevent;
+
+ /* check whether it is the first key */
+ if (!strncmp(uevent, key, keylen))
+ return uevent + keylen;
+
+ /* check 2nd key or further... */
+ do {
+ p = strstr(p, key);
+ if (p == NULL)
+ break;
+
+ if (p[-1] == '\n') /* check we are at a new line */
+ return p + keylen;
+
+ p += keylen; /* skip this one */
+ } while (p - uevent < (ptrdiff_t) total);
+
+ return NULL;
+}
+
+static char *
+strdup_until_nl(const char *p)
+{
+ const char *nl = strchr(p, '\n');
+ if (nl == NULL)
+ return strdup(p); /* no newline, copy until '\0' */
+
+ return strndup(p, nl - p);
+}
+
+static int
+dev_parse_uevent(struct rte_soc_device *dev, const char *uevent)
+{
+ const char *of;
+ const char *compat_n;
+ char *err;
+ long n;
+ char compat[strlen("OF_COMPATIBLE_NNNN=")];
+ long i;
+
+ of = dev_uevent_find(uevent, "OF_FULLNAME=");
+ if (of == NULL)
+ return 1; /* don't care about this device */
+
+ dev->addr.fdt_path = strdup_until_nl(of);
+ if (dev->addr.fdt_path == NULL) {
+ RTE_LOG(ERR, PMD,
+ "Failed to alloc memory for fdt_path\n");
+ return -1;
+ }
+
+ RTE_LOG(DEBUG, EAL, "Detected device %s (%s)\n",
+ dev->addr.name, dev->addr.fdt_path);
+
+ compat_n = dev_uevent_find(uevent, "OF_COMPATIBLE_N=");
+ if (compat_n == NULL) {
+ RTE_LOG(ERR, EAL, "No OF_COMPATIBLE_N found\n");
+ return -1;
+ }
+
+ n = strtoul(compat_n, &err, 0);
+ if (*err != '\n' && err != NULL) {
+ RTE_LOG(ERR, EAL, "Failed to parse OF_COMPATIBLE_N: %.10s\n",
+ err);
+ goto fail_fdt_path;
+ }
+
+ if (n == 0)
+ return 1; /* cannot match anything */
+ if (n > 9999) { /* match NNNN */
+ RTE_LOG(ERR, EAL, "OF_COMPATIBLE_N is invalid: %ld\n", n);
+ goto fail_fdt_path;
+ }
+
+ dev->id = calloc(n + 1, sizeof(*dev->id));
+ if (dev->id == NULL) {
+ RTE_LOG(ERR, PMD, "Failed to alloc memory for ID\n");
+ free(dev->addr.fdt_path);
+ return -1;
+ }
+
+ for (i = 0; i < n; ++i) {
+ snprintf(compat, sizeof(compat), "OF_COMPATIBLE_%lu=", i);
+ const char *val;
+
+ val = dev_uevent_find(uevent, compat);
+ if (val == NULL) {
+ RTE_LOG(ERR, EAL, "%s was not found\n", compat);
+ goto fail_id;
+ }
+
+ dev->id[i]._compatible = strdup_until_nl(val);
+ if (dev->id[i]._compatible == NULL) {
+ RTE_LOG(ERR, PMD,
+ "Failed to alloc memory for compatible\n");
+ goto fail_id;
+ }
+
+ RTE_LOG(DEBUG, EAL, " compatible: %s\n",
+ dev->id[i].compatible);
+ }
+
+ dev->id[n]._compatible = NULL; /* mark last one */
+
+ return 0;
+
+fail_id:
+ while (i-- >= 0)
+ free(dev->id[i]._compatible);
+ free(dev->id);
+fail_fdt_path:
+ free(dev->addr.fdt_path);
+ return -1;
+}
+
+static void
+dev_content_free(struct rte_soc_device *dev)
+{
+ int i;
+
+ if (dev->addr.fdt_path)
+ free(dev->addr.fdt_path);
+
+ if (dev->id != NULL) {
+ for (i = 0; dev->id[i]._compatible; ++i)
+ free(dev->id[i]._compatible);
+
+ free(dev->id);
+ dev->id = NULL;
+ }
+}
+
+/**
+ * Scan one SoC sysfs entry, and fill the devices list from it.
+ * We require to have the uevent file with records: OF_FULLNAME and
+ * OF_COMPATIBLE array (with at least one entry). Otherwise, such device
+ * is skipped.
+ */
+static int
+soc_scan_one(const char *dirname, const char *name)
+{
+ struct rte_soc_device *dev;
+ char *uevent;
+ int ret;
+
+ uevent = dev_read_uevent(dirname);
+ if (uevent == NULL)
+ return -1;
+
+ if (uevent[0] == '\0') {
+ /* ignore directory without uevent file */
+ free(uevent);
+ return 1;
+ }
+
+ dev = malloc(sizeof(*dev) + strlen(name) + 1);
+ if (dev == NULL) {
+ RTE_LOG(ERR, PMD, "Failed to alloc memory for %s\n", name);
+ free(uevent);
+ return -1;
+ }
+
+ memset(dev, 0, sizeof(*dev));
+ dev->addr.name = (char *) (dev + 1);
+ strcpy(dev->addr.name, name);
+
+ ret = dev_parse_uevent(dev, uevent);
+ if (ret)
+ goto fail;
+ free(uevent); /* not needed anymore */
+
+ /* device is valid, add in list (sorted) */
+ if (TAILQ_EMPTY(&soc_device_list)) {
+ TAILQ_INSERT_TAIL(&soc_device_list, dev, next);
+ } else {
+ struct rte_soc_device *dev2;
+
+ TAILQ_FOREACH(dev2, &soc_device_list, next) {
+ ret = rte_eal_compare_soc_addr(&dev->addr, &dev2->addr);
+ if (ret > 0)
+ continue;
+
+ if (ret < 0) {
+ TAILQ_INSERT_BEFORE(dev2, dev, next);
+ } else { /* already registered */
+ dev_content_free(dev2);
+ dev2->addr.fdt_path = dev->addr.fdt_path;
+ dev2->id = dev->id;
+ free(dev);
+ }
+ return 0;
+ }
+ TAILQ_INSERT_TAIL(&soc_device_list, dev, next);
+ }
+
+ return 0;
+
+fail:
+ free(uevent);
+ dev_content_free(dev);
+ free(dev);
+ return ret;
+}
+
+int
+rte_eal_soc_scan_platform_bus(void)
+{
+ struct dirent *e;
+ DIR *dir;
+ char dirname[PATH_MAX];
+
+ dir = opendir(soc_get_sysfs_path());
+ if (dir == NULL) {
+ RTE_LOG(ERR, EAL, "%s(): opendir failed: %s\n",
+ __func__, strerror(errno));
+ return -1;
+ }
+
+ while ((e = readdir(dir)) != NULL) {
+ if (e->d_name[0] == '.')
+ continue;
+
+ snprintf(dirname, sizeof(dirname), "%s/%s",
+ soc_get_sysfs_path(), e->d_name);
+ if (soc_scan_one(dirname, e->d_name) < 0)
+ goto error;
+ }
+ closedir(dir);
+ return 0;
+
+error:
+ closedir(dir);
+ return -1;
+}
+
/* Init the SoC EAL subsystem */
int
rte_eal_soc_init(void)
--
2.7.4
^ permalink raw reply related
* [PATCH v7 17/21] ether: utilize container_of for pci_drv
From: Shreyansh Jain @ 2016-10-28 12:26 UTC (permalink / raw)
To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin
In-Reply-To: <1477657598-826-1-git-send-email-shreyansh.jain@nxp.com>
From: Jan Viktorin <viktorin@rehivetech.com>
It is not necessary to place the rte_pci_driver at the beginning
of the rte_eth_dev struct anymore as we use the container_of macro
to get the parent pointer.
Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
lib/librte_ether/rte_ethdev.c | 4 ++--
lib/librte_ether/rte_ethdev.h | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index fde8112..347c230 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -241,7 +241,7 @@ rte_eth_dev_pci_probe(struct rte_pci_driver *pci_drv,
int diag;
- eth_drv = (struct eth_driver *)pci_drv;
+ eth_drv = container_of(pci_drv, struct eth_driver, pci_drv);
rte_eal_pci_device_name(&pci_dev->addr, ethdev_name,
sizeof(ethdev_name));
@@ -302,7 +302,7 @@ rte_eth_dev_pci_remove(struct rte_pci_device *pci_dev)
if (eth_dev == NULL)
return -ENODEV;
- eth_drv = (const struct eth_driver *)pci_dev->driver;
+ eth_drv = container_of(pci_dev->driver, struct eth_driver, pci_drv);
/* Invoke PMD device uninit function */
if (*eth_drv->eth_dev_uninit) {
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 38641e8..f893fe0 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -1850,7 +1850,7 @@ typedef int (*eth_dev_uninit_t)(struct rte_eth_dev *eth_dev);
* Each Ethernet driver acts as a PCI driver and is represented by a generic
* *eth_driver* structure that holds:
*
- * - An *rte_pci_driver* structure (which must be the first field).
+ * - An *rte_pci_driver* structure.
*
* - The *eth_dev_init* function invoked for each matching PCI device.
*
--
2.7.4
^ permalink raw reply related
* [PATCH v7 16/21] eal/soc: additional features for SoC
From: Shreyansh Jain @ 2016-10-28 12:26 UTC (permalink / raw)
To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin
In-Reply-To: <1477657598-826-1-git-send-email-shreyansh.jain@nxp.com>
From: Jan Viktorin <viktorin@rehivetech.com>
Additional features introduced:
- Find kernel driver through sysfs bindings
- Dummy implementation for mapping to kernel driver
- DMA coherency value from sysfs
- Numa node number from sysfs
- Support for updating device during probe if already registered
Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
[Shreyansh: merge multiple patches into single set]
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
lib/librte_eal/common/eal_common_soc.c | 30 ++++++++
lib/librte_eal/common/eal_private.h | 23 ++++++
lib/librte_eal/common/include/rte_soc.h | 28 +++++++
lib/librte_eal/linuxapp/eal/eal_soc.c | 129 ++++++++++++++++++++++++++++++++
4 files changed, 210 insertions(+)
diff --git a/lib/librte_eal/common/eal_common_soc.c b/lib/librte_eal/common/eal_common_soc.c
index 44f5559..29c38e0 100644
--- a/lib/librte_eal/common/eal_common_soc.c
+++ b/lib/librte_eal/common/eal_common_soc.c
@@ -114,6 +114,26 @@ rte_eal_soc_probe_one_driver(struct rte_soc_driver *drv,
return ret;
}
+ if (!dev->is_dma_coherent) {
+ if (!(drv->drv_flags & RTE_SOC_DRV_ACCEPT_NONCC)) {
+ RTE_LOG(DEBUG, EAL,
+ " device is not DMA coherent, skipping\n");
+ return 1;
+ }
+ }
+
+ if (drv->drv_flags & RTE_SOC_DRV_NEED_MAPPING) {
+ /* map resources */
+ ret = rte_eal_soc_map_device(dev);
+ if (ret)
+ return ret;
+ } else if (drv->drv_flags & RTE_SOC_DRV_FORCE_UNBIND
+ && rte_eal_process_type() == RTE_PROC_PRIMARY) {
+ /* unbind */
+ if (soc_unbind_kernel_driver(dev) < 0)
+ return -1;
+ }
+
dev->driver = drv;
RTE_VERIFY(drv->probe != NULL);
return drv->probe(drv, dev);
@@ -166,6 +186,10 @@ rte_eal_soc_detach_dev(struct rte_soc_driver *drv,
if (drv->remove && (drv->remove(dev) < 0))
return -1; /* negative value is an error */
+ if (drv->drv_flags & RTE_SOC_DRV_NEED_MAPPING)
+ /* unmap resources for devices */
+ rte_eal_soc_unmap_device(dev);
+
/* clear driver structure */
dev->driver = NULL;
@@ -241,6 +265,12 @@ rte_eal_soc_probe_one(const struct rte_soc_addr *addr)
if (addr == NULL)
return -1;
+ /* update current SoC device in global list, kernel bindings might have
+ * changed since last time we looked at it.
+ */
+ if (soc_update_device(addr) < 0)
+ goto err_return;
+
TAILQ_FOREACH(dev, &soc_device_list, next) {
if (rte_eal_compare_soc_addr(&dev->addr, addr))
continue;
diff --git a/lib/librte_eal/common/eal_private.h b/lib/librte_eal/common/eal_private.h
index d810f9f..30c648d 100644
--- a/lib/librte_eal/common/eal_private.h
+++ b/lib/librte_eal/common/eal_private.h
@@ -159,6 +159,29 @@ int pci_update_device(const struct rte_pci_addr *addr);
int pci_unbind_kernel_driver(struct rte_pci_device *dev);
/**
+ * Update a soc device object by asking the kernel for the latest information.
+ *
+ * This function is private to EAL.
+ *
+ * @param addr
+ * The SoC address to look for
+ * @return
+ * - 0 on success.
+ * - negative on error.
+ */
+int soc_update_device(const struct rte_soc_addr *addr);
+
+/**
+ * Unbind kernel driver for this device
+ *
+ * This function is private to EAL.
+ *
+ * @return
+ * 0 on success, negative on error
+ */
+int soc_unbind_kernel_driver(struct rte_soc_device *dev);
+
+/**
* Map the PCI resource of a PCI device in virtual memory
*
* This function is private to EAL.
diff --git a/lib/librte_eal/common/include/rte_soc.h b/lib/librte_eal/common/include/rte_soc.h
index 8be3db7..d7f7ec8 100644
--- a/lib/librte_eal/common/include/rte_soc.h
+++ b/lib/librte_eal/common/include/rte_soc.h
@@ -46,9 +46,11 @@ extern "C" {
#include <stdio.h>
#include <stdlib.h>
+#include <sys/queue.h>
#include <stdint.h>
#include <inttypes.h>
#include <string.h>
+#include <limits.h>
#include <rte_dev.h>
#include <rte_eal.h>
@@ -63,6 +65,14 @@ extern struct soc_device_list soc_device_list;
TAILQ_HEAD(soc_driver_list, rte_soc_driver); /**< SoC drivers in D-linked Q. */
TAILQ_HEAD(soc_device_list, rte_soc_device); /**< SoC devices in D-linked Q. */
+#define SOC_MAX_RESOURCE 6
+
+struct rte_soc_resource {
+ uint64_t phys_addr;
+ uint64_t len;
+ void *addr;
+};
+
struct rte_soc_id {
union {
const char *compatible; /**< OF compatible specification */
@@ -84,8 +94,12 @@ struct rte_soc_device {
struct rte_device device; /**< Inherit code device */
struct rte_soc_addr addr; /**< SoC device Location */
struct rte_soc_id *id; /**< SoC device ID list */
+ struct rte_soc_resource mem_resource[SOC_MAX_RESOURCE];
struct rte_intr_handle intr_handle; /**< Interrupt handle */
struct rte_soc_driver *driver; /**< Associated driver */
+ int numa_node; /**< NUMA node connection */
+ int is_dma_coherent; /**< DMA coherent device */
+ enum rte_kernel_driver kdrv; /**< Kernel driver */
};
struct rte_soc_driver;
@@ -139,6 +153,8 @@ struct rte_soc_driver {
#define RTE_SOC_DRV_INTR_LSC 0x0008
/** Device driver supports detaching capability */
#define RTE_SOC_DRV_DETACHABLE 0x0010
+/** Device driver accepts DMA non-coherent devices */
+#define RTE_SOC_DRV_ACCEPT_NONCC 0x0020
/**
* Utility function to write a SoC device name, this device name can later be
@@ -256,6 +272,18 @@ int rte_eal_soc_probe_one(const struct rte_soc_addr *addr);
int rte_eal_soc_detach(const struct rte_soc_addr *addr);
/**
+ * Map SoC device resources into userspace.
+ *
+ * This is called by the EAL if (drv_flags & RTE_SOC_DRV_NEED_MAPPING).
+ */
+int rte_eal_soc_map_device(struct rte_soc_device *dev);
+
+/**
+ * Unmap the device resources.
+ */
+void rte_eal_soc_unmap_device(struct rte_soc_device *dev);
+
+/**
* Dump discovered SoC devices.
*
* @param f
diff --git a/lib/librte_eal/linuxapp/eal/eal_soc.c b/lib/librte_eal/linuxapp/eal/eal_soc.c
index d8dfe97..95f7565 100644
--- a/lib/librte_eal/linuxapp/eal/eal_soc.c
+++ b/lib/librte_eal/linuxapp/eal/eal_soc.c
@@ -63,6 +63,45 @@ soc_get_sysfs_path(void)
return path;
}
+int
+soc_unbind_kernel_driver(struct rte_soc_device *dev)
+{
+ char devpath[PATH_MAX];
+
+ snprintf(devpath, sizeof(devpath), "%s/%s",
+ soc_get_sysfs_path(), dev->addr.name);
+
+ return rte_eal_unbind_kernel_driver(devpath, dev->addr.name);
+}
+
+int
+rte_eal_soc_map_device(struct rte_soc_device *dev)
+{
+ int ret = -1;
+
+ /* try mapping the NIC resources using VFIO if it exists */
+ switch (dev->kdrv) {
+ default:
+ RTE_LOG(DEBUG, EAL,
+ " Not managed by a supported kernel driver, skipped\n");
+ ret = 1;
+ break;
+ }
+
+ return ret;
+}
+
+void
+rte_eal_soc_unmap_device(struct rte_soc_device *dev)
+{
+ switch (dev->kdrv) {
+ default:
+ RTE_LOG(DEBUG, EAL,
+ " Not managed by a supported kernel driver, skipped\n");
+ break;
+ }
+}
+
static char *
dev_read_uevent(const char *dirname)
{
@@ -260,6 +299,68 @@ dev_content_free(struct rte_soc_device *dev)
}
}
+static int
+dev_setup_associated_driver(struct rte_soc_device *dev, const char *dirname)
+{
+ char filename[PATH_MAX];
+ char driver[PATH_MAX];
+ int ret;
+
+ /* parse driver */
+ snprintf(filename, sizeof(filename), "%s/driver", dirname);
+ ret = rte_eal_get_kernel_driver_by_path(filename, driver);
+ if (ret < 0) {
+ RTE_LOG(ERR, EAL, "Fail to get kernel driver for %s\n",
+ dirname);
+ return 1;
+ }
+
+ if (!ret)
+ dev->kdrv = RTE_KDRV_UNKNOWN;
+ else
+ dev->kdrv = RTE_KDRV_NONE;
+
+ return 0;
+}
+
+static int
+dev_setup_numa_node(struct rte_soc_device *dev, const char *dirname)
+{
+ char filename[PATH_MAX];
+
+ /* if no NUMA support, set default to 0 */
+ unsigned long tmp = 0;
+ int ret = 0;
+
+ /* get numa node */
+ snprintf(filename, sizeof(filename), "%s/numa_node", dirname);
+
+ if (eal_parse_sysfs_value(filename, &tmp) < 0)
+ ret = 1;
+
+ dev->numa_node = tmp;
+ return ret;
+}
+
+static int
+dev_detect_is_coherent(struct rte_soc_device *dev)
+{
+ char filename[PATH_MAX];
+ FILE *f;
+
+ if (dev->addr.fdt_path == NULL)
+ return 0; /* no way to detect */
+
+ snprintf(filename, sizeof(filename), "%s%s/dma-coherent",
+ "/proc/device-tree", dev->addr.fdt_path);
+ f = fopen(filename, "r");
+ if (f == NULL)
+ return 0;
+
+ fclose(f);
+ return 1;
+}
+
/**
* Scan one SoC sysfs entry, and fill the devices list from it.
* We require to have the uevent file with records: OF_FULLNAME and
@@ -299,6 +400,18 @@ soc_scan_one(const char *dirname, const char *name)
goto fail;
free(uevent); /* not needed anymore */
+ ret = dev_setup_associated_driver(dev, dirname);
+ if (ret)
+ goto fail;
+
+ ret = dev_setup_numa_node(dev, dirname);
+ if (ret < 0)
+ goto fail;
+
+ dev->is_dma_coherent = dev_detect_is_coherent(dev);
+ RTE_LOG(DEBUG, EAL, " DMA %s\n",
+ dev->is_dma_coherent ? "coherent" : "non-coherent");
+
/* device is valid, add in list (sorted) */
if (TAILQ_EMPTY(&soc_device_list)) {
TAILQ_INSERT_TAIL(&soc_device_list, dev, next);
@@ -313,6 +426,11 @@ soc_scan_one(const char *dirname, const char *name)
if (ret < 0) {
TAILQ_INSERT_BEFORE(dev2, dev, next);
} else { /* already registered */
+ dev2->kdrv = dev->kdrv;
+ dev2->is_dma_coherent = dev->is_dma_coherent;
+ memmove(dev2->mem_resource, dev->mem_resource,
+ sizeof(dev->mem_resource));
+
dev_content_free(dev2);
dev2->addr.fdt_path = dev->addr.fdt_path;
dev2->id = dev->id;
@@ -333,6 +451,17 @@ fail:
}
int
+soc_update_device(const struct rte_soc_addr *addr)
+{
+ char filename[PATH_MAX];
+
+ snprintf(filename, sizeof(filename), "%s/%s",
+ soc_get_sysfs_path(), addr->name);
+
+ return soc_scan_one(filename, addr->name);
+}
+
+int
rte_eal_soc_scan_platform_bus(void)
{
struct dirent *e;
--
2.7.4
^ permalink raw reply related
* [PATCH v7 18/21] ether: verify we copy info from a PCI device
From: Shreyansh Jain @ 2016-10-28 12:26 UTC (permalink / raw)
To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin
In-Reply-To: <1477657598-826-1-git-send-email-shreyansh.jain@nxp.com>
From: Jan Viktorin <viktorin@rehivetech.com>
Now that different types of ethdev exist, check for presence of PCI dev
while copying out the info.
Similar would be done for SoC.
Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
lib/librte_ether/rte_ethdev.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 347c230..a1e3aaf 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -3206,6 +3206,8 @@ rte_eth_copy_pci_info(struct rte_eth_dev *eth_dev, struct rte_pci_device *pci_de
return;
}
+ RTE_VERIFY(eth_dev->pci_dev != NULL);
+
eth_dev->data->dev_flags = 0;
if (pci_dev->driver->drv_flags & RTE_PCI_DRV_INTR_LSC)
eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC;
--
2.7.4
^ permalink raw reply related
* [PATCH v7 19/21] ether: extract function eth_dev_get_intr_handle
From: Shreyansh Jain @ 2016-10-28 12:26 UTC (permalink / raw)
To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin
In-Reply-To: <1477657598-826-1-git-send-email-shreyansh.jain@nxp.com>
From: Jan Viktorin <viktorin@rehivetech.com>
We abstract access to the intr_handle here as we want to get
it either from the pci_dev or soc_dev.
Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
lib/librte_ether/rte_ethdev.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index a1e3aaf..4c61246 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -2532,6 +2532,16 @@ _rte_eth_dev_callback_process(struct rte_eth_dev *dev,
rte_spinlock_unlock(&rte_eth_dev_cb_lock);
}
+static inline
+struct rte_intr_handle *eth_dev_get_intr_handle(struct rte_eth_dev *dev)
+{
+ if (dev->pci_dev)
+ return &dev->pci_dev->intr_handle;
+
+ RTE_ASSERT(0);
+ return NULL;
+}
+
int
rte_eth_dev_rx_intr_ctl(uint8_t port_id, int epfd, int op, void *data)
{
@@ -2544,7 +2554,7 @@ rte_eth_dev_rx_intr_ctl(uint8_t port_id, int epfd, int op, void *data)
RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
dev = &rte_eth_devices[port_id];
- intr_handle = &dev->pci_dev->intr_handle;
+ intr_handle = eth_dev_get_intr_handle(dev);
if (!intr_handle->intr_vec) {
RTE_PMD_DEBUG_TRACE("RX Intr vector unset\n");
return -EPERM;
@@ -2604,7 +2614,7 @@ rte_eth_dev_rx_intr_ctl_q(uint8_t port_id, uint16_t queue_id,
return -EINVAL;
}
- intr_handle = &dev->pci_dev->intr_handle;
+ intr_handle = eth_dev_get_intr_handle(dev);
if (!intr_handle->intr_vec) {
RTE_PMD_DEBUG_TRACE("RX Intr vector unset\n");
return -EPERM;
--
2.7.4
^ permalink raw reply related
* [PATCH v7 20/21] ether: introduce ethernet dev probe remove
From: Shreyansh Jain @ 2016-10-28 12:26 UTC (permalink / raw)
To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin
In-Reply-To: <1477657598-826-1-git-send-email-shreyansh.jain@nxp.com>
From: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Jan Viktorin <viktorin@rehivetech.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
lib/librte_ether/rte_ethdev.c | 148 +++++++++++++++++++++++++++++++++++++++++-
lib/librte_ether/rte_ethdev.h | 31 +++++++++
2 files changed, 177 insertions(+), 2 deletions(-)
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 4c61246..972e916 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -325,6 +325,101 @@ rte_eth_dev_pci_remove(struct rte_pci_device *pci_dev)
}
int
+rte_eth_dev_soc_probe(struct rte_soc_driver *soc_drv,
+ struct rte_soc_device *soc_dev)
+{
+ struct eth_driver *eth_drv;
+ struct rte_eth_dev *eth_dev;
+ char ethdev_name[RTE_ETH_NAME_MAX_LEN];
+
+ int diag;
+
+ eth_drv = container_of(soc_drv, struct eth_driver, soc_drv);
+
+ rte_eal_soc_device_name(&soc_dev->addr, ethdev_name,
+ sizeof(ethdev_name));
+
+ eth_dev = rte_eth_dev_allocate(ethdev_name);
+ if (eth_dev == NULL)
+ return -ENOMEM;
+
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+ eth_dev->data->dev_private = rte_zmalloc(
+ "ethdev private structure",
+ eth_drv->dev_private_size,
+ RTE_CACHE_LINE_SIZE);
+ if (eth_dev->data->dev_private == NULL)
+ rte_panic("Cannot allocate memzone for private port "
+ "data\n");
+ }
+ eth_dev->soc_dev = soc_dev;
+ eth_dev->driver = eth_drv;
+ eth_dev->data->rx_mbuf_alloc_failed = 0;
+
+ /* init user callbacks */
+ TAILQ_INIT(&(eth_dev->link_intr_cbs));
+
+ /*
+ * Set the default MTU.
+ */
+ eth_dev->data->mtu = ETHER_MTU;
+
+ /* Invoke PMD device initialization function */
+ diag = (*eth_drv->eth_dev_init)(eth_dev);
+ if (diag == 0)
+ return 0;
+
+ RTE_PMD_DEBUG_TRACE("driver %s: eth_dev_init(%s) failed\n",
+ soc_drv->driver.name,
+ soc_dev->addr.name);
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+ rte_free(eth_dev->data->dev_private);
+ rte_eth_dev_release_port(eth_dev);
+ return diag;
+}
+
+int
+rte_eth_dev_soc_remove(struct rte_soc_device *soc_dev)
+{
+ const struct eth_driver *eth_drv;
+ struct rte_eth_dev *eth_dev;
+ char ethdev_name[RTE_ETH_NAME_MAX_LEN];
+ int ret;
+
+ if (soc_dev == NULL)
+ return -EINVAL;
+
+ rte_eal_soc_device_name(&soc_dev->addr, ethdev_name,
+ sizeof(ethdev_name));
+
+ eth_dev = rte_eth_dev_allocated(ethdev_name);
+ if (eth_dev == NULL)
+ return -ENODEV;
+
+ eth_drv = container_of(soc_dev->driver, struct eth_driver, soc_drv);
+
+ /* Invoke PMD device uninit function */
+ if (*eth_drv->eth_dev_uninit) {
+ ret = (*eth_drv->eth_dev_uninit)(eth_dev);
+ if (ret)
+ return ret;
+ }
+
+ /* free ether device */
+ rte_eth_dev_release_port(eth_dev);
+
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+ rte_free(eth_dev->data->dev_private);
+
+ eth_dev->soc_dev = NULL;
+ eth_dev->driver = NULL;
+ eth_dev->data = NULL;
+
+ return 0;
+}
+
+
+int
rte_eth_dev_is_valid_port(uint8_t port_id)
{
if (port_id >= RTE_MAX_ETHPORTS ||
@@ -1557,6 +1652,7 @@ rte_eth_dev_info_get(uint8_t port_id, struct rte_eth_dev_info *dev_info)
RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get);
(*dev->dev_ops->dev_infos_get)(dev, dev_info);
dev_info->pci_dev = dev->pci_dev;
+ dev_info->soc_dev = dev->soc_dev;
dev_info->driver_name = dev->data->drv_name;
dev_info->nb_rx_queues = dev->data->nb_rx_queues;
dev_info->nb_tx_queues = dev->data->nb_tx_queues;
@@ -2535,8 +2631,15 @@ _rte_eth_dev_callback_process(struct rte_eth_dev *dev,
static inline
struct rte_intr_handle *eth_dev_get_intr_handle(struct rte_eth_dev *dev)
{
- if (dev->pci_dev)
+ if (dev->pci_dev) {
+ RTE_ASSERT(dev->soc_dev == NULL);
return &dev->pci_dev->intr_handle;
+ }
+
+ if (dev->soc_dev) {
+ RTE_ASSERT(dev->pci_dev == NULL);
+ return &dev->soc_dev->intr_handle;
+ }
RTE_ASSERT(0);
return NULL;
@@ -2573,6 +2676,23 @@ rte_eth_dev_rx_intr_ctl(uint8_t port_id, int epfd, int op, void *data)
return 0;
}
+static inline
+const char *eth_dev_get_driver_name(const struct rte_eth_dev *dev)
+{
+ if (dev->pci_dev) {
+ RTE_ASSERT(dev->soc_dev == NULL);
+ return dev->driver->pci_drv.driver.name;
+ }
+
+ if (dev->soc_dev) {
+ RTE_ASSERT(dev->pci_dev == NULL);
+ return dev->driver->soc_drv.driver.name;
+ }
+
+ RTE_ASSERT(0);
+ return NULL;
+}
+
const struct rte_memzone *
rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name,
uint16_t queue_id, size_t size, unsigned align,
@@ -2580,9 +2700,11 @@ rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name,
{
char z_name[RTE_MEMZONE_NAMESIZE];
const struct rte_memzone *mz;
+ const char *drv_name;
+ drv_name = eth_dev_get_driver_name(dev);
snprintf(z_name, sizeof(z_name), "%s_%s_%d_%d",
- dev->driver->pci_drv.driver.name, ring_name,
+ drv_name, ring_name,
dev->data->port_id, queue_id);
mz = rte_memzone_lookup(z_name);
@@ -3229,6 +3351,28 @@ rte_eth_copy_pci_info(struct rte_eth_dev *eth_dev, struct rte_pci_device *pci_de
eth_dev->data->drv_name = pci_dev->driver->driver.name;
}
+void
+rte_eth_copy_soc_info(struct rte_eth_dev *eth_dev,
+ struct rte_soc_device *soc_dev)
+{
+ if ((eth_dev == NULL) || (soc_dev == NULL)) {
+ RTE_PMD_DEBUG_TRACE("NULL pointer eth_dev=%p soc_dev=%p\n",
+ eth_dev, soc_dev);
+ return;
+ }
+
+ RTE_ASSERT(eth_dev->soc_dev != NULL);
+
+ eth_dev->data->dev_flags = 0;
+ if (soc_dev->driver->drv_flags & RTE_SOC_DRV_INTR_LSC)
+ eth_dev->data->dev_flags |= RTE_ETH_DEV_INTR_LSC;
+ if (soc_dev->driver->drv_flags & RTE_SOC_DRV_DETACHABLE)
+ eth_dev->data->dev_flags |= RTE_ETH_DEV_DETACHABLE;
+
+ eth_dev->data->numa_node = soc_dev->device.numa_node;
+ eth_dev->data->drv_name = soc_dev->driver->driver.name;
+}
+
int
rte_eth_dev_l2_tunnel_eth_type_conf(uint8_t port_id,
struct rte_eth_l2_tunnel_conf *l2_tunnel)
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index f893fe0..ff7958f 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -180,6 +180,7 @@ extern "C" {
#include <rte_log.h>
#include <rte_interrupts.h>
#include <rte_pci.h>
+#include <rte_soc.h>
#include <rte_dev.h>
#include <rte_devargs.h>
#include "rte_ether.h"
@@ -877,6 +878,7 @@ struct rte_eth_conf {
*/
struct rte_eth_dev_info {
struct rte_pci_device *pci_dev; /**< Device PCI information. */
+ struct rte_soc_device *soc_dev; /**< Device SoC information. */
const char *driver_name; /**< Device Driver name. */
unsigned int if_index; /**< Index to bound host interface, or 0 if none.
Use if_indextoname() to translate into an interface name. */
@@ -1626,6 +1628,7 @@ struct rte_eth_dev {
const struct eth_driver *driver;/**< Driver for this device */
const struct eth_dev_ops *dev_ops; /**< Functions exported by PMD */
struct rte_pci_device *pci_dev; /**< PCI info. supplied by probing */
+ struct rte_soc_device *soc_dev; /**< SoC info. supplied by probing */
/** User application callbacks for NIC interrupts */
struct rte_eth_dev_cb_list link_intr_cbs;
/**
@@ -1860,6 +1863,7 @@ typedef int (*eth_dev_uninit_t)(struct rte_eth_dev *eth_dev);
*/
struct eth_driver {
struct rte_pci_driver pci_drv; /**< The PMD is also a PCI driver. */
+ struct rte_soc_driver soc_drv; /**< The PMD is also a SoC driver. */
eth_dev_init_t eth_dev_init; /**< Device init function. */
eth_dev_uninit_t eth_dev_uninit; /**< Device uninit function. */
unsigned int dev_private_size; /**< Size of device private data. */
@@ -4262,6 +4266,20 @@ void rte_eth_copy_pci_info(struct rte_eth_dev *eth_dev,
struct rte_pci_device *pci_dev);
/**
+ * Copy SoC device info to the Ethernet device data.
+ *
+ * @param eth_dev
+ * The *eth_dev* pointer is the address of the *rte_eth_dev* structure.
+ * @param soc_dev
+ * The *soc_dev* pointer is the address of the *rte_soc_device* structure.
+ *
+ * @return
+ * - 0 on success, negative on error
+ */
+void rte_eth_copy_soc_info(struct rte_eth_dev *eth_dev,
+ struct rte_soc_device *soc_dev);
+
+/**
* Create memzone for HW rings.
* malloc can't be used as the physical address is needed.
* If the memzone is already created, then this function returns a ptr
@@ -4376,6 +4394,19 @@ int rte_eth_dev_pci_probe(struct rte_pci_driver *pci_drv,
*/
int rte_eth_dev_pci_remove(struct rte_pci_device *pci_dev);
+/**
+ * Wrapper for use by SoC drivers as a .devinit function to attach to a ethdev
+ * interface.
+ */
+int rte_eth_dev_soc_probe(struct rte_soc_driver *soc_drv,
+ struct rte_soc_device *soc_dev);
+
+/**
+ * Wrapper for use by SoC drivers as a .devuninit function to detach a ethdev
+ * interface.
+ */
+int rte_eth_dev_soc_remove(struct rte_soc_device *soc_dev);
+
#ifdef __cplusplus
}
#endif
--
2.7.4
^ permalink raw reply related
* [PATCH v7 21/21] eal/crypto: Support rte_soc_driver/device for cryptodev
From: Shreyansh Jain @ 2016-10-28 12:26 UTC (permalink / raw)
To: dev; +Cc: Shreyansh Jain, thomas.monjalon, viktorin
In-Reply-To: <1477657598-826-1-git-send-email-shreyansh.jain@nxp.com>
- rte_cryptodev_driver/rte_cryptodev_dev embeds rte_soc_driver/device for
linking SoC PMDs to crypto devices.
- Add probe and remove functions linked
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
Signed-off-by: Shreyansh Jain <shreyansh.jain@nxp.com>
---
lib/librte_cryptodev/rte_cryptodev.c | 122 ++++++++++++++++++++++++-
lib/librte_cryptodev/rte_cryptodev.h | 3 +
lib/librte_cryptodev/rte_cryptodev_pmd.h | 18 +++-
lib/librte_cryptodev/rte_cryptodev_version.map | 2 +
4 files changed, 140 insertions(+), 5 deletions(-)
diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index 127e8d0..77ec9fe 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -422,7 +422,8 @@ rte_cryptodev_pci_probe(struct rte_pci_driver *pci_drv,
int retval;
- cryptodrv = (struct rte_cryptodev_driver *)pci_drv;
+ cryptodrv = container_of(pci_drv, struct rte_cryptodev_driver,
+ pci_drv);
if (cryptodrv == NULL)
return -ENODEV;
@@ -489,7 +490,8 @@ rte_cryptodev_pci_remove(struct rte_pci_device *pci_dev)
if (cryptodev == NULL)
return -ENODEV;
- cryptodrv = (const struct rte_cryptodev_driver *)pci_dev->driver;
+ cryptodrv = container_of(pci_dev->driver, struct rte_cryptodev_driver,
+ pci_drv);
if (cryptodrv == NULL)
return -ENODEV;
@@ -513,6 +515,111 @@ rte_cryptodev_pci_remove(struct rte_pci_device *pci_dev)
return 0;
}
+
+int
+rte_cryptodev_soc_probe(struct rte_soc_driver *soc_drv,
+ struct rte_soc_device *soc_dev)
+{
+ struct rte_cryptodev_driver *cryptodrv;
+ struct rte_cryptodev *cryptodev;
+
+ char cryptodev_name[RTE_CRYPTODEV_NAME_MAX_LEN];
+
+ int retval;
+
+ cryptodrv = container_of(soc_drv, struct rte_cryptodev_driver,
+ soc_drv);
+
+ rte_eal_soc_device_name(&soc_dev->addr, cryptodev_name,
+ sizeof(cryptodev_name));
+
+ cryptodev = rte_cryptodev_pmd_allocate(cryptodev_name,
+ rte_socket_id());
+ if (cryptodev == NULL)
+ return -ENOMEM;
+
+
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
+ cryptodev->data->dev_private =
+ rte_zmalloc_socket(
+ "cryptodev private structure",
+ cryptodrv->dev_private_size,
+ RTE_CACHE_LINE_SIZE,
+ rte_socket_id());
+
+ if (cryptodev->data->dev_private == NULL)
+ rte_panic("Cannot allocate memzone for private "
+ "device data");
+ }
+
+ cryptodev->soc_dev = soc_dev;
+ cryptodev->driver = cryptodrv;
+
+ /* init user callbacks */
+ TAILQ_INIT(&(cryptodev->link_intr_cbs));
+
+ /* Invoke PMD device initialization function */
+ retval = (*cryptodrv->cryptodev_init)(cryptodrv, cryptodev);
+ if (retval == 0)
+ return 0;
+
+ CDEV_LOG_ERR("driver %s: cryptodev_init(%s) failed\n",
+ soc_drv->driver.name,
+ soc_dev->addr.name);
+
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+ rte_free(cryptodev->data->dev_private);
+
+ cryptodev->attached = RTE_CRYPTODEV_DETACHED;
+ cryptodev_globals.nb_devs--;
+
+ return -ENXIO;
+}
+
+int
+rte_cryptodev_soc_remove(struct rte_soc_device *soc_dev)
+{
+ const struct rte_cryptodev_driver *cryptodrv;
+ struct rte_cryptodev *cryptodev;
+ char cryptodev_name[RTE_CRYPTODEV_NAME_MAX_LEN];
+ int ret;
+
+ if (soc_dev == NULL)
+ return -EINVAL;
+
+ rte_eal_soc_device_name(&soc_dev->addr, cryptodev_name,
+ sizeof(cryptodev_name));
+
+ cryptodev = rte_cryptodev_pmd_get_named_dev(cryptodev_name);
+ if (cryptodev == NULL)
+ return -ENODEV;
+
+ cryptodrv = container_of(soc_dev->driver,
+ struct rte_cryptodev_driver, soc_drv);
+ if (cryptodrv == NULL)
+ return -ENODEV;
+
+ /* Invoke PMD device uninit function */
+ if (*cryptodrv->cryptodev_uninit) {
+ ret = (*cryptodrv->cryptodev_uninit)(cryptodrv, cryptodev);
+ if (ret)
+ return ret;
+ }
+
+ /* free crypto device */
+ rte_cryptodev_pmd_release_device(cryptodev);
+
+ if (rte_eal_process_type() == RTE_PROC_PRIMARY)
+ rte_free(cryptodev->data->dev_private);
+
+ cryptodev->pci_dev = NULL;
+ cryptodev->soc_dev = NULL;
+ cryptodev->driver = NULL;
+ cryptodev->data = NULL;
+
+ return 0;
+}
+
uint16_t
rte_cryptodev_queue_pair_count(uint8_t dev_id)
{
@@ -868,8 +975,15 @@ rte_cryptodev_info_get(uint8_t dev_id, struct rte_cryptodev_info *dev_info)
(*dev->dev_ops->dev_infos_get)(dev, dev_info);
dev_info->pci_dev = dev->pci_dev;
- if (dev->driver)
- dev_info->driver_name = dev->driver->pci_drv.driver.name;
+ dev_info->soc_dev = dev->soc_dev;
+ if (dev->driver) {
+ if (dev->soc_dev)
+ dev_info->driver_name
+ = dev->driver->soc_drv.driver.name;
+ else
+ dev_info->driver_name
+ = dev->driver->pci_drv.driver.name;
+ }
}
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index 8f63e8f..85ce5cb 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -244,6 +244,7 @@ struct rte_cryptodev_info {
const char *driver_name; /**< Driver name. */
enum rte_cryptodev_type dev_type; /**< Device type */
struct rte_pci_device *pci_dev; /**< PCI information. */
+ struct rte_soc_device *soc_dev; /**< SoC information. */
uint64_t feature_flags; /**< Feature flags */
@@ -623,6 +624,8 @@ struct rte_cryptodev {
/**< Supported features */
struct rte_pci_device *pci_dev;
/**< PCI info. supplied by probing */
+ struct rte_soc_device *soc_dev;
+ /**< SoC info. supplied by probing/Scanning */
enum rte_cryptodev_type dev_type;
/**< Crypto device type */
diff --git a/lib/librte_cryptodev/rte_cryptodev_pmd.h b/lib/librte_cryptodev/rte_cryptodev_pmd.h
index abfe2dc..a8af2ce 100644
--- a/lib/librte_cryptodev/rte_cryptodev_pmd.h
+++ b/lib/librte_cryptodev/rte_cryptodev_pmd.h
@@ -48,6 +48,7 @@ extern "C" {
#include <rte_dev.h>
#include <rte_pci.h>
+#include <rte_soc.h>
#include <rte_malloc.h>
#include <rte_mbuf.h>
#include <rte_mempool.h>
@@ -131,7 +132,8 @@ typedef int (*cryptodev_uninit_t)(const struct rte_cryptodev_driver *drv,
* - The size of the private data to allocate for each matching device.
*/
struct rte_cryptodev_driver {
- struct rte_pci_driver pci_drv; /**< The PMD is also a PCI driver. */
+ struct rte_pci_driver pci_drv; /**< The PMD is PCI type driver. */
+ struct rte_soc_driver soc_drv; /**< The PMD is SoC type driver. */
unsigned dev_private_size; /**< Size of device private data. */
cryptodev_init_t cryptodev_init; /**< Device init function. */
@@ -519,6 +521,20 @@ int rte_cryptodev_pci_probe(struct rte_pci_driver *pci_drv,
*/
int rte_cryptodev_pci_remove(struct rte_pci_device *pci_dev);
+/**
+ * Wrapper for use by SoC drivers as a .devinit function to attach to a
+ * cryptodev interface.
+ */
+int rte_cryptodev_soc_probe(struct rte_soc_driver *soc_drv,
+ struct rte_soc_device *soc_dev);
+
+/**
+ * Wrapper for use by SoC drivers as a .devuninit function to detach a
+ * cryptodev interface.
+ */
+int rte_cryptodev_soc_remove(struct rte_soc_device *soc_dev);
+
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map b/lib/librte_cryptodev/rte_cryptodev_version.map
index 9dde0e7..d81073e 100644
--- a/lib/librte_cryptodev/rte_cryptodev_version.map
+++ b/lib/librte_cryptodev/rte_cryptodev_version.map
@@ -44,5 +44,7 @@ DPDK_16.11 {
rte_cryptodev_pci_probe;
rte_cryptodev_pci_remove;
+ rte_cryptodev_soc_probe;
+ rte_cryptodev_soc_remove;
} DPDK_16.07;
--
2.7.4
^ permalink raw reply related
* Re: Solarflare PMD submission question
From: Thomas Monjalon @ 2016-10-28 12:33 UTC (permalink / raw)
To: Andrew Rybchenko; +Cc: dev
In-Reply-To: <2de43e28-37f8-86f5-b45f-2e598137b3dc@solarflare.com>
2016-10-28 13:50, Andrew Rybchenko:
> First of all I'd like to double check that it is clear that we discuss
> libefx
> (base driver in terms of DPDK) import here. The PMD itself is already split
> in 20+ patches.
I don't know libefx. In DPDK, a base driver is often a subdirectory
inside the PMD. Will it be the case?
> The only thing which comes to my mind is to split libefx import on subsystem
> basis (few files per subsystem). It is artificial and added files will
> be abandoned
> until the patch which adds them into build. It could be something like:
> 1. External interfaces definition
> 2. Internal interfaces definition
> 3. Registers definition (hardware interface)
> 4. Management CPU interface definition (it is one file, but still big
> 650K)
> 5. Management CPU interface implementation
> and so on for NIC global controls, interrupts, event queue, transmit,
> receive,
> filtering etc.
Yes it is artificial.
The most valuable would be a transversal logical split, kind of feature
per feature, in order to explain how the device works.
Such commit is also the opportunity to explain acronyms and so on.
> > It would be also really appreciated to provide a design documentation
> > in doc/guides/nics. Are the datasheets open? A link in the doc would help.
>
> We have a documentation which grows together with supported features,
> but it is rather for users. Important design decisions (not so many) are
> documented nearby corresponding code. Unfortunately there is no open
> datasheets. Management CPU interface definition has comments.
Without neither a datasheet, nor a comprehensive code introduction, it is
almost impossible to dive in your code. So it misses the point about bringing
it to an Open Source project.
Please do the the effort to bring some knowledge to the community.
Thanks
^ permalink raw reply
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