Date: Sat, 9 Jun 2012 14:13:42 +0000 (UTC) From: Davide Italiano <davide@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r236815 - in projects/calloutng/sys: kern sys Message-ID: <201206091413.q59EDgGt037051@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: davide Date: Sat Jun 9 14:13:42 2012 New Revision: 236815 URL: http://svn.freebsd.org/changeset/base/236815 Log: Implement support for SWI-less callouts, so that we can run callout directly from hardware interrupt context rather than from SWI context. In this way, under some conditions, there's no need to wake up another CPU from sleep and perfor a context switch, avoiding a waste of time. Discussed with: mav Modified: projects/calloutng/sys/kern/kern_timeout.c projects/calloutng/sys/kern/subr_sleepqueue.c projects/calloutng/sys/sys/callout.h Modified: projects/calloutng/sys/kern/kern_timeout.c ============================================================================== --- projects/calloutng/sys/kern/kern_timeout.c Sat Jun 9 13:07:44 2012 (r236814) +++ projects/calloutng/sys/kern/kern_timeout.c Sat Jun 9 14:13:42 2012 (r236815) @@ -402,10 +402,18 @@ callout_tick(void) TAILQ_FOREACH(tmp, sc, c_links.tqe) { if ((!flag || flag == 1) && bintime_cmp(&tmp->c_time, &now, <=)) { - TAILQ_INSERT_TAIL(cc->cc_localexp,tmp,c_staiter); - TAILQ_REMOVE(sc, tmp, c_links.tqe); - tmp->c_flags |= CALLOUT_PROCESSED; - need_softclock = 1; + if (tmp->c_flags & CALLOUT_DIRECT) { + tmp->c_func(tmp->c_arg); + TAILQ_REMOVE(sc, tmp, c_links.tqe); + tmp->c_flags &= ~CALLOUT_PENDING; + } + else { + TAILQ_INSERT_TAIL(cc->cc_localexp, + tmp,c_staiter); + TAILQ_REMOVE(sc, tmp, c_links.tqe); + tmp->c_flags |= CALLOUT_PROCESSED; + need_softclock = 1; + } } if ((flag == 1 || flag == 2) && bintime_cmp(&tmp->c_time, &now, >)) { @@ -466,7 +474,7 @@ callout_lock(struct callout *c) static void callout_cc_add(struct callout *c, struct callout_cpu *cc, - struct bintime to_bintime, void (*func)(void *), void *arg, int cpu) + struct bintime to_bintime, void (*func)(void *), void *arg, int cpu, int direct) { int bucket; @@ -476,6 +484,8 @@ callout_cc_add(struct callout *c, struct } c->c_arg = arg; c->c_flags |= (CALLOUT_ACTIVE | CALLOUT_PENDING); + if (direct) + c->c_flags |= CALLOUT_DIRECT; c->c_flags &= ~CALLOUT_PROCESSED; c->c_func = func; c->c_time = to_bintime; @@ -654,7 +664,7 @@ skip: */ new_cc = callout_cpu_switch(c, cc, new_cpu); callout_cc_add(c, new_cc, new_time, new_func, new_arg, - new_cpu); + new_cpu, 0); CC_UNLOCK(new_cc); CC_LOCK(cc); #else @@ -818,7 +828,7 @@ callout_handle_init(struct callout_handl */ int callout_reset_bt_on(struct callout *c, struct bintime bt, void (*ftn)(void *), - void *arg, int cpu) + void *arg, int cpu, int direct) { struct callout_cpu *cc; int cancelled = 0; @@ -892,7 +902,7 @@ callout_reset_bt_on(struct callout *c, s } #endif - callout_cc_add(c, cc, bt, ftn, arg, cpu); + callout_cc_add(c, cc, bt, ftn, arg, cpu, direct); CTR6(KTR_CALLOUT, "%sscheduled %p func %p arg %p in %ld %ld", cancelled ? "re" : "", c, c->c_func, c->c_arg, bt.sec, bt.frac); CC_UNLOCK(cc); @@ -910,7 +920,7 @@ callout_reset_on(struct callout *c, int getbinuptime(&now); bintime_mul(&bt,to_ticks); bintime_add(&bt,&now); - return (callout_reset_bt_on(c, bt, ftn, arg, cpu)); + return (callout_reset_bt_on(c, bt, ftn, arg, cpu, 0)); } /* Modified: projects/calloutng/sys/kern/subr_sleepqueue.c ============================================================================== --- projects/calloutng/sys/kern/subr_sleepqueue.c Sat Jun 9 13:07:44 2012 (r236814) +++ projects/calloutng/sys/kern/subr_sleepqueue.c Sat Jun 9 14:13:42 2012 (r236815) @@ -374,7 +374,7 @@ sleepq_set_timeout_bt(void *wchan, struc MPASS(TD_ON_SLEEPQ(td)); MPASS(td->td_sleepqueue == NULL); MPASS(wchan != NULL); - callout_reset_bt_on(&td->td_slpcallout, bt, sleepq_timeout, td, PCPU_GET(cpuid)); + callout_reset_bt_on(&td->td_slpcallout, bt, sleepq_timeout, td, PCPU_GET(cpuid), 0); } void Modified: projects/calloutng/sys/sys/callout.h ============================================================================== --- projects/calloutng/sys/sys/callout.h Sat Jun 9 13:07:44 2012 (r236814) +++ projects/calloutng/sys/sys/callout.h Sat Jun 9 14:13:42 2012 (r236815) @@ -48,6 +48,7 @@ #define CALLOUT_SHAREDLOCK 0x0020 /* callout lock held in shared mode */ #define CALLOUT_DFRMIGRATION 0x0040 /* callout in deferred migration mode */ #define CALLOUT_PROCESSED 0x0080 /* callout in wheel or processing list? */ +#define CALLOUT_DIRECT 0x1000 /* allow exec from hw int context */ struct callout_handle { struct callout *callout; @@ -69,7 +70,7 @@ void _callout_init_lock(struct callout * NULL, (flags)) #define callout_pending(c) ((c)->c_flags & CALLOUT_PENDING) int callout_reset_bt_on(struct callout *, struct bintime, void(*)(void *), - void *, int); + void *, int, int); int callout_reset_on(struct callout *, int, void (*)(void *), void *, int); #define callout_reset(c, on_tick, fn, arg) \ callout_reset_on((c), (on_tick), (fn), (arg), (c)->c_cpu)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201206091413.q59EDgGt037051>