introduce a function, proclist_foreach_call, to iterate all procs on

a proclist and call the specified function for each of them.
primarily to fix a procfs locking problem, but i think that it's useful for
others as well.

while i'm here, introduce PROCLIST_FOREACH macro, which is similar to
LIST_FOREACH but skips marker entries which are used by proclist_foreach_call.
This commit is contained in:
yamt 2004-10-01 16:30:52 +00:00
parent dc8336fa20
commit 0994e6acb8
14 changed files with 94 additions and 40 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: darwin_sysctl.c,v 1.32 2004/07/28 22:24:06 manu Exp $ */
/* $NetBSD: darwin_sysctl.c,v 1.33 2004/10/01 16:30:52 yamt Exp $ */
/*-
* Copyright (c) 2002 The NetBSD Foundation, Inc.
@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: darwin_sysctl.c,v 1.32 2004/07/28 22:24:06 manu Exp $");
__KERNEL_RCSID(0, "$NetBSD: darwin_sysctl.c,v 1.33 2004/10/01 16:30:52 yamt Exp $");
#include <sys/types.h>
#include <sys/param.h>
@ -652,7 +652,7 @@ darwin_sysctl_dokproc(SYSCTLFN_ARGS)
pd = proclists;
again:
for (p = LIST_FIRST(pd->pd_list); p != NULL; p = LIST_NEXT(p, p_list)) {
PROCLIST_FOREACH(p, pd->pd_list) {
/*
* Skip embryonic processes.
*/

View File

