|
|
343f6f |
From 3a80bc50c949760f7159b59ba30a70f95c223448 Mon Sep 17 00:00:00 2001
|
|
|
343f6f |
From: Alejandro Lucero <alejandro.lucero@netronome.com>
|
|
|
343f6f |
Date: Tue, 10 Jul 2018 18:25:48 +0100
|
|
|
343f6f |
Subject: [1/5] mem: add function for checking memsegs IOVAs addresses
|
|
|
343f6f |
|
|
|
343f6f |
A device can suffer addressing limitations. This functions checks
|
|
|
343f6f |
memsegs have iovas within the supported range based on dma mask.
|
|
|
343f6f |
|
|
|
343f6f |
PMD should use this during initialization if supported devices
|
|
|
343f6f |
suffer addressing limitations, returning an error if this function
|
|
|
343f6f |
returns memsegs out of range.
|
|
|
343f6f |
|
|
|
343f6f |
Another potential usage is for emulated IOMMU hardware with addressing
|
|
|
343f6f |
limitations.
|
|
|
343f6f |
|
|
|
343f6f |
Applicable to v17.11.3 only.
|
|
|
343f6f |
|
|
|
343f6f |
Signed-off-by: Alejandro Lucero <alejandro.lucero@netronome.com>
|
|
|
343f6f |
Acked-by: Anatoly Burakov <anatoly.burakov@intel.com>
|
|
|
343f6f |
Acked-by: Eelco Chaudron <echaudro@redhat.com>
|
|
|
343f6f |
---
|
|
|
343f6f |
lib/librte_eal/common/eal_common_memory.c | 48 ++++++++++++++++++++++++++++++
|
|
|
343f6f |
lib/librte_eal/common/include/rte_memory.h | 3 ++
|
|
|
343f6f |
lib/librte_eal/rte_eal_version.map | 1 +
|
|
|
343f6f |
3 files changed, 52 insertions(+)
|
|
|
343f6f |
|
|
|
343f6f |
diff --git a/lib/librte_eal/common/eal_common_memory.c b/lib/librte_eal/common/eal_common_memory.c
|
|
|
343f6f |
index fc6c44d..00ab393 100644
|
|
|
343f6f |
--- a/lib/librte_eal/common/eal_common_memory.c
|
|
|
343f6f |
+++ b/lib/librte_eal/common/eal_common_memory.c
|
|
|
343f6f |
@@ -109,6 +109,54 @@ rte_dump_physmem_layout(FILE *f)
|
|
|
343f6f |
}
|
|
|
343f6f |
}
|
|
|
343f6f |
|
|
|
343f6f |
+#if defined(RTE_ARCH_X86)
|
|
|
343f6f |
+#define X86_VA_WIDTH 47 /* From Documentation/x86/x86_64/mm.txt */
|
|
|
343f6f |
+#define MAX_DMA_MASK_BITS X86_VA_WIDTH
|
|
|
343f6f |
+#else
|
|
|
343f6f |
+/* 63 bits is good enough for a sanity check */
|
|
|
343f6f |
+#define MAX_DMA_MASK_BITS 63
|
|
|
343f6f |
+#endif
|
|
|
343f6f |
+
|
|
|
343f6f |
+/* check memseg iovas are within the required range based on dma mask */
|
|
|
343f6f |
+int
|
|
|
343f6f |
+rte_eal_check_dma_mask(uint8_t maskbits)
|
|
|
343f6f |
+{
|
|
|
343f6f |
+
|
|
|
343f6f |
+ const struct rte_mem_config *mcfg;
|
|
|
343f6f |
+ uint64_t mask;
|
|
|
343f6f |
+ int i;
|
|
|
343f6f |
+
|
|
|
343f6f |
+ /* sanity check */
|
|
|
343f6f |
+ if (maskbits > MAX_DMA_MASK_BITS) {
|
|
|
343f6f |
+ RTE_LOG(INFO, EAL, "wrong dma mask size %u (Max: %u)\n",
|
|
|
343f6f |
+ maskbits, MAX_DMA_MASK_BITS);
|
|
|
343f6f |
+ return -1;
|
|
|
343f6f |
+ }
|
|
|
343f6f |
+
|
|
|
343f6f |
+ /* create dma mask */
|
|
|
343f6f |
+ mask = ~((1ULL << maskbits) - 1);
|
|
|
343f6f |
+
|
|
|
343f6f |
+ /* get pointer to global configuration */
|
|
|
343f6f |
+ mcfg = rte_eal_get_configuration()->mem_config;
|
|
|
343f6f |
+
|
|
|
343f6f |
+ for (i = 0; i < RTE_MAX_MEMSEG; i++) {
|
|
|
343f6f |
+ if (mcfg->memseg[i].addr == NULL)
|
|
|
343f6f |
+ break;
|
|
|
343f6f |
+
|
|
|
343f6f |
+ if (mcfg->memseg[i].iova & mask) {
|
|
|
343f6f |
+ RTE_LOG(INFO, EAL,
|
|
|
343f6f |
+ "memseg[%d] iova %"PRIx64" out of range:\n",
|
|
|
343f6f |
+ i, mcfg->memseg[i].iova);
|
|
|
343f6f |
+
|
|
|
343f6f |
+ RTE_LOG(INFO, EAL, "\tusing dma mask %"PRIx64"\n",
|
|
|
343f6f |
+ mask);
|
|
|
343f6f |
+ return -1;
|
|
|
343f6f |
+ }
|
|
|
343f6f |
+ }
|
|
|
343f6f |
+
|
|
|
343f6f |
+ return 0;
|
|
|
343f6f |
+}
|
|
|
343f6f |
+
|
|
|
343f6f |
/* return the number of memory channels */
|
|
|
343f6f |
unsigned rte_memory_get_nchannel(void)
|
|
|
343f6f |
{
|
|
|
343f6f |
diff --git a/lib/librte_eal/common/include/rte_memory.h b/lib/librte_eal/common/include/rte_memory.h
|
|
|
343f6f |
index 80a8fc0..b2a0168 100644
|
|
|
343f6f |
--- a/lib/librte_eal/common/include/rte_memory.h
|
|
|
343f6f |
+++ b/lib/librte_eal/common/include/rte_memory.h
|
|
|
343f6f |
@@ -209,6 +209,9 @@ unsigned rte_memory_get_nchannel(void);
|
|
|
343f6f |
*/
|
|
|
343f6f |
unsigned rte_memory_get_nrank(void);
|
|
|
343f6f |
|
|
|
343f6f |
+/* check memsegs iovas are within a range based on dma mask */
|
|
|
343f6f |
+int rte_eal_check_dma_mask(uint8_t maskbits);
|
|
|
343f6f |
+
|
|
|
343f6f |
/**
|
|
|
343f6f |
* Drivers based on uio will not load unless physical
|
|
|
343f6f |
* addresses are obtainable. It is only possible to get
|
|
|
343f6f |
diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
|
|
|
343f6f |
index f4f46c1..aa6cf87 100644
|
|
|
343f6f |
--- a/lib/librte_eal/rte_eal_version.map
|
|
|
343f6f |
+++ b/lib/librte_eal/rte_eal_version.map
|
|
|
343f6f |
@@ -184,6 +184,7 @@ DPDK_17.11 {
|
|
|
343f6f |
|
|
|
343f6f |
rte_eal_create_uio_dev;
|
|
|
343f6f |
rte_bus_get_iommu_class;
|
|
|
343f6f |
+ rte_eal_check_dma_mask;
|
|
|
343f6f |
rte_eal_has_pci;
|
|
|
343f6f |
rte_eal_iova_mode;
|
|
|
343f6f |
rte_eal_mbuf_default_mempool_ops;
|
|
|
343f6f |
--
|
|
|
343f6f |
1.8.3.1
|
|
|
343f6f |
|