From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from EUR02-AM5-obe.outbound.protection.outlook.com (mail-eopbgr00052.outbound.protection.outlook.com [40.107.0.52]) by dpdk.org (Postfix) with ESMTP id C9B5E5F16 for ; Wed, 13 Feb 2019 20:07:12 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Mellanox.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=Nm4o78Xja47QiNrwiDit8XtkR6LEBkfEs+LPNqow6XQ=; b=nmfPfFuFbVMVcZDfXnvxs14ygVFKpjyO/zwAs47OnqlAgOdw+xN7Yxands/PCe/wei6Y/ds3CQuSlUZ/pAOzNRdR9y7PIID+kZBdoOcfLGe3UEs7ek6CaX4BgkPBo6tZ9SOOER0MDE2AKyGChpXPQhCh4eyeKS3Ti5hgrByjbd0= Received: from AM0PR0502MB3795.eurprd05.prod.outlook.com (52.133.47.29) by AM0PR0502MB3794.eurprd05.prod.outlook.com (52.133.48.157) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1622.16; Wed, 13 Feb 2019 19:07:11 +0000 Received: from AM0PR0502MB3795.eurprd05.prod.outlook.com ([fe80::386e:f86:50bf:31be]) by AM0PR0502MB3795.eurprd05.prod.outlook.com ([fe80::386e:f86:50bf:31be%5]) with mapi id 15.20.1622.016; Wed, 13 Feb 2019 19:07:11 +0000 From: Shahaf Shuler To: =?iso-8859-1?Q?Ga=EBtan_Rivet?= CC: "anatoly.burakov@intel.com" , Yongseok Koh , Thomas Monjalon , "ferruh.yigit@intel.com" , "nhorman@tuxdriver.com" , "dev@dpdk.org" Thread-Topic: [PATCH 3/6] bus: introduce DMA memory mapping for external memory Thread-Index: AQHUw42zZufhWV3+PkCK3R9dCCgPAKXd2cBw Date: Wed, 13 Feb 2019 19:07:11 +0000 Message-ID: References: <323319abdbdc238c3586dafe9ad49dab554d6e64.1550048188.git.shahafs@mellanox.com> <20190213111702.wj3cqg6skttqduc4@bidouze.vm.6wind.com> In-Reply-To: <20190213111702.wj3cqg6skttqduc4@bidouze.vm.6wind.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: spf=none (sender IP is ) smtp.mailfrom=shahafs@mellanox.com; x-originating-ip: [31.154.10.105] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: b2016c6b-7a87-4575-b9fd-08d691e67526 x-ms-office365-filtering-ht: Tenant x-microsoft-antispam: BCL:0; PCL:0; RULEID:(2390118)(7020095)(4652040)(8989299)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(5600110)(711020)(4605077)(4618075)(2017052603328)(7153060)(7193020); SRVR:AM0PR0502MB3794; x-ms-traffictypediagnostic: AM0PR0502MB3794: x-ld-processed: a652971c-7d2e-4d9b-a6a4-d149256f461b,ExtAddr x-microsoft-exchange-diagnostics: =?iso-8859-1?Q?1; AM0PR0502MB3794; 23:JuNuTI/2vQ2U+TaOcDtaWFii8mqzZbE2rKSLU?= =?iso-8859-1?Q?/NKXpNgOlDNRXycI7euLC3zQJJn35iBHkET4rAu8HZPIpKyXV2vJvjqilN?= =?iso-8859-1?Q?JK20d2ynkxZQ3A8K57na1VMxZrMwy/lf5ptMd8LHAqx8/60KszBHXtxhjw?= =?iso-8859-1?Q?Ho12zBfw0HDpARkYwPzTCM8EIcX00SXEwWieFY4nviKy4RH+Hv81Hk8NER?= =?iso-8859-1?Q?VCFR6w6J7sdD1wZc3FZfthrp9ksw5GHpF6YET99acaGoYwpxWT9sIgThyv?= =?iso-8859-1?Q?60K+evCbnOJhR88TMuKjrbjT7SqiSv1jnjGiFtHpM46kIhuA/4PYBVOAUk?= =?iso-8859-1?Q?lPeylTSZ1zBSDjQz41l33UySuWRVJZDoLLdaYQPZwO1DmYmpdOVNUtA4kF?= =?iso-8859-1?Q?zFgDdDs5AAUIpqztNWSGPPiTUQF4UhsxR3u99Q/2JBy3NYtmiV30lv+B5c?= =?iso-8859-1?Q?J+KJnmuJ/LxGkWRs3zba5DpBo+eXGgDbrJ2ZBD4P0kG3O1jK9XAw7kgJC5?= =?iso-8859-1?Q?jC8GsyuVEgkzUc86tfi89IO8vRY/89vsY85kZ0R6GZH7MJ55ZuUpzN0G0S?= =?iso-8859-1?Q?hSDx0R4DIajjFfmShRnMr1e/+g19Xija/k/FXzVbl2cjcs+gcGeWb/jR91?= =?iso-8859-1?Q?Og47Oi64sfkXfvhE32pOHlmbmPLSEHl4UyuEtlTBJc9GWrj/peZQhp28nD?= =?iso-8859-1?Q?WkqC3Gi/uIPnN49kZRBQa3Q+YULssJbLgXFywq1j11Q1bMnnXKvrsBOKuu?= =?iso-8859-1?Q?1qdQ4B9E/C9myslhYBJR/zmp08ttaI2lhlThrZWU3RzSVZAPzHfQYj/nhm?= =?iso-8859-1?Q?xDkr8Rw6Fts5n6kJtAMF9rdD4yCI46tVFNm9VULqfgAOgXTgJNZq63fPNn?= =?iso-8859-1?Q?jLw/lc7Dd67wCD3ut7H3vfzBMMqZTvtBMudyKSfxInmy8N/NTa/e2sCT3E?= =?iso-8859-1?Q?7T0qYKLFpUAORRkgA9LYsyjXFfM9QUwVyL+M8nFVnnDiuPXRD+eCspRcTI?= =?iso-8859-1?Q?EL7qmkUmnVzdcJf2mkWO2ruma2UYfi/kq8Gt96yppYb60fvN2CE4bvTDiv?= =?iso-8859-1?Q?pp9thDMkbrEuL3xp16ifySBtLXNt5/MHuu1XUHpzEvBQFJGmCNkFMJu0Gb?= =?iso-8859-1?Q?rbRNqo1QItI936UUItaSuyPc0aPu6OxmXztr9LHyu+3TKTOdnEPWoQyWSr?= =?iso-8859-1?Q?OAJAx9EI9XwIjZqpf6n2u62DFHklZwQD1MPQnGdCCcOf6p3EXudHakDnA+?= =?iso-8859-1?Q?nWo0vizNC5eHYqRCODYcu7VGNIAghcBNZhRP6STkw=3D=3D?= x-microsoft-antispam-prvs: x-forefront-prvs: 094700CA91 x-forefront-antispam-report: SFV:NSPM; SFS:(10009020)(39860400002)(136003)(376002)(366004)(396003)(346002)(199004)(189003)(11346002)(6116002)(446003)(3846002)(81166006)(316002)(30864003)(54906003)(186003)(66574012)(7736002)(8936002)(8676002)(305945005)(81156014)(6246003)(74316002)(71200400001)(71190400001)(68736007)(486006)(476003)(7696005)(99286004)(6506007)(76176011)(66066001)(33656002)(9686003)(55016002)(102836004)(478600001)(14454004)(86362001)(4326008)(97736004)(106356001)(229853002)(105586002)(2906002)(26005)(53936002)(6916009)(256004)(14444005)(25786009)(6436002); DIR:OUT; SFP:1101; SCL:1; SRVR:AM0PR0502MB3794; H:AM0PR0502MB3795.eurprd05.prod.outlook.com; FPR:; SPF:None; LANG:en; PTR:InfoNoRecords; A:1; MX:1; received-spf: None (protection.outlook.com: mellanox.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 x-microsoft-antispam-message-info: oBq/cLnl0jW2Mw66xMknPXEtvS/STFgFnYsvp4NqqT9OklnG9TNDJrFEchooNwsZkORY8U5fcQMbkiDlGuwNAkbMWiqAKjeZamC34ZfJaUnIN3mLnPTr6divQgu7PGkC1RxKEeKxNMWgXUJygfwdkcu5WYlr5O+lpxdI4R7RxHXo6AEW4c/qHFaczD49ThYpK6hoqRB26xZYluTPuLP6y+brlesh4b+oEccrlO3QRWq2f3PBqgQP8NeFpLJQXMsOcJO7gx+5nOsuAvuxWR2kAYP6ckj4TjuYRgFXeSVd/WTVnd8SnVV9b9/OQcyc8i9pObDo7+pGKxFoyBFiJOZscwRl9/PeMPc5OG2/r90FtX7VDvrwhxW1xYMN9THisF1m0HWNB/jWpBqxJaGSAndUpl2Qzd7z/C+Aj6e96e1o7zE= Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-OriginatorOrg: Mellanox.com X-MS-Exchange-CrossTenant-Network-Message-Id: b2016c6b-7a87-4575-b9fd-08d691e67526 X-MS-Exchange-CrossTenant-originalarrivaltime: 13 Feb 2019 19:07:11.1770 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: a652971c-7d2e-4d9b-a6a4-d149256f461b X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM0PR0502MB3794 Subject: Re: [dpdk-dev] [PATCH 3/6] bus: introduce DMA memory mapping for external memory X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 13 Feb 2019 19:07:13 -0000 Wednesday, February 13, 2019 1:17 PM, Ga=EBtan Rivet: > Subject: Re: [PATCH 3/6] bus: introduce DMA memory mapping for external > memory >=20 > On Wed, Feb 13, 2019 at 11:10:23AM +0200, Shahaf Shuler wrote: > > The DPDK APIs expose 3 different modes to work with memory used for > DMA: > > > > 1. Use the DPDK owned memory (backed by the DPDK provided > hugepages). > > This memory is allocated by the DPDK libraries, included in the DPDK > > memory system (memseg lists) and automatically DMA mapped by the > DPDK > > layers. > > > > 2. Use memory allocated by the user and register to the DPDK memory > > systems. This is also referred as external memory. Upon registration > > of the external memory, the DPDK layers will DMA map it to all needed > > devices. > > > > 3. Use memory allocated by the user and not registered to the DPDK > > memory system. This is for users who wants to have tight control on > > this memory. The user will need to explicitly call DMA map function in > > order to register such memory to the different devices. > > > > The scope of the patch focus on #3 above. > > > > Currently the only way to map external memory is through VFIO > > (rte_vfio_dma_map). While VFIO is common, there are other vendors > > which use different ways to map memory (e.g. Mellanox and NXP). > > >=20 > How are those other vendors' devices mapped initially right now? Are they > using #2 scheme instead? Then the user will remap everything using #3? It is not a re-map, it is a completely different mode for the memory manage= ment.=20 The first question to ask is "how the application wants to manage its memor= y" ? If it is either #1 or #2 above, no problem to make the mapping internal on = the "other vendor devices" as they can register to the memory event callbac= k which trigger every time new memory is added to the DPDK memory managemen= t system.=20 For #3 the memory does not exists in the DPDK memory management system, and= no memory events. Hence the application needs to explicitly call the dma M= AP.=20 The change on this patch is just to make it more generic than calling only = VFIO.=20 >=20 > Would it be interesting to be able to describe a mapping prior to probing= a > device and refer to it upon hotplug? Not sure it is an interesting use case. I don't see the need to setup the a= pplication memory before the probing of the devices.=20 Regarding hotplug - this is a feature we can add on top of this series (for= example if device was removed and hotplug back). This will require to stor= e the mapping on some database, like VFIO does.=20 >=20 > > The work in this patch moves the DMA mapping to vendor agnostic APIs. > > A new map and unmap ops were added to rte_bus structure. > > Implementation of those was done currently only on the PCI bus. The > > implementation takes the driver map and umap implementation as bypass > to the VFIO mapping. > > That is, in case of no specific map/unmap from the PCI driver, VFIO > > mapping, if possible, will be used. >=20 > This paragraph should be rewritten to better fit a commit log. >=20 > > > > Application use with those APIs is quite simple: > > * allocate memory > > * take a device, and query its rte_device. > > * call the bus map function for this device. >=20 > Is the device already configured with the existing mappings? Should the > application stop it before attempting to map its allocated memory? Am not following. When the application wants to register new memory for DMA for this device i= t calls map. When it wants to unregister it calls unmap. w/o explicit call = to the map function the memory cannot be used for DMA. >=20 > > > > Future work will deprecate the rte_vfio_dma_map and > rte_vfio_dma_unmap > > APIs, leaving the PCI device APIs as the preferred option for the user. > > > > Signed-off-by: Shahaf Shuler > > --- > > drivers/bus/pci/pci_common.c | 78 > ++++++++++++++++++++++++++++ > > drivers/bus/pci/rte_bus_pci.h | 14 +++++ > > lib/librte_eal/common/eal_common_bus.c | 22 ++++++++ > > lib/librte_eal/common/include/rte_bus.h | 57 ++++++++++++++++++++ > > lib/librte_eal/rte_eal_version.map | 2 + > > 5 files changed, 173 insertions(+) > > > > diff --git a/drivers/bus/pci/pci_common.c > > b/drivers/bus/pci/pci_common.c index 6276e5d695..018080c48b 100644 > > --- a/drivers/bus/pci/pci_common.c > > +++ b/drivers/bus/pci/pci_common.c > > @@ -528,6 +528,82 @@ pci_unplug(struct rte_device *dev) > > return ret; > > } > > > > +/** > > + * DMA Map memory segment to device. After a successful call the > > +device > > + * will be able to read/write from/to this segment. > > + * > > + * @param dev > > + * Pointer to the PCI device. > > + * @param addr > > + * Starting virtual address of memory to be mapped. > > + * @param iova > > + * Starting IOVA address of memory to be mapped. > > + * @param len > > + * Length of memory segment being mapped. > > + * @return > > + * - 0 On success. > > + * - Negative value and rte_errno is set otherwise. > > + */ >=20 > This doc should be on the callback typedef, not their implementation. > The rte_errno error spec should also be documented higher-up in the > abstraction pile, on the bus callback I think. Everyone should follow the= same > error codes for applications to really be able to use any implementation > generically. OK.=20 >=20 > > +static int __rte_experimental >=20 > The __rte_experimental is not necessary in compilation units themselves, > only in the headers. >=20 > In any case, it would only be the publicly available API that must be mar= ked > as such, so more the callback typedefs than their implementations. OK >=20 > > +pci_dma_map(struct rte_device *dev, void *addr, uint64_t iova, size_t > > +len) { > > + struct rte_pci_device *pdev =3D RTE_DEV_TO_PCI(dev); > > + > > + if (!pdev || !pdev->driver) { >=20 > pdev cannot be null here, nor should its driver be. So you say to relay on it and drop the check? >=20 > > + rte_errno =3D EINVAL; > > + return -rte_errno; > > + } > > + if (pdev->driver->map) > > + return pdev->driver->map(pdev, addr, iova, len); > > + /** > > + * In case driver don't provides any specific mapping > > + * try fallback to VFIO. > > + */ > > + if (pdev->kdrv =3D=3D RTE_KDRV_VFIO) > > + return rte_vfio_container_dma_map(-1, (uintptr_t)addr, > iova, > > + len); >=20 > Reiterating: RTE_VFIO_DEFAULT_CONTAINER_FD is more readable I think > than > -1 here. >=20 > > + rte_errno =3D ENOTSUP; > > + return -rte_errno; > > +} > > + > > +/** > > + * Un-map memory segment to device. After a successful call the > > +device > > + * will not be able to read/write from/to this segment. > > + * > > + * @param dev > > + * Pointer to the PCI device. > > + * @param addr > > + * Starting virtual address of memory to be unmapped. > > + * @param iova > > + * Starting IOVA address of memory to be unmapped. > > + * @param len > > + * Length of memory segment being unmapped. > > + * @return > > + * - 0 On success. > > + * - Negative value and rte_errno is set otherwise. > > + */ > > +static int __rte_experimental >=20 > Same as before for __rte_experimental and doc. >=20 > > +pci_dma_unmap(struct rte_device *dev, void *addr, uint64_t iova, > > +size_t len) { > > + struct rte_pci_device *pdev =3D RTE_DEV_TO_PCI(dev); > > + > > + if (!pdev || !pdev->driver) { > > + rte_errno =3D EINVAL; > > + return -rte_errno; > > + } > > + if (pdev->driver->unmap) > > + return pdev->driver->unmap(pdev, addr, iova, len); > > + /** > > + * In case driver don't provides any specific mapping > > + * try fallback to VFIO. > > + */ > > + if (pdev->kdrv =3D=3D RTE_KDRV_VFIO) > > + return rte_vfio_container_dma_unmap(-1, (uintptr_t)addr, > iova, > > + len); > > + rte_errno =3D ENOTSUP; > > + return -rte_errno; > > +} > > + > > struct rte_pci_bus rte_pci_bus =3D { > > .bus =3D { > > .scan =3D rte_pci_scan, > > @@ -536,6 +612,8 @@ struct rte_pci_bus rte_pci_bus =3D { > > .plug =3D pci_plug, > > .unplug =3D pci_unplug, > > .parse =3D pci_parse, > > + .map =3D pci_dma_map, > > + .unmap =3D pci_dma_unmap, > > .get_iommu_class =3D rte_pci_get_iommu_class, > > .dev_iterate =3D rte_pci_dev_iterate, > > .hot_unplug_handler =3D pci_hot_unplug_handler, diff --git > > a/drivers/bus/pci/rte_bus_pci.h b/drivers/bus/pci/rte_bus_pci.h index > > f0d6d81c00..00b2d412c7 100644 > > --- a/drivers/bus/pci/rte_bus_pci.h > > +++ b/drivers/bus/pci/rte_bus_pci.h > > @@ -114,6 +114,18 @@ typedef int (pci_probe_t)(struct rte_pci_driver > > *, struct rte_pci_device *); typedef int (pci_remove_t)(struct > > rte_pci_device *); > > > > /** > > + * Driver-specific DMA mapping. > > + */ > > +typedef int (pci_dma_map_t)(struct rte_pci_device *dev, void *addr, > > + uint64_t iova, size_t len); > > + > > +/** > > + * Driver-specific DMA unmapping. > > + */ > > +typedef int (pci_dma_unmap_t)(struct rte_pci_device *dev, void *addr, > > + uint64_t iova, size_t len); > > + > > +/** > > * A structure describing a PCI driver. > > */ > > struct rte_pci_driver { > > @@ -122,6 +134,8 @@ struct rte_pci_driver { > > struct rte_pci_bus *bus; /**< PCI bus reference. */ > > pci_probe_t *probe; /**< Device Probe function. */ > > pci_remove_t *remove; /**< Device Remove function. */ > > + pci_dma_map_t *map; /**< device dma map function. */ > > + pci_dma_unmap_t *unmap; /**< device dma unmap > function. */ >=20 > I'd call both callbacks dma_map and dma_unmap. It's clearer and more > consistent. OK.=20 >=20 > > const struct rte_pci_id *id_table; /**< ID table, NULL terminated. */ > > uint32_t drv_flags; /**< Flags RTE_PCI_DRV_*. */ > > }; > > diff --git a/lib/librte_eal/common/eal_common_bus.c > > b/lib/librte_eal/common/eal_common_bus.c > > index c8f1901f0b..b7911d5ddd 100644 > > --- a/lib/librte_eal/common/eal_common_bus.c > > +++ b/lib/librte_eal/common/eal_common_bus.c > > @@ -285,3 +285,25 @@ rte_bus_sigbus_handler(const void *failure_addr) > > > > return ret; > > } > > + > > +int __rte_experimental > > +rte_bus_dma_map(struct rte_device *dev, void *addr, uint64_t iova, > > + size_t len) > > +{ > > + if (dev->bus->map =3D=3D NULL || len =3D=3D 0) { > > + rte_errno =3D EINVAL; > > + return -rte_errno; > > + } > > + return dev->bus->map(dev, addr, iova, len); } > > + > > +int __rte_experimental > > +rte_bus_dma_unmap(struct rte_device *dev, void *addr, uint64_t iova, > > + size_t len) > > +{ > > + if (dev->bus->unmap =3D=3D NULL || len =3D=3D 0) { > > + rte_errno =3D EINVAL; > > + return -rte_errno; > > + } > > + return dev->bus->unmap(dev, addr, iova, len); } >=20 > These functions should be called rte_dev_dma_{map,unmap} and be part of > eal_common_dev.c instead. Will move.=20 >=20 > > diff --git a/lib/librte_eal/common/include/rte_bus.h > > b/lib/librte_eal/common/include/rte_bus.h > > index 6be4b5cabe..90e4bf51b2 100644 > > --- a/lib/librte_eal/common/include/rte_bus.h > > +++ b/lib/librte_eal/common/include/rte_bus.h > > @@ -168,6 +168,48 @@ typedef int (*rte_bus_unplug_t)(struct rte_device > > *dev); typedef int (*rte_bus_parse_t)(const char *name, void *addr); > > > > /** > > + * Bus specific DMA map function. > > + * After a successful call, the memory segment will be mapped to the > > + * given device. > > + * > > + * @param dev > > + * Device pointer. > > + * @param addr > > + * Virtual address to map. > > + * @param iova > > + * IOVA address to map. > > + * @param len > > + * Length of the memory segment being mapped. > > + * > > + * @return > > + * 0 if mapping was successful. > > + * Negative value and rte_errno is set otherwise. > > + */ > > +typedef int (*rte_bus_map_t)(struct rte_device *dev, void *addr, > > + uint64_t iova, size_t len); > > + > > +/** > > + * Bus specific DMA unmap function. > > + * After a successful call, the memory segment will no longer be > > + * accessible by the given device. > > + * > > + * @param dev > > + * Device pointer. > > + * @param addr > > + * Virtual address to unmap. > > + * @param iova > > + * IOVA address to unmap. > > + * @param len > > + * Length of the memory segment being mapped. > > + * > > + * @return > > + * 0 if un-mapping was successful. > > + * Negative value and rte_errno is set otherwise. > > + */ > > +typedef int (*rte_bus_unmap_t)(struct rte_device *dev, void *addr, > > + uint64_t iova, size_t len); > > + > > +/** > > * Implement a specific hot-unplug handler, which is responsible for > > * handle the failure when device be hot-unplugged. When the event of > > * hot-unplug be detected, it could call this function to handle @@ > > -238,6 +280,8 @@ struct rte_bus { > > rte_bus_plug_t plug; /**< Probe single device for drivers */ > > rte_bus_unplug_t unplug; /**< Remove single device from driver > */ > > rte_bus_parse_t parse; /**< Parse a device name */ > > + rte_bus_map_t map; /**< DMA map for device in the bus */ > > + rte_bus_unmap_t unmap; /**< DMA unmap for device in the > bus */ >=20 > Same as for the driver callbacks, dma_map and dma_unmap seem a better > fit for the field names. OK >=20 > > struct rte_bus_conf conf; /**< Bus configuration */ > > rte_bus_get_iommu_class_t get_iommu_class; /**< Get iommu > class */ > > rte_dev_iterate_t dev_iterate; /**< Device iterator. */ @@ -356,6 > > +400,19 @@ struct rte_bus *rte_bus_find_by_name(const char > *busname); > > enum rte_iova_mode rte_bus_get_iommu_class(void); > > > > /** > > + * Wrapper to call the bus specific DMA map function. > > + */ > > +int __rte_experimental > > +rte_bus_dma_map(struct rte_device *dev, void *addr, uint64_t iova, > > +size_t len); > > + > > +/** > > + * Wrapper to call the bus specific DMA unmap function. > > + */ > > +int __rte_experimental > > +rte_bus_dma_unmap(struct rte_device *dev, void *addr, uint64_t iova, > > + size_t len); > > + > > +/** >=20 > Same as earlier -> these seem device-level functions, not bus-related. > You won't map those addresses to all devices on the bus. >=20 > > * Helper for Bus registration. > > * The constructor has higher priority than PMD constructors. > > */ > > diff --git a/lib/librte_eal/rte_eal_version.map > > b/lib/librte_eal/rte_eal_version.map > > index eb5f7b9cbd..23f3adb73a 100644 > > --- a/lib/librte_eal/rte_eal_version.map > > +++ b/lib/librte_eal/rte_eal_version.map > > @@ -364,4 +364,6 @@ EXPERIMENTAL { > > rte_service_may_be_active; > > rte_socket_count; > > rte_socket_id_by_idx; > > + rte_bus_dma_map; > > + rte_bus_dma_unmap; > > }; > > -- > > 2.12.0 > > >=20 > -- > Ga=EBtan Rivet > 6WIND