From patchwork Thu Jun 7 07:37:01 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Hunt, David" X-Patchwork-Id: 40771 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 234331B3FF; Thu, 7 Jun 2018 16:39:57 +0200 (CEST) Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by dpdk.org (Postfix) with ESMTP id BC1AE1B1E3 for ; Thu, 7 Jun 2018 16:39:53 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga102.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 07 Jun 2018 07:39:52 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.49,486,1520924400"; d="scan'208";a="62111500" Received: from silpixa00399952.ir.intel.com (HELO silpixa00399952.ger.corp.intel.com) ([10.237.223.64]) by fmsmga001.fm.intel.com with ESMTP; 07 Jun 2018 07:39:52 -0700 From: David Hunt To: dev@dpdk.org Cc: david.hunt@intel.com Date: Thu, 7 Jun 2018 08:37:01 +0100 Message-Id: <20180607073705.32895-3-david.hunt@intel.com> X-Mailer: git-send-email 2.17.0 In-Reply-To: <20180607073705.32895-1-david.hunt@intel.com> References: <20180607073705.32895-1-david.hunt@intel.com> Subject: [dpdk-dev] [PATCH v1 2/6] examples/vm_power: add core list parameter 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: , Errors-To: dev-bounces@dpdk.org Sender: "dev" Add in the '-l' command line parameter (also --core-list) So the user can now pass --corelist=4,6,8-10 and it will expand out to 4,6,8,9,10 using the parse function provided in parse.c (parse_set). This list of cores is then used to enable out-of-band monitoring to scale up and down these cores based on the ratio of branch hits versus branch misses. The ratio will be low when a poll loop is spinning with no packets being received, so the frequency will be scaled down. Also , as part of this change, we introduce a core_info struct which keeps information on each core in the system, and whether we're doing out of band monitoring on them. Signed-off-by: David Hunt --- examples/vm_power_manager/Makefile | 2 +- examples/vm_power_manager/main.c | 34 ++++++++- examples/vm_power_manager/parse.c | 93 +++++++++++++++++++++++ examples/vm_power_manager/parse.h | 20 +++++ examples/vm_power_manager/power_manager.c | 31 ++++++++ examples/vm_power_manager/power_manager.h | 20 +++++ 6 files changed, 197 insertions(+), 3 deletions(-) create mode 100644 examples/vm_power_manager/parse.c create mode 100644 examples/vm_power_manager/parse.h diff --git a/examples/vm_power_manager/Makefile b/examples/vm_power_manager/Makefile index ef2a9f959..0c925967c 100644 --- a/examples/vm_power_manager/Makefile +++ b/examples/vm_power_manager/Makefile @@ -19,7 +19,7 @@ APP = vm_power_mgr # all source are stored in SRCS-y SRCS-y := main.c vm_power_cli.c power_manager.c channel_manager.c -SRCS-y += channel_monitor.c +SRCS-y += channel_monitor.c parse.c CFLAGS += -O3 -I$(RTE_SDK)/lib/librte_power/ CFLAGS += $(WERROR_FLAGS) diff --git a/examples/vm_power_manager/main.c b/examples/vm_power_manager/main.c index 043b374bc..cc2a1289c 100644 --- a/examples/vm_power_manager/main.c +++ b/examples/vm_power_manager/main.c @@ -29,6 +29,7 @@ #include "channel_monitor.h" #include "power_manager.h" #include "vm_power_cli.h" +#include "parse.h" #include #include #include @@ -135,18 +136,22 @@ parse_portmask(const char *portmask) static int parse_args(int argc, char **argv) { - int opt, ret; + int opt, ret, cnt, i; char **argvopt; + uint16_t *oob_enable; int option_index; char *prgname = argv[0]; + struct core_info *ci; static struct option lgopts[] = { { "mac-updating", no_argument, 0, 1}, { "no-mac-updating", no_argument, 0, 0}, + { "core-list", optional_argument, 0, 'l'}, {NULL, 0, 0, 0} }; argvopt = argv; + ci = get_core_info(); - while ((opt = getopt_long(argc, argvopt, "p:q:T:", + while ((opt = getopt_long(argc, argvopt, "l:p:q:T:", lgopts, &option_index)) != EOF) { switch (opt) { @@ -158,6 +163,27 @@ parse_args(int argc, char **argv) return -1; } break; + case 'l': + oob_enable = malloc(ci->core_count * sizeof(uint16_t)); + if (oob_enable == NULL) { + printf("Error - Unable to allocate memory\n"); + return -1; + } + cnt = parse_set(optarg, oob_enable, ci->core_count); + if (cnt < 0) { + printf("Invalid core-list - [%s]\n", + optarg); + break; + } + for (i = 0; i < ci->core_count; i++) { + if (oob_enable[i]) { + printf("***Using core %d\n", i); + ci->cd[i].oob_enabled = 1; + ci->cd[i].global_enabled_cpus = 1; + } + } + free(oob_enable); + break; /* long options */ case 0: break; @@ -263,6 +289,10 @@ main(int argc, char **argv) uint16_t portid; + ret = core_info_init(); + if (ret < 0) + rte_panic("Cannot allocate core info\n"); + ret = rte_eal_init(argc, argv); if (ret < 0) rte_panic("Cannot init EAL\n"); diff --git a/examples/vm_power_manager/parse.c b/examples/vm_power_manager/parse.c new file mode 100644 index 000000000..9de15c4a7 --- /dev/null +++ b/examples/vm_power_manager/parse.c @@ -0,0 +1,93 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation. + * Copyright(c) 2014 6WIND S.A. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "parse.h" + +/* + * Parse elem, the elem could be single number/range or group + * 1) A single number elem, it's just a simple digit. e.g. 9 + * 2) A single range elem, two digits with a '-' between. e.g. 2-6 + * 3) A group elem, combines multiple 1) or 2) e.g 0,2-4,6 + * Within group, '-' used for a range separator; + * ',' used for a single number. + */ +int +parse_set(const char *input, uint16_t set[], unsigned int num) +{ + unsigned int idx; + const char *str = input; + char *end = NULL; + unsigned int min, max; + + memset(set, 0, num * sizeof(uint16_t)); + + while (isblank(*str)) + str++; + + /* only digit or left bracket is qualify for start point */ + if (!isdigit(*str) || *str == '\0') + return -1; + + while (isblank(*str)) + str++; + if (*str == '\0') + return -1; + + min = num; + do { + + /* go ahead to the first digit */ + while (isblank(*str)) + str++; + if (!isdigit(*str)) + return -1; + + /* get the digit value */ + errno = 0; + idx = strtoul(str, &end, 10); + if (errno || end == NULL || idx >= num) + return -1; + + /* go ahead to separator '-' and ',' */ + while (isblank(*end)) + end++; + if (*end == '-') { + if (min == num) + min = idx; + else /* avoid continuous '-' */ + return -1; + } else if ((*end == ',') || (*end == '\0')) { + max = idx; + + if (min == num) + min = idx; + + for (idx = RTE_MIN(min, max); + idx <= RTE_MAX(min, max); idx++) { + set[idx] = 1; + } + min = num; + } else + return -1; + + str = end + 1; + } while (*end != '\0'); + + return str - input; +} diff --git a/examples/vm_power_manager/parse.h b/examples/vm_power_manager/parse.h new file mode 100644 index 000000000..a5971e9a2 --- /dev/null +++ b/examples/vm_power_manager/parse.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018 Intel Corporation + */ + +#ifndef PARSE_H_ +#define PARSE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +int +parse_set(const char *, uint16_t [], unsigned int); + +#ifdef __cplusplus +} +#endif + + +#endif /* PARSE_H_ */ diff --git a/examples/vm_power_manager/power_manager.c b/examples/vm_power_manager/power_manager.c index 35db25591..a7849e48a 100644 --- a/examples/vm_power_manager/power_manager.c +++ b/examples/vm_power_manager/power_manager.c @@ -12,6 +12,7 @@ #include #include +#include #include #include @@ -54,6 +55,7 @@ struct freq_info { static struct freq_info global_core_freq_info[POWER_MGR_MAX_CPUS]; +struct core_info ci; static uint64_t global_enabled_cpus; #define SYSFS_CPU_PATH "/sys/devices/system/cpu/cpu%u/topology/core_id" @@ -76,6 +78,35 @@ set_host_cpus_mask(void) return num_cpus; } +struct core_info * +get_core_info(void) +{ + return &ci; +} + +int +core_info_init(void) +{ + struct core_info *ci; + int i; + + ci = get_core_info(); + + ci->core_count = get_nprocs_conf(); + ci->cd = malloc(ci->core_count * sizeof(struct core_details)); + if (!ci->cd) { + RTE_LOG(ERR, POWER_MANAGER, "Failed to allocate memory for core info."); + return -1; + } + for (i = 0; i < ci->core_count; i++) { + ci->cd[i].global_enabled_cpus = 1; + ci->cd[i].oob_enabled = 0; + ci->cd[i].msr_fd = 0; + } + printf("%d cores in system\n", ci->core_count); + return 0; +} + int power_manager_init(void) { diff --git a/examples/vm_power_manager/power_manager.h b/examples/vm_power_manager/power_manager.h index 8a8a84aa4..45385de37 100644 --- a/examples/vm_power_manager/power_manager.h +++ b/examples/vm_power_manager/power_manager.h @@ -8,6 +8,26 @@ #ifdef __cplusplus extern "C" { #endif +struct core_details { + uint64_t last_branches; + uint64_t last_branch_misses; + uint16_t global_enabled_cpus; + uint16_t oob_enabled; + int msr_fd; +}; + +struct core_info { + uint16_t core_count; + struct core_details *cd; +}; + +struct core_info * +get_core_info(void); + +int +core_info_init(void); + +#define RTE_LOGTYPE_POWER_MANAGER RTE_LOGTYPE_USER1 /* Maximum number of CPUS to manage */ #define POWER_MGR_MAX_CPUS 64