Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 10 Jun 2013 12:15:11 -0400
From:      John Baldwin <jhb@freebsd.org>
To:        Julian Stecklina <jsteckli@os.inf.tu-dresden.de>
Cc:        freebsd-stable@freebsd.org
Subject:   Re: Reproducable Infiniband panic
Message-ID:  <201306101215.11640.jhb@freebsd.org>
In-Reply-To: <51B5C0BC.2000402@os.inf.tu-dresden.de>
References:  <51B07705.207@os.inf.tu-dresden.de> <201306071206.52994.jhb@freebsd.org> <51B5C0BC.2000402@os.inf.tu-dresden.de>

next in thread | previous in thread | raw e-mail | index | archive | help
On Monday, June 10, 2013 8:04:12 am Julian Stecklina wrote:
> On 06/07/2013 06:06 PM, John Baldwin wrote:
> > On Friday, June 07, 2013 5:07:34 am Julian Stecklina wrote:
> >> On 06/06/2013 08:57 PM, John Baldwin wrote:
> >>> On Thursday, June 06, 2013 9:54:35 am Andriy Gapon wrote:
> >> [...]
> >>>> The problem seems to be in incorrect interaction between devfs_close_f 
> > and
> >>>> linux_file_dtor.  The latter expects curthread->td_fpop to have a valid 
> > reasonable
> >>>> value.  But the former sets curthread->td_fpop to fp only around 
> > vnops.fo_close()
> >>>> call and then restores it back to some (what?) previous value before 
> > calling
> >>>> devfs_fpdrop->devfs_destroy_cdevpriv.  In this case the previous value is 
> > NULL.
> >>>
> >>> It is normally NULL in this case.  Why does linux_file_dtor even look at
> >>> td_fpop?
> >>>
> >>> Ah.  I think it should not do that and make the data it uses in the dtor 
> > more
> >>> self-contained:
> [...]
> 
> Seems to fix my panic. Thanks!

Can you please retest this updated version?  I had thought that I didn't need
a reference count on the vnode, but devfs drops its reference count before the
cdevpriv destructor is called.

Index: sys/ofed/include/linux/fs.h
===================================================================
--- sys/ofed/include/linux/fs.h	(revision 251604)
+++ sys/ofed/include/linux/fs.h	(working copy)
@@ -73,6 +73,7 @@
 	struct dentry	f_dentry_store;
 	struct selinfo	f_selinfo;
 	struct sigio	*f_sigio;
+	struct vnode	*f_vnode;
 };
 
 #define	file		linux_file
Index: sys/ofed/include/linux/linux_compat.c
===================================================================
--- sys/ofed/include/linux/linux_compat.c	(revision 251604)
+++ sys/ofed/include/linux/linux_compat.c	(working copy)
@@ -212,7 +212,8 @@
 	struct linux_file *filp;
 
 	filp = cdp;
-	filp->f_op->release(curthread->td_fpop->f_vnode, filp);
+	filp->f_op->release(filp->f_vnode, filp);
+	vdrop(filp->f_vnode);
 	kfree(filp);
 }
 
@@ -232,6 +233,8 @@
 	filp->f_dentry = &filp->f_dentry_store;
 	filp->f_op = ldev->ops;
 	filp->f_flags = file->f_flag;
+	vhold(file->f_vnode);
+	filp->f_vnode = file->f_vnode;
 	if (filp->f_op->open) {
 		error = -filp->f_op->open(file->f_vnode, filp);
 		if (error) {

-- 
John Baldwin



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201306101215.11640.jhb>