DPDK patches and discussions
 help / color / mirror / Atom feed
From: Anatoly Burakov <anatoly.burakov@intel.com>
To: dev@dpdk.org
Cc: David Hunt <david.hunt@intel.com>, Ray Kinsella <mdr@ashroe.eu>,
	Neil Horman <nhorman@tuxdriver.com>,
	reshma.pattan@intel.com, hkalra@marvell.com,
	jerinjacobk@gmail.com, yinan.wang@intel.com
Subject: [dpdk-dev] [PATCH v2 6/7] power: add API to probe support for a specific env
Date: Thu, 18 Jun 2020 18:18:28 +0100	[thread overview]
Message-ID: <be6f9802bf7b58d0771f91f9d611f7a592a33ce0.1592500565.git.anatoly.burakov@intel.com> (raw)
In-Reply-To: <cover.1592500565.git.anatoly.burakov@intel.com>
In-Reply-To: <cover.1592500565.git.anatoly.burakov@intel.com>

Currently, there is no way to know if the power management env is
supported without trying to initialize it. The init API also does
not distinguish between failure due to some error and failure due to
power management not being available on the platform in the first
place.

Thus, add an API that provides capability of probing support for a
specific power management API.

Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
Suggested-by: Jerin Jacob <jerinjacobk@gmail.com>
---
 lib/librte_power/Makefile               |  1 +
 lib/librte_power/guest_channel.c        | 26 +++++++++++++
 lib/librte_power/guest_channel.h        | 12 ++++++
 lib/librte_power/meson.build            |  3 +-
 lib/librte_power/power_acpi_cpufreq.c   |  7 ++++
 lib/librte_power/power_acpi_cpufreq.h   | 10 +++++
 lib/librte_power/power_common.c         | 52 +++++++++++++++++++++++++
 lib/librte_power/power_common.h         |  3 ++
 lib/librte_power/power_kvm_vm.c         |  5 +++
 lib/librte_power/power_kvm_vm.h         | 10 +++++
 lib/librte_power/power_pstate_cpufreq.c |  7 ++++
 lib/librte_power/power_pstate_cpufreq.h | 10 +++++
 lib/librte_power/rte_power.c            | 17 ++++++++
 lib/librte_power/rte_power.h            | 18 +++++++++
 lib/librte_power/rte_power_version.map  |  1 +
 15 files changed, 181 insertions(+), 1 deletion(-)
 create mode 100644 lib/librte_power/power_common.c

diff --git a/lib/librte_power/Makefile b/lib/librte_power/Makefile
index 087d643ee5..3b067b615f 100644
--- a/lib/librte_power/Makefile
+++ b/lib/librte_power/Makefile
@@ -16,6 +16,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_POWER) := rte_power.c power_acpi_cpufreq.c
 SRCS-$(CONFIG_RTE_LIBRTE_POWER) += power_kvm_vm.c guest_channel.c
 SRCS-$(CONFIG_RTE_LIBRTE_POWER) += rte_power_empty_poll.c
 SRCS-$(CONFIG_RTE_LIBRTE_POWER) += power_pstate_cpufreq.c
+SRCS-$(CONFIG_RTE_LIBRTE_POWER) += power_common.c
 
 # install this header file
 SYMLINK-$(CONFIG_RTE_LIBRTE_POWER)-include := rte_power.h  rte_power_empty_poll.h
diff --git a/lib/librte_power/guest_channel.c b/lib/librte_power/guest_channel.c
index b984d55bc8..7b5926e5c4 100644
--- a/lib/librte_power/guest_channel.c
+++ b/lib/librte_power/guest_channel.c
@@ -2,6 +2,7 @@
  * Copyright(c) 2010-2014 Intel Corporation
  */
 
+#include <glob.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
@@ -25,6 +26,31 @@
 
 static int global_fds[RTE_MAX_LCORE] = { [0 ... RTE_MAX_LCORE-1] = -1 };
 
