[dpdk-dev] [PATCH v2 2/5] EAL: Add new EAL "--qtest-virtio" option
Tetsuya Mukawa
mukawa at igel.co.jp
Wed Feb 10 04:40:10 CET 2016
To work with qtest virtio-net PMD, virtual address that maps hugepages
should be between (1 << 31) to (1 << 44). This patch adds one more option
to map like this. Also all hugepages should consists of one file.
Because of this, the option will work only when '--single-file' option is
specified.
Signed-off-by: Tetsuya Mukawa <mukawa at igel.co.jp>
---
lib/librte_eal/common/eal_common_options.c | 10 ++++
lib/librte_eal/common/eal_internal_cfg.h | 1 +
lib/librte_eal/common/eal_options.h | 2 +
lib/librte_eal/linuxapp/eal/eal_memory.c | 81 +++++++++++++++++++++++++++++-
4 files changed, 93 insertions(+), 1 deletion(-)
diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
index 65bccbd..34c8bd1 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -96,6 +96,7 @@ eal_long_options[] = {
{OPT_VMWARE_TSC_MAP, 0, NULL, OPT_VMWARE_TSC_MAP_NUM },
{OPT_XEN_DOM0, 0, NULL, OPT_XEN_DOM0_NUM },
{OPT_SINGLE_FILE, 0, NULL, OPT_SINGLE_FILE_NUM },
+ {OPT_QTEST_VIRTIO, 0, NULL, OPT_QTEST_VIRTIO_NUM },
{0, 0, NULL, 0 }
};
@@ -902,6 +903,10 @@ eal_parse_common_option(int opt, const char *optarg,
conf->single_file = 1;
break;
+ case OPT_QTEST_VIRTIO_NUM:
+ conf->qtest_virtio = 1;
+ break;
+
/* don't know what to do, leave this to caller */
default:
return 1;
@@ -971,6 +976,11 @@ eal_check_common_options(struct internal_config *internal_cfg)
"be specified together with --"OPT_SINGLE_FILE"\n");
return -1;
}
+ if (internal_cfg->qtest_virtio && !internal_cfg->single_file) {
+ RTE_LOG(ERR, EAL, "Option --"OPT_QTEST_VIRTIO" cannot "
+ "be specified without --"OPT_SINGLE_FILE"\n");
+ return -1;
+ }
if (internal_cfg->no_hugetlbfs && internal_cfg->hugepage_unlink) {
RTE_LOG(ERR, EAL, "Option --"OPT_HUGE_UNLINK" cannot "
diff --git a/lib/librte_eal/common/eal_internal_cfg.h b/lib/librte_eal/common/eal_internal_cfg.h
index 9117ed9..7f3df39 100644
--- a/lib/librte_eal/common/eal_internal_cfg.h
+++ b/lib/librte_eal/common/eal_internal_cfg.h
@@ -71,6 +71,7 @@ struct internal_config {
volatile unsigned no_hpet; /**< true to disable HPET */
volatile unsigned vmware_tsc_map; /**< true to use VMware TSC mapping
* instead of native TSC */
+ volatile unsigned qtest_virtio; /**< mmap hugepages to fit qtest virtio PMD */
volatile unsigned no_shconf; /**< true if there is no shared config */
volatile unsigned create_uio_dev; /**< true to create /dev/uioX devices */
volatile enum rte_proc_type_t process_type; /**< multi-process proc type */
diff --git a/lib/librte_eal/common/eal_options.h b/lib/librte_eal/common/eal_options.h
index e5da14a..b33a3c3 100644
--- a/lib/librte_eal/common/eal_options.h
+++ b/lib/librte_eal/common/eal_options.h
@@ -85,6 +85,8 @@ enum {
OPT_XEN_DOM0_NUM,
#define OPT_SINGLE_FILE "single-file"
OPT_SINGLE_FILE_NUM,
+#define OPT_QTEST_VIRTIO "qtest-virtio"
+ OPT_QTEST_VIRTIO_NUM,
OPT_LONG_MAX_NUM
};
diff --git a/lib/librte_eal/linuxapp/eal/eal_memory.c b/lib/librte_eal/linuxapp/eal/eal_memory.c
index a6b3616..677d6a7 100644
--- a/lib/librte_eal/linuxapp/eal/eal_memory.c
+++ b/lib/librte_eal/linuxapp/eal/eal_memory.c
@@ -1092,6 +1092,73 @@ calc_num_pages_per_socket(uint64_t * memory,
}
/*
+ * Find memory space that fits qtest virtio-net PMD.
+ */
+static void *
+rte_eal_get_free_region(uint64_t alloc_size, uint64_t pagesz)
+{
+ uint64_t start, end, next_start;
+ uint64_t high_limit, low_limit;
+ char buf[1024], *p;
+ FILE *fp;
+ void *addr = NULL;
+
+ /* all hugepages should be mapped between below values */
+ low_limit = 1UL << 31;
+ high_limit = 1UL << 44;
+
+ /* allocation size should be aligned by page size */
+ if (alloc_size != RTE_ALIGN_CEIL(alloc_size, pagesz)) {
+ rte_panic("Invalid allocation size 0x%lx\n", alloc_size);
+ return NULL;
+ }
+
+ /*
+ * address should be aligned by allocation size because
+ * BAR register requiers such an address
+ */
+ low_limit = RTE_ALIGN_CEIL(low_limit, alloc_size);
+ high_limit = RTE_ALIGN_FLOOR(high_limit, alloc_size);
+
+ fp = fopen("/proc/self/maps", "r");
+ if (fp == NULL) {
+ rte_panic("Cannot open /proc/self/maps\n");
+ return NULL;
+ }
+
+ next_start = 0;
+ do {
+ start = next_start;
+
+ if ((p = fgets(buf, sizeof(buf), fp)) != NULL) {
+ if (sscanf(p, "%lx-%lx ", &end, &next_start) < 2)
+ break;
+
+ next_start = RTE_ALIGN_CEIL(next_start, alloc_size);
+ end = RTE_ALIGN_CEIL(end, alloc_size) - 1;
+ } else
+ end = UINT64_MAX;
+
+ if (start >= high_limit)
+ break;
+ if (end < low_limit)
+ continue;
+
+ start = RTE_MAX(start, low_limit);
+ end = RTE_MIN(end, high_limit - 1);
+
+ if (end - start >= alloc_size - 1) {
+ addr = (void *)start;
+ break;
+ }
+ } while (end != UINT64_MAX);
+
+ fclose(fp);
+
+ return addr;
+}
+
+/*
* Prepare physical memory mapping: fill configuration structure with
* these infos, return 0 on success.
* 1. map N huge pages in separate files in hugetlbfs
@@ -1132,6 +1199,7 @@ rte_eal_hugepage_init(void)
uint64_t pagesize;
unsigned socket_id = rte_socket_id();
char filepath[MAX_HUGEPAGE_PATH];
+ void *fixed;
if (internal_config.no_hugetlbfs) {
eal_get_hugefile_path(filepath, sizeof(filepath),
@@ -1158,7 +1226,18 @@ rte_eal_hugepage_init(void)
return -1;
}
- addr = mmap(NULL, internal_config.memory,
+ if (internal_config.qtest_virtio) {
+ fixed = rte_eal_get_free_region(
+ internal_config.memory, pagesize);
+ if (fixed == NULL) {
+ RTE_LOG(ERR, EAL, "no free space to mmap %s\n",
+ filepath);
+ return -1;
+ }
+ } else
+ fixed = NULL;
+
+ addr = mmap(fixed, internal_config.memory,
PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_POPULATE, fd, 0);
if (addr == MAP_FAILED) {
--
2.1.4
More information about the dev
mailing list