[PATCH] nvme: do not reset controllers in NVME_CTRL_NEW state
Maurizio Lombardi
mlombard at arkamax.eu
Tue Sep 15 06:49:36 PDT 2026
On Tue Sep 15, 2026 at 3:11 PM CEST, Daniel Wagner wrote:
> On Tue, Sep 15, 2026 at 11:58:27AM +0200, Maurizio Lombardi wrote:
>> During NVMe controller creation, the controller is exposed to sysfs via
>> nvme_add_ctrl() while it is still in the NVME_CTRL_NEW state.
>> This creates a narrow race window where a userspace process can write to
>> the reset_controller sysfs node before the initialization thread
>> transitions the state to NVME_CTRL_CONNECTING.
>>
>> If a reset is triggered during this window, the state machine allows the
>> transition from NVME_CTRL_NEW to NVME_CTRL_RESETTING, and the reset work
>> is queued. However, the original creation thread continues its execution,
>> subsequently moving the state to NVME_CTRL_CONNECTING and finally to
>> NVME_CTRL_LIVE.
>>
>> When the delayed reset work finally executes, it attempts to tear down
>> the controller and transition the state to NVME_CTRL_CONNECTING. Because
>> the state is now NVME_CTRL_LIVE, this transition fails, triggering a
>> WARN_ON in the reset work.
>>
>> Fix this by removing NVME_CTRL_NEW from the allowed prior states for
>> the NVME_CTRL_RESETTING transition.
>>
>> Fixes: 8bfc3b4c6f9d ("nvmet: switch loopback target state to connecting when resetting")
>> Reported-by: syzbot+4a1d521d19d6321f5aad at syzkaller.appspotmail.com
>> Signed-off-by: Maurizio Lombardi <mlombard at redhat.com or why it was
>> there it there in the first place
>
> Looks reasonable. It might be worth explaining why we don't need to
> handle the NEW -> RESETTING state transition or why it was there in the
> first place.
Maybe the last paragraph could be expanded in the following way:
"
Fix this by removing NVME_CTRL_NEW from the allowed prior states for
the NVME_CTRL_RESETTING transition. It is safe to drop this transition
entirely because a controller in the NVME_CTRL_NEW state is merely
allocated and not yet initialized, a reset operation at this stage is
meaningless.
"
For what concernes the "why it was there in the first place" question,
I think that the reason is that in ancient times a CONNECTING state
didn't exist. The controller initialization was done via a reset;
so the transition was NEW -> RESETTING -> LIVE.
Maurizio
More information about the Linux-nvme
mailing list