+int
+guest_channel_host_check_exists(const char *path)
+{
+	char glob_path[PATH_MAX];
+	glob_t g;
+	int ret;
+
+	/* we cannot know in advance which cores have VM channels, so glob */
+	snprintf(glob_path, PATH_MAX, "%s.*", path);
+
+	ret = glob(glob_path, GLOB_NOSORT, NULL, &g);
+	if (ret != 0) {
+		/* couldn't read anything */
+		ret = 0;
+		goto out;
+	}
+
+	/* do we have at least one match? */
+	ret = g.gl_pathc > 0;
+
+out:
+	globfree(&g);
+	return ret;
+}
+
 int
 guest_channel_host_connect(const char *path, unsigned int lcore_id)
 {
diff --git a/lib/librte_power/guest_channel.h b/lib/librte_power/guest_channel.h
index 025961606c..e15db46fc7 100644
--- a/lib/librte_power/guest_channel.h
+++ b/lib/librte_power/guest_channel.h
@@ -10,6 +10,18 @@ extern "C" {
 
 #include <channel_commands.h>
 
+/**
+ * Check if any Virtio-Serial VM end-points exist in path.
+ *
+ * @param path
+ *  The path to the serial device on the filesystem
+ *
+ * @return
+ *  - 1 if at least one potential end-point found.
+ *  - 0 if no end-points found.
+ */
+int guest_channel_host_check_exists(const char *path);
+
 /**
  * Connect to the Virtio-Serial VM end-point located in path. It is
  * thread safe for unique lcore_ids. This function must be only called once from
diff --git a/lib/librte_power/meson.build b/lib/librte_power/meson.build
index cdf08f6df3..78c031c943 100644
--- a/lib/librte_power/meson.build
+++ b/lib/librte_power/meson.build
@@ -8,6 +8,7 @@ endif
 sources = files('rte_power.c', 'power_acpi_cpufreq.c',
 		'power_kvm_vm.c', 'guest_channel.c',
 		'rte_power_empty_poll.c',
-		'power_pstate_cpufreq.c')
+		'power_pstate_cpufreq.c',
+		'power_common.c')
 headers = files('rte_power.h','rte_power_empty_poll.h')
 deps += ['timer']
diff --git a/lib/librte_power/power_acpi_cpufreq.c b/lib/librte_power/power_acpi_cpufreq.c
index f443fce69f..583815a07e 100644
--- a/lib/librte_power/power_acpi_cpufreq.c
+++ b/lib/librte_power/power_acpi_cpufreq.c
@@ -59,6 +59,7 @@
 		"/sys/devices/system/cpu/cpu%u/cpufreq/scaling_available_frequencies"
 #define POWER_SYSFILE_SETSPEED   \
 		"/sys/devices/system/cpu/cpu%u/cpufreq/scaling_setspeed"
+#define POWER_ACPI_DRIVER "acpi-cpufreq"
 
 /*
  * MSR related
@@ -289,6 +290,12 @@ power_init_for_setting_freq(struct rte_power_info *pi)
 	return -1;
 }
 
+int
+power_acpi_cpufreq_check_supported(void)
+{
+	return cpufreq_check_scaling_driver(POWER_ACPI_DRIVER);
+}
+
 int
 power_acpi_cpufreq_init(unsigned int lcore_id)
 {
diff --git a/lib/librte_power/power_acpi_cpufreq.h b/lib/librte_power/power_acpi_cpufreq.h
index 1af7416073..038857b3a6 100644
--- a/lib/librte_power/power_acpi_cpufreq.h
+++ b/lib/librte_power/power_acpi_cpufreq.h
@@ -20,6 +20,16 @@
 extern "C" {
 #endif
 
+/**
+ * Check if ACPI power management is supported.
+ *
+ * @return
+ *   - 1 if supported
+ *   - 0 if unsupported
+ *   - -1 if error, with rte_errno indicating reason for error.
+ */
+int power_acpi_cpufreq_check_supported(void);
+
 /**
  * Initialize power management for a specific lcore. It will check and set the
  * governor to userspace for the lcore, get the available frequencies, and
diff --git a/lib/librte_power/power_common.c b/lib/librte_power/power_common.c
new file mode 100644
index 0000000000..59023d986b
--- /dev/null
+++ b/lib/librte_power/power_common.c
@@ -0,0 +1,52 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2020 Intel Corporation
+ */
+
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "power_common.h"
+
+#define POWER_SYSFILE_SCALING_DRIVER   \
+		"/sys/devices/system/cpu/cpu%u/cpufreq/scaling_driver"
+
+int
+cpufreq_check_scaling_driver(const char *driver_name)
+{
+	unsigned int lcore_id = 0; /* always check core 0 */
+	char fullpath[PATH_MAX];
+	char readbuf[PATH_MAX];
+	char *s;
+	FILE *f;
+
+	/*
+	 * Check if scaling driver matches what we expect.
+	 */
+	snprintf(fullpath, sizeof(fullpath), POWER_SYSFILE_SCALING_DRIVER,
+			lcore_id);
+	f = fopen(fullpath, "r");
+
+	/* if there's no driver at all, bail out */
+	if (f == NULL)
+		return 0;
+
+	s = fgets(readbuf, sizeof(readbuf), f);
+	/* don't need it any more */
+	fclose(f);
+
+	/* if we can't read it, consider unsupported */
+	if (s == NULL)
+		return 0;
+
+	/* does the driver name match? */
+	if (strncmp(readbuf, driver_name, sizeof(readbuf)) != 0)
+		return 0;
+
+	/*
+	 * We might have a situation where the driver is supported, but we don't
+	 * have permissions to do frequency scaling. This error should not be
+	 * handled here, so consider the system to support scaling for now.
+	 */
+	return 1;
+}
diff --git a/lib/librte_power/power_common.h b/lib/librte_power/power_common.h
index feeb5777b7..fab3ca995a 100644
--- a/lib/librte_power/power_common.h
+++ b/lib/librte_power/power_common.h
@@ -7,4 +7,7 @@
 
 #define RTE_POWER_INVALID_FREQ_INDEX (~0)
 
+/* check if scaling driver matches one we want */
+int cpufreq_check_scaling_driver(const char *driver);
+
 #endif /* _POWER_COMMON_H_ */
diff --git a/lib/librte_power/power_kvm_vm.c b/lib/librte_power/power_kvm_vm.c
index 2bb17beb17..409c3e03ab 100644
--- a/lib/librte_power/power_kvm_vm.c
+++ b/lib/librte_power/power_kvm_vm.c
@@ -15,6 +15,11 @@
 
 static struct channel_packet pkt[RTE_MAX_LCORE];
 
+int
+power_kvm_vm_check_supported(void)
+{
+	return guest_channel_host_check_exists(FD_PATH);
+}
 
 int
 power_kvm_vm_init(unsigned int lcore_id)
diff --git a/lib/librte_power/power_kvm_vm.h b/lib/librte_power/power_kvm_vm.h
index 94d4aa1213..73b4c82e57 100644
--- a/lib/librte_power/power_kvm_vm.h
+++ b/lib/librte_power/power_kvm_vm.h
@@ -20,6 +20,16 @@
 extern "C" {
 #endif
 
+/**
+ * Check if KVM power management is supported.
+ *
+ * @return
+ *   - 1 if supported
+ *   - 0 if unsupported
+ *   - -1 if error, with rte_errno indicating reason for error.
+ */
+int power_kvm_vm_check_supported(void);
+
 /**
  * Initialize power management for a specific lcore.
  *
diff --git a/lib/librte_power/power_pstate_cpufreq.c b/lib/librte_power/power_pstate_cpufreq.c
index 2d8a9499dc..2526441a4c 100644
--- a/lib/librte_power/power_pstate_cpufreq.c
+++ b/lib/librte_power/power_pstate_cpufreq.c
@@ -71,6 +71,7 @@
 		"/sys/devices/system/cpu/cpu%u/cpufreq/cpuinfo_min_freq"
 #define POWER_SYSFILE_BASE_FREQ  \
 		"/sys/devices/system/cpu/cpu%u/cpufreq/base_frequency"
+#define POWER_PSTATE_DRIVER "intel_pstate"
 #define POWER_MSR_PATH  "/dev/cpu/%u/msr"
 
 /*
@@ -531,6 +532,12 @@ power_get_available_freqs(struct pstate_power_info *pi)
 	return ret;
 }
 
+int
+power_pstate_cpufreq_check_supported(void)
+{
+	return cpufreq_check_scaling_driver(POWER_PSTATE_DRIVER);
+}
+
 int
 power_pstate_cpufreq_init(unsigned int lcore_id)
 {
diff --git a/lib/librte_power/power_pstate_cpufreq.h b/lib/librte_power/power_pstate_cpufreq.h
index 6fd801881f..0be0bd6b81 100644
--- a/lib/librte_power/power_pstate_cpufreq.h
+++ b/lib/librte_power/power_pstate_cpufreq.h
@@ -20,6 +20,16 @@
 extern "C" {
 #endif
 
+/**
+ * Check if pstate power management is supported.
+ *
+ * @return
+ *   - 1 if supported
+ *   - 0 if unsupported
+ *   - -1 if error, with rte_errno indicating reason for error.
+ */
+int power_pstate_cpufreq_check_supported(void);
+
 /**
  * Initialize power management for a specific lcore. It will check and set the
  * governor to performance for the lcore, get the available frequencies, and
diff --git a/lib/librte_power/rte_power.c b/lib/librte_power/rte_power.c
index 6b77227275..98eaba9154 100644
--- a/lib/librte_power/rte_power.c
+++ b/lib/librte_power/rte_power.c
@@ -2,6 +2,7 @@
  * Copyright(c) 2010-2014 Intel Corporation
  */
 
+#include <rte_errno.h>
 #include <rte_spinlock.h>
 
 #include "rte_power.h"
@@ -43,6 +44,22 @@ reset_power_function_ptrs(void)
 	rte_power_get_capabilities = NULL;
 }
 
+int
+rte_power_check_env_supported(enum power_management_env env)
+{
+	switch (env) {
+	case PM_ENV_ACPI_CPUFREQ:
+		return power_acpi_cpufreq_check_supported();
+	case PM_ENV_PSTATE_CPUFREQ:
+		return power_pstate_cpufreq_check_supported();
+	case PM_ENV_KVM_VM:
+		return power_kvm_vm_check_supported();
+	default:
+		rte_errno = EINVAL;
+		return -1;
+	}
+}
+
 int
 rte_power_set_env(enum power_management_env env)
 {
diff --git a/lib/librte_power/rte_power.h b/lib/librte_power/rte_power.h
index 427058b811..bbbde4dfb4 100644
--- a/lib/librte_power/rte_power.h
+++ b/lib/librte_power/rte_power.h
@@ -23,6 +23,24 @@ extern "C" {
 enum power_management_env {PM_ENV_NOT_SET, PM_ENV_ACPI_CPUFREQ, PM_ENV_KVM_VM,
 		PM_ENV_PSTATE_CPUFREQ};
 
+/**
+ * @warning
+ * @b EXPERIMENTAL: this API may change, or be removed, without prior notice
+ *
+ * Check if a specific power management environment type is supported on a
+ * currently running system.
+ *
+ * @param env
+ *   The environment type to check support for.
+ *
+ * @return
+ *   - 1 if supported
+ *   - 0 if unsupported
+ *   - -1 if error, with rte_errno indicating reason for error.
+ */
+__rte_experimental
+int rte_power_check_env_supported(enum power_management_env env);
+
 /**
  * Set the default power management implementation. If this is not called prior
  * to rte_power_init(), then auto-detect of the environment will take place.
diff --git a/lib/librte_power/rte_power_version.map b/lib/librte_power/rte_power_version.map
index 55a168f56e..00ee5753e2 100644
--- a/lib/librte_power/rte_power_version.map
+++ b/lib/librte_power/rte_power_version.map
@@ -26,6 +26,7 @@ EXPERIMENTAL {
 	global:
 
 	rte_empty_poll_detection;
+	rte_power_check_env_supported;
 	rte_power_empty_poll_stat_fetch;
 	rte_power_empty_poll_stat_free;
 	rte_power_empty_poll_stat_init;
-- 
2.17.1

  parent reply	other threads:[~2020-06-18 17:19 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-28  9:13 [dpdk-dev] [PATCH 0/3] Add interrupt-only mode to l3fwd-power Anatoly Burakov
2020-05-28  9:13 ` [dpdk-dev] [PATCH 1/3] l3fwd-power: disable interrupts by default Anatoly Burakov
2020-05-28  9:13 ` [dpdk-dev] [PATCH 2/3] l3fwd-power: only allow supported power library envs Anatoly Burakov
2020-05-28  9:13 ` [dpdk-dev] [PATCH 3/3] l3fwd-power: add interrupt-only mode Anatoly Burakov
2020-05-29 13:19   ` Harman Kalra
2020-05-29 14:19     ` Burakov, Anatoly
2020-05-30 10:02       ` [dpdk-dev] [EXT] " Harman Kalra
2020-06-01 12:50         ` Burakov, Anatoly
2020-06-02 10:23           ` Harman Kalra
2020-06-02 12:16             ` Harman Kalra
2020-06-15 11:31               ` Burakov, Anatoly
2020-06-15 11:43                 ` Jerin Jacob
2020-06-15 15:05                   ` Burakov, Anatoly
2020-06-15 15:21                     ` Jerin Jacob
2020-06-15 15:45                       ` Burakov, Anatoly
2020-06-15 16:29                         ` Jerin Jacob
2020-06-16  9:31                           ` Burakov, Anatoly
2020-06-16 17:09                             ` Jerin Jacob
2020-06-08  1:24 ` [dpdk-dev] [PATCH 0/3] Add interrupt-only mode to l3fwd-power Wang, Yinan
2020-06-18 17:18 ` [dpdk-dev] [PATCH v2 0/7] " Anatoly Burakov
2020-06-19 10:53   ` [dpdk-dev] [PATCH v3 " Anatoly Burakov
2020-07-11 11:35     ` Thomas Monjalon
2020-06-19 10:53   ` [dpdk-dev] [PATCH v3 1/7] l3fwd-power: disable interrupts by default Anatoly Burakov
2020-06-19 10:53   ` [dpdk-dev] [PATCH v3 2/7] l3fwd-power: only allow supported power library envs Anatoly Burakov
2020-06-19 10:53   ` [dpdk-dev] [PATCH v3 3/7] l3fwd-power: code style and flow fixes Anatoly Burakov
2020-06-19 10:53   ` [dpdk-dev] [PATCH v3 4/7] l3fwd-power: add support for requesting legacy mode Anatoly Burakov
2020-06-19 10:53   ` [dpdk-dev] [PATCH v3 5/7] l3fwd-power: add interrupt-only mode Anatoly Burakov
2020-06-19 10:53   ` [dpdk-dev] [PATCH v3 6/7] power: add API to probe support for a specific env Anatoly Burakov
2020-06-19 10:53   ` [dpdk-dev] [PATCH v3 7/7] l3fwd-power: add auto-selection of default mode Anatoly Burakov
2020-07-11 10:07     ` Thomas Monjalon
2020-06-18 17:18 ` [dpdk-dev] [PATCH v2 1/7] l3fwd-power: disable interrupts by default Anatoly Burakov
2020-06-18 17:18 ` [dpdk-dev] [PATCH v2 2/7] l3fwd-power: only allow supported power library envs Anatoly Burakov
2020-06-18 17:18 ` [dpdk-dev] [PATCH v2 3/7] l3fwd-power: code style and flow fixes Anatoly Burakov
2020-06-18 17:18 ` [dpdk-dev] [PATCH v2 4/7] l3fwd-power: add support for requesting legacy mode Anatoly Burakov
2020-06-18 17:18 ` [dpdk-dev] [PATCH v2 5/7] l3fwd-power: add interrupt-only mode Anatoly Burakov
2020-06-18 17:18 ` Anatoly Burakov [this message]
2020-06-18 17:18 ` [dpdk-dev] [PATCH v2 7/7] l3fwd-power: add auto-selection of default mode Anatoly Burakov
2020-06-19  7:37   ` [dpdk-dev] [EXT] " Harman Kalra
2020-06-19  9:56     ` Burakov, Anatoly

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=be6f9802bf7b58d0771f91f9d611f7a592a33ce0.1592500565.git.anatoly.burakov@intel.com \
    --to=anatoly.burakov@intel.com \
    --cc=david.hunt@intel.com \
    --cc=dev@dpdk.org \
    --cc=hkalra@marvell.com \
    --cc=jerinjacobk@gmail.com \
    --cc=mdr@ashroe.eu \
    --cc=nhorman@tuxdriver.com \
    --cc=reshma.pattan@intel.com \
    --cc=yinan.wang@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).