kern/145339: [zfs] deadlock after detaching block device from raidz pool

Andriy Gapon avg at icyb.net.ua
Thu May 13 05:50:07 UTC 2010


The following reply was made to PR kern/145339; it has been noted by GNATS.

From: Andriy Gapon <avg at icyb.net.ua>
To: Alex Bakhtin <alex.bakhtin at gmail.com>
Cc: bug-followup at freebsd.org, Pawel Jakub Dawidek <pjd at freebsd.org>
Subject: Re: kern/145339: [zfs] deadlock after detaching block device from
 	raidz pool
Date: Thu, 13 May 2010 08:44:52 +0300

 on 04/05/2010 02:23 Alex Bakhtin said the following:
 > 
 >     So, I can still easily reproduce this problem on 8-STABLE. Your
 > simple patch helps to avoid page fault but dead-locks the system. Are
 > you sure that you can just return at this point? Probably it make
 > sense to set some error flag before return?
 
 You are correct, my simple patch is far from being correct.
 And properly fixing the problem is not trivial.
 
 Some issues:
 1. vdev_geom_release() sets vdev_tsd to NULL before shutting down the
 corresponding gc_queue; because of that, bios that may later come via
 vdev_geom_io_intr() can not be mapped to their gc_queue and thus there is no
 choice but to drop them on the floor.
 2. Shutdown logic in vdev_geom_worker() does not seem to be reliable.  I think
 that vdev thread may get stuck forever if a bio happens to be on gc_queue when
 vdev_geom_release() is called.  In that case gc_state check may be skipped and
 gc_queue may never be waken up again.
 3. I am not sure if pending zios are taken care of when vdev_geom_release() is
 called.  If not, then they may get stuck forever.
 
 Hopefully Pawel can help us here.
 
 > 2010/4/23 Andriy Gapon <avg at icyb.net.ua>:
 >> Can you try this patch?
 >>
 >> --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
 >> +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
 >> @@ -603,6 +603,9 @@ vdev_geom_io_intr(struct bio *bp)
 >>        zio = bp->bio_caller1;
 >>        ctx = zio->io_vd->vdev_tsd;
 >>
 >> +       if (ctx == NULL)
 >> +               return;
 >> +
 >>        if ((zio->io_error = bp->bio_error) == 0 && bp->bio_resid != 0)
 >>                zio->io_error = EIO;
 >>
 >>
 >> --
 >> Andriy Gapon
 >>
 
 
 -- 
 Andriy Gapon


More information about the freebsd-fs mailing list