Reproducable Infiniband panic
John Baldwin
jhb at freebsd.org
Mon Jun 10 16:21:11 UTC 2013
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
More information about the freebsd-stable
mailing list