diff options
author | jhb <jhb@FreeBSD.org> | 2000-12-15 21:23:32 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2000-12-15 21:23:32 +0000 |
commit | 415f02cbaf57fb59bc31f00b3a78c1421286196e (patch) | |
tree | ba1e60d53bb18210c6a5b270279ce10a2c511871 /sys/kern | |
parent | e9d51c0803304de86917105a749c982aa3159aa2 (diff) | |
download | FreeBSD-src-415f02cbaf57fb59bc31f00b3a78c1421286196e.zip FreeBSD-src-415f02cbaf57fb59bc31f00b3a78c1421286196e.tar.gz |
Delay waking up processes select'ing on the log device directly from
the kernel console. Instead, change logwakeup() to set a flag in the
softc. A callout then wakes up every so often and wakes up any processes
selecting on /dev/log (such as syslogd) if the flag is set. By default
this callout fires 5 times a second, but that can be adjusted by the
sysctl kern.log_wakeups_per_second.
Reviewed by: phk
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/subr_log.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/sys/kern/subr_log.c b/sys/kern/subr_log.c index 9c430c7..8580f79 100644 --- a/sys/kern/subr_log.c +++ b/sys/kern/subr_log.c @@ -50,11 +50,13 @@ #include <sys/kernel.h> #include <sys/poll.h> #include <sys/filedesc.h> +#include <sys/sysctl.h> #define LOG_RDPRI (PZERO + 1) #define LOG_ASYNC 0x04 #define LOG_RDWAIT 0x08 +#define LOG_NEEDWAKEUP 0x10 static d_open_t logopen; static d_close_t logclose; @@ -62,6 +64,8 @@ static d_read_t logread; static d_ioctl_t logioctl; static d_poll_t logpoll; +static void logtimeout(void *arg); + #define CDEV_MAJOR 7 static struct cdevsw log_cdevsw = { /* open */ logopen, @@ -84,10 +88,16 @@ static struct logsoftc { int sc_state; /* see above for possibilities */ struct selinfo sc_selp; /* process waiting on select call */ struct sigio *sc_sigio; /* information for async I/O */ + struct callout sc_callout; /* callout to wakeup syslog */ } logsoftc; int log_open; /* also used in log() */ +/* Times per second to check for a pending syslog wakeup. */ +static int log_wakeups_per_second = 5; +SYSCTL_INT(_kern, OID_AUTO, log_wakeups_per_second, CTLFLAG_RW, + &log_wakeups_per_second, 0, ""); + /*ARGSUSED*/ static int logopen(dev_t dev, int flags, int mode, struct proc *p) @@ -95,7 +105,10 @@ logopen(dev_t dev, int flags, int mode, struct proc *p) if (log_open) return (EBUSY); log_open = 1; + callout_init(&logsoftc.sc_callout, 0); fsetown(p->p_pid, &logsoftc.sc_sigio); /* signal process only */ + callout_reset(&logsoftc.sc_callout, hz / log_wakeups_per_second, + logtimeout, NULL); return (0); } @@ -104,6 +117,7 @@ static int logclose(dev_t dev, int flag, int mode, struct proc *p) { + callout_stop(&logsoftc.sc_callout); log_open = 0; logsoftc.sc_state = 0; funsetown(logsoftc.sc_sigio); @@ -175,6 +189,19 @@ logpoll(dev_t dev, int events, struct proc *p) void logwakeup(void) { + + if (!log_open) + return; + logsoftc.sc_state |= LOG_NEEDWAKEUP; +} + +static void +logtimeout(void *arg) +{ + + if ((logsoftc.sc_state & LOG_NEEDWAKEUP) == 0) + return; + logsoftc.sc_state &= ~LOG_NEEDWAKEUP; if (!log_open) return; selwakeup(&logsoftc.sc_selp); @@ -184,6 +211,8 @@ logwakeup(void) wakeup((caddr_t)msgbufp); logsoftc.sc_state &= ~LOG_RDWAIT; } + callout_reset(&logsoftc.sc_callout, hz / log_wakeups_per_second, + logtimeout, NULL); } /*ARGSUSED*/ |