]> Zhao Yanbai Git Server - minix.git/commitdiff
SMP - BKL statistics
authorTomas Hruby <tom@minix3.org>
Wed, 15 Sep 2010 14:10:37 +0000 (14:10 +0000)
committerTomas Hruby <tom@minix3.org>
Wed, 15 Sep 2010 14:10:37 +0000 (14:10 +0000)
- pressing 'B' on the serial cnsole prints statistics for BKL per cpu.

- 'b' resets the counters

- it presents number of cycles each CPU spends in kernel, how many
  cycyles it spends spinning while waiting for the BKL

- it shows optimistic estimation in how many cases we get the lock
  immediately without spinning. As the test is not atomic the lock may
  be already held by some other cpu before we actually try to acquire
  it.

kernel/arch/i386/arch_clock.c
kernel/arch/i386/arch_system.c
kernel/glo.h

index 27483fccff76ec1ef7d55da58c90ebbeb1d55155..d56fd44927f2b8dd66a30004701c1e3f6b05c3de 100644 (file)
@@ -217,9 +217,25 @@ PUBLIC void context_stop(struct proc * p)
                p->p_cycles = add64(p->p_cycles, sub64(tsc, *__tsc_ctr_switch));
                BKL_UNLOCK();
        } else {
+               u64_t bkl_tsc, tmp;
+               unsigned cpu = cpuid;
+               atomic_t succ;
+               
+               read_tsc_64(&bkl_tsc);
+               /* this only gives a good estimate */
+               succ = big_kernel_lock.val;
+               
                BKL_LOCK();
+               
                read_tsc_64(&tsc);
-               p->p_cycles = add64(p->p_cycles, sub64(tsc, *__tsc_ctr_switch));
+
+               bkl_ticks[cpu] = add64(bkl_ticks[cpu], sub64(tsc, bkl_tsc));
+               bkl_tries[cpu]++;
+               bkl_succ[cpu] += !(!(succ == 0));
+
+               tmp = sub64(tsc, *__tsc_ctr_switch);
+               kernel_ticks[cpu] = add64(kernel_ticks[cpu], tmp);
+               p->p_cycles = add64(p->p_cycles, tmp);
        }
        
        *__tsc_ctr_switch = tsc;
index 84fd53892929bc90cff7c8422b9ad4ab135bc1a6..5cc381adc4af7b1bf2ecdd826701f5f4b5423af9 100644 (file)
@@ -420,6 +420,31 @@ PRIVATE void ser_dump_segs(void)
        }
 }
 
+#ifdef CONFIG_SMP
+PRIVATE void dump_bkl_usage(void)
+{
+       unsigned cpu;
+
+       printf("--- BKL usage ---\n");
+       for (cpu = 0; cpu < ncpus; cpu++) {
+               printf("cpu %3d kernel ticks 0x%x%08x bkl ticks 0x%x%08x succ %d tries %d\n", cpu,
+                               kernel_ticks[cpu].hi, kernel_ticks[cpu].lo, 
+                               bkl_ticks[cpu].hi, bkl_ticks[cpu].lo,
+                               bkl_succ[cpu], bkl_tries[cpu]);
+       }
+}
+
+PRIVATE void reset_bkl_usage(void)
+{
+       unsigned cpu;
+
+       memset(kernel_ticks, 0, sizeof(kernel_ticks));
+       memset(bkl_ticks, 0, sizeof(bkl_ticks));
+       memset(bkl_tries, 0, sizeof(bkl_tries));
+       memset(bkl_succ, 0, sizeof(bkl_succ));
+}
+#endif
+
 PRIVATE void ser_debug(const int c)
 {
        serial_debug_active = 1;
@@ -429,6 +454,14 @@ PRIVATE void ser_debug(const int c)
        case 'Q':
                minix_shutdown(NULL);
                NOT_REACHABLE;
+#ifdef CONFIG_SMP
+       case 'B':
+               dump_bkl_usage();
+               break;
+       case 'b':
+               reset_bkl_usage();
+               break;
+#endif
        case '1':
                ser_dump_proc();
                break;
index 3ac06075aa2ca90242b5e13177dd0da1e082f7be..3c790acda36baae4d81c9e80bc11aa0ecd63388e 100644 (file)
@@ -80,4 +80,10 @@ extern struct segdesc_s gdt[];               /* global descriptor table */
 
 EXTERN volatile int serial_debug_active;
 
+/* BKL stats */
+EXTERN u64_t kernel_ticks[CONFIG_MAX_CPUS];
+EXTERN u64_t bkl_ticks[CONFIG_MAX_CPUS];
+EXTERN unsigned bkl_tries[CONFIG_MAX_CPUS];
+EXTERN unsigned bkl_succ[CONFIG_MAX_CPUS];
+
 #endif /* GLO_H */