Skip to content

Commit

Permalink
Add zio_wait() executor/waiter locking
Browse files Browse the repository at this point in the history
There exists a plausible cache concurrency issue with zio_wait().
This might occur because the zio->io_waiter to not assigned under
a lock in zio_wait(), is not checked under a lock in zio_done(),
and the zio may be dispatched to another thread for handling.
That said, none of the actual crash dumps I've looked at show
that this has ever occurred.

Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Issue openzfs#2523
  • Loading branch information
behlendorf committed Sep 11, 2014
1 parent ab577c4 commit c3dfab6
Showing 1 changed file with 6 additions and 1 deletion.
7 changes: 6 additions & 1 deletion module/zfs/zio.c
Original file line number Diff line number Diff line change
Expand Up @@ -1381,7 +1381,9 @@ __attribute__((always_inline))
static inline void
__zio_execute(zio_t *zio)
{
mutex_enter(&zio->io_lock);
zio->io_executor = curthread;
mutex_exit(&zio->io_lock);

while (zio->io_stage < ZIO_STAGE_DONE) {
enum zio_stage pipeline = zio->io_pipeline;
Expand Down Expand Up @@ -1459,7 +1461,9 @@ zio_wait(zio_t *zio)
ASSERT(zio->io_stage == ZIO_STAGE_OPEN);
VERIFY(zio->io_executor == NULL);

mutex_enter(&zio->io_lock);
zio->io_waiter = curthread;
mutex_exit(&zio->io_lock);

__zio_execute(zio);

Expand Down Expand Up @@ -3320,12 +3324,13 @@ zio_done(zio_t *zio)
zio_notify_parent(pio, zio, ZIO_WAIT_DONE);
}

mutex_enter(&zio->io_lock);
if (zio->io_waiter != NULL) {
mutex_enter(&zio->io_lock);
zio->io_executor = NULL;
cv_broadcast(&zio->io_cv);
mutex_exit(&zio->io_lock);
} else {
mutex_exit(&zio->io_lock);
zio_destroy(zio);
}

Expand Down

0 comments on commit c3dfab6

Please sign in to comment.