From 835bc691899baa57585dbef6035920f4905812a7 Mon Sep 17 00:00:00 2001 From: dyson Date: Tue, 2 Jul 1996 13:38:10 +0000 Subject: Implement locking for pfs nodes, when at the leaf. Concurrent access to information from a single process causes hangs. Specifically, this fixes problems (hangs) with concurrent ps commands, when the system is under heavy memory load. Reviewed by: davidg --- sys/fs/procfs/procfs.h | 3 ++- sys/fs/procfs/procfs_subr.c | 39 +++++++++++++++++++++++++++++---------- sys/miscfs/procfs/procfs.h | 3 ++- sys/miscfs/procfs/procfs_subr.c | 39 +++++++++++++++++++++++++++++---------- 4 files changed, 62 insertions(+), 22 deletions(-) (limited to 'sys') diff --git a/sys/fs/procfs/procfs.h b/sys/fs/procfs/procfs.h index 69d88bd..b639980 100644 --- a/sys/fs/procfs/procfs.h +++ b/sys/fs/procfs/procfs.h @@ -36,7 +36,7 @@ * * @(#)procfs.h 8.6 (Berkeley) 2/3/94 * - * $Id: procfs.h,v 1.10 1996/06/17 22:43:35 dyson Exp $ + * $Id: procfs.h,v 1.11 1996/06/18 05:15:58 dyson Exp $ */ /* @@ -68,6 +68,7 @@ struct pfsnode { u_short pfs_mode; /* mode bits for stat() */ u_long pfs_flags; /* open flags */ u_long pfs_fileno; /* unique file id */ + pid_t pfs_lockowner; /* pfs lock owner */ }; #define PROCFS_NOTELEN 64 /* max length of a note (/proc/$pid/note) */ diff --git a/sys/fs/procfs/procfs_subr.c b/sys/fs/procfs/procfs_subr.c index 872a4e9..7d0de04 100644 --- a/sys/fs/procfs/procfs_subr.c +++ b/sys/fs/procfs/procfs_subr.c @@ -36,7 +36,7 @@ * * @(#)procfs_subr.c 8.4 (Berkeley) 1/27/94 * - * $Id: procfs_subr.c,v 1.7 1996/06/17 22:43:35 dyson Exp $ + * $Id: procfs_subr.c,v 1.8 1996/06/18 05:15:59 dyson Exp $ */ #include @@ -130,6 +130,7 @@ loop: pfs->pfs_type = pfs_type; pfs->pfs_vnode = *vpp; pfs->pfs_flags = 0; + pfs->pfs_lockowner = 0; pfs->pfs_fileno = PROCFS_FILENO(pid, pfs_type); switch (pfs_type) { @@ -230,40 +231,58 @@ procfs_rw(ap) struct proc *curp = uio->uio_procp; struct pfsnode *pfs = VTOPFS(vp); struct proc *p; + int rtval; p = PFIND(pfs->pfs_pid); if (p == 0) return (EINVAL); + while (pfs->pfs_lockowner) { + tsleep(&pfs->pfs_lockowner, PRIBIO, "pfslck", 0); + } + pfs->pfs_lockowner = curproc->p_pid; + switch (pfs->pfs_type) { case Pnote: case Pnotepg: - return (procfs_donote(curp, p, pfs, uio)); + rtval = procfs_donote(curp, p, pfs, uio); + break; case Pregs: - return (procfs_doregs(curp, p, pfs, uio)); + rtval = procfs_doregs(curp, p, pfs, uio); + break; case Pfpregs: - return (procfs_dofpregs(curp, p, pfs, uio)); + rtval = procfs_dofpregs(curp, p, pfs, uio); + break; case Pctl: - return (procfs_doctl(curp, p, pfs, uio)); + rtval = procfs_doctl(curp, p, pfs, uio); + break; case Pstatus: - return (procfs_dostatus(curp, p, pfs, uio)); + rtval = procfs_dostatus(curp, p, pfs, uio); + break; case Pmap: - return (procfs_domap(curp, p, pfs, uio)); + rtval = procfs_domap(curp, p, pfs, uio); + break; case Pmem: - return (procfs_domem(curp, p, pfs, uio)); + rtval = procfs_domem(curp, p, pfs, uio); + break; case Ptype: - return (procfs_dotype(curp, p, pfs, uio)); + rtval = procfs_dotype(curp, p, pfs, uio); + break; default: - return (EOPNOTSUPP); + rtval = EOPNOTSUPP; + break; } + pfs->pfs_lockowner = 0; + wakeup(&pfs->pfs_lockowner); + return rtval; } /* diff --git a/sys/miscfs/procfs/procfs.h b/sys/miscfs/procfs/procfs.h index 69d88bd..b639980 100644 --- a/sys/miscfs/procfs/procfs.h +++ b/sys/miscfs/procfs/procfs.h @@ -36,7 +36,7 @@ * * @(#)procfs.h 8.6 (Berkeley) 2/3/94 * - * $Id: procfs.h,v 1.10 1996/06/17 22:43:35 dyson Exp $ + * $Id: procfs.h,v 1.11 1996/06/18 05:15:58 dyson Exp $ */ /* @@ -68,6 +68,7 @@ struct pfsnode { u_short pfs_mode; /* mode bits for stat() */ u_long pfs_flags; /* open flags */ u_long pfs_fileno; /* unique file id */ + pid_t pfs_lockowner; /* pfs lock owner */ }; #define PROCFS_NOTELEN 64 /* max length of a note (/proc/$pid/note) */ diff --git a/sys/miscfs/procfs/procfs_subr.c b/sys/miscfs/procfs/procfs_subr.c index 872a4e9..7d0de04 100644 --- a/sys/miscfs/procfs/procfs_subr.c +++ b/sys/miscfs/procfs/procfs_subr.c @@ -36,7 +36,7 @@ * * @(#)procfs_subr.c 8.4 (Berkeley) 1/27/94 * - * $Id: procfs_subr.c,v 1.7 1996/06/17 22:43:35 dyson Exp $ + * $Id: procfs_subr.c,v 1.8 1996/06/18 05:15:59 dyson Exp $ */ #include @@ -130,6 +130,7 @@ loop: pfs->pfs_type = pfs_type; pfs->pfs_vnode = *vpp; pfs->pfs_flags = 0; + pfs->pfs_lockowner = 0; pfs->pfs_fileno = PROCFS_FILENO(pid, pfs_type); switch (pfs_type) { @@ -230,40 +231,58 @@ procfs_rw(ap) struct proc *curp = uio->uio_procp; struct pfsnode *pfs = VTOPFS(vp); struct proc *p; + int rtval; p = PFIND(pfs->pfs_pid); if (p == 0) return (EINVAL); + while (pfs->pfs_lockowner) { + tsleep(&pfs->pfs_lockowner, PRIBIO, "pfslck", 0); + } + pfs->pfs_lockowner = curproc->p_pid; + switch (pfs->pfs_type) { case Pnote: case Pnotepg: - return (procfs_donote(curp, p, pfs, uio)); + rtval = procfs_donote(curp, p, pfs, uio); + break; case Pregs: - return (procfs_doregs(curp, p, pfs, uio)); + rtval = procfs_doregs(curp, p, pfs, uio); + break; case Pfpregs: - return (procfs_dofpregs(curp, p, pfs, uio)); + rtval = procfs_dofpregs(curp, p, pfs, uio); + break; case Pctl: - return (procfs_doctl(curp, p, pfs, uio)); + rtval = procfs_doctl(curp, p, pfs, uio); + break; case Pstatus: - return (procfs_dostatus(curp, p, pfs, uio)); + rtval = procfs_dostatus(curp, p, pfs, uio); + break; case Pmap: - return (procfs_domap(curp, p, pfs, uio)); + rtval = procfs_domap(curp, p, pfs, uio); + break; case Pmem: - return (procfs_domem(curp, p, pfs, uio)); + rtval = procfs_domem(curp, p, pfs, uio); + break; case Ptype: - return (procfs_dotype(curp, p, pfs, uio)); + rtval = procfs_dotype(curp, p, pfs, uio); + break; default: - return (EOPNOTSUPP); + rtval = EOPNOTSUPP; + break; } + pfs->pfs_lockowner = 0; + wakeup(&pfs->pfs_lockowner); + return rtval; } /* -- cgit v1.1