Re: [RFC][PATCH] cutting up struct kernel_stat into cpu_stat

2001-07-08 Thread Pavel Machek

Hi!

> The attached patch-in-progress removes the per-cpu statistics from
> struct kernel_stat and puts them in a cpu_stat structure, one per cpu,
> cacheline padded.  The data is still coolated and presented through
> /proc/stat, but another file /proc/cpustat is also added.  The locking
> is as nonexistant as it was with kernel_stat, but who cares, they're
> just fuzzy stats to be eyeballed by system tuners :).

Looks good to me... Should improve performance plus adds per-cpu data...


-- 
Philips Velo 1: 1"x4"x8", 300gram, 60, 12MB, 40bogomips, linux, mutt,
details at http://atrey.karlin.mff.cuni.cz/~pavel/velo/index.html.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/



Re: [RFC][PATCH] cutting up struct kernel_stat into cpu_stat

2001-06-21 Thread Albert D. Cahalan

Zach Brown writes:

> The attached patch-in-progress removes the per-cpu statistics from
> struct kernel_stat and puts them in a cpu_stat structure, one per cpu,
> cacheline padded.  The data is still coolated and presented through
> /proc/stat, but another file /proc/cpustat is also added.  The locking
> is as nonexistant as it was with kernel_stat, but who cares, they're
> just fuzzy stats to be eyeballed by system tuners :).

Hey! The lack of atomicity causes "top" to do one of 3 things
for the idle time report, depending on the version:

1. negative numbers
2. wrap-around (4200.00% idle)
3. truncate to zero (the numbers don't add up)

This is because top sees the idle time run backwards for a moment.
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/



[RFC][PATCH] cutting up struct kernel_stat into cpu_stat

2001-06-21 Thread Zach Brown

The attached patch-in-progress removes the per-cpu statistics from
struct kernel_stat and puts them in a cpu_stat structure, one per cpu,
cacheline padded.  The data is still coolated and presented through
/proc/stat, but another file /proc/cpustat is also added.  The locking
is as nonexistant as it was with kernel_stat, but who cares, they're
just fuzzy stats to be eyeballed by system tuners :).

A tool for printing the cpu stats specifically can be found near:

http://www.osdlab.org/sw_resources/cpustat/index.shtml

Its output is almost identical to solaris' mpstat.  

I'm not sure I like the macro use, but it shields the callers from the
union garbage.  We can easily also make a THIS_CPU_STAT_ADD() interface,
as some have hinted would be nice :)

Currently its mostly ( :) ) only collecting the stats that were
collected in kernel_stat.  I'd like to add more stats -- page faults,
syscalls, cross-cpu calls, etc.  I understand people not wanting more
live cachelines in the fast paths.  I can make CPU_CRITICAL_STAT defines
that are config-ed out..

comments?  If its ok I can whip up a patch that updates all the ports
use of ->irqs[] as well.

- z
[ heading out for lunch :) ]


--- linux-2.4.5-cpustat/fs/proc/proc_misc.c.cpustat Fri Apr 13 20:26:07 2001
+++ linux-2.4.5-cpustat/fs/proc/proc_misc.c Thu Jun 21 12:23:49 2001
@@ -265,32 +265,36 @@
int i, len;
extern unsigned long total_forks;
unsigned long jif = jiffies;
-   unsigned int sum = 0, user = 0, nice = 0, system = 0;
+   unsigned int sum = 0, user = 0, nice = 0, system = 0, ctxt = 0;
int major, disk;
 
for (i = 0 ; i < smp_num_cpus; i++) {
int cpu = cpu_logical_map(i), j;
 
-   user += kstat.per_cpu_user[cpu];
-   nice += kstat.per_cpu_nice[cpu];
-   system += kstat.per_cpu_system[cpu];
+   user += CPU_STAT_VAL(cpu, user);
+   nice += CPU_STAT_VAL(cpu, nice);
+   system += CPU_STAT_VAL(cpu, system);
+   ctxt += CPU_STAT_VAL(cpu, context_swtch);
 #if !defined(CONFIG_ARCH_S390)
for (j = 0 ; j < NR_IRQS ; j++)
-   sum += kstat.irqs[cpu][j];
+   sum += CPU_STAT_VAL(cpu, irqs[j]);
 #endif
}
 
len = sprintf(page, "cpu  %u %u %u %lu\n", user, nice, system,
  jif * smp_num_cpus - (user + nice + system));
-   for (i = 0 ; i < smp_num_cpus; i++)
+   for (i = 0 ; i < smp_num_cpus; i++) {
+   unsigned int user_i, nice_i, system_i;
+
+   user_i = CPU_STAT_VAL(cpu_logical_map(i), user);
+   nice_i = CPU_STAT_VAL(cpu_logical_map(i), nice);
+   system_i = CPU_STAT_VAL(cpu_logical_map(i), system);
+
len += sprintf(page + len, "cpu%d %u %u %u %lu\n",
i,
-   kstat.per_cpu_user[cpu_logical_map(i)],
-   kstat.per_cpu_nice[cpu_logical_map(i)],
-   kstat.per_cpu_system[cpu_logical_map(i)],
-   jif - (  kstat.per_cpu_user[cpu_logical_map(i)] \
-  + kstat.per_cpu_nice[cpu_logical_map(i)] \
-  + kstat.per_cpu_system[cpu_logical_map(i)]));
+   user_i, nice_i, system_i, 
+   jif - (  user_i + nice_i + system_i ) );
+   }
len += sprintf(page + len,
"page %u %u\n"
 "swap %u %u\n"
@@ -330,13 +334,58 @@
"\nctxt %u\n"
"btime %lu\n"
"processes %lu\n",
-   kstat.context_swtch,
+   ctxt, 
xtime.tv_sec - jif / HZ,
total_forks);
 
return proc_calc_metrics(page, start, off, count, eof, len);
 }
 
+static int cstat_read_proc(char *page, char **start, off_t off,
+int count, int *eof, void *data)
+{
+   int i, len;
+
+   len = sprintf(page, "cpu_stat 0.0\n");
+
+   for (i = 0 ; i < smp_num_cpus; i++) {
+   unsigned int user, nice, system;
+   int j, cpu = cpu_logical_map(i);
+
+#if !defined(CONFIG_ARCH_S390)
+   len += sprintf(page + len, "cpu%d irqs ",  cpu);
+   for (j = 0 ; j < NR_IRQS ; j++) {
+   len += sprintf(page + len, " %u", 
+   CPU_STAT_VAL(cpu, irqs[j]));
+   }
+   len += sprintf(page + len, "\n");
+#endif
+#if defined(CONFIG_SMP)
+   len += sprintf(page + len, "cpu%d context_migration %u\n",  
+   cpu, CPU_STAT_VAL(cpu, context_migration));
+#endif
+   len += sprintf(page + len, "cpu%d bottom_halves %u\n",  
+   cpu, CPU_STAT_VAL(cpu, bh));
+   len += sprintf(page + len, "cpu%d context_switches %u\n",  
+   cpu, CPU_STAT_VAL(cpu, context_swtch));