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
This commit is contained in:
John Baldwin 2000-12-15 21:23:32 +00:00
parent 38d66a0de3
commit a9b1370731
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=70069

View File

@ -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*/