Skip site navigation (1)Skip section navigation (2)
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>