[georg@dts.su: Re[2]: fatal trap 12]

Kostik Belousov kostikbel at gmail.com
Sat Jun 6 18:07:46 UTC 2009


[Please, remove the questions@ on the reply, this is the topic for
fs@].


On Sat, Jun 06, 2009 at 08:16:00PM +0400, Chagin Dmitry wrote:
> ----- Forwarded message from georg at dts.su -----
> 
> Date: Sat, 6 Jun 2009 10:58:11 +0400
> From: georg at dts.su
> To: freebsd-questions at freebsd.org
> Subject: Re[2]: fatal trap 12
> 
> Hello, Freebsd-questions.
> 
> After one of new crash I have this:
> 
> GNU gdb 6.1.1 [FreeBSD]
> Copyright 2004 Free Software Foundation, Inc.
> GDB is free software, covered by the GNU General Public License, and you are
> welcome to change it and/or distribute copies of it under certain conditions.
> Type "show copying" to see the conditions.
> There is absolutely no warranty for GDB.  Type "show warranty" for details.
> This GDB was configured as "amd64-marcel-freebsd"...
> 
> Unread portion of the kernel message buffer:
> 
> 
> Fatal trap 12: page fault while in kernel mode
> cpuid = 2; apic id = 02
> fault virtual address   = 0x0
> fault code              = supervisor read data, page not present
> instruction pointer     = 0x8:0xffffffff804c4eb8
> stack pointer           = 0x10:0xffffff807a0478f0
> frame pointer           = 0x10:0xffffff807a047930
> code segment            = base 0x0, limit 0xfffff, type 0x1b
>                         = DPL 0, pres 1, long 1, def32 0, gran 1
> processor eflags        = interrupt enabled, resume, IOPL = 0
> current process         = 32668 (perl5.10.0)
> Physical memory: 4082 MB
> Dumping 1647 MB: 1632 1616 1600 1584 1568 1552 1536 1520 1504 1488 1472 1456 1440 1424 1408 1392 1376 1360 1344 1328 1312 1296 1280 1264 1248 1232 1216 1200 1184 1168 1152 1136 1120 1104 1088 1072 1056 1040 1024 1008 992 976 960 944 928 912 896 880 864 848 832 816 800 784 768 752 736 720 704 688 672 656 640 624 608 592 576 560 544 528 512 496 480 464 448 432 416 400 384 368 352 336 320 304 288 272 256 240 224 208 192 176 160 144 128 112 96 80 64 48 32 16
> 
> Reading symbols from /boot/kernel/accf_http.ko...Reading symbols from /boot/kernel/accf_http.ko.symbols...done.
> done.
> Loaded symbols for /boot/kernel/accf_http.ko
> #0  doadump () at pcpu.h:195
> 195             __asm __volatile("movq %%gs:0,%0" : "=r" (td));
> (kgdb) list *0xffffffff804c4eb8
> 0xffffffff804c4eb8 is in pfs_ioctl (/usr/src/sys/fs/pseudofs/pseudofs_vnops.c:265).
> 260     static int
> 261     pfs_ioctl(struct vop_ioctl_args *va)
> 262     {
> 263             struct vnode *vn = va->a_vp;
> 264             struct pfs_vdata *pvd = vn->v_data;
> 265             struct pfs_node *pn = pvd->pvd_pn;
> 266             struct proc *proc;
> 267             int error;
> 268
> 269             PFS_TRACE(("%s: %lx", pn->pn_name, va->a_command));
> (kgdb) backtrace
> #0  doadump () at pcpu.h:195
> #1  0xffffffff801c8dac in db_fncall (dummy1=Variable "dummy1" is not available.
> ) at /usr/src/sys/ddb/db_command.c:516
> #2  0xffffffff801c92df in db_command (last_cmdp=0xffffffff80b30c88, cmd_table=0x0, dopager=1) at /usr/src/sys/ddb/db_command.c:413
> #3  0xffffffff801c94f0 in db_command_loop () at /usr/src/sys/ddb/db_command.c:466
> #4  0xffffffff801cb0d9 in db_trap (type=Variable "type" is not available.
> ) at /usr/src/sys/ddb/db_main.c:228
> #5  0xffffffff80554e55 in kdb_trap (type=12, code=0, tf=0xffffff807a047840) at /usr/src/sys/kern/subr_kdb.c:524
> #6  0xffffffff807fae80 in trap_fatal (frame=0xffffff807a047840, eva=Variable "eva" is not available.
> ) at /usr/src/sys/amd64/amd64/trap.c:752
> #7  0xffffffff807fb254 in trap_pfault (frame=0xffffff807a047840, usermode=0) at /usr/src/sys/amd64/amd64/trap.c:673
> #8  0xffffffff807fbc02 in trap (frame=0xffffff807a047840) at /usr/src/sys/amd64/amd64/trap.c:444
> #9  0xffffffff807df35e in calltrap () at /usr/src/sys/amd64/amd64/exception.S:209
> #10 0xffffffff804c4eb8 in pfs_ioctl (va=0xffffff807a047a10) at /usr/src/sys/fs/pseudofs/pseudofs_vnops.c:264
> #11 0xffffffff805bb1d3 in vn_ioctl (fp=Variable "fp" is not available.
> ) at vnode_if.h:437
> #12 0xffffffff80562d02 in kern_ioctl (td=0xffffff0006682000, fd=3, com=1076655123, data=0xffffff00ad2b7d40 "") at file.h:269
> #13 0xffffffff80563029 in ioctl (td=0xffffff0006682000, uap=0xffffff807a047bf0) at /usr/src/sys/kern/sys_generic.c:571
> #14 0xffffffff807fb4d6 in syscall (frame=0xffffff807a047c80) at /usr/src/sys/amd64/amd64/trap.c:900
> #15 0xffffffff807df56b in Xfast_syscall () at /usr/src/sys/amd64/amd64/exception.S:330
> #16 0x0000000800c9c0ec in ?? ()
> Previous frame inner to this frame (corrupt stack?)
> (kgdb)
> 
> 
> Can You help me? What can I do? Server crash periodicaly...

