Hello,
At present, there is no middle between cool running and automatic adjustement
mode.
I would suggest to add an "on demand" adjustement mode which set hw.setperf to
maximum when CPU idle is lesser then 10% and reduce it when CPU idle is greater
than
30%. Also, when hw.setperf is at maximum, verification of CPU idle is slow down.
This is based on a previous suggestion of Laurence Tratt.
PS : please add me to recepient if you reply.
Index: apm-proto.h
===================================================================
RCS file: /cvs/src/usr.sbin/apmd/apm-proto.h,v
retrieving revision 1.9
diff -u -p -r1.9 apm-proto.h
--- apm-proto.h 26 Mar 2012 20:17:45 -0000 1.9
+++ apm-proto.h 2 Mar 2015 14:56:34 -0000
@@ -38,6 +38,7 @@ enum apm_action {
SETPERF_LOW,
SETPERF_HIGH,
SETPERF_AUTO,
+ SETPERF_ONDEMAND,
SETPERF_COOL
};
@@ -52,6 +53,7 @@ enum apm_perfmode {
PERF_NONE = -1,
PERF_MANUAL,
PERF_AUTO,
+ PERF_ONDEMAND,
PERF_COOL
};
Index: apmd.8
===================================================================
RCS file: /cvs/src/usr.sbin/apmd/apmd.8,v
retrieving revision 1.44
diff -u -p -r1.44 apmd.8
--- apmd.8 24 Jul 2014 01:04:58 -0000 1.44
+++ apmd.8 2 Mar 2015 14:56:34 -0000
@@ -77,6 +77,16 @@ level is low.
BIOS-initiated suspend or standby requests are
ignored if the system is connected to line current and not running from
batteries (user requests are still honored).
+.It Fl O
+Start
+.Nm
+in on demand performance adjustement mode.
+Set
+.Va hw.setperf
+to maximum when CPU idle is lesser than 90%, reduce it if CPU idle is
+greater than 30%. When
+.Va hw.setperf
+is at maximum, verification of CPU idle is ten times slower.
.It Fl C
Start
.Nm
Index: apmd.c
===================================================================
RCS file: /cvs/src/usr.sbin/apmd/apmd.c,v
retrieving revision 1.65
diff -u -p -r1.65 apmd.c
--- apmd.c 26 Jul 2014 10:48:59 -0000 1.65
+++ apmd.c 2 Mar 2015 14:56:34 -0000
@@ -76,7 +76,7 @@ int bind_socket(const char *sn);
enum apm_state handle_client(int sock_fd, int ctl_fd);
int get_avg_idle_mp(int ncpu);
int get_avg_idle_up(void);
-void perf_status(struct apm_power_info *pinfo, int ncpu);
+long perf_status(struct apm_power_info *pinfo, int ncpu);
void suspend(int ctl_fd);
void stand_by(int ctl_fd);
void hibernate(int ctl_fd);
@@ -301,13 +301,14 @@ get_avg_idle_up(void)
return avg_idle;
}
-void
+long
perf_status(struct apm_power_info *pinfo, int ncpu)
{
int avg_idle;
int hw_perf_mib[] = {CTL_HW, HW_SETPERF};
int perf;
int forcehi = 0;
+ long timeout = 1;
size_t perf_sz = sizeof(perf);
if (ncpu > 1) {
@@ -330,6 +331,7 @@ perf_status(struct apm_power_info *pinfo
pinfo->battery_state == APM_BATTERY_ABSENT)
forcehi = 1;
break;
+ case PERF_ONDEMAND:
case PERF_COOL:
forcehi = 0;
break;
@@ -339,9 +341,13 @@ perf_status(struct apm_power_info *pinfo
syslog(LOG_INFO, "cannot read hw.setperf");
if (forcehi || (avg_idle < PERFINCTHRES && perf < PERFMAX)) {
- perf += PERFINC;
- if (perf > PERFMAX)
+ if (doperf == PERF_ONDEMAND) {
perf = PERFMAX;
+ } else {
+ perf += PERFINC;
+ if (perf > PERFMAX)
+ perf = PERFMAX;
+ }
setperf(perf);
} else if (avg_idle > PERFDECTHRES && perf > PERFMIN) {
perf -= PERFDEC;
@@ -349,6 +355,13 @@ perf_status(struct apm_power_info *pinfo
perf = PERFMIN;
setperf(perf);
}
+ if (doperf == PERF_ONDEMAND) {
+ if (perf == PERFMAX)
+ timeout = 999999999;
+ else
+ timeout = 100000000;
+ }
+ return timeout;
}
char socketname[MAXPATHLEN];
@@ -452,6 +465,11 @@ handle_client(int sock_fd, int ctl_fd)
reply.newstate = NORMAL;
syslog(LOG_NOTICE, "setting hw.setperf automatically");
break;
+ case SETPERF_ONDEMAND:
+ doperf = PERF_ONDEMAND;
+ reply.newstate = NORMAL;
+ syslog(LOG_NOTICE, "setting hw.setperf on demand");
+ break;
case SETPERF_COOL:
doperf = PERF_COOL;
reply.newstate = NORMAL;
@@ -525,7 +543,7 @@ main(int argc, char *argv[])
int ncpu;
size_t ncpu_sz = sizeof(ncpu);
- while ((ch = getopt(argc, argv, "aACdHLsf:t:S:")) != -1)
+ while ((ch = getopt(argc, argv, "aAOCdHLsf:t:S:")) != -1)
switch(ch) {
case 'a':
noacsleep = 1;
@@ -552,6 +570,11 @@ main(int argc, char *argv[])
usage();
doperf = PERF_AUTO;
break;
+ case 'O':
+ if (doperf != PERF_NONE)
+ usage();
+ doperf = PERF_ONDEMAND;
+ break;
case 'C':
if (doperf != PERF_NONE)
usage();
@@ -633,7 +656,8 @@ main(int argc, char *argv[])
if (sysctl(ncpu_mib, 2, &ncpu, &ncpu_sz, NULL, 0) < 0)
error("cannot read hw.ncpu", NULL);
- if (doperf == PERF_AUTO || doperf == PERF_COOL) {
+ if (doperf == PERF_AUTO || doperf == PERF_COOL ||
+ doperf == PERF_ONDEMAND) {
setperf(0);
setperf(100);
}
@@ -642,12 +666,16 @@ main(int argc, char *argv[])
sts = ts;
- if (doperf == PERF_AUTO || doperf == PERF_COOL) {
- sts.tv_sec = 1;
- perf_status(&pinfo, ncpu);
- }
+ if (doperf == PERF_ONDEMAND) {
+ sts.tv_sec = 0;
+ sts.tv_nsec = perf_status(&pinfo, ncpu);
+ apmtimeout += 1;
+ } else if (doperf == PERF_AUTO || doperf == PERF_COOL) {
+ sts.tv_sec = perf_status(&pinfo, ncpu);
+ apmtimeout += sts.tv_sec;
+ } else
+ apmtimeout += sts.tv_sec;
- apmtimeout += sts.tv_sec;
if ((rv = kevent(kq, NULL, 0, ev, 1, &sts)) < 0)
break;
Index: apm.8
===================================================================
RCS file: /cvs/src/usr.sbin/apm/apm.8,v
retrieving revision 1.39
diff -u -p -r1.39 apm.8
--- apm.8 21 Jan 2014 03:15:46 -0000 1.39
+++ apm.8 2 Mar 2015 14:57:28 -0000
@@ -80,6 +80,16 @@ means connected, 2 means backup power so
Display the battery status.
0 means high, 1 means low, 2 means
critical, 3 means charging, 4 means absent, and 255 means unknown.
+.It Fl O
+Set
+.Xr apmd 8
+to on demand performance adjustement mode.
+In this mode,
+.Va hw.setperf
+is set to maximum when CPU idle is lesser than 90% and is reduce
+if CPU idle is greater than 30%. When
+.Va hw.setperf
+is at maximum, verification of CPU idle is ten times slower.
.It Fl C
Set
.Xr apmd 8
Index: apm.c
===================================================================
RCS file: /cvs/src/usr.sbin/apm/apm.c,v
retrieving revision 1.27
diff -u -p -r1.27 apm.c
--- apm.c 11 Jul 2012 13:27:13 -0000 1.27
+++ apm.c 2 Mar 2015 14:57:28 -0000
@@ -158,7 +158,7 @@ main(int argc, char *argv[])
int cpuspeed_mib[] = { CTL_HW, HW_CPUSPEED }, cpuspeed;
size_t cpuspeed_sz = sizeof(cpuspeed);
- while ((ch = getopt(argc, argv, "ACHLlmbvaPSzZf:")) != -1) {
+ while ((ch = getopt(argc, argv, "AOCHLlmbvaPSzZf:")) != -1) {
switch (ch) {
case 'v':
verbose = TRUE;
@@ -186,6 +186,11 @@ main(int argc, char *argv[])
usage();
action = SETPERF_AUTO;
break;
+ case 'O':
+ if (action != NONE)
+ usage();
+ action = SETPERF_ONDEMAND;
+ break;
case 'C':
if (action != NONE)
usage();
@@ -267,6 +272,7 @@ main(int argc, char *argv[])
case SETPERF_LOW:
case SETPERF_HIGH:
case SETPERF_AUTO:
+ case SETPERF_ONDEMAND:
case SETPERF_COOL:
if (fd == -1)
errx(1, "cannot connect to apmd, "