Author: avg
Date: Wed Jun 28 13:59:20 2017
New Revision: 320452
URL: https://svnweb.freebsd.org/changeset/base/320452

Log:
  fix an architectural problem introduced in r320156, ZFS ABD import
  
  The implementation of ZFS refcount_t uses the emulated illumos mutex
  (the sx lock) and the waiting memory allocation when ZFS_DEBUG is
  enabled.  This makes refcount_t unsuitable for use in GEOM g_up
  thread where sleeping is prohibited.
  
  When importing the ABD change I modified vdev_geom using illumos
  vdev_disk as an example.  As a result, I added a call to abd_return_buf
  in vdev_geom_io_intr.  The latter is called on g_up thread while the
  former uses refcount_t.
  
  This change fixes the problem by deferring the abd_return_buf call to
  the previously unused vdev_geom_io_done that is called on a ZFS zio
  taskqueue thread where sleeping is allowed.
  
  A side bonus of this change is that now a vdev zio has a pointer
  to its corresponding bio while the zio is active.
  
  Reported by:  Shawn Webb <shawn.w...@hardenedbsd.org>
  Tested by:    Shawn Webb <shawn.w...@hardenedbsd.org>
  MFC after:    1 week
  X-MFC with:   r320156

Modified:
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h
  head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h       Wed Jun 
28 13:56:15 2017        (r320451)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h       Wed Jun 
28 13:59:20 2017        (r320452)
@@ -453,6 +453,10 @@ struct zio {
        avl_node_t      io_alloc_node;
        zio_alloc_list_t        io_alloc_list;
 
+#ifdef __FreeBSD__
+       struct bio      *io_bio;
+#endif
+
        /* Internal pipeline state */
        enum zio_flag   io_flags;
        enum zio_stage  io_stage;

Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
==============================================================================
--- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c     Wed Jun 
28 13:56:15 2017        (r320451)
+++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c     Wed Jun 
28 13:59:20 2017        (r320452)
@@ -989,13 +989,6 @@ vdev_geom_io_intr(struct bio *bp)
                break;
        }
 
-       if (zio->io_type == ZIO_TYPE_READ) {
-               abd_return_buf_copy(zio->io_abd, bp->bio_data, zio->io_size);
-       } else if (zio->io_type == ZIO_TYPE_WRITE) {
-               abd_return_buf(zio->io_abd, bp->bio_data, zio->io_size);
-       }
-
-       g_destroy_bio(bp);
        zio_delay_interrupt(zio);
 }
 
@@ -1087,6 +1080,7 @@ sendreq:
                break;
        }
        bp->bio_done = vdev_geom_io_intr;
+       zio->io_bio = bp;
 
        g_io_request(bp, cp);
 }
@@ -1094,6 +1088,15 @@ sendreq:
 static void
 vdev_geom_io_done(zio_t *zio)
 {
+       struct bio *bp = zio->io_bio;
+
+       if (zio->io_type == ZIO_TYPE_READ) {
+               abd_return_buf_copy(zio->io_abd, bp->bio_data, zio->io_size);
+       } else if (zio->io_type == ZIO_TYPE_WRITE) {
+               abd_return_buf(zio->io_abd, bp->bio_data, zio->io_size);
+       }
+
+       g_destroy_bio(bp);
 }
 
 static void
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to