Author: cperciva
Date: Sat Feb 29 22:31:23 2020
New Revision: 358478
URL: https://svnweb.freebsd.org/changeset/base/358478

Log:
  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

Modified:
  head/usr.sbin/powerd/powerd.8
  head/usr.sbin/powerd/powerd.c

Modified: head/usr.sbin/powerd/powerd.8
==============================================================================
--- head/usr.sbin/powerd/powerd.8       Sat Feb 29 22:16:27 2020        
(r358477)
+++ head/usr.sbin/powerd/powerd.8       Sat Feb 29 22:31:23 2020        
(r358478)
@@ -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

Modified: head/usr.sbin/powerd/powerd.c
==============================================================================
--- head/usr.sbin/powerd/powerd.c       Sat Feb 29 22:16:27 2020        
(r358477)
+++ head/usr.sbin/powerd/powerd.c       Sat Feb 29 22:31:23 2020        
(r358478)
@@ -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;
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to