svn commit: r236815 - in projects/calloutng/sys: kern sys
Davide Italiano
davide at FreeBSD.org
Sat Jun 9 14:13:43 UTC 2012
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)
More information about the svn-src-projects
mailing list