Date: Sun, 4 May 2014 14:05:15 +0000 (UTC) From: Steven Hartland <smh@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r265321 - in head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs: . sys Message-ID: <201405041405.s44E5FU9006213@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: smh Date: Sun May 4 14:05:14 2014 New Revision: 265321 URL: http://svnweb.freebsd.org/changeset/base/265321 Log: Use a zio flag to prevent recursion of vdev_queue_io_done which can cause stack overflow for IO's which return ZIO_PIPELINE_CONTINUE from the zio_vdev_io_start stage and hence don't suspend and complete in a different thread. This prevents double fault panic on slow machines running ZFS on GELI volumes which return EOPNOTSUPP directly to BIO_DELETE requests. MFC after: 1 month X-MFC-With: r265152 Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_queue.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 Sun May 4 12:32:37 2014 (r265320) +++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zio.h Sun May 4 14:05:14 2014 (r265321) @@ -196,6 +196,7 @@ enum zio_flag { ZIO_FLAG_NOPWRITE = 1 << 25, ZIO_FLAG_REEXECUTED = 1 << 26, ZIO_FLAG_DELEGATED = 1 << 27, + ZIO_FLAG_QUEUE_IO_DONE = 1 << 28, }; #define ZIO_FLAG_MUSTSUCCEED 0 Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_queue.c ============================================================================== --- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_queue.c Sun May 4 12:32:37 2014 (r265320) +++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_queue.c Sun May 4 14:05:14 2014 (r265321) @@ -796,14 +796,25 @@ vdev_queue_io_done(zio_t *zio) vq->vq_io_complete_ts = gethrtime(); + if (zio->io_flags & ZIO_FLAG_QUEUE_IO_DONE) { + /* + * Executing from a previous vdev_queue_io_done so + * to avoid recursion we just unlock and return. + */ + mutex_exit(&vq->vq_lock); + return; + } + while ((nio = vdev_queue_io_to_issue(vq)) != NULL) { mutex_exit(&vq->vq_lock); + nio->io_flags |= ZIO_FLAG_QUEUE_IO_DONE; if (nio->io_done == vdev_queue_agg_io_done) { zio_nowait(nio); } else { zio_vdev_io_reissue(nio); zio_execute(nio); } + nio->io_flags &= ~ZIO_FLAG_QUEUE_IO_DONE; mutex_enter(&vq->vq_lock); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201405041405.s44E5FU9006213>