6119fdc606
- ofpathname: speed up l2of_scsi() - ofpathname: failed to boot - update lparstat man page with -E option - enable support for ibm,drc-info property
216 lines
6.4 KiB
Diff
216 lines
6.4 KiB
Diff
From 8f0bf6a9dd14c16ee95092f43c45ee256f10637b Mon Sep 17 00:00:00 2001
|
|
Message-Id: <8f0bf6a9dd14c16ee95092f43c45ee256f10637b.1587532692.git.kamalesh@linux.vnet.ibm.com>
|
|
In-Reply-To: <cover.1587532692.git.kamalesh@linux.vnet.ibm.com>
|
|
References: <cover.1587532692.git.kamalesh@linux.vnet.ibm.com>
|
|
From: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
|
|
Date: Tue, 21 Apr 2020 07:58:19 -0500
|
|
Subject: [PATCH V4 05/14] lparstat: Assign file descriptors to speed up read
|
|
To: powerpc-utils-devel@googlegroups.com
|
|
Cc: Tyrel Datwyler <tyreld@linux.ibm.com>,
|
|
Nathan Lynch <nathanl@linux.ibm.com>,
|
|
Naveen N . Rao <naveen.n.rao@linux.vnet.ibm.com>,
|
|
Gautham R . Shenoy <ego@linux.vnet.ibm.com>,
|
|
Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
|
|
|
|
For every sampling interval, three per-cpu sysfs files is read to
|
|
capture spurr, idle_purr and idle_spurr values. Every read takes
|
|
three file operation such as open, read, close, future this scales
|
|
with number of CPUs in the system. To reduce the latency involved
|
|
in open and close, assign a permanent file descriptors per online cpu.
|
|
|
|
without caching file descriptors
|
|
---------------------------------
|
|
|
|
System Configuration
|
|
type=Dedicated mode=Capped smt=8 lcpu=4 mem=8302464 kB cpus=0 ent=4.00
|
|
|
|
---Actual--- -Normalized-
|
|
%busy %idle Frequency %busy %idle
|
|
------ ------ ------------- ------ ------
|
|
0.04 99.95 3.16GHz[100%] 0.04 99.95 1.1003219
|
|
0.15 99.85 3.16GHz[100%] 0.15 99.85 1.1003222
|
|
0.04 99.96 3.16GHz[100%] 0.04 99.96 1.1003179
|
|
0.03 99.97 3.16GHz[100%] 0.03 99.97 1.1003183
|
|
0.03 99.97 3.16GHz[100%] 0.03 99.97 1.1003166
|
|
|
|
with caching file descriptors
|
|
------------------------------
|
|
|
|
System Configuration
|
|
type=Dedicated mode=Capped smt=8 lcpu=4 mem=8302464 kB cpus=0 ent=4.00
|
|
|
|
---Actual--- -Normalized-
|
|
%busy %idle Frequency %busy %idle
|
|
------ ------ ------------- ------ ------
|
|
0.03 99.96 3.16GHz[100%] 0.03 99.97 1.1001793
|
|
0.03 99.97 3.16GHz[100%] 0.03 99.97 1.1001775
|
|
0.03 99.97 3.16GHz[100%] 0.03 99.97 1.1001775
|
|
0.02 99.98 3.16GHz[100%] 0.02 99.98 1.1001766
|
|
0.02 99.98 3.16GHz[100%] 0.02 99.98 1.1001762
|
|
|
|
Signed-off-by: Kamalesh Babulal <kamalesh@linux.vnet.ibm.com>
|
|
---
|
|
src/lparstat.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
src/lparstat.h | 12 +++++++
|
|
2 files changed, 100 insertions(+)
|
|
|
|
diff --git a/src/lparstat.c b/src/lparstat.c
|
|
index 24c48ad..f5c0ce5 100644
|
|
--- a/src/lparstat.c
|
|
+++ b/src/lparstat.c
|
|
@@ -27,6 +27,8 @@
|
|
#include <string.h>
|
|
#include <getopt.h>
|
|
#include <unistd.h>
|
|
+#include <fcntl.h>
|
|
+#include <signal.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/time.h>
|
|
#include "lparstat.h"
|
|
@@ -43,6 +45,8 @@ static int threads_per_cpu;
|
|
static int cpus_in_system;
|
|
static int threads_in_system;
|
|
|
|
+static cpu_sysfs_fd *cpu_sysfs_fds;
|
|
+
|
|
struct sysentry *get_sysentry(char *name)
|
|
{
|
|
struct sysentry *se = &system_data[0];
|
|
@@ -93,6 +97,80 @@ static int get_one_smt_state(int core)
|
|
return __get_one_smt_state(core, threads_per_cpu);
|
|
}
|
|
|
|
+static int assign_read_fd(const char *path)
|
|
+{
|
|
+ int rc = 0;
|
|
+
|
|
+ rc = access(path, R_OK);
|
|
+ if (rc)
|
|
+ return -1;
|
|
+
|
|
+ rc = open(path, O_RDONLY);
|
|
+ return rc;
|
|
+}
|
|
+
|
|
+static void close_cpu_sysfs_fds(int threads_in_system)
|
|
+{
|
|
+ int i;
|
|
+
|
|
+ for (i = 0; i < threads_in_system && cpu_sysfs_fds[i].spurr; i++) {
|
|
+ close(cpu_sysfs_fds[i].spurr);
|
|
+ close(cpu_sysfs_fds[i].idle_purr);
|
|
+ close(cpu_sysfs_fds[i].idle_spurr);
|
|
+ }
|
|
+
|
|
+ free(cpu_sysfs_fds);
|
|
+}
|
|
+
|
|
+static int assign_cpu_sysfs_fds(int threads_in_system)
|
|
+{
|
|
+ int cpu_idx, i;
|
|
+ char sysfs_file_path[SYSFS_PATH_MAX];
|
|
+
|
|
+ cpu_sysfs_fds =
|
|
+ (cpu_sysfs_fd*)calloc(sizeof(cpu_sysfs_fd), threads_in_system);
|
|
+ if (!cpu_sysfs_fds) {
|
|
+ fprintf(stderr, "Failed to allocate memory for sysfs file descriptors\n");
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ for (cpu_idx = 0, i = 0; i < threads_in_system; i++) {
|
|
+ if (!cpu_online(i))
|
|
+ continue;
|
|
+
|
|
+ cpu_sysfs_fds[cpu_idx].cpu = i;
|
|
+
|
|
+ snprintf(sysfs_file_path, SYSFS_PATH_MAX, SYSFS_PERCPU_SPURR, i);
|
|
+ cpu_sysfs_fds[cpu_idx].spurr = assign_read_fd(sysfs_file_path);
|
|
+ if (cpu_sysfs_fds[cpu_idx].spurr == -1)
|
|
+ goto error;
|
|
+
|
|
+ snprintf(sysfs_file_path, SYSFS_PATH_MAX, SYSFS_PERCPU_IDLE_PURR, i);
|
|
+ cpu_sysfs_fds[cpu_idx].idle_purr = assign_read_fd(sysfs_file_path);
|
|
+ if (cpu_sysfs_fds[cpu_idx].idle_purr == -1)
|
|
+ goto error;
|
|
+
|
|
+ snprintf(sysfs_file_path, SYSFS_PATH_MAX, SYSFS_PERCPU_IDLE_SPURR, i);
|
|
+ cpu_sysfs_fds[cpu_idx].idle_spurr = assign_read_fd(sysfs_file_path);
|
|
+ if (cpu_sysfs_fds[cpu_idx].idle_spurr == -1)
|
|
+ goto error;
|
|
+
|
|
+ cpu_idx++;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+error:
|
|
+ fprintf(stderr, "Failed to open %s\n", sysfs_file_path);
|
|
+ close_cpu_sysfs_fds(threads_in_system);
|
|
+ return -1;
|
|
+}
|
|
+
|
|
+static void sig_int_handler(int signal)
|
|
+{
|
|
+ close_cpu_sysfs_fds(threads_in_system);
|
|
+ exit(1);
|
|
+}
|
|
+
|
|
void get_time()
|
|
{
|
|
struct timeval t;
|
|
@@ -659,6 +737,15 @@ void init_sysinfo(void)
|
|
rc = get_nominal_frequency();
|
|
if (rc)
|
|
exit(rc);
|
|
+
|
|
+ if (signal(SIGINT, sig_int_handler) == SIG_ERR) {
|
|
+ fprintf(stderr, "Failed to add signal handler\n");
|
|
+ exit(-1);
|
|
+ }
|
|
+
|
|
+ rc = assign_cpu_sysfs_fds(threads_in_system);
|
|
+ if (rc)
|
|
+ exit(rc);
|
|
}
|
|
|
|
void init_sysdata(void)
|
|
@@ -841,5 +928,6 @@ int main(int argc, char *argv[])
|
|
else
|
|
print_default_output(interval, count);
|
|
|
|
+ close_cpu_sysfs_fds(threads_in_system);
|
|
return 0;
|
|
}
|
|
diff --git a/src/lparstat.h b/src/lparstat.h
|
|
index c1bac28..617737b 100644
|
|
--- a/src/lparstat.h
|
|
+++ b/src/lparstat.h
|
|
@@ -25,6 +25,10 @@
|
|
#define SYSDATA_NAME_SZ 64
|
|
#define SYSDATA_DESCR_SZ 128
|
|
|
|
+#define SYSFS_PERCPU_SPURR "/sys/devices/system/cpu/cpu%d/spurr"
|
|
+#define SYSFS_PERCPU_IDLE_PURR "/sys/devices/system/cpu/cpu%d/idle_purr"
|
|
+#define SYSFS_PERCPU_IDLE_SPURR "/sys/devices/system/cpu/cpu%d/idle_spurr"
|
|
+
|
|
struct sysentry {
|
|
char value[SYSDATA_VALUE_SZ]; /* value from file */
|
|
char old_value[SYSDATA_VALUE_SZ]; /* previous value from file */
|
|
@@ -33,6 +37,14 @@ struct sysentry {
|
|
void (*get)(struct sysentry *, char *);
|
|
};
|
|
|
|
+struct cpu_sysfs_file_desc {
|
|
+ int cpu; /* cpu number */
|
|
+ int spurr; /* per-cpu /sys/devices/system/cpu/cpuX/spurr file descriptor */
|
|
+ int idle_purr; /* per-cpu /sys/devices/system/cpu/cpuX/idle_purr file descriptor */
|
|
+ int idle_spurr; /* per-cpu /sys/devices/system/cpu/cpuX/idle_spurr file descriptor */
|
|
+};
|
|
+typedef struct cpu_sysfs_file_desc cpu_sysfs_fd;
|
|
+
|
|
extern void get_smt_state(struct sysentry *, char *);
|
|
extern void get_capped_mode(struct sysentry *, char *);
|
|
extern void get_memory_mode(struct sysentry *, char *);
|
|
--
|
|
2.25.3
|
|
|