From: Sepherosa Ziehau Date: Wed, 12 Oct 2005 05:17:38 +0000 (+0000) Subject: - Make device polling use seperate SYSTIMER instead of hardclock X-Git-Tag: v2.0.1~5822 X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/a327a6db3cda827865f43fbd6b2066b7b97118a0 - Make device polling use seperate SYSTIMER instead of hardclock - Add "kern.polling.pollhz" sysctl-node/tunable-variable, which can be used to set device polling frequency(1 ~ 20000) on a *running* system Idea-and-Hint-from: dillon Review-by: dillon, kernel@, submmit@ Test-with: fxp(4) --- diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c index 07bf5a0561..d1126b9083 100644 --- a/sys/kern/kern_clock.c +++ b/sys/kern/kern_clock.c @@ -70,7 +70,7 @@ * * @(#)kern_clock.c 8.5 (Berkeley) 1/21/94 * $FreeBSD: src/sys/kern/kern_clock.c,v 1.105.2.10 2002/10/17 13:19:40 maxim Exp $ - * $DragonFly: src/sys/kern/kern_clock.c,v 1.47 2005/10/11 09:59:56 corecode Exp $ + * $DragonFly: src/sys/kern/kern_clock.c,v 1.48 2005/10/12 05:17:38 sephe Exp $ */ #include "opt_ntp.h" @@ -102,8 +102,47 @@ #endif #ifdef DEVICE_POLLING +#ifndef DEVICE_POLLING_FREQ_MAX +#define DEVICE_POLLING_FREQ_MAX 20000 +#endif +#define DEVICE_POLLING_FREQ_DEFAULT 1000 + extern void init_device_poll(void); extern void hardclock_device_poll(void); + +static int sysctl_pollhz(SYSCTL_HANDLER_ARGS); + +static struct systimer gd0_pollclock; +static int pollhz = DEVICE_POLLING_FREQ_DEFAULT; + +TUNABLE_INT("kern.polling.pollhz", &pollhz); +SYSCTL_DECL(_kern_polling); +SYSCTL_PROC(_kern_polling, OID_AUTO, pollhz, CTLTYPE_INT | CTLFLAG_RW, + 0, 0, sysctl_pollhz, "I", "Device polling frequency"); + +static int +sysctl_pollhz(SYSCTL_HANDLER_ARGS) +{ + int error, phz; + + crit_enter(); + phz = pollhz; + crit_exit(); + + error = sysctl_handle_int(oidp, &phz, 0, req); + if (error || req->newptr == NULL) + return error; + if (phz <= 0) + return EINVAL; + else if (phz > DEVICE_POLLING_FREQ_MAX) + phz = DEVICE_POLLING_FREQ_MAX; + + crit_enter(); + pollhz = phz; + gd0_pollclock.periodic = sys_cputimer->fromhz(phz); + crit_exit(); + return 0; +} #endif /* DEVICE_POLLING */ static void initclocks (void *dummy); @@ -194,6 +233,9 @@ SYSCTL_PROC(_kern, OID_AUTO, basetime, CTLTYPE_STRUCT|CTLFLAG_RD, 0, 0, static void hardclock(systimer_t info, struct intrframe *frame); static void statclock(systimer_t info, struct intrframe *frame); static void schedclock(systimer_t info, struct intrframe *frame); +#ifdef DEVICE_POLLING +static void pollclock(systimer_t info, struct intrframe *frame); +#endif static void getnanotime_nbt(struct timespec *nbt, struct timespec *tsp); int ticks; /* system master ticks at hz */ @@ -239,6 +281,15 @@ initclocks_pcpu(void) if (gd->gd_cpuid == 0) { gd->gd_time_seconds = 1; gd->gd_cpuclock_base = sys_cputimer->count(); + +#ifdef DEVICE_POLLING + if (pollhz <= 0) + pollhz = DEVICE_POLLING_FREQ_DEFAULT; + else if (pollhz > DEVICE_POLLING_FREQ_MAX) + pollhz = DEVICE_POLLING_FREQ_MAX; + + systimer_init_periodic_nq(&gd0_pollclock, pollclock, NULL, pollhz); +#endif } else { /* XXX */ gd->gd_time_seconds = globaldata_find(0)->gd_time_seconds; @@ -363,10 +414,6 @@ hardclock(systimer_t info, struct intrframe *frame) ++ticks; -#ifdef DEVICE_POLLING - hardclock_device_poll(); /* mpsafe, short and quick */ -#endif /* DEVICE_POLLING */ - #if 0 if (tco->tc_poll_pps) tco->tc_poll_pps(tco); @@ -671,6 +718,14 @@ schedclock(systimer_t info, struct intrframe *frame) } } +#ifdef DEVICE_POLLING +static void +pollclock(systimer_t info __unused, struct intrframe *frame __unused) +{ + hardclock_device_poll(); /* mpsafe, short and quick */ +} +#endif + /* * Compute number of ticks for the specified amount of time. The * return value is intended to be used in a clock interrupt timed