]> xenbits.xensource.com Git - people/ssmith/nc2-2.6.27.git/commitdiff
patch CA-14360-loadavg-not-uninterruptible
authorSteven Smith <ssmith@weybridge.uk.xensource.com>
Tue, 30 Jun 2009 11:55:47 +0000 (12:55 +0100)
committerSteven Smith <ssmith@weybridge.uk.xensource.com>
Tue, 30 Jun 2009 11:55:47 +0000 (12:55 +0100)
fs/proc/proc_misc.c
include/linux/sched.h
kernel/timer.c

index cc0de4e38ce5ef5f759218888048c507a0f38da0..1475adbbfc7613ac3abe720d14429b29174340aa 100644 (file)
@@ -104,6 +104,24 @@ static int loadavg_read_proc(char *page, char **start, off_t off,
        return proc_calc_metrics(page, start, off, count, eof, len);
 }
 
+static int loadavg_not_uninterruptible_read_proc(char *page, char **start, off_t off,
+                                int count, int *eof, void *data)
+{
+       int a, b, c;
+       int len;
+
+       a = avenrun_not_uninterruptible[0] + (FIXED_1/200);
+       b = avenrun_not_uninterruptible[1] + (FIXED_1/200);
+       c = avenrun_not_uninterruptible[2] + (FIXED_1/200);
+       len = sprintf(page,"%d.%02d %d.%02d %d.%02d %ld/%d %d (not uninterruptible)\n",
+               LOAD_INT(a), LOAD_FRAC(a),
+               LOAD_INT(b), LOAD_FRAC(b),
+               LOAD_INT(c), LOAD_FRAC(c),
+               nr_running(), nr_threads,
+               task_active_pid_ns(current)->last_pid);
+       return proc_calc_metrics(page, start, off, count, eof, len);
+}
+
 static int uptime_read_proc(char *page, char **start, off_t off,
                                 int count, int *eof, void *data)
 {
@@ -979,6 +997,7 @@ void __init proc_misc_init(void)
                int (*read_proc)(char*,char**,off_t,int,int*,void*);
        } *p, simple_ones[] = {
                {"loadavg",     loadavg_read_proc},
+               {"loadavg_not_uninterruptible",     loadavg_not_uninterruptible_read_proc},
                {"uptime",      uptime_read_proc},
                {"meminfo",     meminfo_read_proc},
                {"version",     version_read_proc},
index 3ae06ca9ac053b4a16c995127871558214e9f528..c7bba1f4a10216152848718019ec293d8e5f8ec2 100644 (file)
@@ -115,6 +115,7 @@ struct pfm_context;
  *    11 bit fractions.
  */
 extern unsigned long avenrun[];                /* Load averages */
+extern unsigned long avenrun_not_uninterruptible[];            /* Load averages minus uninterruptible */
 
 #define FSHIFT         11              /* nr of bits of precision */
 #define FIXED_1                (1<<FSHIFT)     /* 1.0 as fixed-point */
index 4d4f9445997b1a7345b6e3a91fc553599a636c75..18008d2e57f3164b25d572cf8ecfed5ab6c3a0f6 100644 (file)
@@ -1062,6 +1062,14 @@ static unsigned long count_active_tasks(void)
        return nr_active() * FIXED_1;
 }
 
+/*
+ * Nr of running (not uninterruptible) tasks - counted in fixed-point numbers
+ */
+static unsigned long count_running_tasks(void)
+{
+       return nr_running() * FIXED_1;
+}
+
 /*
  * Hmm.. Changed this, as the GNU make sources (load.c) seems to
  * imply that avenrun[] is the standard name for this kind of thing.
@@ -1074,6 +1082,10 @@ unsigned long avenrun[3];
 
 EXPORT_SYMBOL(avenrun);
 
+unsigned long avenrun_not_uninterruptible[3];
+
+EXPORT_SYMBOL(avenrun_not_uninterruptible);
+
 /*
  * calc_load - given tick count, update the avenrun load estimates.
  * This is called while holding a write_lock on xtime_lock.
@@ -1081,6 +1093,7 @@ EXPORT_SYMBOL(avenrun);
 static inline void calc_load(unsigned long ticks)
 {
        unsigned long active_tasks; /* fixed-point */
+       unsigned long running_tasks; /* fixed-point */
        static int count = LOAD_FREQ;
 
        count -= ticks;
@@ -1090,6 +1103,11 @@ static inline void calc_load(unsigned long ticks)
                        CALC_LOAD(avenrun[0], EXP_1, active_tasks);
                        CALC_LOAD(avenrun[1], EXP_5, active_tasks);
                        CALC_LOAD(avenrun[2], EXP_15, active_tasks);
+                       /* Normal loadavg minus uninterruptible */
+                       running_tasks = count_running_tasks();
+                       CALC_LOAD(avenrun_not_uninterruptible[0], EXP_1, running_tasks);
+                       CALC_LOAD(avenrun_not_uninterruptible[1], EXP_5, running_tasks);
+                       CALC_LOAD(avenrun_not_uninterruptible[2], EXP_15, running_tasks);
                        count += LOAD_FREQ;
                } while (count < 0);
        }