xref: /dpdk/lib/power/rte_power_qos.c (revision dd6fd75bf662e89edf2cda8f34c37e762e79c274)
1*dd6fd75bSHuisong Li /* SPDX-License-Identifier: BSD-3-Clause
2*dd6fd75bSHuisong Li  * Copyright(c) 2024 HiSilicon Limited
3*dd6fd75bSHuisong Li  */
4*dd6fd75bSHuisong Li 
5*dd6fd75bSHuisong Li #include <errno.h>
6*dd6fd75bSHuisong Li #include <stdlib.h>
7*dd6fd75bSHuisong Li #include <string.h>
8*dd6fd75bSHuisong Li 
9*dd6fd75bSHuisong Li #include <rte_lcore.h>
10*dd6fd75bSHuisong Li #include <rte_log.h>
11*dd6fd75bSHuisong Li 
12*dd6fd75bSHuisong Li #include "power_common.h"
13*dd6fd75bSHuisong Li #include "rte_power_qos.h"
14*dd6fd75bSHuisong Li 
15*dd6fd75bSHuisong Li #define PM_QOS_SYSFILE_RESUME_LATENCY_US	\
16*dd6fd75bSHuisong Li 	"/sys/devices/system/cpu/cpu%u/power/pm_qos_resume_latency_us"
17*dd6fd75bSHuisong Li 
18*dd6fd75bSHuisong Li #define PM_QOS_CPU_RESUME_LATENCY_BUF_LEN	32
19*dd6fd75bSHuisong Li 
20*dd6fd75bSHuisong Li int
21*dd6fd75bSHuisong Li rte_power_qos_set_cpu_resume_latency(uint16_t lcore_id, int latency)
22*dd6fd75bSHuisong Li {
23*dd6fd75bSHuisong Li 	char buf[PM_QOS_CPU_RESUME_LATENCY_BUF_LEN];
24*dd6fd75bSHuisong Li 	uint32_t cpu_id;
25*dd6fd75bSHuisong Li 	FILE *f;
26*dd6fd75bSHuisong Li 	int ret;
27*dd6fd75bSHuisong Li 
28*dd6fd75bSHuisong Li 	if (!rte_lcore_is_enabled(lcore_id)) {
29*dd6fd75bSHuisong Li 		POWER_LOG(ERR, "lcore id %u is not enabled", lcore_id);
30*dd6fd75bSHuisong Li 		return -EINVAL;
31*dd6fd75bSHuisong Li 	}
32*dd6fd75bSHuisong Li 	ret = power_get_lcore_mapped_cpu_id(lcore_id, &cpu_id);
33*dd6fd75bSHuisong Li 	if (ret != 0)
34*dd6fd75bSHuisong Li 		return ret;
35*dd6fd75bSHuisong Li 
36*dd6fd75bSHuisong Li 	if (latency < 0) {
37*dd6fd75bSHuisong Li 		POWER_LOG(ERR, "latency should be greater than and equal to 0");
38*dd6fd75bSHuisong Li 		return -EINVAL;
39*dd6fd75bSHuisong Li 	}
40*dd6fd75bSHuisong Li 
41*dd6fd75bSHuisong Li 	ret = open_core_sysfs_file(&f, "w", PM_QOS_SYSFILE_RESUME_LATENCY_US, cpu_id);
42*dd6fd75bSHuisong Li 	if (ret != 0) {
43*dd6fd75bSHuisong Li 		POWER_LOG(ERR, "Failed to open "PM_QOS_SYSFILE_RESUME_LATENCY_US" : %s",
44*dd6fd75bSHuisong Li 			  cpu_id, strerror(errno));
45*dd6fd75bSHuisong Li 		return ret;
46*dd6fd75bSHuisong Li 	}
47*dd6fd75bSHuisong Li 
48*dd6fd75bSHuisong Li 	/*
49*dd6fd75bSHuisong Li 	 * Based on the sysfs interface pm_qos_resume_latency_us under
50*dd6fd75bSHuisong Li 	 * @PM_QOS_SYSFILE_RESUME_LATENCY_US directory in kernel, their meaning
51*dd6fd75bSHuisong Li 	 * is as follows for different input string.
52*dd6fd75bSHuisong Li 	 * 1> the resume latency is 0 if the input is "n/a".
53*dd6fd75bSHuisong Li 	 * 2> the resume latency is no constraint if the input is "0".
54*dd6fd75bSHuisong Li 	 * 3> the resume latency is the actual value to be set.
55*dd6fd75bSHuisong Li 	 */
56*dd6fd75bSHuisong Li 	if (latency == RTE_POWER_QOS_STRICT_LATENCY_VALUE)
57*dd6fd75bSHuisong Li 		snprintf(buf, sizeof(buf), "%s", "n/a");
58*dd6fd75bSHuisong Li 	else if (latency == RTE_POWER_QOS_RESUME_LATENCY_NO_CONSTRAINT)
59*dd6fd75bSHuisong Li 		snprintf(buf, sizeof(buf), "%u", 0);
60*dd6fd75bSHuisong Li 	else
61*dd6fd75bSHuisong Li 		snprintf(buf, sizeof(buf), "%u", latency);
62*dd6fd75bSHuisong Li 
63*dd6fd75bSHuisong Li 	ret = write_core_sysfs_s(f, buf);
64*dd6fd75bSHuisong Li 	if (ret != 0)
65*dd6fd75bSHuisong Li 		POWER_LOG(ERR, "Failed to write "PM_QOS_SYSFILE_RESUME_LATENCY_US" : %s",
66*dd6fd75bSHuisong Li 			  cpu_id, strerror(errno));
67*dd6fd75bSHuisong Li 
68*dd6fd75bSHuisong Li 	fclose(f);
69*dd6fd75bSHuisong Li 
70*dd6fd75bSHuisong Li 	return ret;
71*dd6fd75bSHuisong Li }
72*dd6fd75bSHuisong Li 
73*dd6fd75bSHuisong Li int
74*dd6fd75bSHuisong Li rte_power_qos_get_cpu_resume_latency(uint16_t lcore_id)
75*dd6fd75bSHuisong Li {
76*dd6fd75bSHuisong Li 	char buf[PM_QOS_CPU_RESUME_LATENCY_BUF_LEN];
77*dd6fd75bSHuisong Li 	int latency = -1;
78*dd6fd75bSHuisong Li 	uint32_t cpu_id;
79*dd6fd75bSHuisong Li 	FILE *f;
80*dd6fd75bSHuisong Li 	int ret;
81*dd6fd75bSHuisong Li 
82*dd6fd75bSHuisong Li 	if (!rte_lcore_is_enabled(lcore_id)) {
83*dd6fd75bSHuisong Li 		POWER_LOG(ERR, "lcore id %u is not enabled", lcore_id);
84*dd6fd75bSHuisong Li 		return -EINVAL;
85*dd6fd75bSHuisong Li 	}
86*dd6fd75bSHuisong Li 	ret = power_get_lcore_mapped_cpu_id(lcore_id, &cpu_id);
87*dd6fd75bSHuisong Li 	if (ret != 0)
88*dd6fd75bSHuisong Li 		return ret;
89*dd6fd75bSHuisong Li 
90*dd6fd75bSHuisong Li 	ret = open_core_sysfs_file(&f, "r", PM_QOS_SYSFILE_RESUME_LATENCY_US, cpu_id);
91*dd6fd75bSHuisong Li 	if (ret != 0) {
92*dd6fd75bSHuisong Li 		POWER_LOG(ERR, "Failed to open "PM_QOS_SYSFILE_RESUME_LATENCY_US" : %s",
93*dd6fd75bSHuisong Li 			  cpu_id, strerror(errno));
94*dd6fd75bSHuisong Li 		return ret;
95*dd6fd75bSHuisong Li 	}
96*dd6fd75bSHuisong Li 
97*dd6fd75bSHuisong Li 	ret = read_core_sysfs_s(f, buf, sizeof(buf));
98*dd6fd75bSHuisong Li 	if (ret != 0) {
99*dd6fd75bSHuisong Li 		POWER_LOG(ERR, "Failed to read "PM_QOS_SYSFILE_RESUME_LATENCY_US" : %s",
100*dd6fd75bSHuisong Li 			  cpu_id, strerror(errno));
101*dd6fd75bSHuisong Li 		goto out;
102*dd6fd75bSHuisong Li 	}
103*dd6fd75bSHuisong Li 
104*dd6fd75bSHuisong Li 	/*
105*dd6fd75bSHuisong Li 	 * Based on the sysfs interface pm_qos_resume_latency_us under
106*dd6fd75bSHuisong Li 	 * @PM_QOS_SYSFILE_RESUME_LATENCY_US directory in kernel, their meaning
107*dd6fd75bSHuisong Li 	 * is as follows for different output string.
108*dd6fd75bSHuisong Li 	 * 1> the resume latency is 0 if the output is "n/a".
109*dd6fd75bSHuisong Li 	 * 2> the resume latency is no constraint if the output is "0".
110*dd6fd75bSHuisong Li 	 * 3> the resume latency is the actual value in used for other string.
111*dd6fd75bSHuisong Li 	 */
112*dd6fd75bSHuisong Li 	if (strcmp(buf, "n/a") == 0)
113*dd6fd75bSHuisong Li 		latency = RTE_POWER_QOS_STRICT_LATENCY_VALUE;
114*dd6fd75bSHuisong Li 	else {
115*dd6fd75bSHuisong Li 		latency = strtoul(buf, NULL, 10);
116*dd6fd75bSHuisong Li 		latency = latency == 0 ? RTE_POWER_QOS_RESUME_LATENCY_NO_CONSTRAINT : latency;
117*dd6fd75bSHuisong Li 	}
118*dd6fd75bSHuisong Li 
119*dd6fd75bSHuisong Li out:
120*dd6fd75bSHuisong Li 	fclose(f);
121*dd6fd75bSHuisong Li 
122*dd6fd75bSHuisong Li 	return latency != -1 ? latency : ret;
123*dd6fd75bSHuisong Li }
124