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
This commit is contained in:
parent
c6eea46989
commit
835bc69189
@ -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) */
|
||||
|
@ -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 <sys/param.h>
|
||||
@ -130,6 +130,7 @@ procfs_allocvp(mp, vpp, pid, pfs_type)
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -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) */
|
||||
|
@ -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 <sys/param.h>
|
||||
@ -130,6 +130,7 @@ procfs_allocvp(mp, vpp, pid, pfs_type)
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user