Introduce a mechanism to suspend/resume system processes. Suspend syncer
and bufdaemon prior to disk sync during system shutdown.
This commit is contained in:
parent
e960abaf96
commit
5e95083920
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=55539
@ -30,6 +30,7 @@
|
||||
#include <sys/systm.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/kthread.h>
|
||||
#include <sys/signalvar.h>
|
||||
#include <sys/unistd.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
@ -97,3 +98,42 @@ kthread_exit(int ecode)
|
||||
exit1(curproc, W_EXITCODE(ecode, 0));
|
||||
}
|
||||
|
||||
/*
|
||||
* Advise a kernel process to suspend (or resume) in its main loop.
|
||||
* Participation is voluntary.
|
||||
*/
|
||||
int
|
||||
suspend_kproc(struct proc *p, int timo)
|
||||
{
|
||||
/*
|
||||
* Make sure this is indeed a system process and we can safely
|
||||
* use the p_siglist field.
|
||||
*/
|
||||
if ((p->p_flag & P_SYSTEM) == 0)
|
||||
return (EINVAL);
|
||||
SIGADDSET(p->p_siglist, SIGSTOP);
|
||||
return tsleep((caddr_t)&p->p_siglist, PPAUSE, "suspkp", timo);
|
||||
}
|
||||
|
||||
int
|
||||
resume_kproc(struct proc *p)
|
||||
{
|
||||
/*
|
||||
* Make sure this is indeed a system process and we can safely
|
||||
* use the p_siglist field.
|
||||
*/
|
||||
if ((p->p_flag & P_SYSTEM) == 0)
|
||||
return (EINVAL);
|
||||
SIGDELSET(p->p_siglist, SIGSTOP);
|
||||
wakeup((caddr_t)&p->p_siglist);
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
kproc_suspend_loop(struct proc *p)
|
||||
{
|
||||
while (SIGISMEMBER(p->p_siglist, SIGSTOP)) {
|
||||
wakeup((caddr_t)&p->p_siglist);
|
||||
tsleep((caddr_t)&p->p_siglist, PPAUSE, "kpsusp", 0);
|
||||
}
|
||||
}
|
||||
|
@ -52,6 +52,7 @@
|
||||
#include <sys/proc.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/kthread.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/sysctl.h>
|
||||
@ -571,3 +572,34 @@ poweroff_wait(void *junk, int howto)
|
||||
return;
|
||||
DELAY(poweroff_delay * 1000);
|
||||
}
|
||||
|
||||
/*
|
||||
* Some system processes (e.g. syncer) need to be stopped at appropriate
|
||||
* points in their main loops prior to a system shutdown, so that they
|
||||
* won't interfere with the shutdown process (e.g. by holding a disk buf
|
||||
* to cause sync to fail). For each of these system processes, register
|
||||
* shutdown_kproc() as a handler for one of shutdown events.
|
||||
*/
|
||||
static int kproc_shutdown_wait = 60;
|
||||
SYSCTL_INT(_kern_shutdown, OID_AUTO, kproc_shutdown_wait, CTLFLAG_RW,
|
||||
&kproc_shutdown_wait, 0, "");
|
||||
|
||||
void
|
||||
shutdown_kproc(void *arg, int howto)
|
||||
{
|
||||
struct proc *p;
|
||||
int error;
|
||||
|
||||
if (panicstr)
|
||||
return;
|
||||
|
||||
p = (struct proc *)arg;
|
||||
printf("Waiting (max %d seconds) for system process `%s' to stop...",
|
||||
kproc_shutdown_wait * hz, p->p_comm);
|
||||
error = suspend_kproc(p, kproc_shutdown_wait);
|
||||
|
||||
if (error == EWOULDBLOCK)
|
||||
printf("timed out\n");
|
||||
else
|
||||
printf("stopped\n");
|
||||
}
|
||||
|
@ -29,13 +29,20 @@
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/kthread.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/vmmeter.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/eventhandler.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/kthread.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/reboot.h>
|
||||
#include <sys/resourcevar.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/vmmeter.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_param.h>
|
||||
#include <vm/vm_kern.h>
|
||||
@ -44,11 +51,6 @@
|
||||
#include <vm/vm_object.h>
|
||||
#include <vm/vm_extern.h>
|
||||
#include <vm/vm_map.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/resourcevar.h>
|
||||
#include <sys/conf.h>
|
||||
|
||||
static MALLOC_DEFINE(M_BIOBUF, "BIO buffer", "BIO buffer");
|
||||
|
||||
@ -1666,6 +1668,13 @@ static void
|
||||
buf_daemon()
|
||||
{
|
||||
int s;
|
||||
|
||||
/*
|
||||
* This process needs to be suspended prior to shutdown sync.
|
||||
*/
|
||||
EVENTHANDLER_REGISTER(shutdown_pre_sync, shutdown_kproc, bufdaemonproc,
|
||||
SHUTDOWN_PRI_LAST);
|
||||
|
||||
/*
|
||||
* This process is allowed to take the buffer cache to the limit
|
||||
*/
|
||||
@ -1676,7 +1685,9 @@ buf_daemon()
|
||||
bd_flushto = hidirtybuffers; /* dynamically adjusted */
|
||||
bd_flushinc = 1;
|
||||
|
||||
while (TRUE) {
|
||||
for (;;) {
|
||||
kproc_suspend_loop(bufdaemonproc);
|
||||
|
||||
bd_request = 0;
|
||||
|
||||
/*
|
||||
|
@ -46,20 +46,23 @@
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/dirent.h>
|
||||
#include <sys/domain.h>
|
||||
#include <sys/eventhandler.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/kthread.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/reboot.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/domain.h>
|
||||
#include <sys/dirent.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/vmmeter.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/vnode.h>
|
||||
|
||||
#include <machine/limits.h>
|
||||
|
||||
@ -72,7 +75,6 @@
|
||||
#include <vm/vm_pager.h>
|
||||
#include <vm/vnode_pager.h>
|
||||
#include <vm/vm_zone.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
static MALLOC_DEFINE(M_NETADDR, "Export Host", "Export host address structure");
|
||||
|
||||
@ -975,9 +977,14 @@ sched_sync(void)
|
||||
int s;
|
||||
struct proc *p = updateproc;
|
||||
|
||||
EVENTHANDLER_REGISTER(shutdown_pre_sync, shutdown_kproc, p,
|
||||
SHUTDOWN_PRI_LAST);
|
||||
|
||||
p->p_flag |= P_BUFEXHAUST;
|
||||
|
||||
for (;;) {
|
||||
kproc_suspend_loop(p);
|
||||
|
||||
starttime = time_second;
|
||||
|
||||
/*
|
||||
|
@ -46,20 +46,23 @@
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/dirent.h>
|
||||
#include <sys/domain.h>
|
||||
#include <sys/eventhandler.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/kthread.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/reboot.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/domain.h>
|
||||
#include <sys/dirent.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/vmmeter.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/vnode.h>
|
||||
|
||||
#include <machine/limits.h>
|
||||
|
||||
@ -72,7 +75,6 @@
|
||||
#include <vm/vm_pager.h>
|
||||
#include <vm/vnode_pager.h>
|
||||
#include <vm/vm_zone.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
static MALLOC_DEFINE(M_NETADDR, "Export Host", "Export host address structure");
|
||||
|
||||
@ -975,9 +977,14 @@ sched_sync(void)
|
||||
int s;
|
||||
struct proc *p = updateproc;
|
||||
|
||||
EVENTHANDLER_REGISTER(shutdown_pre_sync, shutdown_kproc, p,
|
||||
SHUTDOWN_PRI_LAST);
|
||||
|
||||
p->p_flag |= P_BUFEXHAUST;
|
||||
|
||||
for (;;) {
|
||||
kproc_suspend_loop(p);
|
||||
|
||||
starttime = time_second;
|
||||
|
||||
/*
|
||||
|
@ -47,4 +47,9 @@ int kthread_create __P((void (*)(void *), void *, struct proc **,
|
||||
const char *, ...)) __printflike(4, 5);
|
||||
void kthread_exit __P((int)) __dead2;
|
||||
|
||||
int suspend_kproc __P((struct proc *, int));
|
||||
int resume_kproc __P((struct proc *));
|
||||
void kproc_suspend_loop __P((struct proc *));
|
||||
void shutdown_kproc __P((void *, int));
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user