The issue is that VOP_IOCTL interface takes unlocked vnode, which
may be reclaimed at any moment. The right thing to do is to fix
this before 8.0 freezed KPI. Please, try the patch below.


diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
index a7f47b2..018e6bd 100644
--- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
+++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
@@ -258,7 +258,7 @@ zfs_ioctl(vnode_t *vp, u_long com, intptr_t data, int flag, cred_t *cred,
     int *rvalp, caller_context_t *ct)
 {
 	offset_t off;
-	int error;
+	int error, locked;
 	zfsvfs_t *zfsvfs;
 	znode_t *zp;
 
@@ -276,6 +276,8 @@ zfs_ioctl(vnode_t *vp, u_long com, intptr_t data, int flag, cred_t *cred,
 
 	case _FIO_SEEK_DATA:
 	case _FIO_SEEK_HOLE:
+		locked = VOP_ISLOCKED(vp);
+		VOP_UNLOCK(vp, 0);
 		if (ddi_copyin((void *)data, &off, sizeof (off), flag))
 			return (EFAULT);
 
@@ -287,10 +289,15 @@ zfs_ioctl(vnode_t *vp, u_long com, intptr_t data, int flag, cred_t *cred,
 		/* offset parameter is in/out */
 		error = zfs_holey(vp, com, &off);
 		ZFS_EXIT(zfsvfs);
-		if (error)
+		if (error) {
+			vn_lock(vp, locked | LK_RETRY);
 			return (error);
-		if (ddi_copyout(&off, (void *)data, sizeof (off), flag))
+		}
+		if (ddi_copyout(&off, (void *)data, sizeof (off), flag)) {
+			vn_lock(vp, locked | LK_RETRY);
 			return (EFAULT);
+		}
+		vn_lock(vp, locked | LK_RETRY);
 		return (0);
 	}
 	return (ENOTTY);
diff --git a/sys/fs/coda/coda_vnops.c b/sys/fs/coda/coda_vnops.c
index c5c6cb1..0bf84c4 100644
--- a/sys/fs/coda/coda_vnops.c
+++ b/sys/fs/coda/coda_vnops.c
@@ -420,7 +420,7 @@ coda_ioctl(struct vop_ioctl_args *ap)
 	struct ucred *cred = ap->a_cred;
 	struct thread *td = ap->a_td;
 	/* locals */
-	int error;
+	int error, locked;
 	struct vnode *tvp;
 	struct nameidata ndp;
 	struct PioctlData *iap = (struct PioctlData *)data;
@@ -440,6 +440,8 @@ coda_ioctl(struct vop_ioctl_args *ap)
 		    "ctlvp")););
 		return (EOPNOTSUPP);
 	}
