DragonFly bugs List (threaded) for 2004-10
[
Date Prev][
Date Next]
[
Thread Prev][
Thread Next]
[
Date Index][
Thread Index]
Re: linux_procfs panic (was Re: Fwd: DragonFly ISO release build failure)
Here's the patch to fix the linprocfs problem. Since linprocfs wasn't
working at all before (in HEAD), I have already committed this.
I also ripped out the single sequential linked list with a simple
hash table to make linprocfs more efficient.
-Matt
Matthew Dillon
<dillon@xxxxxxxxxxxxx>
Index: linprocfs_subr.c
===================================================================
RCS file: /cvs/src/sys/emulation/linux/i386/linprocfs/linprocfs_subr.c,v
retrieving revision 1.13
diff -u -r1.13 linprocfs_subr.c
--- linprocfs_subr.c 12 Oct 2004 19:20:38 -0000 1.13
+++ linprocfs_subr.c 19 Oct 2004 09:27:21 -0000
@@ -39,7 +39,7 @@
* @(#)procfs_subr.c 8.6 (Berkeley) 5/14/95
*
* $FreeBSD: src/sys/i386/linux/linprocfs/linprocfs_subr.c,v 1.3.2.4 2001/06/25 19:46:47 pirzyk Exp $
- * $DragonFly: src/sys/emulation/linux/i386/linprocfs/linprocfs_subr.c,v 1.13 2004/10/12 19:20:38 dillon Exp $
+ * $DragonFly$
*/
#include <sys/param.h>
@@ -50,7 +50,10 @@
#include <sys/mount.h>
#include "linprocfs.h"
-static struct pfsnode *pfshead;
+#define PFSHSIZE 256
+#define PFSHMASK (PFSHSIZE - 1)
+
+static struct pfsnode *pfshead[PFSHSIZE];
static int pfsvplock;
extern int procfs_domem (struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio);
@@ -95,7 +98,7 @@
int error;
loop:
- for (pfs = pfshead; pfs != 0; pfs = pfs->pfs_next) {
+ for (pfs = pfshead[pid & PFSHMASK]; pfs; pfs = pfs->pfs_next) {
vp = PFSTOV(pfs);
if (pfs->pfs_pid == pid &&
pfs->pfs_type == pfs_type &&
@@ -199,7 +202,7 @@
}
/* add to procfs vnode list */
- for (pp = &pfshead; *pp; pp = &(*pp)->pfs_next)
+ for (pp = &pfshead[pid & PFSHMASK]; *pp; pp = &(*pp)->pfs_next)
continue;
*pp = pfs;
@@ -223,15 +226,14 @@
struct pfsnode **pfspp;
struct pfsnode *pfs = VTOPFS(vp);
- for (pfspp = &pfshead; *pfspp != 0; pfspp = &(*pfspp)->pfs_next) {
- if (*pfspp == pfs) {
- *pfspp = pfs->pfs_next;
- break;
- }
+ pfspp = &pfshead[pfs->pfs_pid & PFSHMASK];
+ while (*pfspp != pfs) {
+ KKASSERT(*pfspp != NULL);
+ pfspp = &(*pfspp)->pfs_next;
}
-
+ *pfspp = pfs->pfs_next;
FREE(vp->v_data, M_TEMP);
- vp->v_data = 0;
+ vp->v_data = NULL;
return (0);
}
@@ -365,32 +367,23 @@
linprocfs_exit(struct thread *td)
{
struct pfsnode *pfs;
- pid_t pid = (td->td_proc) ? td->td_proc->p_pid : -1; /* YYY */
+ struct vnode *vp;
+ pid_t pid;
+
+ KKASSERT(td->td_proc);
+ pid = td->td_proc->p_pid;
/*
- * The reason for this loop is not obvious -- basicly,
- * linprocfs_freevp(), which is called via vgone() (eventually),
- * removes the specified procfs node from the pfshead list.
- * It does this by *pfsp = pfs->pfs_next, meaning that it
- * overwrites the node. So when we do pfs = pfs->next, we
- * end up skipping the node that replaces the one that was
- * vgone'd. Since it may have been the last one on the list,
- * it may also have been set to null -- but *our* pfs pointer,
- * here, doesn't see this. So the loop starts from the beginning
- * again.
- *
- * This is not a for() loop because the final event
- * would be "pfs = pfs->pfs_next"; in the case where
- * pfs is set to pfshead again, that would mean that
- * pfshead is skipped over.
- *
+ * Remove all the procfs vnodes associated with an exiting process.
*/
- pfs = pfshead;
- while (pfs) {
+restart:
+ for (pfs = pfshead[pid & PFSHMASK]; pfs; pfs = pfs->pfs_next) {
if (pfs->pfs_pid == pid) {
- vgone(PFSTOV(pfs));
- pfs = pfshead;
- } else
- pfs = pfs->pfs_next;
+ vp = PFSTOV(pfs);
+ if (vx_get(vp) == 0)
+ vgone(vp);
+ goto restart;
+ }
}
}
+
[
Date Prev][
Date Next]
[
Thread Prev][
Thread Next]
[
Date Index][
Thread Index]