From c975a5d3594c900588a145e7dddea2f808cfe131 Mon Sep 17 00:00:00 2001 From: Conrad Meyer Date: Fri, 25 Mar 2016 19:35:29 +0000 Subject: [PATCH] Add td_swinvoltick to track last involuntary context switch Expose in DDB via "show thread." Reviewed by: markj Sponsored by: EMC / Isilon Storage Division --- sys/ddb/db_ps.c | 12 ++++++++++++ sys/kern/kern_synch.c | 4 +++- sys/sys/proc.h | 1 + 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/sys/ddb/db_ps.c b/sys/ddb/db_ps.c index f38c89fe7ae..76ab2c58624 100644 --- a/sys/ddb/db_ps.c +++ b/sys/ddb/db_ps.c @@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -302,6 +303,7 @@ DB_SHOW_COMMAND(thread, db_show_thread) struct thread *td; struct lock_object *lock; bool comma; + int delta; /* Determine which thread to examine. */ if (have_addr) @@ -376,6 +378,16 @@ DB_SHOW_COMMAND(thread, db_show_thread) td->td_wchan); db_printf(" priority: %d\n", td->td_priority); db_printf(" container lock: %s (%p)\n", lock->lo_name, lock); + if (td->td_swvoltick != 0) { + delta = (u_int)ticks - (u_int)td->td_swvoltick; + db_printf(" last voluntary switch: %d ms ago\n", + 1000 * delta / hz); + } + if (td->td_swinvoltick != 0) { + delta = (u_int)ticks - (u_int)td->td_swinvoltick; + db_printf(" last involuntary switch: %d ms ago\n", + 1000 * delta / hz); + } } DB_SHOW_COMMAND(proc, db_show_proc) diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c index 8c847736f9d..432312e761a 100644 --- a/sys/kern/kern_synch.c +++ b/sys/kern/kern_synch.c @@ -438,8 +438,10 @@ mi_switch(int flags, struct thread *newtd) if (flags & SW_VOL) { td->td_ru.ru_nvcsw++; td->td_swvoltick = ticks; - } else + } else { td->td_ru.ru_nivcsw++; + td->td_swinvoltick = ticks; + } #ifdef SCHED_STATS SCHED_STAT_INC(sched_switch_stats[flags & SW_TYPE_MASK]); #endif diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 5d96406b875..2d1769e4309 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -254,6 +254,7 @@ struct thread { int td_slptick; /* (t) Time at sleep. */ int td_blktick; /* (t) Time spent blocked. */ int td_swvoltick; /* (t) Time at last SW_VOL switch. */ + int td_swinvoltick; /* (t) Time at last SW_INVOL switch. */ u_int td_cow; /* (*) Number of copy-on-write faults */ struct rusage td_ru; /* (t) rusage information. */ struct rusage_ext td_rux; /* (t) Internal rusage information. */