@ -1,4 +1,4 @@
/* $NetBSD: irix_exec.c,v 1.38 2004/08/08 08:42:03 jdolecek Exp $ */
/* $NetBSD: irix_exec.c,v 1.39 2004/10/01 16:30:52 yamt Exp $ */
/*-
* Copyright (c) 2001-2002 The NetBSD Foundation, Inc.
@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: irix_exec.c,v 1.38 2004/08/08 08:42:03 jdolecek Exp $");
__KERNEL_RCSID(0, "$NetBSD: irix_exec.c,v 1.39 2004/10/01 16:30:52 yamt Exp $");
#ifdef _KERNEL_OPT
#include "opt_syscall_debug.h"
@ -199,7 +199,7 @@ irix_e_proc_exit(p)
* Send SIGHUP to child process as requested using prctl(2)
*/
proclist_lock_read();
LIST_FOREACH(pp, &allproc, p_list) {
PROCLIST_FOREACH(pp, &allproc) {
/* Select IRIX processes */
if (irix_check_exec(pp) == 0)
continue;

View File

@ -1,4 +1,4 @@
/* $NetBSD: mach_port.c,v 1.54 2004/08/21 18:58:31 hubertf Exp $ */
/* $NetBSD: mach_port.c,v 1.55 2004/10/01 16:30:52 yamt Exp $ */
/*-
* Copyright (c) 2002-2003 The NetBSD Foundation, Inc.
@ -39,7 +39,7 @@
#include "opt_compat_darwin.h"
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: mach_port.c,v 1.54 2004/08/21 18:58:31 hubertf Exp $");
__KERNEL_RCSID(0, "$NetBSD: mach_port.c,v 1.55 2004/10/01 16:30:52 yamt Exp $");
#include <sys/types.h>
#include <sys/param.h>
@ -1002,7 +1002,7 @@ mach_debug_port(void)
struct mach_right *mrs;
struct proc *p;
LIST_FOREACH(p, &allproc, p_list) {
PROCLIST_FOREACH(p, &allproc) {
if ((p->p_emul != &emul_mach) &&
#ifdef COMPAT_DARWIN
(p->p_emul != &emul_darwin) &&

View File

@ -1,4 +1,4 @@
/* $NetBSD: init_main.c,v 1.239 2004/07/05 07:28:45 pk Exp $ */
/* $NetBSD: init_main.c,v 1.240 2004/10/01 16:30:52 yamt Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1991, 1992, 1993
@ -71,7 +71,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.239 2004/07/05 07:28:45 pk Exp $");
__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.240 2004/10/01 16:30:52 yamt Exp $");
#include "fs_nfs.h"
#include "opt_nfsserver.h"
@ -561,6 +561,7 @@ main(void)
proclist_lock_read();
s = splsched();
LIST_FOREACH(p, &allproc, p_list) {
KASSERT((p->p_flag & P_MARKER) == 0);
p->p_stats->p_start = mono_time = boottime = time;
LIST_FOREACH(l, &p->p_lwps, l_sibling) {
if (l->l_cpu != NULL)

View File

@ -1,4 +1,4 @@
/* $NetBSD: init_sysctl.c,v 1.31 2004/07/27 12:46:18 atatat Exp $ */
/* $NetBSD: init_sysctl.c,v 1.32 2004/10/01 16:30:52 yamt Exp $ */
/*-
* Copyright (c) 2003 The NetBSD Foundation, Inc.
@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: init_sysctl.c,v 1.31 2004/07/27 12:46:18 atatat Exp $");
__KERNEL_RCSID(0, "$NetBSD: init_sysctl.c,v 1.32 2004/10/01 16:30:52 yamt Exp $");
#include "opt_sysv.h"
#include "opt_multiprocessor.h"
@ -1893,7 +1893,7 @@ sysctl_doeproc(SYSCTLFN_ARGS)
pd = proclists;
again:
for (p = LIST_FIRST(pd->pd_list); p != NULL; p = LIST_NEXT(p, p_list)) {
PROCLIST_FOREACH(p, pd->pd_list) {
/*
* Skip embryonic processes.
*/

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_exec.c,v 1.190 2004/09/17 14:11:25 skrll Exp $ */
/* $NetBSD: kern_exec.c,v 1.191 2004/10/01 16:30:52 yamt Exp $ */
/*-
* Copyright (C) 1993, 1994, 1996 Christopher G. Demetriou
@ -33,7 +33,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.190 2004/09/17 14:11:25 skrll Exp $");
__KERNEL_RCSID(0, "$NetBSD: kern_exec.c,v 1.191 2004/10/01 16:30:52 yamt Exp $");
#include "opt_ktrace.h"
#include "opt_syscall_debug.h"
@ -1025,7 +1025,7 @@ emul_unregister(const char *name)
*/
proclist_lock_read();
for (pd = proclists; pd->pd_list != NULL && !error; pd++) {
LIST_FOREACH(ptmp, pd->pd_list, p_list) {
PROCLIST_FOREACH(ptmp, pd->pd_list) {
if (ptmp->p_emul == it->el_emul) {
error = EBUSY;
break;

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_exit.c,v 1.142 2004/08/07 03:34:37 christos Exp $ */
/* $NetBSD: kern_exit.c,v 1.143 2004/10/01 16:30:52 yamt Exp $ */
/*-
* Copyright (c) 1998, 1999 The NetBSD Foundation, Inc.
@ -74,7 +74,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_exit.c,v 1.142 2004/08/07 03:34:37 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: kern_exit.c,v 1.143 2004/10/01 16:30:52 yamt Exp $");
#include "opt_ktrace.h"
#include "opt_perfctrs.h"
@ -396,7 +396,7 @@ exit1(struct lwp *l, int rv)
* p_opptr anymore.
*/
if (p->p_flag & P_CHTRACED) {
LIST_FOREACH(q, &allproc, p_list) {
PROCLIST_FOREACH(q, &allproc) {
if (q->p_opptr == p)
q->p_opptr = NULL;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_ktrace.c,v 1.93 2004/09/22 22:15:03 enami Exp $ */
/* $NetBSD: kern_ktrace.c,v 1.94 2004/10/01 16:30:53 yamt Exp $ */
/*
* Copyright (c) 1989, 1993
@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_ktrace.c,v 1.93 2004/09/22 22:15:03 enami Exp $");
__KERNEL_RCSID(0, "$NetBSD: kern_ktrace.c,v 1.94 2004/10/01 16:30:53 yamt Exp $");
#include "opt_ktrace.h"
#include "opt_compat_mach.h"
@ -734,7 +734,7 @@ ktrace_common(struct proc *curp, int ops, int facs, int pid, struct file *fp)
goto done;
proclist_lock_read();
LIST_FOREACH(p, &allproc, p_list) {
PROCLIST_FOREACH(p, &allproc) {
if (p->p_tracep == ktd) {
if (ktrcanset(curp, p))
ktrderef(p);
@ -1094,7 +1094,7 @@ again:
"ktrace write failed, errno %d, tracing stopped\n",
error);
proclist_lock_read();
LIST_FOREACH(p, &allproc, p_list) {
PROCLIST_FOREACH(p, &allproc) {
if (p->p_tracep == ktd)
ktrderef(p);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_proc.c,v 1.78 2004/05/06 22:20:30 pk Exp $ */
/* $NetBSD: kern_proc.c,v 1.79 2004/10/01 16:30:53 yamt Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@ -69,7 +69,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_proc.c,v 1.78 2004/05/06 22:20:30 pk Exp $");
__KERNEL_RCSID(0, "$NetBSD: kern_proc.c,v 1.79 2004/10/01 16:30:53 yamt Exp $");
#include "opt_kstack.h"
@ -93,6 +93,7 @@ __KERNEL_RCSID(0, "$NetBSD: kern_proc.c,v 1.78 2004/05/06 22:20:30 pk Exp $");
#include <sys/ras.h>
#include <sys/sa.h>
#include <sys/savar.h>
#include <uvm/uvm_extern.h>
/*
* Other process lists
@ -1083,3 +1084,35 @@ kstack_check_magic(const struct lwp *l)
}
}
#endif /* KSTACK_CHECK_MAGIC */
#define PROCLIST_ASSERT_LOCKED_READ() \
KASSERT(lockstatus(&proclist_lock) == LK_SHARED)
int
proclist_foreach_call(struct proclist *list,
int (*callback)(struct proc *, void *arg), void *arg)
{
struct proc marker;
struct proc *p;
struct lwp * const l = curlwp;
int ret = 0;
marker.p_flag = P_MARKER;
PHOLD(l);
proclist_lock_read();
for (p = LIST_FIRST(list); ret == 0 && p != NULL;) {
if (p->p_flag & P_MARKER) {
p = LIST_NEXT(p, p_list);
continue;
}
LIST_INSERT_AFTER(p, &marker, p_list);
ret = (*callback)(p, arg);
PROCLIST_ASSERT_LOCKED_READ();
p = LIST_NEXT(&marker, p_list);
LIST_REMOVE(&marker, p_list);
}
proclist_unlock_read();
PRELE(l);
return ret;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_resource.c,v 1.85 2004/05/13 17:56:14 kleink Exp $ */
/* $NetBSD: kern_resource.c,v 1.86 2004/10/01 16:30:54 yamt Exp $ */
/*-
* Copyright (c) 1982, 1986, 1991, 1993
@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_resource.c,v 1.85 2004/05/13 17:56:14 kleink Exp $");
__KERNEL_RCSID(0, "$NetBSD: kern_resource.c,v 1.86 2004/10/01 16:30:54 yamt Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -116,7 +116,7 @@ sys_getpriority(l, v, retval)
if (SCARG(uap, who) == 0)
SCARG(uap, who) = curp->p_ucred->cr_uid;
proclist_lock_read();
LIST_FOREACH(p, &allproc, p_list) {
PROCLIST_FOREACH(p, &allproc) {
if (p->p_ucred->cr_uid == (uid_t) SCARG(uap, who) &&
p->p_nice < low)
low = p->p_nice;
@ -179,7 +179,7 @@ sys_setpriority(l, v, retval)
if (SCARG(uap, who) == 0)
SCARG(uap, who) = curp->p_ucred->cr_uid;
proclist_lock_read();
LIST_FOREACH(p, &allproc, p_list) {
PROCLIST_FOREACH(p, &allproc) {
if (p->p_ucred->cr_uid == (uid_t) SCARG(uap, who)) {
error = donice(curp, p, SCARG(uap, prio));
found++;

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_sig.c,v 1.198 2004/09/28 08:59:20 jdolecek Exp $ */
/* $NetBSD: kern_sig.c,v 1.199 2004/10/01 16:30:55 yamt Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1991, 1993
@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.198 2004/09/28 08:59:20 jdolecek Exp $");
__KERNEL_RCSID(0, "$NetBSD: kern_sig.c,v 1.199 2004/10/01 16:30:55 yamt Exp $");
#include "opt_ktrace.h"
#include "opt_compat_sunos.h"
@ -812,7 +812,7 @@ killpg1(struct proc *cp, ksiginfo_t *ksi, int pgid, int all)
* broadcast
*/
proclist_lock_read();
LIST_FOREACH(p, &allproc, p_list) {
PROCLIST_FOREACH(p, &allproc) {
if (p->p_pid <= 1 || p->p_flag & P_SYSTEM ||
p == cp || !CANSIGNAL(cp, pc, p, signum))
continue;

View File

@ -1,4 +1,4 @@
/* $NetBSD: kern_synch.c,v 1.144 2004/05/18 11:59:11 yamt Exp $ */
/* $NetBSD: kern_synch.c,v 1.145 2004/10/01 16:30:55 yamt Exp $ */
/*-
* Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
@ -74,7 +74,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kern_synch.c,v 1.144 2004/05/18 11:59:11 yamt Exp $");
__KERNEL_RCSID(0, "$NetBSD: kern_synch.c,v 1.145 2004/10/01 16:30:55 yamt Exp $");
#include "opt_ddb.h"
#include "opt_ktrace.h"
@ -255,7 +255,7 @@ schedcpu(void *arg)
int clkhz;
proclist_lock_read();
LIST_FOREACH(p, &allproc, p_list) {
PROCLIST_FOREACH(p, &allproc) {
/*
* Increment time in/out of memory and sleep time
* (if sleeping). We ignore overflow; with 16-bit int's

View File

@ -1,4 +1,4 @@
/* $NetBSD: vfs_syscalls.c,v 1.211 2004/09/13 20:02:20 jdolecek Exp $ */
/* $NetBSD: vfs_syscalls.c,v 1.212 2004/10/01 16:30:56 yamt Exp $ */
/*
* Copyright (c) 1989, 1993
@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.211 2004/09/13 20:02:20 jdolecek Exp $");
__KERNEL_RCSID(0, "$NetBSD: vfs_syscalls.c,v 1.212 2004/10/01 16:30:56 yamt Exp $");
#include "opt_compat_netbsd.h"
#include "opt_compat_43.h"
@ -399,7 +399,7 @@ checkdirs(olddp)
if (VFS_ROOT(olddp->v_mountedhere, &newdp))
panic("mount: lost mount");
proclist_lock_read();
LIST_FOREACH(p, &allproc, p_list) {
PROCLIST_FOREACH(p, &allproc) {
cwdi = p->p_cwdi;
if (cwdi->cwdi_cdir == olddp) {
vrele(cwdi->cwdi_cdir);

View File

@ -1,4 +1,4 @@
/* $NetBSD: proc.h,v 1.194 2004/09/17 23:26:42 enami Exp $ */
/* $NetBSD: proc.h,v 1.195 2004/10/01 16:30:52 yamt Exp $ */
/*-
* Copyright (c) 1986, 1989, 1991, 1993
@ -298,6 +298,7 @@ struct proc {
#define P_STOPFORK 0x00800000 /* Child will be stopped on fork(2) */
#define P_STOPEXEC 0x01000000 /* Will be stopped on exec(2) */
#define P_STOPEXIT 0x02000000 /* Will be stopped at process exit */
#define P_MARKER 0x80000000 /* Is a dummy marker process */
/*
* Macro to compute the exit signal to be delivered.
@ -475,6 +476,25 @@ int proclist_lock_write(void);
void proclist_unlock_write(int);
void p_sugid(struct proc *);
int proclist_foreach_call(struct proclist *,
int (*)(struct proc *, void *arg), void *);
static __inline struct proc *_proclist_skipmarker(struct proc *);
static __inline struct proc *
_proclist_skipmarker(struct proc *p0)
{
struct proc *p = p0;
while (p != NULL && p->p_flag & P_MARKER)
p = LIST_NEXT(p, p_list);
return p;
}
#define PROCLIST_FOREACH(var, head) \
for ((var) = LIST_FIRST(head); \
((var) = _proclist_skipmarker(var)) != NULL; \
(var) = LIST_NEXT(var, p_list))
/* Compatibility with old, non-interlocked tsleep call */
#define tsleep(chan, pri, wmesg, timo) \
ltsleep(chan, pri, wmesg, timo, NULL)