From patchwork Wed Mar 9 08:33:20 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tetsuya Mukawa X-Patchwork-Id: 11262 X-Patchwork-Delegate: yuanhan.liu@linux.intel.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [IPv6:::1]) by dpdk.org (Postfix) with ESMTP id 30ABF3772; Wed, 9 Mar 2016 09:33:53 +0100 (CET) Received: from mail-pf0-f179.google.com (mail-pf0-f179.google.com [209.85.192.179]) by dpdk.org (Postfix) with ESMTP id C0DA3376D for ; Wed, 9 Mar 2016 09:33:51 +0100 (CET) Received: by mail-pf0-f179.google.com with SMTP id 129so34719695pfw.1 for ; Wed, 09 Mar 2016 00:33:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=igel-co-jp.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :in-reply-to:references; bh=8ze7xQwtTWTtjiyh9eoe9DCFogoZsuVOgewV5cPBu/g=; b=LEfhfEkIEZQZciQKnYAg9wYrTI1kU8LpzKtcZOYQkFzz7w3A1K68SKGEP2iCmDgaJD +caIR28RVenGinf1de5BPFsKjtK7SolWZuEUGI0UURj0SSoFAFodZGiyLonGS3FHazX4 iz6Yyd4iW2ggO9BMC1ehdhA7/rr79EAemDOMDuFQNiVDIafjNCAlaSYPfv7WDTUqT40g FpEYEOrN02L1+3e8kT9MoN7FIjRj5hibYnd4WP9UflC6E+PAkDY8HDtiEzu/GG6LfOvu h3/0O2xMVHkAwUh473Weq8Q0AqC6FQQKo22ykqS3yjzeJ2AqI7CygtnEaVnP4SqQuIoW E9wg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:in-reply-to:references; bh=8ze7xQwtTWTtjiyh9eoe9DCFogoZsuVOgewV5cPBu/g=; b=jbm6BGRcHL+557p26QqLWvWQ6yYyRVR8aQekuiJnxPoFrXQToTWW61OIEfPtfyilUH iNHJPqUB8MYb1J+IT8f0K4ce6CXo80gbUQzBoUjNZR0Gcmg57dGpPmDb/I8DWLErIt3o Af0IGgxs80aRcShjYlPGiPEgzQOgXDSI7o6MqJHxJus02LDildNbvfPFrllkSrin8G+R 2nGzHB7hLa7VwqS+heWhNN1UCDsqMY7RYNjHdl44sHzI2zqIOC9jVGPymRXY2molcmaY glCNB7SE0/Vn0hkWwwpu3iXVYgkEEJRm4WoLzNg2TO18nr/07fYQ5MReijRPUAYZUIq8 ekhg== X-Gm-Message-State: AD7BkJK/PcuD/xECtBjUYPhBNKMvVFiM8v3cdZxx4dtO54jpi7oqg55nhTEuFzrBTID09w== X-Received: by 10.98.17.151 with SMTP id 23mr2271380pfr.37.1457512431222; Wed, 09 Mar 2016 00:33:51 -0800 (PST) Received: from localhost.localdomain (napt.igel.co.jp. [219.106.231.132]) by smtp.gmail.com with ESMTPSA id qh8sm10350238pac.40.2016.03.09.00.33.49 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 09 Mar 2016 00:33:50 -0800 (PST) From: Tetsuya Mukawa To: dev@dpdk.org, jianfeng.tan@intel.com, huawei.xie@intel.com, yuanhan.liu@linux.intel.com Date: Wed, 9 Mar 2016 17:33:20 +0900 Message-Id: <1457512409-24403-4-git-send-email-mukawa@igel.co.jp> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1457512409-24403-1-git-send-email-mukawa@igel.co.jp> References: <1457512409-24403-1-git-send-email-mukawa@igel.co.jp> In-Reply-To: <1456129075-14909-4-git-send-email-mukawa@igel.co.jp> References: <1456129075-14909-4-git-send-email-mukawa@igel.co.jp> Subject: [dpdk-dev] [PATCH v4 03/12] EAL: Add a new "--range-virtaddr" option X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" The option specifies how to mmap EAL memory. If the option is specified like '--range-virtaddr=-', EAL will check /proc/maps, then tries to find free region between addr1 and addr2. If a region is found, EAL will treat it as if 'base-virtaddr' is specified. Because of this, the option will not work with '--base-virtaddr'. Signed-off-by: Tetsuya Mukawa --- lib/librte_eal/common/eal_common_options.c | 9 ++++ lib/librte_eal/common/eal_internal_cfg.h | 2 + lib/librte_eal/common/eal_options.h | 2 + lib/librte_eal/linuxapp/eal/eal.c | 39 ++++++++++++++ lib/librte_eal/linuxapp/eal/eal_memory.c | 82 +++++++++++++++++++++++++++++- 5 files changed, 133 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..3b4f789 100644 --- a/lib/librte_eal/common/eal_common_options.c +++ b/lib/librte_eal/common/eal_common_options.c @@ -74,6 +74,7 @@ eal_short_options[] = const struct option eal_long_options[] = { {OPT_BASE_VIRTADDR, 1, NULL, OPT_BASE_VIRTADDR_NUM }, + {OPT_RANGE_VIRTADDR, 1, NULL, OPT_RANGE_VIRTADDR_NUM }, {OPT_CREATE_UIO_DEV, 0, NULL, OPT_CREATE_UIO_DEV_NUM }, {OPT_FILE_PREFIX, 1, NULL, OPT_FILE_PREFIX_NUM }, {OPT_HELP, 0, NULL, OPT_HELP_NUM }, @@ -137,6 +138,8 @@ eal_reset_internal_config(struct internal_config *internal_cfg) for (i = 0; i < MAX_HUGEPAGE_SIZES; i++) internal_cfg->hugepage_info[i].lock_descriptor = -1; internal_cfg->base_virtaddr = 0; + internal_cfg->range_virtaddr_start = 0; + internal_cfg->range_virtaddr_end = 0; internal_cfg->syslog_facility = LOG_DAEMON; /* default value from build option */ @@ -985,6 +988,12 @@ eal_check_common_options(struct internal_config *internal_cfg) return -1; } + if (internal_cfg->base_virtaddr && internal_cfg->range_virtaddr_end) { + RTE_LOG(ERR, EAL, "Option --"OPT_RANGE_VIRTADDR" cannot " + "be specified together with --"OPT_BASE_VIRTADDR"\n"); + return -1; + } + return 0; } diff --git a/lib/librte_eal/common/eal_internal_cfg.h b/lib/librte_eal/common/eal_internal_cfg.h index 9117ed9..0734630 100644 --- a/lib/librte_eal/common/eal_internal_cfg.h +++ b/lib/librte_eal/common/eal_internal_cfg.h @@ -78,6 +78,8 @@ struct internal_config { volatile unsigned force_sockets; volatile uint64_t socket_mem[RTE_MAX_NUMA_NODES]; /**< amount of memory per socket */ uintptr_t base_virtaddr; /**< base address to try and reserve memory from */ + uintptr_t range_virtaddr_start; /**< start address of mappable region */ + uintptr_t range_virtaddr_end; /**< end address of mappable region */ volatile int syslog_facility; /**< facility passed to openlog() */ volatile uint32_t log_level; /**< default log level */ /** default interrupt mode for VFIO */ diff --git a/lib/librte_eal/common/eal_options.h b/lib/librte_eal/common/eal_options.h index e5da14a..8e4cf1d 100644 --- a/lib/librte_eal/common/eal_options.h +++ b/lib/librte_eal/common/eal_options.h @@ -47,6 +47,8 @@ enum { OPT_LONG_MIN_NUM = 256, #define OPT_BASE_VIRTADDR "base-virtaddr" OPT_BASE_VIRTADDR_NUM, +#define OPT_RANGE_VIRTADDR "range-virtaddr" + OPT_RANGE_VIRTADDR_NUM, #define OPT_CREATE_UIO_DEV "create-uio-dev" OPT_CREATE_UIO_DEV_NUM, #define OPT_FILE_PREFIX "file-prefix" diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c index 6bae02c..62b7a57 100644 --- a/lib/librte_eal/linuxapp/eal/eal.c +++ b/lib/librte_eal/linuxapp/eal/eal.c @@ -444,6 +444,35 @@ eal_parse_base_virtaddr(const char *arg) } static int +eal_parse_range_virtaddr(const char *range) +{ + char *p, *endptr; + uint64_t tmp_start, tmp_end; + + p = strchr(range, '-'); + if (p == NULL) + return -1; + *p++ = '\0'; + + errno = 0; + tmp_start = strtoul(range, &endptr, 0); + if ((errno != 0) || endptr == NULL || (*endptr != '\0')) + return -1; + + tmp_end = strtoul(p, &endptr, 0); + if ((errno != 0) || endptr == NULL || (*endptr != '\0')) + return -1; + + if (tmp_start >= tmp_end) + return -1; + + internal_config.range_virtaddr_start = tmp_start; + internal_config.range_virtaddr_end = tmp_end; + + return 0; +} + +static int eal_parse_vfio_intr(const char *mode) { unsigned i; @@ -604,6 +633,16 @@ eal_parse_args(int argc, char **argv) } break; + case OPT_RANGE_VIRTADDR_NUM: + if (eal_parse_range_virtaddr(optarg) < 0) { + RTE_LOG(ERR, EAL, "invalid parameter for --" + OPT_RANGE_VIRTADDR "\n"); + eal_usage(prgname); + ret = -1; + goto out; + } + break; + case OPT_VFIO_INTR_NUM: if (eal_parse_vfio_intr(optarg) < 0) { RTE_LOG(ERR, EAL, "invalid parameters for --" diff --git a/lib/librte_eal/linuxapp/eal/eal_memory.c b/lib/librte_eal/linuxapp/eal/eal_memory.c index bc04b3d..e15bf4c 100644 --- a/lib/librte_eal/linuxapp/eal/eal_memory.c +++ b/lib/librte_eal/linuxapp/eal/eal_memory.c @@ -251,6 +251,66 @@ aslr_enabled(void) } /* + * Find memory space that fits user request. + */ +static uintptr_t +rte_eal_get_free_region(uint64_t pagesz) +{ + uint64_t alloc_size, start, end, next_start; + uint64_t low_limit, high_limit; + uintptr_t addr = 0; + char buf[1024], *p; + FILE *fp; + + alloc_size = internal_config.memory; + low_limit = internal_config.range_virtaddr_start; + high_limit = internal_config.range_virtaddr_end; + + /* 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 0; + } + + fp = fopen("/proc/self/maps", "r"); + if (fp == NULL) { + rte_panic("Cannot open /proc/self/maps\n"); + return 0; + } + + 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 = start; + break; + } + } while (end != UINT64_MAX); + + fclose(fp); + + return addr; +} + +/* * Try to mmap *size bytes in /dev/zero. If it is successful, return the * pointer to the mmap'd area and keep *size unmodified. Else, retry * with a smaller zone: decrease *size by hugepage_sz until it reaches @@ -1095,6 +1155,25 @@ rte_eal_hugepage_init(void) /* get pointer to global configuration */ mcfg = rte_eal_get_configuration()->mem_config; + if (internal_config.range_virtaddr_end) { + uint64_t pagesize = RTE_PGSIZE_4K; + struct hugepage_info *hpi; + unsigned n; + uintptr_t addr; + + /* determine maximum hugepage size */ + for (n = 0; n < internal_config.num_hugepage_sizes; n++) { + hpi = &internal_config.hugepage_info[n]; + pagesize = RTE_MAX(hpi->hugepage_sz, pagesize); + } + + addr = rte_eal_get_free_region(pagesize); + if (addr == 0) + RTE_LOG(WARNING, EAL, + "no free space to mmap in specified region\n"); + internal_config.base_virtaddr = addr; + } + /* when hugetlbfs is disabled or single-file option is specified */ if (internal_config.no_hugetlbfs || internal_config.single_file) { int fd; @@ -1127,7 +1206,8 @@ rte_eal_hugepage_init(void) return -1; } - addr = mmap(NULL, internal_config.memory, + addr = mmap((void *)internal_config.base_virtaddr, + internal_config.memory, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_POPULATE, fd, 0); if (addr == MAP_FAILED) {