From 055c52583a2794da8ba1e85a48cce3832372b12f Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Wed, 8 Nov 2017 14:15:11 +0000 Subject: New upstream version 17.11-rc3 Change-Id: I6a5baa40612fe0c20f30b5fa773a6cbbac63a685 Signed-off-by: Luca Boccassi --- lib/librte_power/Makefile | 1 + lib/librte_power/channel_commands.h | 44 ++++++++++++ lib/librte_power/guest_channel.c | 7 ++ lib/librte_power/guest_channel.h | 15 ++++ lib/librte_power/rte_power.c | 9 +++ lib/librte_power/rte_power.h | 41 +++++++++++ lib/librte_power/rte_power_acpi_cpufreq.c | 111 +++++++++++++++++++++++++++++- lib/librte_power/rte_power_acpi_cpufreq.h | 40 +++++++++++ lib/librte_power/rte_power_kvm_vm.c | 19 +++++ lib/librte_power/rte_power_kvm_vm.h | 35 +++++++++- lib/librte_power/rte_power_version.map | 10 +++ 11 files changed, 330 insertions(+), 2 deletions(-) (limited to 'lib/librte_power') diff --git a/lib/librte_power/Makefile b/lib/librte_power/Makefile index 06cd10e8..1b1491d7 100644 --- a/lib/librte_power/Makefile +++ b/lib/librte_power/Makefile @@ -35,6 +35,7 @@ include $(RTE_SDK)/mk/rte.vars.mk LIB = librte_power.a CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR) -O3 -fno-strict-aliasing +LDLIBS += -lrte_eal EXPORT_MAP := rte_power_version.map diff --git a/lib/librte_power/channel_commands.h b/lib/librte_power/channel_commands.h index 383897bf..f0f5f0a2 100644 --- a/lib/librte_power/channel_commands.h +++ b/lib/librte_power/channel_commands.h @@ -39,6 +39,7 @@ extern "C" { #endif #include +#include /* Maximum number of channels per VM */ #define CHANNEL_CMDS_MAX_VM_CHANNELS 64 @@ -46,17 +47,60 @@ extern "C" { /* Valid Commands */ #define CPU_POWER 1 #define CPU_POWER_CONNECT 2 +#define PKT_POLICY 3 /* CPU Power Command Scaling */ #define CPU_POWER_SCALE_UP 1 #define CPU_POWER_SCALE_DOWN 2 #define CPU_POWER_SCALE_MAX 3 #define CPU_POWER_SCALE_MIN 4 +#define CPU_POWER_ENABLE_TURBO 5 +#define CPU_POWER_DISABLE_TURBO 6 +#define HOURS 24 + +#define MAX_VFS 10 +#define VM_MAX_NAME_SZ 32 + +#define MAX_VCPU_PER_VM 8 + +struct t_boost_status { + bool tbEnabled; +}; + +struct timer_profile { + int busy_hours[HOURS]; + int quiet_hours[HOURS]; + int hours_to_use_traffic_profile[HOURS]; +}; + +enum workload {HIGH, MEDIUM, LOW}; +enum policy_to_use { + TRAFFIC, + TIME, + WORKLOAD +}; + +struct traffic { + uint32_t min_packet_thresh; + uint32_t avg_max_packet_thresh; + uint32_t max_max_packet_thresh; +}; struct channel_packet { uint64_t resource_id; /**< core_num, device */ uint32_t unit; /**< scale down/up/min/max */ uint32_t command; /**< Power, IO, etc */ + char vm_name[VM_MAX_NAME_SZ]; + + uint64_t vfid[MAX_VFS]; + int nb_mac_to_monitor; + struct traffic traffic_policy; + uint8_t vcpu_to_control[MAX_VCPU_PER_VM]; + uint8_t num_vcpu; + struct timer_profile timer_policy; + enum workload workload; + enum policy_to_use policy_to_use; + struct t_boost_status t_boost_status; }; diff --git a/lib/librte_power/guest_channel.c b/lib/librte_power/guest_channel.c index 85c92fab..fa5de0f5 100644 --- a/lib/librte_power/guest_channel.c +++ b/lib/librte_power/guest_channel.c @@ -148,6 +148,13 @@ guest_channel_send_msg(struct channel_packet *pkt, unsigned lcore_id) return 0; } +int rte_power_guest_channel_send_msg(struct channel_packet *pkt, + unsigned int lcore_id) +{ + return guest_channel_send_msg(pkt, lcore_id); +} + + void guest_channel_host_disconnect(unsigned lcore_id) { diff --git a/lib/librte_power/guest_channel.h b/lib/librte_power/guest_channel.h index 9e18af52..741339ca 100644 --- a/lib/librte_power/guest_channel.h +++ b/lib/librte_power/guest_channel.h @@ -81,6 +81,21 @@ void guest_channel_host_disconnect(unsigned lcore_id); */ int guest_channel_send_msg(struct channel_packet *pkt, unsigned lcore_id); +/** + * Send a message contained in pkt over the Virtio-Serial to the host endpoint. + * + * @param pkt + * Pointer to a populated struct channel_packet + * + * @param lcore_id + * lcore_id. + * + * @return + * - 0 on success. + * - Negative on error. + */ +int rte_power_guest_channel_send_msg(struct channel_packet *pkt, + unsigned int lcore_id); #ifdef __cplusplus } diff --git a/lib/librte_power/rte_power.c b/lib/librte_power/rte_power.c index 998ed1c9..b327a865 100644 --- a/lib/librte_power/rte_power.c +++ b/lib/librte_power/rte_power.c @@ -50,6 +50,9 @@ rte_power_freq_change_t rte_power_freq_up = NULL; rte_power_freq_change_t rte_power_freq_down = NULL; rte_power_freq_change_t rte_power_freq_max = NULL; rte_power_freq_change_t rte_power_freq_min = NULL; +rte_power_freq_change_t rte_power_turbo_status; +rte_power_freq_change_t rte_power_freq_enable_turbo; +rte_power_freq_change_t rte_power_freq_disable_turbo; int rte_power_set_env(enum power_management_env env) @@ -65,6 +68,9 @@ rte_power_set_env(enum power_management_env env) rte_power_freq_down = rte_power_acpi_cpufreq_freq_down; rte_power_freq_min = rte_power_acpi_cpufreq_freq_min; rte_power_freq_max = rte_power_acpi_cpufreq_freq_max; + rte_power_turbo_status = rte_power_acpi_turbo_status; + rte_power_freq_enable_turbo = rte_power_acpi_enable_turbo; + rte_power_freq_disable_turbo = rte_power_acpi_disable_turbo; } else if (env == PM_ENV_KVM_VM) { rte_power_freqs = rte_power_kvm_vm_freqs; rte_power_get_freq = rte_power_kvm_vm_get_freq; @@ -73,6 +79,9 @@ rte_power_set_env(enum power_management_env env) rte_power_freq_down = rte_power_kvm_vm_freq_down; rte_power_freq_min = rte_power_kvm_vm_freq_min; rte_power_freq_max = rte_power_kvm_vm_freq_max; + rte_power_turbo_status = rte_power_kvm_vm_turbo_status; + rte_power_freq_enable_turbo = rte_power_kvm_vm_enable_turbo; + rte_power_freq_disable_turbo = rte_power_kvm_vm_disable_turbo; } else { RTE_LOG(ERR, POWER, "Invalid Power Management Environment(%d) set\n", env); diff --git a/lib/librte_power/rte_power.h b/lib/librte_power/rte_power.h index 67e0ec02..b17b7a53 100644 --- a/lib/librte_power/rte_power.h +++ b/lib/librte_power/rte_power.h @@ -236,6 +236,47 @@ extern rte_power_freq_change_t rte_power_freq_max; */ extern rte_power_freq_change_t rte_power_freq_min; +/** + * Query the Turbo Boost status of a specific lcore. + * Review each environments specific documentation for usage.. + * + * @param lcore_id + * lcore id. + * + * @return + * - 1 Turbo Boost is enabled for this lcore. + * - 0 Turbo Boost is disabled for this lcore. + * - Negative on error. + */ +extern rte_power_freq_change_t rte_power_turbo_status; + +/** + * Enable Turbo Boost for this lcore. + * Review each environments specific documentation for usage.. + * + * @param lcore_id + * lcore id. + * + * @return + * - 0 on success. + * - Negative on error. + */ +extern rte_power_freq_change_t rte_power_freq_enable_turbo; + +/** + * Disable Turbo Boost for this lcore. + * Review each environments specific documentation for usage.. + * + * @param lcore_id + * lcore id. + * + * @return + * - 0 on success. + * - Negative on error. + */ +extern rte_power_freq_change_t rte_power_freq_disable_turbo; + + #ifdef __cplusplus } #endif diff --git a/lib/librte_power/rte_power_acpi_cpufreq.c b/lib/librte_power/rte_power_acpi_cpufreq.c index a56c9b59..01ac5acb 100644 --- a/lib/librte_power/rte_power_acpi_cpufreq.c +++ b/lib/librte_power/rte_power_acpi_cpufreq.c @@ -87,6 +87,14 @@ #define POWER_SYSFILE_SETSPEED \ "/sys/devices/system/cpu/cpu%u/cpufreq/scaling_setspeed" +/* + * MSR related + */ +#define PLATFORM_INFO 0x0CE +#define TURBO_RATIO_LIMIT 0x1AD +#define IA32_PERF_CTL 0x199 +#define CORE_TURBO_DISABLE_BIT ((uint64_t)1<<32) + enum power_state { POWER_IDLE = 0, POWER_ONGOING, @@ -105,6 +113,8 @@ struct rte_power_info { char governor_ori[32]; /**< Original governor name */ uint32_t curr_idx; /**< Freq index in freqs array */ volatile uint32_t state; /**< Power in use state */ + uint16_t turbo_available; /**< Turbo Boost available */ + uint16_t turbo_enable; /**< Turbo Boost enable/disable */ } __rte_cache_aligned; static struct rte_power_info lcore_power_info[RTE_MAX_LCORE]; @@ -244,6 +254,18 @@ power_get_available_freqs(struct rte_power_info *pi) POWER_CONVERT_TO_DECIMAL); } + if ((pi->freqs[0]-1000) == pi->freqs[1]) { + pi->turbo_available = 1; + pi->turbo_enable = 1; + POWER_DEBUG_TRACE("Lcore %u Can do Turbo Boost\n", + pi->lcore_id); + } else { + pi->turbo_available = 0; + pi->turbo_enable = 0; + POWER_DEBUG_TRACE("Turbo Boost not available on Lcore %u\n", + pi->lcore_id); + } + ret = 0; POWER_DEBUG_TRACE("%d frequencie(s) of lcore %u are available\n", count, pi->lcore_id); @@ -525,7 +547,17 @@ rte_power_acpi_cpufreq_freq_max(unsigned lcore_id) } /* Frequencies in the array are from high to low. */ - return set_freq_internal(&lcore_power_info[lcore_id], 0); + if (lcore_power_info[lcore_id].turbo_available) { + if (lcore_power_info[lcore_id].turbo_enable) + /* Set to Turbo */ + return set_freq_internal( + &lcore_power_info[lcore_id], 0); + else + /* Set to max non-turbo */ + return set_freq_internal( + &lcore_power_info[lcore_id], 1); + } else + return set_freq_internal(&lcore_power_info[lcore_id], 0); } int @@ -543,3 +575,80 @@ rte_power_acpi_cpufreq_freq_min(unsigned lcore_id) /* Frequencies in the array are from high to low. */ return set_freq_internal(pi, pi->nb_freqs - 1); } + + +int +rte_power_acpi_turbo_status(unsigned int lcore_id) +{ + struct rte_power_info *pi; + + if (lcore_id >= RTE_MAX_LCORE) { + RTE_LOG(ERR, POWER, "Invalid lcore ID\n"); + return -1; + } + + pi = &lcore_power_info[lcore_id]; + + return pi->turbo_enable; +} + + +int +rte_power_acpi_enable_turbo(unsigned int lcore_id) +{ + struct rte_power_info *pi; + + if (lcore_id >= RTE_MAX_LCORE) { + RTE_LOG(ERR, POWER, "Invalid lcore ID\n"); + return -1; + } + + pi = &lcore_power_info[lcore_id]; + + if (pi->turbo_available) + pi->turbo_enable = 1; + else { + pi->turbo_enable = 0; + RTE_LOG(ERR, POWER, + "Failed to enable turbo on lcore %u\n", + lcore_id); + return -1; + } + + /* Max may have changed, so call to max function */ + if (rte_power_acpi_cpufreq_freq_max(lcore_id) < 0) { + RTE_LOG(ERR, POWER, + "Failed to set frequency of lcore %u to max\n", + lcore_id); + return -1; + } + + return 0; +} + +int +rte_power_acpi_disable_turbo(unsigned int lcore_id) +{ + struct rte_power_info *pi; + + if (lcore_id >= RTE_MAX_LCORE) { + RTE_LOG(ERR, POWER, "Invalid lcore ID\n"); + return -1; + } + + pi = &lcore_power_info[lcore_id]; + + pi->turbo_enable = 0; + + if ((pi->turbo_available) && (pi->curr_idx <= 1)) { + /* Try to set freq to max by default coming out of turbo */ + if (rte_power_acpi_cpufreq_freq_max(lcore_id) < 0) { + RTE_LOG(ERR, POWER, + "Failed to set frequency of lcore %u to max\n", + lcore_id); + return -1; + } + } + + return 0; +} diff --git a/lib/librte_power/rte_power_acpi_cpufreq.h b/lib/librte_power/rte_power_acpi_cpufreq.h index 68578e9b..eee0ca0a 100644 --- a/lib/librte_power/rte_power_acpi_cpufreq.h +++ b/lib/librte_power/rte_power_acpi_cpufreq.h @@ -185,6 +185,46 @@ int rte_power_acpi_cpufreq_freq_max(unsigned lcore_id); */ int rte_power_acpi_cpufreq_freq_min(unsigned lcore_id); +/** + * Get the turbo status of a specific lcore. + * It should be protected outside of this function for threadsafe. + * + * @param lcore_id + * lcore id. + * + * @return + * - 1 Turbo Boost is enabled on this lcore. + * - 0 Turbo Boost is disabled on this lcore. + * - Negative on error. + */ +int rte_power_acpi_turbo_status(unsigned int lcore_id); + +/** + * Enable Turbo Boost on a specific lcore. + * It should be protected outside of this function for threadsafe. + * + * @param lcore_id + * lcore id. + * + * @return + * - 0 Turbo Boost is enabled successfully on this lcore. + * - Negative on error. + */ +int rte_power_acpi_enable_turbo(unsigned int lcore_id); + +/** + * Disable Turbo Boost on a specific lcore. + * It should be protected outside of this function for threadsafe. + * + * @param lcore_id + * lcore id. + * + * @return + * - 0 Turbo Boost disabled successfully on this lcore. + * - Negative on error. + */ +int rte_power_acpi_disable_turbo(unsigned int lcore_id); + #ifdef __cplusplus } #endif diff --git a/lib/librte_power/rte_power_kvm_vm.c b/lib/librte_power/rte_power_kvm_vm.c index a1badf34..99060625 100644 --- a/lib/librte_power/rte_power_kvm_vm.c +++ b/lib/librte_power/rte_power_kvm_vm.c @@ -134,3 +134,22 @@ rte_power_kvm_vm_freq_min(unsigned lcore_id) { return send_msg(lcore_id, CPU_POWER_SCALE_MIN); } + +int +rte_power_kvm_vm_turbo_status(__attribute__((unused)) unsigned int lcore_id) +{ + RTE_LOG(ERR, POWER, "rte_power_turbo_status is not implemented for Virtual Machine Power Management\n"); + return -ENOTSUP; +} + +int +rte_power_kvm_vm_enable_turbo(unsigned int lcore_id) +{ + return send_msg(lcore_id, CPU_POWER_ENABLE_TURBO); +} + +int +rte_power_kvm_vm_disable_turbo(unsigned int lcore_id) +{ + return send_msg(lcore_id, CPU_POWER_DISABLE_TURBO); +} diff --git a/lib/librte_power/rte_power_kvm_vm.h b/lib/librte_power/rte_power_kvm_vm.h index dcbc878a..9af41d64 100644 --- a/lib/librte_power/rte_power_kvm_vm.h +++ b/lib/librte_power/rte_power_kvm_vm.h @@ -172,8 +172,41 @@ int rte_power_kvm_vm_freq_max(unsigned lcore_id); */ int rte_power_kvm_vm_freq_min(unsigned lcore_id); +/** + * It should be protected outside of this function for threadsafe. + * + * @param lcore_id + * lcore id. + * + * @return + * -ENOTSUP + */ +int rte_power_kvm_vm_turbo_status(unsigned int lcore_id); + +/** + * It should be protected outside of this function for threadsafe. + * + * @param lcore_id + * lcore id. + * + * @return + * - 1 on success. + * - Negative on error. + */ +int rte_power_kvm_vm_enable_turbo(unsigned int lcore_id); + +/** + * It should be protected outside of this function for threadsafe. + * + * @param lcore_id + * lcore id. + * + * @return + * - 1 on success. + * - Negative on error. + */ +int rte_power_kvm_vm_disable_turbo(unsigned int lcore_id); #ifdef __cplusplus } #endif - #endif diff --git a/lib/librte_power/rte_power_version.map b/lib/librte_power/rte_power_version.map index db75ff3e..96dc42ec 100644 --- a/lib/librte_power/rte_power_version.map +++ b/lib/librte_power/rte_power_version.map @@ -16,3 +16,13 @@ DPDK_2.0 { local: *; }; + +DPDK_17.11 { + global: + + rte_power_guest_channel_send_msg; + rte_power_freq_disable_turbo; + rte_power_freq_enable_turbo; + rte_power_turbo_status; + +} DPDK_2.0; \ No newline at end of file -- cgit 1.2.3-korg