+	locked = VOP_ISLOCKED(vp);
+	VOP_UNLOCK(vp, 0);
 
 	/*
 	 * Look up the pathname.
@@ -455,7 +457,7 @@ coda_ioctl(struct vop_ioctl_args *ap)
 		MARK_INT_FAIL(CODA_IOCTL_STATS);
 		CODADEBUG(CODA_IOCTL, myprintf(("coda_ioctl error: lookup "
 		    "returns %d\n", error)););
-		return (error);
+		goto out;
 	}
 
 	/*
@@ -469,11 +471,13 @@ coda_ioctl(struct vop_ioctl_args *ap)
 		CODADEBUG(CODA_IOCTL,
 		myprintf(("coda_ioctl error: %s not a coda object\n",
 		    iap->path)););
-		return (EINVAL);
+		error = EINVAL;
+		goto out;
 	}
 	if (iap->vi.in_size > VC_MAXDATASIZE) {
 		NDFREE(&ndp, 0);
-		return (EINVAL);
+		error = EINVAL;
+		goto out;
 	}
 	error = venus_ioctl(vtomi(tvp), &((VTOC(tvp))->c_fid), com, flag,
 	    data, cred, td->td_proc);
@@ -484,6 +488,8 @@ coda_ioctl(struct vop_ioctl_args *ap)
 		    error)););
 	vrele(tvp);
 	NDFREE(&ndp, NDF_ONLY_PNBUF);
+ out:
+	vn_lock(vp, locked | LK_RETRY);
 	return (error);
 }
 
diff --git a/sys/fs/deadfs/dead_vnops.c b/sys/fs/deadfs/dead_vnops.c
index 7a07b38..22029a7 100644
--- a/sys/fs/deadfs/dead_vnops.c
+++ b/sys/fs/deadfs/dead_vnops.c
@@ -180,8 +180,8 @@ dead_ioctl(ap)
 		struct proc *a_p;
 	} */ *ap;
 {
-	/* XXX: Doesn't this just recurse back here ? */
-	return (VOP_IOCTL_AP(ap));
+
+	return (EIO);
 }
 
 /*
diff --git a/sys/fs/fifofs/fifo_vnops.c b/sys/fs/fifofs/fifo_vnops.c
index 66963bc..8d20297 100644
--- a/sys/fs/fifofs/fifo_vnops.c
+++ b/sys/fs/fifofs/fifo_vnops.c
@@ -89,8 +89,6 @@ struct fifoinfo {
 static vop_print_t	fifo_print;
 static vop_open_t	fifo_open;
 static vop_close_t	fifo_close;
-static vop_ioctl_t	fifo_ioctl;
-static vop_kqfilter_t	fifo_kqfilter;
 static vop_pathconf_t	fifo_pathconf;
 static vop_advlock_t	fifo_advlock;
 
@@ -116,8 +114,8 @@ struct vop_vector fifo_specops = {
 	.vop_close =		fifo_close,
 	.vop_create =		VOP_PANIC,
 	.vop_getattr =		VOP_EBADF,
-	.vop_ioctl =		fifo_ioctl,
-	.vop_kqfilter =		fifo_kqfilter,
+	.vop_ioctl =		VOP_PANIC,
+	.vop_kqfilter =		VOP_PANIC,
 	.vop_link =		VOP_PANIC,
 	.vop_mkdir =		VOP_PANIC,
 	.vop_mknod =		VOP_PANIC,
@@ -300,42 +298,6 @@ fail1:
 	return (0);
 }
 
-/*
- * Now unused vnode ioctl routine.
- */
-/* ARGSUSED */
-static int
-fifo_ioctl(ap)
-	struct vop_ioctl_args /* {
-		struct vnode *a_vp;
-		u_long  a_command;
-		caddr_t  a_data;
-		int  a_fflag;
-		struct ucred *a_cred;
-		struct thread *a_td;
-	} */ *ap;
-{
-
-	printf("WARNING: fifo_ioctl called unexpectedly\n");
-	return (ENOTTY);
-}
-
-/*
- * Now unused vnode kqfilter routine.
- */
-/* ARGSUSED */
-static int
-fifo_kqfilter(ap)
-	struct vop_kqfilter_args /* {
-		struct vnode *a_vp;
-		struct knote *a_kn;
-	} */ *ap;
-{
-
-	printf("WARNING: fifo_kqfilter called unexpectedly\n");
-	return (EINVAL);
-}
-
 static void
 filt_fifordetach(struct knote *kn)
 {
diff --git a/sys/fs/unionfs/union_vnops.c b/sys/fs/unionfs/union_vnops.c
index 8505cac..6f5d555 100644
--- a/sys/fs/unionfs/union_vnops.c
+++ b/sys/fs/unionfs/union_vnops.c
@@ -913,12 +913,10 @@ unionfs_ioctl(struct vop_ioctl_args *ap)
 
 	KASSERT_UNIONFS_VNODE(ap->a_vp);
 
- 	vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY);
 	unp = VTOUNIONFS(ap->a_vp);
 	unionfs_get_node_status(unp, ap->a_td, &unsp);
 	ovp = (unsp->uns_upper_opencnt ? unp->un_uppervp : unp->un_lowervp);
 	unionfs_tryrem_node_status(unp, unsp);
