aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2010-07-30 13:38:46 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2010-07-30 13:38:46 +0200
commit9bb0510b9b065cf81ee6f9e4e34bea8a32915eed (patch)
tree2f364f3e7dc0cc5cb79025acfec530650c7fa8ff
parent64c67891a252cfee5ad155abcc49a008d7023d08 (diff)
downloadbusybox-w32-9bb0510b9b065cf81ee6f9e4e34bea8a32915eed.tar.gz
busybox-w32-9bb0510b9b065cf81ee6f9e4e34bea8a32915eed.tar.bz2
busybox-w32-9bb0510b9b065cf81ee6f9e4e34bea8a32915eed.zip
mpstat: fix total par-cpu IRQ counts
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--procps/mpstat.c43
1 files changed, 33 insertions, 10 deletions
diff --git a/procps/mpstat.c b/procps/mpstat.c
index a1f3937c9..d19abee97 100644
--- a/procps/mpstat.c
+++ b/procps/mpstat.c
@@ -163,6 +163,7 @@ static double percent_value(data_t prev, data_t curr, data_t itv)
163 163
164static double hz_value(data_t prev, data_t curr, data_t itv) 164static double hz_value(data_t prev, data_t curr, data_t itv)
165{ 165{
166 //bb_error_msg("curr:%lld prev:%lld G.hz:%u", curr, prev, G.hz);
166 return ((double)overflow_safe_sub(prev, curr)) / itv * G.hz; 167 return ((double)overflow_safe_sub(prev, curr)) / itv * G.hz;
167} 168}
168 169
@@ -413,6 +414,8 @@ static void write_stats_core(int prev, int current,
413 continue; 414 continue;
414 } 415 }
415 } 416 }
417 //bb_error_msg("G.st_irq[%u][%u].irq_nr:%lld - G.st_irq[%u][%u].irq_nr:%lld",
418 // current, cpu, G.st_irq[prev][cpu].irq_nr, prev, cpu, G.st_irq[current][cpu].irq_nr);
416 printf(" %9.2f\n", hz_value(G.st_irq[prev][cpu].irq_nr, G.st_irq[current][cpu].irq_nr, per_cpu_itv)); 419 printf(" %9.2f\n", hz_value(G.st_irq[prev][cpu].irq_nr, G.st_irq[current][cpu].irq_nr, per_cpu_itv));
417 } 420 }
418 } 421 }
@@ -523,16 +526,23 @@ static void get_cpu_statistics(struct stats_cpu *cpu, data_t *up, data_t *up0)
523static void get_irqs_from_stat(struct stats_irq *irq) 526static void get_irqs_from_stat(struct stats_irq *irq)
524{ 527{
525 FILE *fp; 528 FILE *fp;
529 unsigned cpu;
526 char buf[1024]; 530 char buf[1024];
527 531
532 for (cpu = 1; cpu <= G.cpu_nr; cpu++) {
533 irq->irq_nr = 0;
534 }
535
528 fp = fopen_for_read(PROCFS_STAT); 536 fp = fopen_for_read(PROCFS_STAT);
529 if (!fp) 537 if (!fp)
530 return; 538 return;
531 539
532 while (fgets(buf, sizeof(buf), fp)) { 540 while (fgets(buf, sizeof(buf), fp)) {
533 if (strncmp(buf, "intr ", 5) == 0) 541 //bb_error_msg("/proc/stat:'%s'", buf);
542 if (strncmp(buf, "intr ", 5) == 0) {
534 /* Read total number of IRQs since system boot */ 543 /* Read total number of IRQs since system boot */
535 sscanf(buf + 5, "%"FMT_DATA"u", &irq->irq_nr); 544 sscanf(buf + 5, "%"FMT_DATA"u", &irq->irq_nr);
545 }
536 } 546 }
537 547
538 fclose(fp); 548 fclose(fp);
@@ -554,12 +564,20 @@ static void get_irqs_from_interrupts(const char *fname,
554 unsigned irq; 564 unsigned irq;
555 int cpu_index[G.cpu_nr]; 565 int cpu_index[G.cpu_nr];
556 int iindex; 566 int iindex;
557 int len, digit;
558 567
559 for (cpu = 1; cpu <= G.cpu_nr; cpu++) { 568// Moved to get_irqs_from_stat(), which is called once, not twice,
560 irq_i = &G.st_irq[current][cpu]; 569// unlike get_irqs_from_interrupts().
561 irq_i->irq_nr = 0; 570// Otherwise reading of /proc/softirqs
562 } 571// was resetting counts to 0 after we painstakingly collected them from
572// /proc/interrupts. Which resulted in:
573// 01:32:47 PM CPU intr/s
574// 01:32:47 PM all 591.47
575// 01:32:47 PM 0 0.00 <= ???
576// 01:32:47 PM 1 0.00 <= ???
577// for (cpu = 1; cpu <= G.cpu_nr; cpu++) {
578// G.st_irq[current][cpu].irq_nr = 0;
579// //bb_error_msg("G.st_irq[%u][%u].irq_nr=0", current, cpu);
580// }
563 581
564 fp = fopen_for_read(fname); 582 fp = fopen_for_read(fname);
565 if (!fp) 583 if (!fp)
@@ -587,11 +605,15 @@ static void get_irqs_from_interrupts(const char *fname,
587 while (fgets(buf, buflen, fp) 605 while (fgets(buf, buflen, fp)
588 && irq < irqs_per_cpu 606 && irq < irqs_per_cpu
589 ) { 607 ) {
608 int len;
609 char last_char;
590 char *cp; 610 char *cp;
591 /* Skip over "<irq>:" */ 611
612 /* Skip over "IRQNAME:" */
592 cp = strchr(buf, ':'); 613 cp = strchr(buf, ':');
593 if (!cp) 614 if (!cp)
594 continue; 615 continue;
616 last_char = cp[-1];
595 617
596 ic = &per_cpu_stats[current][irq]; 618 ic = &per_cpu_stats[current][irq];
597 len = cp - buf; 619 len = cp - buf;
@@ -600,7 +622,6 @@ static void get_irqs_from_interrupts(const char *fname,
600 } 622 }
601 safe_strncpy(ic->irq_name, buf, len + 1); 623 safe_strncpy(ic->irq_name, buf, len + 1);
602 //bb_error_msg("%s: irq%d:'%s' buf:'%s'", fname, irq, ic->irq_name, buf); 624 //bb_error_msg("%s: irq%d:'%s' buf:'%s'", fname, irq, ic->irq_name, buf);
603 digit = isdigit(buf[len - 1]);
604 cp++; 625 cp++;
605 626
606 for (cpu = 0; cpu < iindex; cpu++) { 627 for (cpu = 0; cpu < iindex; cpu++) {
@@ -608,9 +629,11 @@ static void get_irqs_from_interrupts(const char *fname,
608 ic = &per_cpu_stats[current][cpu_index[cpu] * irqs_per_cpu + irq]; 629 ic = &per_cpu_stats[current][cpu_index[cpu] * irqs_per_cpu + irq];
609 irq_i = &G.st_irq[current][cpu_index[cpu] + 1]; 630 irq_i = &G.st_irq[current][cpu_index[cpu] + 1];
610 ic->interrupt = strtoul(cp, &next, 10); 631 ic->interrupt = strtoul(cp, &next, 10);
611 if (digit) { 632 /* Count only numerical IRQs */
612 /* Do not count non-numerical IRQs */ 633 if (isdigit(last_char)) {
613 irq_i->irq_nr += ic->interrupt; 634 irq_i->irq_nr += ic->interrupt;
635 //bb_error_msg("G.st_irq[%u][%u].irq_nr + %u = %lld",
636 // current, cpu_index[cpu] + 1, ic->interrupt, irq_i->irq_nr);
614 } 637 }
615 cp = next; 638 cp = next;
616 } 639 }