diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2010-07-30 13:38:46 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2010-07-30 13:38:46 +0200 |
commit | 9bb0510b9b065cf81ee6f9e4e34bea8a32915eed (patch) | |
tree | 2f364f3e7dc0cc5cb79025acfec530650c7fa8ff | |
parent | 64c67891a252cfee5ad155abcc49a008d7023d08 (diff) | |
download | busybox-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.c | 43 |
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 | ||
164 | static double hz_value(data_t prev, data_t curr, data_t itv) | 164 | static 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) | |||
523 | static void get_irqs_from_stat(struct stats_irq *irq) | 526 | static 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 | } |