aboutsummaryrefslogtreecommitdiff
path: root/usr.sbin/powerd
diff options
context:
space:
mode:
authorColin Percival <cperciva@FreeBSD.org>2020-02-29 22:31:23 +0000
committerColin Percival <cperciva@FreeBSD.org>2020-02-29 22:31:23 +0000
commitd91382866fc261ac16cf78f204eb7490f082f3d4 (patch)
treec83d9334b9407307f6bb78595d3c11821e96ee15 /usr.sbin/powerd
parent9ea5bef27f082bf3f3284d867f29ad32c1227379 (diff)
downloadsrc-d91382866fc261ac16cf78f204eb7490f082f3d4.tar.gz
src-d91382866fc261ac16cf78f204eb7490f082f3d4.zip
Add -N option to powerd(8) to ignore "nice" time.
With powerd_flags="-N", this makes powerd(8) exclude "nice" time when computing the CPU utilization. This makes it possible to prevent CPU-intensive "background" processes from spinning up the CPU. Note that only *userland* CPU usage belonging to "nice" processes is excluded; we do not track whether time spent in the kernel is on behalf of nice or non-nice processes, so kernel-intensive nice processes can still result in the CPU being sped up. MFC after: 2 weeks Differential Revision: https://reviews.freebsd.org/D23868
Notes
Notes: svn path=/head/; revision=358478
Diffstat (limited to 'usr.sbin/powerd')
-rw-r--r--usr.sbin/powerd/powerd.85
-rw-r--r--usr.sbin/powerd/powerd.c31
2 files changed, 26 insertions, 10 deletions
diff --git a/usr.sbin/powerd/powerd.8 b/usr.sbin/powerd/powerd.8
index 7ab295a555d4..9f057edcc947 100644
--- a/usr.sbin/powerd/powerd.8
+++ b/usr.sbin/powerd/powerd.8
@@ -37,6 +37,7 @@
.Op Fl i Ar percent
.Op Fl m Ar freq
.Op Fl M Ar freq
+.Op Fl N
.Op Fl n Ar mode
.Op Fl p Ar ival
.Op Fl P Ar pidfile
@@ -102,6 +103,10 @@ The default is 50% or lower.
Specifies the minimum frequency to throttle down to.
.It Fl M Ar freq
Specifies the maximum frequency to throttle up to.
+.It Fl N
+Treat "nice" time as idle for the purpose of load calculation;
+i.e. do not increase the CPU frequency if the CPU is only busy
+with "nice" processes.
.It Fl n Ar mode
Selects the
.Ar mode
diff --git a/usr.sbin/powerd/powerd.c b/usr.sbin/powerd/powerd.c
index 22aafa2005a9..2acb14503685 100644
--- a/usr.sbin/powerd/powerd.c
+++ b/usr.sbin/powerd/powerd.c
@@ -86,7 +86,7 @@ static const char *modes[] = {
#define DEVDPIPE "/var/run/devd.pipe"
#define DEVCTL_MAXBUF 1024
-static int read_usage_times(int *load);
+static int read_usage_times(int *load, int nonice);
static int read_freqs(int *numfreqs, int **freqs, int **power,
int minfreq, int maxfreq);
static int set_freq(int freq);
@@ -135,15 +135,17 @@ static struct timeval tried_devd;
* This function returns summary load of all CPUs. It was made so
* intentionally to not reduce performance in scenarios when several
* threads are processing requests as a pipeline -- running one at
- * a time on different CPUs and waiting for each other.
+ * a time on different CPUs and waiting for each other. If nonice
+ * is nonzero, only user+sys+intr time will be counted as load; any
+ * nice time will be treated as if idle.
*/
static int
-read_usage_times(int *load)
+read_usage_times(int *load, int nonice)
{
static long *cp_times = NULL, *cp_times_old = NULL;
static int ncpus = 0;
size_t cp_times_len;
- int error, cpu, i, total;
+ int error, cpu, i, total, excl;
if (cp_times == NULL) {
cp_times_len = 0;
@@ -175,8 +177,12 @@ read_usage_times(int *load)
}
if (total == 0)
continue;
- *load += 100 - (cp_times[cpu * CPUSTATES + CP_IDLE] -
- cp_times_old[cpu * CPUSTATES + CP_IDLE]) * 100 / total;
+ excl = cp_times[cpu * CPUSTATES + CP_IDLE] -
+ cp_times_old[cpu * CPUSTATES + CP_IDLE];
+ if (nonice)
+ excl += cp_times[cpu * CPUSTATES + CP_NICE] -
+ cp_times_old[cpu * CPUSTATES + CP_NICE];
+ *load += 100 - excl * 100 / total;
}
}
@@ -473,7 +479,7 @@ usage(void)
{
fprintf(stderr,
-"usage: powerd [-v] [-a mode] [-b mode] [-i %%] [-m freq] [-M freq] [-n mode] [-p ival] [-r %%] [-s source] [-P pidfile]\n");
+"usage: powerd [-v] [-a mode] [-b mode] [-i %%] [-m freq] [-M freq] [-N] [-n mode] [-p ival] [-r %%] [-s source] [-P pidfile]\n");
exit(1);
}
@@ -490,6 +496,7 @@ main(int argc, char * argv[])
int ch, mode, mode_ac, mode_battery, mode_none, idle, to;
uint64_t mjoules_used;
size_t len;
+ int nonice;
/* Default mode for all AC states is adaptive. */
mode_ac = mode_none = MODE_HIADAPTIVE;
@@ -499,12 +506,13 @@ main(int argc, char * argv[])
poll_ival = DEFAULT_POLL_INTERVAL;
mjoules_used = 0;
vflag = 0;
+ nonice = 0;
/* User must be root to control frequencies. */
if (geteuid() != 0)
errx(1, "must be root to run");
- while ((ch = getopt(argc, argv, "a:b:i:m:M:n:p:P:r:s:v")) != -1)
+ while ((ch = getopt(argc, argv, "a:b:i:m:M:Nn:p:P:r:s:v")) != -1)
switch (ch) {
case 'a':
parse_mode(optarg, &mode_ac, ch);
@@ -539,6 +547,9 @@ main(int argc, char * argv[])
usage();
}
break;
+ case 'N':
+ nonice = 1;
+ break;
case 'n':
parse_mode(optarg, &mode_none, ch);
break;
@@ -584,7 +595,7 @@ main(int argc, char * argv[])
err(1, "lookup freq_levels");
/* Check if we can read the load and supported freqs. */
- if (read_usage_times(NULL))
+ if (read_usage_times(NULL, nonice))
err(1, "read_usage_times");
if (read_freqs(&numfreqs, &freqs, &mwatts, minfreq, maxfreq))
err(1, "error reading supported CPU frequencies");
@@ -766,7 +777,7 @@ main(int argc, char * argv[])
}
/* Adaptive mode; get the current CPU usage times. */
- if (read_usage_times(&load)) {
+ if (read_usage_times(&load, nonice)) {
if (vflag)
warn("read_usage_times() failed");
continue;