From patchwork Fri Jul 13 14:22:54 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Hunt, David" X-Patchwork-Id: 43055 X-Patchwork-Delegate: pablo.de.lara.guarch@intel.com 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 E668B2BF5; Fri, 13 Jul 2018 16:23:22 +0200 (CEST) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by dpdk.org (Postfix) with ESMTP id 772981E2F for ; Fri, 13 Jul 2018 16:23:20 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 13 Jul 2018 07:23:19 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.51,347,1526367600"; d="scan'208";a="56278182" Received: from silpixa00399952.ir.intel.com (HELO silpixa00399952.ger.corp.intel.com) ([10.237.223.64]) by orsmga007.jf.intel.com with ESMTP; 13 Jul 2018 07:23:18 -0700 From: David Hunt To: dev@dpdk.org Cc: david.hunt@intel.com, thomas@monjalon.net Date: Fri, 13 Jul 2018 15:22:54 +0100 Message-Id: <20180713142302.34576-2-david.hunt@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180713142302.34576-1-david.hunt@intel.com> References: <20180626092317.11031-2-david.hunt@intel.com> <20180713142302.34576-1-david.hunt@intel.com> Subject: [dpdk-dev] [PATCH v4 1/9] examples/vm_power: add check for port count 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" If we don't pass any ports to the app, we don't need to create any mempools, and we don't need to init any ports. Signed-off-by: David Hunt Acked-by: Radu Nicolau --- examples/vm_power_manager/main.c | 81 +++++++++++++++++--------------- 1 file changed, 43 insertions(+), 38 deletions(-) diff --git a/examples/vm_power_manager/main.c b/examples/vm_power_manager/main.c index 8911f2659..0d3846971 100644 --- a/examples/vm_power_manager/main.c +++ b/examples/vm_power_manager/main.c @@ -278,51 +278,56 @@ main(int argc, char **argv) nb_ports = rte_eth_dev_count_avail(); - mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL", NUM_MBUFS * nb_ports, - MBUF_CACHE_SIZE, 0, RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); + if (nb_ports > 0) { + mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL", + NUM_MBUFS * nb_ports, MBUF_CACHE_SIZE, 0, + RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); - if (mbuf_pool == NULL) - rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n"); + if (mbuf_pool == NULL) + rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n"); - /* Initialize ports. */ - RTE_ETH_FOREACH_DEV(portid) { - struct ether_addr eth; - int w, j; - int ret; + /* Initialize ports. */ + RTE_ETH_FOREACH_DEV(portid) { + struct ether_addr eth; + int w, j; + int ret; - if ((enabled_port_mask & (1 << portid)) == 0) - continue; + if ((enabled_port_mask & (1 << portid)) == 0) + continue; - eth.addr_bytes[0] = 0xe0; - eth.addr_bytes[1] = 0xe0; - eth.addr_bytes[2] = 0xe0; - eth.addr_bytes[3] = 0xe0; - eth.addr_bytes[4] = portid + 0xf0; + eth.addr_bytes[0] = 0xe0; + eth.addr_bytes[1] = 0xe0; + eth.addr_bytes[2] = 0xe0; + eth.addr_bytes[3] = 0xe0; + eth.addr_bytes[4] = portid + 0xf0; - if (port_init(portid, mbuf_pool) != 0) - rte_exit(EXIT_FAILURE, "Cannot init port %"PRIu8 "\n", + if (port_init(portid, mbuf_pool) != 0) + rte_exit(EXIT_FAILURE, + "Cannot init port %"PRIu8 "\n", portid); - for (w = 0; w < MAX_VFS; w++) { - eth.addr_bytes[5] = w + 0xf0; - - ret = rte_pmd_ixgbe_set_vf_mac_addr(portid, - w, ð); - if (ret == -ENOTSUP) - ret = rte_pmd_i40e_set_vf_mac_addr(portid, - w, ð); - if (ret == -ENOTSUP) - ret = rte_pmd_bnxt_set_vf_mac_addr(portid, - w, ð); - - switch (ret) { - case 0: - printf("Port %d VF %d MAC: ", - portid, w); - for (j = 0; j < 6; j++) { - printf("%02x", eth.addr_bytes[j]); - if (j < 5) - printf(":"); + for (w = 0; w < MAX_VFS; w++) { + eth.addr_bytes[5] = w + 0xf0; + + ret = rte_pmd_ixgbe_set_vf_mac_addr(portid, + w, ð); + if (ret == -ENOTSUP) + ret = rte_pmd_i40e_set_vf_mac_addr( + portid, w, ð); + if (ret == -ENOTSUP) + ret = rte_pmd_bnxt_set_vf_mac_addr( + portid, w, ð); + + switch (ret) { + case 0: + printf("Port %d VF %d MAC: ", + portid, w); + for (j = 0; j < 5; j++) { + printf("%02x:", + eth.addr_bytes[j]); + } + printf("%02x\n", eth.addr_bytes[5]); + break; } printf("\n"); break; From patchwork Fri Jul 13 14:22:55 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Hunt, David" X-Patchwork-Id: 43056 X-Patchwork-Delegate: pablo.de.lara.guarch@intel.com 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 8FFF62C17; Fri, 13 Jul 2018 16:23:24 +0200 (CEST) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by dpdk.org (Postfix) with ESMTP id 4EF801E2F for ; Fri, 13 Jul 2018 16:23:21 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 13 Jul 2018 07:23:20 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.51,347,1526367600"; d="scan'208";a="56278187" Received: from silpixa00399952.ir.intel.com (HELO silpixa00399952.ger.corp.intel.com) ([10.237.223.64]) by orsmga007.jf.intel.com with ESMTP; 13 Jul 2018 07:23:19 -0700 From: David Hunt To: dev@dpdk.org Cc: david.hunt@intel.com, thomas@monjalon.net Date: Fri, 13 Jul 2018 15:22:55 +0100 Message-Id: <20180713142302.34576-3-david.hunt@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180713142302.34576-1-david.hunt@intel.com> References: <20180626092317.11031-2-david.hunt@intel.com> <20180713142302.34576-1-david.hunt@intel.com> Subject: [dpdk-dev] [PATCH v4 2/9] 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 Acked-by: Radu Nicolau --- examples/vm_power_manager/Makefile | 2 +- examples/vm_power_manager/main.c | 34 +++++++++- examples/vm_power_manager/parse.c | 81 +++++++++++++++++++++++ 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, 185 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 0d3846971..613a40af0 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 @@ -133,18 +134,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) { @@ -156,6 +161,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; @@ -261,6 +287,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..8231533b6 --- /dev/null +++ b/examples/vm_power_manager/parse.c @@ -0,0 +1,81 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation. + * Copyright(c) 2014 6WIND S.A. + */ + +#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 From patchwork Fri Jul 13 14:22:56 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Hunt, David" X-Patchwork-Id: 43057 X-Patchwork-Delegate: pablo.de.lara.guarch@intel.com 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 902F02C38; Fri, 13 Jul 2018 16:23:26 +0200 (CEST) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by dpdk.org (Postfix) with ESMTP id 9C3072BE5 for ; Fri, 13 Jul 2018 16:23:22 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 13 Jul 2018 07:23:22 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.51,347,1526367600"; d="scan'208";a="56278193" Received: from silpixa00399952.ir.intel.com (HELO silpixa00399952.ger.corp.intel.com) ([10.237.223.64]) by orsmga007.jf.intel.com with ESMTP; 13 Jul 2018 07:23:21 -0700 From: David Hunt To: dev@dpdk.org Cc: david.hunt@intel.com, thomas@monjalon.net Date: Fri, 13 Jul 2018 15:22:56 +0100 Message-Id: <20180713142302.34576-4-david.hunt@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180713142302.34576-1-david.hunt@intel.com> References: <20180626092317.11031-2-david.hunt@intel.com> <20180713142302.34576-1-david.hunt@intel.com> Subject: [dpdk-dev] [PATCH v4 3/9] examples/vm_power: add oob monitoring functions 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" This patch introduces the out-of-band (oob) core monitoring functions. The functions are similar to the channel manager functions. There are function to add and remove cores from the list of cores being monitored. There is a function to initialise the monitor setup, run the monitor thread, and exit the monitor. The monitor thread runs in it's own lcore, and is separate functionality to the channel monitor which is epoll based. THis thread is timer based. It loops through all monitored cores, calculates the branch ratio, scales up or down the core, then sleeps for an interval (~250 uS). The method it uses to read the branch counters is a pread on the /dev/cpu/x/msr file, so the 'msr' kernel module needs to be loaded. Also, since the msr.h file has been made unavailable in recent kernels, we have #defines for the relevant MSRs included in the code. The makefile has a switch for x86 and non-x86 platforms, and compiles stub function for non-x86 platforms. Signed-off-by: David Hunt Acked-by: Radu Nicolau --- examples/vm_power_manager/Makefile | 5 + examples/vm_power_manager/oob_monitor.h | 68 +++++ examples/vm_power_manager/oob_monitor_nop.c | 38 +++ examples/vm_power_manager/oob_monitor_x86.c | 259 ++++++++++++++++++++ 4 files changed, 370 insertions(+) create mode 100644 examples/vm_power_manager/oob_monitor.h create mode 100644 examples/vm_power_manager/oob_monitor_nop.c create mode 100644 examples/vm_power_manager/oob_monitor_x86.c diff --git a/examples/vm_power_manager/Makefile b/examples/vm_power_manager/Makefile index 0c925967c..13a5205ba 100644 --- a/examples/vm_power_manager/Makefile +++ b/examples/vm_power_manager/Makefile @@ -20,6 +20,11 @@ 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 parse.c +ifeq ($(CONFIG_RTE_ARCH_X86_64),y) +SRCS-y += oob_monitor_x86.c +else +SRCS-y += oob_monitor_nop.c +endif CFLAGS += -O3 -I$(RTE_SDK)/lib/librte_power/ CFLAGS += $(WERROR_FLAGS) diff --git a/examples/vm_power_manager/oob_monitor.h b/examples/vm_power_manager/oob_monitor.h new file mode 100644 index 000000000..b96e08df7 --- /dev/null +++ b/examples/vm_power_manager/oob_monitor.h @@ -0,0 +1,68 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018 Intel Corporation + */ + +#ifndef OOB_MONITOR_H_ +#define OOB_MONITOR_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * Setup the Branch Monitor resources required to initialize epoll. + * Must be called first before calling other functions. + * + * @return + * - 0 on success. + * - Negative on error. + */ +int branch_monitor_init(void); + +/** + * Run the OOB branch monitor, loops forever on on epoll_wait. + * + * + * @return + * None + */ +void run_branch_monitor(void); + +/** + * Exit the OOB Branch Monitor. + * + * @return + * None + */ +void branch_monitor_exit(void); + +/** + * Add a core to the list of cores to monitor. + * + * @param core + * Core Number + * + * @return + * - 0 on success. + * - Negative on error. + */ +int add_core_to_monitor(int core); + +/** + * Remove a previously added core from core list. + * + * @param core + * Core Number + * + * @return + * - 0 on success. + * - Negative on error. + */ +int remove_core_from_monitor(int core); + +#ifdef __cplusplus +} +#endif + + +#endif /* OOB_MONITOR_H_ */ diff --git a/examples/vm_power_manager/oob_monitor_nop.c b/examples/vm_power_manager/oob_monitor_nop.c new file mode 100644 index 000000000..7e7b8bc14 --- /dev/null +++ b/examples/vm_power_manager/oob_monitor_nop.c @@ -0,0 +1,38 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation + */ + +#include "oob_monitor.h" + +void branch_monitor_exit(void) +{ +} + +__attribute__((unused)) static float +apply_policy(__attribute__((unused)) int core) +{ + return 0.0; +} + +int +add_core_to_monitor(__attribute__((unused)) int core) +{ + return 0; +} + +int +remove_core_from_monitor(__attribute__((unused)) int core) +{ + return 0; +} + +int +branch_monitor_init(void) +{ + return 0; +} + +void +run_branch_monitor(void) +{ +} diff --git a/examples/vm_power_manager/oob_monitor_x86.c b/examples/vm_power_manager/oob_monitor_x86.c new file mode 100644 index 000000000..62d503ca5 --- /dev/null +++ b/examples/vm_power_manager/oob_monitor_x86.c @@ -0,0 +1,259 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2018 Intel Corporation + */ + +#include +#include +#include + +#include "oob_monitor.h" +#include "power_manager.h" +#include "channel_manager.h" + +static volatile unsigned run_loop = 1; +static uint64_t g_branches, g_branch_misses; +static int g_active; + +void branch_monitor_exit(void) +{ + run_loop = 0; +} + +/* Number of microseconds between each poll */ +#define INTERVAL 100 +#define PRINT_LOOP_COUNT (1000000/INTERVAL) +#define RATIO_THRESHOLD 0.03 +#define IA32_PERFEVTSEL0 0x186 +#define IA32_PERFEVTSEL1 0x187 +#define IA32_PERFCTR0 0xc1 +#define IA32_PERFCTR1 0xc2 +#define IA32_PERFEVT_BRANCH_HITS 0x05300c4 +#define IA32_PERFEVT_BRANCH_MISS 0x05300c5 + +static float +apply_policy(int core) +{ + struct core_info *ci; + uint64_t counter; + uint64_t branches, branch_misses; + uint32_t last_branches, last_branch_misses; + int hits_diff, miss_diff; + float ratio; + int ret; + + g_active = 0; + ci = get_core_info(); + + last_branches = ci->cd[core].last_branches; + last_branch_misses = ci->cd[core].last_branch_misses; + + ret = pread(ci->cd[core].msr_fd, &counter, + sizeof(counter), IA32_PERFCTR0); + if (ret < 0) + RTE_LOG(ERR, POWER_MANAGER, + "unable to read counter for core %u\n", + core); + branches = counter; + + ret = pread(ci->cd[core].msr_fd, &counter, + sizeof(counter), IA32_PERFCTR1); + if (ret < 0) + RTE_LOG(ERR, POWER_MANAGER, + "unable to read counter for core %u\n", + core); + branch_misses = counter; + + + ci->cd[core].last_branches = branches; + ci->cd[core].last_branch_misses = branch_misses; + + hits_diff = (int)branches - (int)last_branches; + if (hits_diff <= 0) { + /* Likely a counter overflow condition, skip this round */ + return -1.0; + } + + miss_diff = (int)branch_misses - (int)last_branch_misses; + if (miss_diff <= 0) { + /* Likely a counter overflow condition, skip this round */ + return -1.0; + } + + g_branches = hits_diff; + g_branch_misses = miss_diff; + + if (hits_diff < (INTERVAL*100)) { + /* Likely no workload running on this core. Skip. */ + return -1.0; + } + + ratio = (float)miss_diff * (float)100 / (float)hits_diff; + + if (ratio < RATIO_THRESHOLD) + power_manager_scale_core_min(core); + else + power_manager_scale_core_max(core); + + g_active = 1; + return ratio; +} + +int +add_core_to_monitor(int core) +{ + struct core_info *ci; + char proc_file[UNIX_PATH_MAX]; + int ret; + + ci = get_core_info(); + + if (core < ci->core_count) { + long setup; + + snprintf(proc_file, UNIX_PATH_MAX, "/dev/cpu/%d/msr", core); + ci->cd[core].msr_fd = open(proc_file, O_RDWR | O_SYNC); + if (ci->cd[core].msr_fd < 0) { + RTE_LOG(ERR, POWER_MANAGER, + "Error opening MSR file for core %d " + "(is msr kernel module loaded?)\n", + core); + return -1; + } + /* + * Set up branch counters + */ + setup = IA32_PERFEVT_BRANCH_HITS; + ret = pwrite(ci->cd[core].msr_fd, &setup, + sizeof(setup), IA32_PERFEVTSEL0); + if (ret < 0) { + RTE_LOG(ERR, POWER_MANAGER, + "unable to set counter for core %u\n", + core); + return ret; + } + setup = IA32_PERFEVT_BRANCH_MISS; + ret = pwrite(ci->cd[core].msr_fd, &setup, + sizeof(setup), IA32_PERFEVTSEL1); + if (ret < 0) { + RTE_LOG(ERR, POWER_MANAGER, + "unable to set counter for core %u\n", + core); + return ret; + } + /* + * Close the file and re-open as read only so + * as not to hog the resource + */ + close(ci->cd[core].msr_fd); + ci->cd[core].msr_fd = open(proc_file, O_RDONLY); + if (ci->cd[core].msr_fd < 0) { + RTE_LOG(ERR, POWER_MANAGER, + "Error opening MSR file for core %d " + "(is msr kernel module loaded?)\n", + core); + return -1; + } + ci->cd[core].oob_enabled = 1; + } + return 0; +} + +int +remove_core_from_monitor(int core) +{ + struct core_info *ci; + char proc_file[UNIX_PATH_MAX]; + int ret; + + ci = get_core_info(); + + if (ci->cd[core].oob_enabled) { + long setup; + + /* + * close the msr file, then reopen rw so we can + * disable the counters + */ + if (ci->cd[core].msr_fd != 0) + close(ci->cd[core].msr_fd); + snprintf(proc_file, UNIX_PATH_MAX, "/dev/cpu/%d/msr", core); + ci->cd[core].msr_fd = open(proc_file, O_RDWR | O_SYNC); + if (ci->cd[core].msr_fd < 0) { + RTE_LOG(ERR, POWER_MANAGER, + "Error opening MSR file for core %d " + "(is msr kernel module loaded?)\n", + core); + return -1; + } + setup = 0x0; /* clear event */ + ret = pwrite(ci->cd[core].msr_fd, &setup, + sizeof(setup), IA32_PERFEVTSEL0); + if (ret < 0) { + RTE_LOG(ERR, POWER_MANAGER, + "unable to set counter for core %u\n", + core); + return ret; + } + setup = 0x0; /* clear event */ + ret = pwrite(ci->cd[core].msr_fd, &setup, + sizeof(setup), IA32_PERFEVTSEL1); + if (ret < 0) { + RTE_LOG(ERR, POWER_MANAGER, + "unable to set counter for core %u\n", + core); + return ret; + } + + close(ci->cd[core].msr_fd); + ci->cd[core].msr_fd = 0; + ci->cd[core].oob_enabled = 0; + } + return 0; +} + +int +branch_monitor_init(void) +{ + return 0; +} + +void +run_branch_monitor(void) +{ + struct core_info *ci; + int print = 0; + float ratio; + int printed; + int reads = 0; + + ci = get_core_info(); + + while (run_loop) { + + if (!run_loop) + break; + usleep(INTERVAL); + int j; + print++; + printed = 0; + for (j = 0; j < ci->core_count; j++) { + if (ci->cd[j].oob_enabled) { + ratio = apply_policy(j); + if ((print > PRINT_LOOP_COUNT) && (g_active)) { + printf(" %d: %.4f {%lu} {%d}", j, + ratio, g_branches, + reads); + printed = 1; + reads = 0; + } else { + reads++; + } + } + } + if (print > PRINT_LOOP_COUNT) { + if (printed) + printf("\n"); + print = 0; + } + } +} From patchwork Fri Jul 13 14:22:57 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Hunt, David" X-Patchwork-Id: 43058 X-Patchwork-Delegate: pablo.de.lara.guarch@intel.com 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 5B41431FC; Fri, 13 Jul 2018 16:23:30 +0200 (CEST) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by dpdk.org (Postfix) with ESMTP id 8F9AD2BE5 for ; Fri, 13 Jul 2018 16:23:23 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 13 Jul 2018 07:23:23 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.51,347,1526367600"; d="scan'208";a="56278206" Received: from silpixa00399952.ir.intel.com (HELO silpixa00399952.ger.corp.intel.com) ([10.237.223.64]) by orsmga007.jf.intel.com with ESMTP; 13 Jul 2018 07:23:22 -0700 From: David Hunt To: dev@dpdk.org Cc: david.hunt@intel.com, thomas@monjalon.net Date: Fri, 13 Jul 2018 15:22:57 +0100 Message-Id: <20180713142302.34576-5-david.hunt@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180713142302.34576-1-david.hunt@intel.com> References: <20180626092317.11031-2-david.hunt@intel.com> <20180713142302.34576-1-david.hunt@intel.com> Subject: [dpdk-dev] [PATCH v4 4/9] examples/vm_power: allow greater than 64 cores 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" To facilitate more info per core, change the global_cpu_mask from a uint64_t to an array. This also removes the limit on 64 cores, allocing the aray at run-time based on the number of cores found in the system. Signed-off-by: David Hunt Acked-by: Radu Nicolau --- examples/vm_power_manager/power_manager.c | 115 +++++++++++----------- 1 file changed, 58 insertions(+), 57 deletions(-) diff --git a/examples/vm_power_manager/power_manager.c b/examples/vm_power_manager/power_manager.c index a7849e48a..4bdde23da 100644 --- a/examples/vm_power_manager/power_manager.c +++ b/examples/vm_power_manager/power_manager.c @@ -19,14 +19,14 @@ #include #include +#include "channel_manager.h" #include "power_manager.h" - -#define RTE_LOGTYPE_POWER_MANAGER RTE_LOGTYPE_USER1 +#include "oob_monitor.h" #define POWER_SCALE_CORE(DIRECTION, core_num , ret) do { \ - if (core_num >= POWER_MGR_MAX_CPUS) \ + if (core_num >= ci.core_count) \ return -1; \ - if (!(global_enabled_cpus & (1ULL << core_num))) \ + if (!(ci.cd[core_num].global_enabled_cpus)) \ return -1; \ rte_spinlock_lock(&global_core_freq_info[core_num].power_sl); \ ret = rte_power_freq_##DIRECTION(core_num); \ @@ -37,7 +37,7 @@ int i; \ for (i = 0; core_mask; core_mask &= ~(1 << i++)) { \ if ((core_mask >> i) & 1) { \ - if (!(global_enabled_cpus & (1ULL << i))) \ + if (!(ci.cd[i].global_enabled_cpus)) \ continue; \ rte_spinlock_lock(&global_core_freq_info[i].power_sl); \ if (rte_power_freq_##DIRECTION(i) != 1) \ @@ -56,28 +56,9 @@ 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" -static unsigned -set_host_cpus_mask(void) -{ - char path[PATH_MAX]; - unsigned i; - unsigned num_cpus = 0; - - for (i = 0; i < POWER_MGR_MAX_CPUS; i++) { - snprintf(path, sizeof(path), SYSFS_CPU_PATH, i); - if (access(path, F_OK) == 0) { - global_enabled_cpus |= 1ULL << i; - num_cpus++; - } else - return num_cpus; - } - return num_cpus; -} - struct core_info * get_core_info(void) { @@ -110,38 +91,45 @@ core_info_init(void) int power_manager_init(void) { - unsigned int i, num_cpus, num_freqs; - uint64_t cpu_mask; + unsigned int i, num_cpus = 0, num_freqs = 0; int ret = 0; + struct core_info *ci; + + rte_power_set_env(PM_ENV_ACPI_CPUFREQ); - num_cpus = set_host_cpus_mask(); - if (num_cpus == 0) { - RTE_LOG(ERR, POWER_MANAGER, "Unable to detected host CPUs, please " - "ensure that sufficient privileges exist to inspect sysfs\n"); + ci = get_core_info(); + if (!ci) { + RTE_LOG(ERR, POWER_MANAGER, + "Failed to get core info!\n"); return -1; } - rte_power_set_env(PM_ENV_ACPI_CPUFREQ); - cpu_mask = global_enabled_cpus; - for (i = 0; cpu_mask; cpu_mask &= ~(1 << i++)) { - if (rte_power_init(i) < 0) - RTE_LOG(ERR, POWER_MANAGER, - "Unable to initialize power manager " - "for core %u\n", i); - num_freqs = rte_power_freqs(i, global_core_freq_info[i].freqs, + + for (i = 0; i < ci->core_count; i++) { + if (ci->cd[i].global_enabled_cpus) { + if (rte_power_init(i) < 0) + RTE_LOG(ERR, POWER_MANAGER, + "Unable to initialize power manager " + "for core %u\n", i); + num_cpus++; + num_freqs = rte_power_freqs(i, + global_core_freq_info[i].freqs, RTE_MAX_LCORE_FREQS); - if (num_freqs == 0) { - RTE_LOG(ERR, POWER_MANAGER, - "Unable to get frequency list for core %u\n", - i); - global_enabled_cpus &= ~(1 << i); - num_cpus--; - ret = -1; + if (num_freqs == 0) { + RTE_LOG(ERR, POWER_MANAGER, + "Unable to get frequency list for core %u\n", + i); + ci->cd[i].oob_enabled = 0; + ret = -1; + } + global_core_freq_info[i].num_freqs = num_freqs; + + rte_spinlock_init(&global_core_freq_info[i].power_sl); } - global_core_freq_info[i].num_freqs = num_freqs; - rte_spinlock_init(&global_core_freq_info[i].power_sl); + if (ci->cd[i].oob_enabled) + add_core_to_monitor(i); } - RTE_LOG(INFO, POWER_MANAGER, "Detected %u host CPUs , enabled core mask:" - " 0x%"PRIx64"\n", num_cpus, global_enabled_cpus); + RTE_LOG(INFO, POWER_MANAGER, "Managing %u cores out of %u available host cores\n", + num_cpus, ci->core_count); return ret; } @@ -156,7 +144,7 @@ power_manager_get_current_frequency(unsigned core_num) core_num, POWER_MGR_MAX_CPUS-1); return -1; } - if (!(global_enabled_cpus & (1ULL << core_num))) + if (!(ci.cd[core_num].global_enabled_cpus)) return 0; rte_spinlock_lock(&global_core_freq_info[core_num].power_sl); @@ -175,15 +163,26 @@ power_manager_exit(void) { unsigned int i; int ret = 0; + struct core_info *ci; - for (i = 0; global_enabled_cpus; global_enabled_cpus &= ~(1 << i++)) { - if (rte_power_exit(i) < 0) { - RTE_LOG(ERR, POWER_MANAGER, "Unable to shutdown power manager " - "for core %u\n", i); - ret = -1; + ci = get_core_info(); + if (!ci) { + RTE_LOG(ERR, POWER_MANAGER, + "Failed to get core info!\n"); + return -1; + } + + for (i = 0; i < ci->core_count; i++) { + if (ci->cd[i].global_enabled_cpus) { + if (rte_power_exit(i) < 0) { + RTE_LOG(ERR, POWER_MANAGER, "Unable to shutdown power manager " + "for core %u\n", i); + ret = -1; + } + ci->cd[i].global_enabled_cpus = 0; } + remove_core_from_monitor(i); } - global_enabled_cpus = 0; return ret; } @@ -299,10 +298,12 @@ int power_manager_scale_core_med(unsigned int core_num) { int ret = 0; + struct core_info *ci; + ci = get_core_info(); if (core_num >= POWER_MGR_MAX_CPUS) return -1; - if (!(global_enabled_cpus & (1ULL << core_num))) + if (!(ci->cd[core_num].global_enabled_cpus)) return -1; rte_spinlock_lock(&global_core_freq_info[core_num].power_sl); ret = rte_power_set_freq(core_num, From patchwork Fri Jul 13 14:22:58 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Hunt, David" X-Patchwork-Id: 43059 X-Patchwork-Delegate: pablo.de.lara.guarch@intel.com 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 56C57324B; Fri, 13 Jul 2018 16:23:32 +0200 (CEST) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by dpdk.org (Postfix) with ESMTP id AAE172C23 for ; Fri, 13 Jul 2018 16:23:24 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 13 Jul 2018 07:23:24 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.51,347,1526367600"; d="scan'208";a="56278211" Received: from silpixa00399952.ir.intel.com (HELO silpixa00399952.ger.corp.intel.com) ([10.237.223.64]) by orsmga007.jf.intel.com with ESMTP; 13 Jul 2018 07:23:23 -0700 From: David Hunt To: dev@dpdk.org Cc: david.hunt@intel.com, thomas@monjalon.net Date: Fri, 13 Jul 2018 15:22:58 +0100 Message-Id: <20180713142302.34576-6-david.hunt@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180713142302.34576-1-david.hunt@intel.com> References: <20180626092317.11031-2-david.hunt@intel.com> <20180713142302.34576-1-david.hunt@intel.com> Subject: [dpdk-dev] [PATCH v4 5/9] examples/vm_power: add thread for oob core monitor 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" Change the app to now require three cores, as the third core will be used to run the oob montoring thread. Signed-off-by: David Hunt Acked-by: Radu Nicolau --- examples/vm_power_manager/main.c | 37 +++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) diff --git a/examples/vm_power_manager/main.c b/examples/vm_power_manager/main.c index 613a40af0..aef97b9ae 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 "oob_monitor.h" #include "parse.h" #include #include @@ -267,6 +268,17 @@ run_monitor(__attribute__((unused)) void *arg) return 0; } +static int +run_core_monitor(__attribute__((unused)) void *arg) +{ + if (branch_monitor_init() < 0) { + printf("Unable to initialize core monitor\n"); + return -1; + } + run_branch_monitor(); + return 0; +} + static void sig_handler(int signo) { @@ -285,12 +297,15 @@ main(int argc, char **argv) unsigned int nb_ports; struct rte_mempool *mbuf_pool; uint16_t portid; + struct core_info *ci; ret = core_info_init(); if (ret < 0) rte_panic("Cannot allocate core info\n"); + ci = get_core_info(); + ret = rte_eal_init(argc, argv); if (ret < 0) rte_panic("Cannot init EAL\n"); @@ -365,16 +380,23 @@ main(int argc, char **argv) } } + check_all_ports_link_status(enabled_port_mask); + lcore_id = rte_get_next_lcore(-1, 1, 0); if (lcore_id == RTE_MAX_LCORE) { - RTE_LOG(ERR, EAL, "A minimum of two cores are required to run " + RTE_LOG(ERR, EAL, "A minimum of three cores are required to run " "application\n"); return 0; } - - check_all_ports_link_status(enabled_port_mask); + printf("Running channel monitor on lcore id %d\n", lcore_id); rte_eal_remote_launch(run_monitor, NULL, lcore_id); + lcore_id = rte_get_next_lcore(lcore_id, 1, 0); + if (lcore_id == RTE_MAX_LCORE) { + RTE_LOG(ERR, EAL, "A minimum of three cores are required to run " + "application\n"); + return 0; + } if (power_manager_init() < 0) { printf("Unable to initialize power manager\n"); return -1; @@ -383,8 +405,17 @@ main(int argc, char **argv) printf("Unable to initialize channel manager\n"); return -1; } + + printf("Running core monitor on lcore id %d\n", lcore_id); + rte_eal_remote_launch(run_core_monitor, NULL, lcore_id); + run_cli(NULL); + branch_monitor_exit(); + rte_eal_mp_wait_lcore(); + + free(ci->cd); + return 0; } From patchwork Fri Jul 13 14:22:59 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Hunt, David" X-Patchwork-Id: 43060 X-Patchwork-Delegate: pablo.de.lara.guarch@intel.com 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 52C1032A5; Fri, 13 Jul 2018 16:23:34 +0200 (CEST) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by dpdk.org (Postfix) with ESMTP id F40852C2F for ; Fri, 13 Jul 2018 16:23:25 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 13 Jul 2018 07:23:25 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.51,347,1526367600"; d="scan'208";a="56278216" Received: from silpixa00399952.ir.intel.com (HELO silpixa00399952.ger.corp.intel.com) ([10.237.223.64]) by orsmga007.jf.intel.com with ESMTP; 13 Jul 2018 07:23:24 -0700 From: David Hunt To: dev@dpdk.org Cc: david.hunt@intel.com, thomas@monjalon.net Date: Fri, 13 Jul 2018 15:22:59 +0100 Message-Id: <20180713142302.34576-7-david.hunt@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180713142302.34576-1-david.hunt@intel.com> References: <20180626092317.11031-2-david.hunt@intel.com> <20180713142302.34576-1-david.hunt@intel.com> Subject: [dpdk-dev] [PATCH v4 6/9] examples/vm_power: add port-list to command line 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 long form of -p, which is --port-list Signed-off-by: David Hunt Acked-by: Radu Nicolau --- examples/vm_power_manager/main.c | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/vm_power_manager/main.c b/examples/vm_power_manager/main.c index aef97b9ae..f9990f153 100644 --- a/examples/vm_power_manager/main.c +++ b/examples/vm_power_manager/main.c @@ -145,6 +145,7 @@ parse_args(int argc, char **argv) { "mac-updating", no_argument, 0, 1}, { "no-mac-updating", no_argument, 0, 0}, { "core-list", optional_argument, 0, 'l'}, + { "port-list", optional_argument, 0, 'p'}, {NULL, 0, 0, 0} }; argvopt = argv; From patchwork Fri Jul 13 14:23:00 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Hunt, David" X-Patchwork-Id: 43061 X-Patchwork-Delegate: pablo.de.lara.guarch@intel.com 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 D6A2D44CF; Fri, 13 Jul 2018 16:23:35 +0200 (CEST) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by dpdk.org (Postfix) with ESMTP id 28E5B2BAE for ; Fri, 13 Jul 2018 16:23:27 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 13 Jul 2018 07:23:26 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.51,347,1526367600"; d="scan'208";a="56278219" Received: from silpixa00399952.ir.intel.com (HELO silpixa00399952.ger.corp.intel.com) ([10.237.223.64]) by orsmga007.jf.intel.com with ESMTP; 13 Jul 2018 07:23:25 -0700 From: David Hunt To: dev@dpdk.org Cc: david.hunt@intel.com, thomas@monjalon.net Date: Fri, 13 Jul 2018 15:23:00 +0100 Message-Id: <20180713142302.34576-8-david.hunt@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180713142302.34576-1-david.hunt@intel.com> References: <20180626092317.11031-2-david.hunt@intel.com> <20180713142302.34576-1-david.hunt@intel.com> Subject: [dpdk-dev] [PATCH v4 7/9] examples/vm_power: add branch ratio policy type 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 the capability for the vm_power_manager to receive a policy of type BRANCH_RATIO. This will add any vcpus in the policy to the oob monitoring thread. Signed-off-by: David Hunt Acked-by: Radu Nicolau --- examples/vm_power_manager/channel_monitor.c | 23 +++++++++++++++++++-- lib/librte_power/channel_commands.h | 3 ++- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/examples/vm_power_manager/channel_monitor.c b/examples/vm_power_manager/channel_monitor.c index 73bddd993..7fa47ba97 100644 --- a/examples/vm_power_manager/channel_monitor.c +++ b/examples/vm_power_manager/channel_monitor.c @@ -27,6 +27,7 @@ #include "channel_commands.h" #include "channel_manager.h" #include "power_manager.h" +#include "oob_monitor.h" #define RTE_LOGTYPE_CHANNEL_MONITOR RTE_LOGTYPE_USER1 @@ -92,6 +93,10 @@ get_pcpu_to_control(struct policy *pol) struct vm_info info; int pcpu, count; uint64_t mask_u64b; + struct core_info *ci; + int ret; + + ci = get_core_info(); RTE_LOG(INFO, CHANNEL_MONITOR, "Looking for pcpu for %s\n", pol->pkt.vm_name); @@ -100,8 +105,22 @@ get_pcpu_to_control(struct policy *pol) for (count = 0; count < pol->pkt.num_vcpu; count++) { mask_u64b = info.pcpu_mask[pol->pkt.vcpu_to_control[count]]; for (pcpu = 0; mask_u64b; mask_u64b &= ~(1ULL << pcpu++)) { - if ((mask_u64b >> pcpu) & 1) - pol->core_share[count].pcpu = pcpu; + if ((mask_u64b >> pcpu) & 1) { + if (pol->pkt.policy_to_use == BRANCH_RATIO) { + ci->cd[pcpu].oob_enabled = 1; + ret = add_core_to_monitor(pcpu); + if (ret == 0) + printf("Monitoring pcpu %d via Branch Ratio\n", + pcpu); + else + printf("Failed to start OOB Monitoring pcpu %d\n", + pcpu); + + } else { + pol->core_share[count].pcpu = pcpu; + printf("Monitoring pcpu %d\n", pcpu); + } + } } } } diff --git a/lib/librte_power/channel_commands.h b/lib/librte_power/channel_commands.h index 5e8b4ab5d..ee638eefa 100644 --- a/lib/librte_power/channel_commands.h +++ b/lib/librte_power/channel_commands.h @@ -48,7 +48,8 @@ enum workload {HIGH, MEDIUM, LOW}; enum policy_to_use { TRAFFIC, TIME, - WORKLOAD + WORKLOAD, + BRANCH_RATIO }; struct traffic { From patchwork Fri Jul 13 14:23: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: 43062 X-Patchwork-Delegate: pablo.de.lara.guarch@intel.com 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 9BC644B4B; Fri, 13 Jul 2018 16:23:37 +0200 (CEST) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by dpdk.org (Postfix) with ESMTP id 676532BAE for ; Fri, 13 Jul 2018 16:23:28 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 13 Jul 2018 07:23:27 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.51,347,1526367600"; d="scan'208";a="56278226" Received: from silpixa00399952.ir.intel.com (HELO silpixa00399952.ger.corp.intel.com) ([10.237.223.64]) by orsmga007.jf.intel.com with ESMTP; 13 Jul 2018 07:23:26 -0700 From: David Hunt To: dev@dpdk.org Cc: david.hunt@intel.com, thomas@monjalon.net Date: Fri, 13 Jul 2018 15:23:01 +0100 Message-Id: <20180713142302.34576-9-david.hunt@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180713142302.34576-1-david.hunt@intel.com> References: <20180626092317.11031-2-david.hunt@intel.com> <20180713142302.34576-1-david.hunt@intel.com> Subject: [dpdk-dev] [PATCH v4 8/9] examples/vm_power: add cli args to guest app 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 new command line arguments to the guest app to make testing and validation of the policy usage easier. These arguments are mainly around setting up the power management policy that is sent from the guest vm to to the vm_power_manager in the host New command line parameters: -n or --vm-name sets the name of the vm to be used by the host OS. -b or --busy-hours sets the list of hours that are predicted to be busy -q or --quiet-hours sets the list of hours that are predicted to be quiet -l or --vcpu-list sets the list of vcpus to monitor -p or --port-list sets the list of posts to monitor when using a workload policy. -o or --policy sets the default policy type TIME WORKLOAD TRAFFIC BRANCH_RATIO The format of the hours or list paramers is a comma-separated list of integers, which can take the form of a. x e.g. --vcpu-list=1 b. x,y e.g. --quiet-hours=3,4 c. x-y e.g. --busy-hours=9-12 d. combination of above (e.g. --busy-hours=4,5-7,9) Signed-off-by: David Hunt Acked-by: Radu Nicolau --- examples/vm_power_manager/guest_cli/Makefile | 2 +- examples/vm_power_manager/guest_cli/main.c | 151 +++++++++++++++++- examples/vm_power_manager/guest_cli/parse.c | 82 ++++++++++ examples/vm_power_manager/guest_cli/parse.h | 19 +++ .../guest_cli/vm_power_cli_guest.c | 113 +++++++------ .../guest_cli/vm_power_cli_guest.h | 6 + 6 files changed, 319 insertions(+), 54 deletions(-) create mode 100644 examples/vm_power_manager/guest_cli/parse.c create mode 100644 examples/vm_power_manager/guest_cli/parse.h diff --git a/examples/vm_power_manager/guest_cli/Makefile b/examples/vm_power_manager/guest_cli/Makefile index d710e22d9..8b1db861e 100644 --- a/examples/vm_power_manager/guest_cli/Makefile +++ b/examples/vm_power_manager/guest_cli/Makefile @@ -14,7 +14,7 @@ include $(RTE_SDK)/mk/rte.vars.mk APP = guest_vm_power_mgr # all source are stored in SRCS-y -SRCS-y := main.c vm_power_cli_guest.c +SRCS-y := main.c vm_power_cli_guest.c parse.c CFLAGS += -O3 -I$(RTE_SDK)/lib/librte_power/ CFLAGS += $(WERROR_FLAGS) diff --git a/examples/vm_power_manager/guest_cli/main.c b/examples/vm_power_manager/guest_cli/main.c index b17936d6b..36365b124 100644 --- a/examples/vm_power_manager/guest_cli/main.c +++ b/examples/vm_power_manager/guest_cli/main.c @@ -2,23 +2,20 @@ * Copyright(c) 2010-2014 Intel Corporation */ -/* #include -#include -#include -#include -#include -#include #include -#include -*/ #include +#include +#include #include #include #include +#include +#include #include "vm_power_cli_guest.h" +#include "parse.h" static void sig_handler(int signo) @@ -32,6 +29,136 @@ sig_handler(int signo) } +#define MAX_HOURS 24 + +/* Parse the argument given in the command line of the application */ +static int +parse_args(int argc, char **argv) +{ + int opt, ret; + char **argvopt; + int option_index; + char *prgname = argv[0]; + const struct option lgopts[] = { + { "vm-name", required_argument, 0, 'n'}, + { "busy-hours", required_argument, 0, 'b'}, + { "quiet-hours", required_argument, 0, 'q'}, + { "port-list", required_argument, 0, 'p'}, + { "vcpu-list", required_argument, 0, 'l'}, + { "policy", required_argument, 0, 'o'}, + {NULL, 0, 0, 0} + }; + struct channel_packet *policy; + unsigned short int hours[MAX_HOURS]; + unsigned short int cores[MAX_VCPU_PER_VM]; + unsigned short int ports[MAX_VCPU_PER_VM]; + int i, cnt, idx; + + policy = get_policy(); + set_policy_defaults(policy); + + argvopt = argv; + + while ((opt = getopt_long(argc, argvopt, "n:b:q:p:", + lgopts, &option_index)) != EOF) { + + switch (opt) { + /* portmask */ + case 'n': + strcpy(policy->vm_name, optarg); + printf("Setting VM Name to [%s]\n", policy->vm_name); + break; + case 'b': + case 'q': + //printf("***Processing set using [%s]\n", optarg); + cnt = parse_set(optarg, hours, MAX_HOURS); + if (cnt < 0) { + printf("Invalid value passed to quiet/busy hours - [%s]\n", + optarg); + break; + } + idx = 0; + for (i = 0; i < MAX_HOURS; i++) { + if (hours[i]) { + if (opt == 'b') { + printf("***Busy Hour %d\n", i); + policy->timer_policy.busy_hours + [idx++] = i; + } else { + printf("***Quiet Hour %d\n", i); + policy->timer_policy.quiet_hours + [idx++] = i; + } + } + } + break; + case 'l': + cnt = parse_set(optarg, cores, MAX_VCPU_PER_VM); + if (cnt < 0) { + printf("Invalid value passed to vcpu-list - [%s]\n", + optarg); + break; + } + idx = 0; + for (i = 0; i < MAX_VCPU_PER_VM; i++) { + if (cores[i]) { + printf("***Using core %d\n", i); + policy->vcpu_to_control[idx++] = i; + } + } + policy->num_vcpu = idx; + printf("Total cores: %d\n", idx); + break; + case 'p': + cnt = parse_set(optarg, ports, MAX_VCPU_PER_VM); + if (cnt < 0) { + printf("Invalid value passed to port-list - [%s]\n", + optarg); + break; + } + idx = 0; + for (i = 0; i < MAX_VCPU_PER_VM; i++) { + if (ports[i]) { + printf("***Using port %d\n", i); + set_policy_mac(i, idx++); + } + } + policy->nb_mac_to_monitor = idx; + printf("Total Ports: %d\n", idx); + break; + case 'o': + if (!strcmp(optarg, "TRAFFIC")) + policy->policy_to_use = TRAFFIC; + else if (!strcmp(optarg, "TIME")) + policy->policy_to_use = TIME; + else if (!strcmp(optarg, "WORKLOAD")) + policy->policy_to_use = WORKLOAD; + else if (!strcmp(optarg, "BRANCH_RATIO")) + policy->policy_to_use = BRANCH_RATIO; + else { + printf("Invalid policy specified: %s\n", + optarg); + return -1; + } + break; + /* long options */ + + case 0: + break; + + default: + return -1; + } + } + + if (optind >= 0) + argv[optind-1] = prgname; + + ret = optind-1; + optind = 0; /* reset getopt lib */ + return ret; +} + int main(int argc, char **argv) { @@ -45,6 +172,14 @@ main(int argc, char **argv) signal(SIGINT, sig_handler); signal(SIGTERM, sig_handler); + argc -= ret; + argv += ret; + + /* parse application arguments (after the EAL ones) */ + ret = parse_args(argc, argv); + if (ret < 0) + rte_exit(EXIT_FAILURE, "Invalid arguments\n"); + rte_power_set_env(PM_ENV_KVM_VM); RTE_LCORE_FOREACH(lcore_id) { rte_power_init(lcore_id); diff --git a/examples/vm_power_manager/guest_cli/parse.c b/examples/vm_power_manager/guest_cli/parse.c new file mode 100644 index 000000000..528df6d6f --- /dev/null +++ b/examples/vm_power_manager/guest_cli/parse.c @@ -0,0 +1,82 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation. + * Copyright(c) 2014 6WIND S.A. + */ + +#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/guest_cli/parse.h b/examples/vm_power_manager/guest_cli/parse.h new file mode 100644 index 000000000..c8aa0ea50 --- /dev/null +++ b/examples/vm_power_manager/guest_cli/parse.h @@ -0,0 +1,19 @@ +/* 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/guest_cli/vm_power_cli_guest.c b/examples/vm_power_manager/guest_cli/vm_power_cli_guest.c index 43bdeacef..0db1b804f 100644 --- a/examples/vm_power_manager/guest_cli/vm_power_cli_guest.c +++ b/examples/vm_power_manager/guest_cli/vm_power_cli_guest.c @@ -33,6 +33,71 @@ struct cmd_quit_result { cmdline_fixed_string_t quit; }; +union PFID { + struct ether_addr addr; + uint64_t pfid; +}; + +static struct channel_packet policy; + +struct channel_packet * +get_policy(void) +{ + return &policy; +} + +int +set_policy_mac(int port, int idx) +{ + struct channel_packet *policy; + union PFID pfid; + + /* Use port MAC address as the vfid */ + rte_eth_macaddr_get(port, &pfid.addr); + + printf("Port %u MAC: %02" PRIx8 ":%02" PRIx8 ":%02" PRIx8 ":" + "%02" PRIx8 ":%02" PRIx8 ":%02" PRIx8 "\n", + port, + pfid.addr.addr_bytes[0], pfid.addr.addr_bytes[1], + pfid.addr.addr_bytes[2], pfid.addr.addr_bytes[3], + pfid.addr.addr_bytes[4], pfid.addr.addr_bytes[5]); + policy = get_policy(); + policy->vfid[idx] = pfid.pfid; + return 0; +} + +void +set_policy_defaults(struct channel_packet *pkt) +{ + set_policy_mac(0, 0); + pkt->nb_mac_to_monitor = 1; + + pkt->t_boost_status.tbEnabled = false; + + pkt->vcpu_to_control[0] = 0; + pkt->vcpu_to_control[1] = 1; + pkt->num_vcpu = 2; + /* Dummy Population. */ + pkt->traffic_policy.min_packet_thresh = 96000; + pkt->traffic_policy.avg_max_packet_thresh = 1800000; + pkt->traffic_policy.max_max_packet_thresh = 2000000; + + pkt->timer_policy.busy_hours[0] = 3; + pkt->timer_policy.busy_hours[1] = 4; + pkt->timer_policy.busy_hours[2] = 5; + pkt->timer_policy.quiet_hours[0] = 11; + pkt->timer_policy.quiet_hours[1] = 12; + pkt->timer_policy.quiet_hours[2] = 13; + + pkt->timer_policy.hours_to_use_traffic_profile[0] = 8; + pkt->timer_policy.hours_to_use_traffic_profile[1] = 10; + + pkt->workload = LOW; + pkt->policy_to_use = TIME; + pkt->command = PKT_POLICY; + strcpy(pkt->vm_name, "ubuntu2"); +} + static void cmd_quit_parsed(__attribute__((unused)) void *parsed_result, __attribute__((unused)) struct cmdline *cl, __attribute__((unused)) void *data) @@ -118,54 +183,12 @@ struct cmd_send_policy_result { cmdline_fixed_string_t cmd; }; -union PFID { - struct ether_addr addr; - uint64_t pfid; -}; - static inline int -send_policy(void) +send_policy(struct channel_packet *pkt) { - struct channel_packet pkt; int ret; - union PFID pfid; - /* Use port MAC address as the vfid */ - rte_eth_macaddr_get(0, &pfid.addr); - printf("Port %u MAC: %02" PRIx8 ":%02" PRIx8 ":%02" PRIx8 ":" - "%02" PRIx8 ":%02" PRIx8 ":%02" PRIx8 "\n", - 1, - pfid.addr.addr_bytes[0], pfid.addr.addr_bytes[1], - pfid.addr.addr_bytes[2], pfid.addr.addr_bytes[3], - pfid.addr.addr_bytes[4], pfid.addr.addr_bytes[5]); - pkt.vfid[0] = pfid.pfid; - - pkt.nb_mac_to_monitor = 1; - pkt.t_boost_status.tbEnabled = false; - - pkt.vcpu_to_control[0] = 0; - pkt.vcpu_to_control[1] = 1; - pkt.num_vcpu = 2; - /* Dummy Population. */ - pkt.traffic_policy.min_packet_thresh = 96000; - pkt.traffic_policy.avg_max_packet_thresh = 1800000; - pkt.traffic_policy.max_max_packet_thresh = 2000000; - - pkt.timer_policy.busy_hours[0] = 3; - pkt.timer_policy.busy_hours[1] = 4; - pkt.timer_policy.busy_hours[2] = 5; - pkt.timer_policy.quiet_hours[0] = 11; - pkt.timer_policy.quiet_hours[1] = 12; - pkt.timer_policy.quiet_hours[2] = 13; - - pkt.timer_policy.hours_to_use_traffic_profile[0] = 8; - pkt.timer_policy.hours_to_use_traffic_profile[1] = 10; - - pkt.workload = LOW; - pkt.policy_to_use = TIME; - pkt.command = PKT_POLICY; - strcpy(pkt.vm_name, "ubuntu2"); - ret = rte_power_guest_channel_send_msg(&pkt, 1); + ret = rte_power_guest_channel_send_msg(pkt, 1); if (ret == 0) return 1; RTE_LOG(DEBUG, POWER, "Error sending message: %s\n", @@ -182,7 +205,7 @@ cmd_send_policy_parsed(void *parsed_result, struct cmdline *cl, if (!strcmp(res->cmd, "now")) { printf("Sending Policy down now!\n"); - ret = send_policy(); + ret = send_policy(&policy); } if (ret != 1) cmdline_printf(cl, "Error sending message: %s\n", diff --git a/examples/vm_power_manager/guest_cli/vm_power_cli_guest.h b/examples/vm_power_manager/guest_cli/vm_power_cli_guest.h index 75a262967..fd77f6a69 100644 --- a/examples/vm_power_manager/guest_cli/vm_power_cli_guest.h +++ b/examples/vm_power_manager/guest_cli/vm_power_cli_guest.h @@ -11,6 +11,12 @@ extern "C" { #include "channel_commands.h" +struct channel_packet *get_policy(void); + +int set_policy_mac(int port, int idx); + +void set_policy_defaults(struct channel_packet *pkt); + void run_cli(__attribute__((unused)) void *arg); #ifdef __cplusplus From patchwork Fri Jul 13 14:23:02 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Hunt, David" X-Patchwork-Id: 43063 X-Patchwork-Delegate: pablo.de.lara.guarch@intel.com 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 DF1564C8B; Fri, 13 Jul 2018 16:23:38 +0200 (CEST) Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) by dpdk.org (Postfix) with ESMTP id 7444C2BFA for ; Fri, 13 Jul 2018 16:23:29 +0200 (CEST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga007.jf.intel.com ([10.7.209.58]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 13 Jul 2018 07:23:29 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.51,347,1526367600"; d="scan'208";a="56278233" Received: from silpixa00399952.ir.intel.com (HELO silpixa00399952.ger.corp.intel.com) ([10.237.223.64]) by orsmga007.jf.intel.com with ESMTP; 13 Jul 2018 07:23:28 -0700 From: David Hunt To: dev@dpdk.org Cc: david.hunt@intel.com, thomas@monjalon.net Date: Fri, 13 Jul 2018 15:23:02 +0100 Message-Id: <20180713142302.34576-10-david.hunt@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180713142302.34576-1-david.hunt@intel.com> References: <20180626092317.11031-2-david.hunt@intel.com> <20180713142302.34576-1-david.hunt@intel.com> Subject: [dpdk-dev] [PATCH v4 9/9] examples/vm_power: make branch ratio configurable 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" For different workloads and poll loops, the theshold may be different for when you want to scale up and down. This patch allows changing of the default branch ratio by using the -b command line argument (or --branch-ratio=) Signed-off-by: David Hunt Acked-by: Radu Nicolau --- examples/vm_power_manager/main.c | 16 +++++++++++++++- examples/vm_power_manager/oob_monitor_x86.c | 3 +-- examples/vm_power_manager/power_manager.c | 1 + examples/vm_power_manager/power_manager.h | 3 +++ 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/examples/vm_power_manager/main.c b/examples/vm_power_manager/main.c index f9990f153..58c5fa45c 100644 --- a/examples/vm_power_manager/main.c +++ b/examples/vm_power_manager/main.c @@ -141,17 +141,19 @@ parse_args(int argc, char **argv) int option_index; char *prgname = argv[0]; struct core_info *ci; + float branch_ratio; static struct option lgopts[] = { { "mac-updating", no_argument, 0, 1}, { "no-mac-updating", no_argument, 0, 0}, { "core-list", optional_argument, 0, 'l'}, { "port-list", optional_argument, 0, 'p'}, + { "branch-ratio", optional_argument, 0, 'b'}, {NULL, 0, 0, 0} }; argvopt = argv; ci = get_core_info(); - while ((opt = getopt_long(argc, argvopt, "l:p:q:T:", + while ((opt = getopt_long(argc, argvopt, "l:p:q:T:b:", lgopts, &option_index)) != EOF) { switch (opt) { @@ -184,6 +186,18 @@ parse_args(int argc, char **argv) } free(oob_enable); break; + case 'b': + branch_ratio = 0.0; + if (strlen(optarg)) + branch_ratio = atof(optarg); + if (branch_ratio <= 0.0) { + printf("invalid branch ratio specified\n"); + return -1; + } + ci->branch_ratio_threshold = branch_ratio; + printf("***Setting branch ratio to %f\n", + branch_ratio); + break; /* long options */ case 0: break; diff --git a/examples/vm_power_manager/oob_monitor_x86.c b/examples/vm_power_manager/oob_monitor_x86.c index 62d503ca5..589c604e5 100644 --- a/examples/vm_power_manager/oob_monitor_x86.c +++ b/examples/vm_power_manager/oob_monitor_x86.c @@ -22,7 +22,6 @@ void branch_monitor_exit(void) /* Number of microseconds between each poll */ #define INTERVAL 100 #define PRINT_LOOP_COUNT (1000000/INTERVAL) -#define RATIO_THRESHOLD 0.03 #define IA32_PERFEVTSEL0 0x186 #define IA32_PERFEVTSEL1 0x187 #define IA32_PERFCTR0 0xc1 @@ -89,7 +88,7 @@ apply_policy(int core) ratio = (float)miss_diff * (float)100 / (float)hits_diff; - if (ratio < RATIO_THRESHOLD) + if (ratio < ci->branch_ratio_threshold) power_manager_scale_core_min(core); else power_manager_scale_core_max(core); diff --git a/examples/vm_power_manager/power_manager.c b/examples/vm_power_manager/power_manager.c index 4bdde23da..b7769c3c3 100644 --- a/examples/vm_power_manager/power_manager.c +++ b/examples/vm_power_manager/power_manager.c @@ -74,6 +74,7 @@ core_info_init(void) ci = get_core_info(); ci->core_count = get_nprocs_conf(); + ci->branch_ratio_threshold = BRANCH_RATIO_THRESHOLD; 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."); diff --git a/examples/vm_power_manager/power_manager.h b/examples/vm_power_manager/power_manager.h index 45385de37..605b3c8f6 100644 --- a/examples/vm_power_manager/power_manager.h +++ b/examples/vm_power_manager/power_manager.h @@ -19,8 +19,11 @@ struct core_details { struct core_info { uint16_t core_count; struct core_details *cd; + float branch_ratio_threshold; }; +#define BRANCH_RATIO_THRESHOLD 0.1 + struct core_info * get_core_info(void);