Add -m and -M options to control the minimum and maximum frequency.
PR: bin/145063 Submitted by: Boris Kochergin <spawk at acm.poly.edu> Reviewed by: cperciva Approved by: rrs (mentor) MFC after: 2 weeks
This commit is contained in:
parent
8fc4852252
commit
cf2280aca7
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=211415
@ -35,6 +35,8 @@
|
|||||||
.Op Fl a Ar mode
|
.Op Fl a Ar mode
|
||||||
.Op Fl b Ar mode
|
.Op Fl b Ar mode
|
||||||
.Op Fl i Ar percent
|
.Op Fl i Ar percent
|
||||||
|
.Op Fl m Ar freq
|
||||||
|
.Op Fl M Ar freq
|
||||||
.Op Fl n Ar mode
|
.Op Fl n Ar mode
|
||||||
.Op Fl p Ar ival
|
.Op Fl p Ar ival
|
||||||
.Op Fl P Ar pidfile
|
.Op Fl P Ar pidfile
|
||||||
@ -79,6 +81,10 @@ to use while on battery power.
|
|||||||
Specifies the CPU load percent level when adaptive
|
Specifies the CPU load percent level when adaptive
|
||||||
mode should begin to degrade performance to save power.
|
mode should begin to degrade performance to save power.
|
||||||
The default is 50% or lower.
|
The default is 50% or lower.
|
||||||
|
.It Fl m Ar freq
|
||||||
|
Specifies the minimum frequency to throttle down to.
|
||||||
|
.It Fl M Ar freq
|
||||||
|
Specifies the maximum frequency to throttle up to.
|
||||||
.It Fl n Ar mode
|
.It Fl n Ar mode
|
||||||
Selects the
|
Selects the
|
||||||
.Ar mode
|
.Ar mode
|
||||||
|
@ -84,7 +84,8 @@ const char *modes[] = {
|
|||||||
#define DEVCTL_MAXBUF 1024
|
#define DEVCTL_MAXBUF 1024
|
||||||
|
|
||||||
static int read_usage_times(int *load);
|
static int read_usage_times(int *load);
|
||||||
static int read_freqs(int *numfreqs, int **freqs, int **power);
|
static int read_freqs(int *numfreqs, int **freqs, int **power,
|
||||||
|
int minfreq, int maxfreq);
|
||||||
static int set_freq(int freq);
|
static int set_freq(int freq);
|
||||||
static void acline_init(void);
|
static void acline_init(void);
|
||||||
static void acline_read(void);
|
static void acline_read(void);
|
||||||
@ -174,10 +175,10 @@ read_usage_times(int *load)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
read_freqs(int *numfreqs, int **freqs, int **power)
|
read_freqs(int *numfreqs, int **freqs, int **power, int minfreq, int maxfreq)
|
||||||
{
|
{
|
||||||
char *freqstr, *p, *q;
|
char *freqstr, *p, *q;
|
||||||
int i;
|
int i, j;
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
|
|
||||||
if (sysctl(levels_mib, 4, NULL, &len, NULL, 0))
|
if (sysctl(levels_mib, 4, NULL, &len, NULL, 0))
|
||||||
@ -201,19 +202,30 @@ read_freqs(int *numfreqs, int **freqs, int **power)
|
|||||||
free(*freqs);
|
free(*freqs);
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
for (i = 0, p = freqstr; i < *numfreqs; i++) {
|
for (i = 0, j = 0, p = freqstr; i < *numfreqs; i++) {
|
||||||
q = strchr(p, ' ');
|
q = strchr(p, ' ');
|
||||||
if (q != NULL)
|
if (q != NULL)
|
||||||
*q = '\0';
|
*q = '\0';
|
||||||
if (sscanf(p, "%d/%d", &(*freqs)[i], &(*power)[i]) != 2) {
|
if (sscanf(p, "%d/%d", &(*freqs)[j], &(*power)[i]) != 2) {
|
||||||
free(freqstr);
|
free(freqstr);
|
||||||
free(*freqs);
|
free(*freqs);
|
||||||
free(*power);
|
free(*power);
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
if (((*freqs)[j] >= minfreq || minfreq == -1) &&
|
||||||
|
((*freqs)[j] <= maxfreq || maxfreq == -1))
|
||||||
|
j++;
|
||||||
p = q + 1;
|
p = q + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*numfreqs = j;
|
||||||
|
if ((*freqs = realloc(*freqs, *numfreqs * sizeof(int))) == NULL) {
|
||||||
|
free(freqstr);
|
||||||
|
free(*freqs);
|
||||||
|
free(*power);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
free(freqstr);
|
free(freqstr);
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -422,7 +434,7 @@ usage(void)
|
|||||||
{
|
{
|
||||||
|
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"usage: powerd [-v] [-a mode] [-b mode] [-i %%] [-n mode] [-p ival] [-r %%] [-P pidfile]\n");
|
"usage: powerd [-v] [-a mode] [-b mode] [-i %%] [-m freq] [-M freq] [-n mode] [-p ival] [-r %%] [-P pidfile]\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -435,6 +447,7 @@ main(int argc, char * argv[])
|
|||||||
struct pidfh *pfh = NULL;
|
struct pidfh *pfh = NULL;
|
||||||
const char *pidfile = NULL;
|
const char *pidfile = NULL;
|
||||||
int freq, curfreq, initfreq, *freqs, i, j, *mwatts, numfreqs, load;
|
int freq, curfreq, initfreq, *freqs, i, j, *mwatts, numfreqs, load;
|
||||||
|
int minfreq = -1, maxfreq = -1;
|
||||||
int ch, mode, mode_ac, mode_battery, mode_none, idle, to;
|
int ch, mode, mode_ac, mode_battery, mode_none, idle, to;
|
||||||
uint64_t mjoules_used;
|
uint64_t mjoules_used;
|
||||||
size_t len;
|
size_t len;
|
||||||
@ -452,7 +465,7 @@ main(int argc, char * argv[])
|
|||||||
if (geteuid() != 0)
|
if (geteuid() != 0)
|
||||||
errx(1, "must be root to run");
|
errx(1, "must be root to run");
|
||||||
|
|
||||||
while ((ch = getopt(argc, argv, "a:b:i:n:p:P:r:v")) != -1)
|
while ((ch = getopt(argc, argv, "a:b:i:m:M:n:p:P:r:v")) != -1)
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case 'a':
|
case 'a':
|
||||||
parse_mode(optarg, &mode_ac, ch);
|
parse_mode(optarg, &mode_ac, ch);
|
||||||
@ -468,6 +481,22 @@ main(int argc, char * argv[])
|
|||||||
usage();
|
usage();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'm':
|
||||||
|
minfreq = atoi(optarg);
|
||||||
|
if (minfreq < 0) {
|
||||||
|
warnx("%d is not a valid CPU frequency",
|
||||||
|
minfreq);
|
||||||
|
usage();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'M':
|
||||||
|
maxfreq = atoi(optarg);
|
||||||
|
if (maxfreq < 0) {
|
||||||
|
warnx("%d is not a valid CPU frequency",
|
||||||
|
maxfreq);
|
||||||
|
usage();
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
parse_mode(optarg, &mode_none, ch);
|
parse_mode(optarg, &mode_none, ch);
|
||||||
break;
|
break;
|
||||||
@ -515,8 +544,10 @@ main(int argc, char * argv[])
|
|||||||
/* Check if we can read the load and supported freqs. */
|
/* Check if we can read the load and supported freqs. */
|
||||||
if (read_usage_times(NULL))
|
if (read_usage_times(NULL))
|
||||||
err(1, "read_usage_times");
|
err(1, "read_usage_times");
|
||||||
if (read_freqs(&numfreqs, &freqs, &mwatts))
|
if (read_freqs(&numfreqs, &freqs, &mwatts, minfreq, maxfreq))
|
||||||
err(1, "error reading supported CPU frequencies");
|
err(1, "error reading supported CPU frequencies");
|
||||||
|
if (numfreqs == 0)
|
||||||
|
errx(1, "no CPU frequencies in user-specified range");
|
||||||
|
|
||||||
/* Run in the background unless in verbose mode. */
|
/* Run in the background unless in verbose mode. */
|
||||||
if (!vflag) {
|
if (!vflag) {
|
||||||
@ -552,6 +583,49 @@ main(int argc, char * argv[])
|
|||||||
i = get_freq_id(curfreq, freqs, numfreqs);
|
i = get_freq_id(curfreq, freqs, numfreqs);
|
||||||
if (freq < 1)
|
if (freq < 1)
|
||||||
freq = 1;
|
freq = 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we are in adaptive mode and the current frequency is outside the
|
||||||
|
* user-defined range, adjust it to be within the user-defined range.
|
||||||
|
*/
|
||||||
|
acline_read();
|
||||||
|
if (acline_status > SRC_UNKNOWN)
|
||||||
|
errx(1, "invalid AC line status %d", acline_status);
|
||||||
|
if ((acline_status == SRC_AC &&
|
||||||
|
(mode_ac == MODE_ADAPTIVE || mode_ac == MODE_HIADAPTIVE)) ||
|
||||||
|
(acline_status == SRC_BATTERY &&
|
||||||
|
(mode_battery == MODE_ADAPTIVE || mode_battery == MODE_HIADAPTIVE)) ||
|
||||||
|
(acline_status == SRC_UNKNOWN &&
|
||||||
|
(mode_none == MODE_ADAPTIVE || mode_none == MODE_HIADAPTIVE))) {
|
||||||
|
/* Read the current frequency. */
|
||||||
|
len = sizeof(curfreq);
|
||||||
|
if (sysctl(freq_mib, 4, &curfreq, &len, NULL, 0) != 0) {
|
||||||
|
if (vflag)
|
||||||
|
warn("error reading current CPU frequency");
|
||||||
|
}
|
||||||
|
if (curfreq < freqs[numfreqs - 1]) {
|
||||||
|
if (vflag) {
|
||||||
|
printf("CPU frequency is below user-defined "
|
||||||
|
"minimum; changing frequency to %d "
|
||||||
|
"MHz\n", freqs[numfreqs - 1]);
|
||||||
|
}
|
||||||
|
if (set_freq(freqs[numfreqs - 1]) != 0) {
|
||||||
|
warn("error setting CPU freq %d",
|
||||||
|
freqs[numfreqs - 1]);
|
||||||
|
}
|
||||||
|
} else if (curfreq > freqs[0]) {
|
||||||
|
if (vflag) {
|
||||||
|
printf("CPU frequency is above user-defined "
|
||||||
|
"maximum; changing frequency to %d "
|
||||||
|
"MHz\n", freqs[0]);
|
||||||
|
}
|
||||||
|
if (set_freq(freqs[0]) != 0) {
|
||||||
|
warn("error setting CPU freq %d",
|
||||||
|
freqs[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
idle = 0;
|
idle = 0;
|
||||||
/* Main loop. */
|
/* Main loop. */
|
||||||
for (;;) {
|
for (;;) {
|
||||||
|
Loading…
Reference in New Issue
Block a user