Skip to content

Commit

Permalink
nvme: Prevent controller state invalid transition
Browse files Browse the repository at this point in the history
Acquiring the nvme_ctrl lock before reading ctrl->state in
nvme_change_ctrl_state() should prevent a theoretical invalid state
transition, in the event of two threads racing inside that function.

I haven't been able to observe this happening with the current code, and
the current state machine seems to be simple enough to not be
affected by these invalid transitions, but future modifications could
make it more likely to happen.

Signed-off-by: Gabriel Krisman Bertazi <[email protected]>
Reviewed-by: Sagi Grimberg <[email protected]>
Reviewed-by: Steve Wise <[email protected]>
Signed-off-by: Jens Axboe <[email protected]>
  • Loading branch information
Gabriel Krisman Bertazi authored and axboe committed Aug 15, 2016
1 parent 694d0d0 commit f6b6a28
Showing 1 changed file with 5 additions and 2 deletions.
7 changes: 5 additions & 2 deletions drivers/nvme/host/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,12 @@ EXPORT_SYMBOL_GPL(nvme_cancel_request);
bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl,
enum nvme_ctrl_state new_state)
{
enum nvme_ctrl_state old_state = ctrl->state;
enum nvme_ctrl_state old_state;
bool changed = false;

spin_lock_irq(&ctrl->lock);

old_state = ctrl->state;
switch (new_state) {
case NVME_CTRL_LIVE:
switch (old_state) {
Expand Down Expand Up @@ -140,11 +142,12 @@ bool nvme_change_ctrl_state(struct nvme_ctrl *ctrl,
default:
break;
}
spin_unlock_irq(&ctrl->lock);

if (changed)
ctrl->state = new_state;

spin_unlock_irq(&ctrl->lock);

return changed;
}
EXPORT_SYMBOL_GPL(nvme_change_ctrl_state);
Expand Down

0 comments on commit f6b6a28

Please sign in to comment.