]> granicus.if.org Git - zfs/commit
Fix deadlock in IO pipeline
authorBrian Behlendorf <behlendorf1@llnl.gov>
Fri, 16 Mar 2018 23:46:06 +0000 (16:46 -0700)
committerGitHub <noreply@github.com>
Fri, 16 Mar 2018 23:46:06 +0000 (16:46 -0700)
commita76f3d0437e5e974f0f748f8735af3539443b388
tree8fafdee26e609aaacc7c59825271d569da6ec4eb
parent17dd88352e655afe1d09e8e75ca1415e79c3510a
Fix deadlock in IO pipeline

In vdev_queue_aggregate() the zio_execute() bypass should not be
called under the vdev queue lock.  This can result in a deadlock
as shown in the stack traces below.

Drop the vdev queue lock then walk the parents of the aggregate IO
to determine the list of component IOs to be bypassed.  This can
be done safely without holding the io_lock since the new aggregate
IO has not yet been returned and its parents cannot change.

---  THREAD 1 ---
arc_read()
  zio_nowait()
    zio_vdev_io_start()
      vdev_queue_io() <--- mutex_enter(vq->vq_lock)
        vdev_queue_io_to_issue()
          vdev_queue_aggregate()
            zio_execute()
              zio_vdev_io_assess()
                zio_wait_for_children() <- mutex_enter(zio->io_lock)

--- THREAD 2 --- (inverse order)
arc_read()
  zio_change_priority() <- mutex_enter(zio->zio_lock)
    vdev_queue_change_io_priority() <- mutex_enter(vq->vq_lock)

Reviewed-by: Tom Caputi <tcaputi@datto.com>
Reviewed-by: Don Brady <don.brady@delphix.com>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #7307
module/zfs/vdev_queue.c