summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/kern/kern_timeout.c
diff options
context:
space:
mode:
Diffstat (limited to 'freebsd/sys/kern/kern_timeout.c')
-rw-r--r--freebsd/sys/kern/kern_timeout.c57
1 files changed, 54 insertions, 3 deletions
diff --git a/freebsd/sys/kern/kern_timeout.c b/freebsd/sys/kern/kern_timeout.c
index 2f478afc..983abba2 100644
--- a/freebsd/sys/kern/kern_timeout.c
+++ b/freebsd/sys/kern/kern_timeout.c
@@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$");
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/callout.h>
+#include <sys/domainset.h>
#include <sys/file.h>
#include <sys/interrupt.h>
#include <sys/kernel.h>
@@ -67,6 +68,7 @@ __FBSDID("$FreeBSD$");
#ifdef DDB
#include <ddb/ddb.h>
+#include <ddb/db_sym.h>
#include <machine/_inttypes.h>
#endif
@@ -154,12 +156,16 @@ u_int callwheelsize, callwheelmask;
struct cc_exec {
struct callout *cc_curr;
void (*cc_drain)(void *);
+#ifndef __rtems__
+ void *cc_last_func;
+ void *cc_last_arg;
+#endif /* __rtems__ */
#ifdef SMP
void (*ce_migration_func)(void *);
void *ce_migration_arg;
- int ce_migration_cpu;
sbintime_t ce_migration_time;
sbintime_t ce_migration_prec;
+ int ce_migration_cpu;
#endif
bool cc_cancel;
bool cc_waiting;
@@ -200,6 +206,8 @@ struct callout_cpu {
#ifndef __rtems__
#define cc_exec_curr(cc, dir) cc->cc_exec_entity[dir].cc_curr
+#define cc_exec_last_func(cc, dir) cc->cc_exec_entity[dir].cc_last_func
+#define cc_exec_last_arg(cc, dir) cc->cc_exec_entity[dir].cc_last_arg
#define cc_exec_drain(cc, dir) cc->cc_exec_entity[dir].cc_drain
#else /* __rtems__ */
#define cc_exec_curr(cc, dir) cc->cc_exec_entity.cc_curr
@@ -426,8 +434,9 @@ callout_cpu_init(struct callout_cpu *cc, int cpu)
SLIST_INIT(&cc->cc_callfree);
cc->cc_inited = 1;
#ifndef __rtems__
- cc->cc_callwheel = malloc(sizeof(struct callout_list) * callwheelsize,
- M_CALLOUT, M_WAITOK);
+ cc->cc_callwheel = malloc_domainset(sizeof(struct callout_list) *
+ callwheelsize, M_CALLOUT,
+ DOMAINSET_PREF(pcpu_find(cpu)->pc_domain), M_WAITOK);
#endif /* __rtems__ */
for (i = 0; i < callwheelsize; i++)
LIST_INIT(&cc->cc_callwheel[i]);
@@ -821,6 +830,10 @@ softclock_call_cc(struct callout *c, struct callout_cpu *cc,
c->c_iflags &= ~CALLOUT_PENDING;
cc_exec_curr(cc, direct) = c;
+#ifndef __rtems__
+ cc_exec_last_func(cc, direct) = c_func;
+ cc_exec_last_arg(cc, direct) = c_arg;
+#endif /* __rtems__ */
cc_exec_cancel(cc, direct) = false;
cc_exec_drain(cc, direct) = NULL;
CC_UNLOCK(cc);
@@ -1876,4 +1889,42 @@ DB_SHOW_COMMAND(callout, db_show_callout)
_show_callout((struct callout *)addr);
}
+
+static void
+_show_last_callout(int cpu, int direct, const char *dirstr)
+{
+ struct callout_cpu *cc;
+ void *func, *arg;
+
+ cc = CC_CPU(cpu);
+ func = cc_exec_last_func(cc, direct);
+ arg = cc_exec_last_arg(cc, direct);
+ db_printf("cpu %d last%s callout function: %p ", cpu, dirstr, func);
+ db_printsym((db_expr_t)func, DB_STGY_ANY);
+ db_printf("\ncpu %d last%s callout argument: %p\n", cpu, dirstr, arg);
+}
+
+DB_SHOW_COMMAND(callout_last, db_show_callout_last)
+{
+ int cpu, last;
+
+ if (have_addr) {
+ if (addr < 0 || addr > mp_maxid || CPU_ABSENT(addr)) {
+ db_printf("no such cpu: %d\n", (int)addr);
+ return;
+ }
+ cpu = last = addr;
+ } else {
+ cpu = 0;
+ last = mp_maxid;
+ }
+
+ while (cpu <= last) {
+ if (!CPU_ABSENT(cpu)) {
+ _show_last_callout(cpu, 0, "");
+ _show_last_callout(cpu, 1, " direct");
+ }
+ cpu++;
+ }
+}
#endif /* DDB */