[kernel][debug] fix threadload to display idle time properly in SMP world
The post SMP algorithm wasn't taking into account time on any given core if the core was currently idle at the time the load interrupt fired. Also track rescheduling ipis and condense the output slightly.
This commit is contained in:
@@ -36,6 +36,7 @@
|
||||
#include <kernel/thread.h>
|
||||
#include <kernel/timer.h>
|
||||
#include <kernel/debug.h>
|
||||
#include <kernel/mp.h>
|
||||
#include <err.h>
|
||||
#include <platform.h>
|
||||
|
||||
@@ -74,16 +75,22 @@ static int cmd_threads(int argc, const cmd_args *argv)
|
||||
static int cmd_threadstats(int argc, const cmd_args *argv)
|
||||
{
|
||||
for (uint i = 0; i < SMP_MAX_CPUS; i++) {
|
||||
if (!(mp.active_cpus & (1 << i)))
|
||||
continue;
|
||||
|
||||
printf("thread stats (cpu %d):\n", i);
|
||||
printf("\ttotal idle time: %lld\n", thread_stats[i].idle_time);
|
||||
printf("\ttotal busy time: %lld\n", current_time_hires() - thread_stats[i].idle_time);
|
||||
printf("\treschedules: %d\n", thread_stats[i].reschedules);
|
||||
printf("\tcontext_switches: %d\n", thread_stats[i].context_switches);
|
||||
printf("\tpreempts: %d\n", thread_stats[i].preempts);
|
||||
printf("\tyields: %d\n", thread_stats[i].yields);
|
||||
printf("\tinterrupts: %d\n", thread_stats[i].interrupts);
|
||||
printf("\ttimer interrupts: %d\n", thread_stats[i].timer_ints);
|
||||
printf("\ttimers: %d\n", thread_stats[i].timers);
|
||||
printf("\treschedules: %lu\n", thread_stats[i].reschedules);
|
||||
#if WITH_SMP
|
||||
printf("\treschedule_ipis: %lu\n", thread_stats[i].reschedule_ipis);
|
||||
#endif
|
||||
printf("\tcontext_switches: %lu\n", thread_stats[i].context_switches);
|
||||
printf("\tpreempts: %lu\n", thread_stats[i].preempts);
|
||||
printf("\tyields: %lu\n", thread_stats[i].yields);
|
||||
printf("\tinterrupts: %lu\n", thread_stats[i].interrupts);
|
||||
printf("\ttimer interrupts: %lu\n", thread_stats[i].timer_ints);
|
||||
printf("\ttimers: %lu\n", thread_stats[i].timers);
|
||||
}
|
||||
|
||||
return 0;
|
||||
@@ -95,21 +102,39 @@ static enum handler_return threadload(struct timer *t, lk_time_t now, void *arg)
|
||||
static lk_bigtime_t last_idle_time[SMP_MAX_CPUS];
|
||||
|
||||
for (uint i = 0; i < SMP_MAX_CPUS; i++) {
|
||||
/* dont display time for inactiv cpus */
|
||||
if (!(mp.active_cpus & (1 << i)))
|
||||
continue;
|
||||
|
||||
lk_bigtime_t idle_time = thread_stats[i].idle_time;
|
||||
#if 0
|
||||
if (get_current_thread()->priority == IDLE_PRIORITY) {
|
||||
|
||||
/* if the cpu is currently idle, add the time since it went idle up until now to the idle counter */
|
||||
bool is_idle = !!(mp.idle_cpus & (1 << i));
|
||||
if (is_idle) {
|
||||
idle_time += current_time_hires() - thread_stats[i].last_idle_timestamp;
|
||||
}
|
||||
#endif
|
||||
|
||||
lk_bigtime_t delta_time = idle_time - last_idle_time[i];
|
||||
lk_bigtime_t busy_time = 1000000ULL - (delta_time > 1000000ULL ? 1000000ULL : delta_time);
|
||||
|
||||
uint busypercent = (busy_time * 10000) / (1000000);
|
||||
|
||||
// printf("idle_time %lld, busytime %lld\n", idle_time - last_idle_time, busy_time);
|
||||
printf("cpu %u LOAD: %d.%02d%%, cs %d, ints %d, timer ints %d, timers %d\n", i,
|
||||
printf("cpu %u LOAD: "
|
||||
"%u.%02u%%, "
|
||||
"cs %lu, "
|
||||
"pmpts %lu, "
|
||||
#if WITH_SMP
|
||||
"rs_ipis %lu, "
|
||||
#endif
|
||||
"ints %lu, "
|
||||
"tmr ints %lu, "
|
||||
"tmrs %lu\n",
|
||||
i,
|
||||
busypercent / 100, busypercent % 100,
|
||||
thread_stats[i].context_switches - old_stats[i].context_switches,
|
||||
thread_stats[i].preempts - old_stats[i].preempts,
|
||||
#if WITH_SMP
|
||||
thread_stats[i].reschedule_ipis - old_stats[i].reschedule_ipis,
|
||||
#endif
|
||||
thread_stats[i].interrupts - old_stats[i].interrupts,
|
||||
thread_stats[i].timer_ints - old_stats[i].timer_ints,
|
||||
thread_stats[i].timers - old_stats[i].timers);
|
||||
@@ -216,4 +241,4 @@ static int cmd_kevlog(int argc, const cmd_args *argv)
|
||||
|
||||
#endif // WITH_KERNEL_EVLOG
|
||||
|
||||
|
||||
// vim: set noexpandtab:
|
||||
|
||||
Reference in New Issue
Block a user