-	VOP_UNLOCK(ap->a_vp, 0);
 
 	if (ovp == NULLVP)
 		return (EBADF);
diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_vnops.c b/sys/gnu/fs/xfs/FreeBSD/xfs_vnops.c
index 6d8d4eb..9b2c4b0 100644
--- a/sys/gnu/fs/xfs/FreeBSD/xfs_vnops.c
+++ b/sys/gnu/fs/xfs/FreeBSD/xfs_vnops.c
@@ -1163,17 +1163,20 @@ _xfs_ioctl(
 		struct thread *a_td;
 	} */ *ap)
 {
-/* 	struct vnode *vp = ap->a_vp; */
+ 	struct vnode *vp = ap->a_vp;
 /* 	struct thread *p = ap->a_td; */
 /* 	struct file *fp; */
-	int error;
+	int error, locked;
 
-	xfs_vnode_t *xvp = VPTOXFSVP(ap->a_vp);
+	xfs_vnode_t *xvp = VPTOXFSVP(vp);
 
 	printf("_xfs_ioctl cmd 0x%lx data %p\n",ap->a_command,ap->a_data);
 
+	locked = VOP_ISLOCKED(vp);
+	VOP_UNLOCK(vp, 0);
 //	XVOP_IOCTL(xvp,(void *)NULL,(void *)NULL,ap->a_fflag,ap->a_command,ap->a_data,error);
 	error = xfs_ioctl(xvp->v_bh.bh_first,NULL,NULL,ap->a_fflag,ap->a_command,ap->a_data);
+	vn_lock(vp, locked | LK_RETRY);
 
 	return error;
 }
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c
index 702faae..e48f81f 100644
--- a/sys/kern/vfs_vnops.c
+++ b/sys/kern/vfs_vnops.c
@@ -817,13 +817,12 @@ vn_ioctl(fp, com, data, active_cred, td)
 
 	vfslocked = VFS_LOCK_GIANT(vp->v_mount);
 	error = ENOTTY;
+	vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
 	switch (vp->v_type) {
 	case VREG:
 	case VDIR:
 		if (com == FIONREAD) {
-			vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
 			error = VOP_GETATTR(vp, &vattr, active_cred);
-			VOP_UNLOCK(vp, 0);
 			if (!error)
 				*(int *)data = vattr.va_size - fp->f_offset;
 		}
@@ -837,6 +836,7 @@ vn_ioctl(fp, com, data, active_cred, td)
 	default:
 		break;
 	}
+	VOP_UNLOCK(vp, 0);
 	VFS_UNLOCK_GIANT(vfslocked);
 	return (error);
 }
diff --git a/sys/kern/vnode_if.src b/sys/kern/vnode_if.src
index 81c0dff..81ef11c 100644
--- a/sys/kern/vnode_if.src
+++ b/sys/kern/vnode_if.src
@@ -209,7 +209,7 @@ vop_write {
 };
 
 
-%% ioctl	vp	U U U
+%% ioctl	vp	L L L
 
 vop_ioctl {
 	IN struct vnode *vp;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 195 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/freebsd-questions/attachments/20090606/e62ce630/attachment.pgp


More information about the freebsd-questions mailing list