Commit 746d0ac
nvmet: pci-epf: Do not complete commands twice if nvmet_req_init() fails
Have nvmet_req_init() and req->execute() complete failed commands.
Description of the problem:
nvmet_req_init() calls __nvmet_req_complete() internally upon failure,
e.g., unsupported opcode, which calls the "queue_response" callback,
this results in nvmet_pci_epf_queue_response() being called, which will
call nvmet_pci_epf_complete_iod() if data_len is 0 or if dma_dir is
different from DMA_TO_DEVICE. This results in a double completion as
nvmet_pci_epf_exec_iod_work() also calls nvmet_pci_epf_complete_iod()
when nvmet_req_init() fails.
Steps to reproduce:
On the host send a command with an unsupported opcode with nvme-cli,
For example the admin command "security receive"
$ sudo nvme security-recv /dev/nvme0n1 -n1 -x4096
This triggers a double completion as nvmet_req_init() fails and
nvmet_pci_epf_queue_response() is called, here iod->dma_dir is still
in the default state of "DMA_NONE" as set by default in
nvmet_pci_epf_alloc_iod(), so nvmet_pci_epf_complete_iod() is called.
Because nvmet_req_init() failed nvmet_pci_epf_complete_iod() is also
called in nvmet_pci_epf_exec_iod_work() leading to a double completion.
This not only sends two completions to the host but also corrupts the
state of the PCI NVMe target leading to kernel oops.
This patch lets nvmet_req_init() and req->execute() complete all failed
commands, and removes the double completion case in
nvmet_pci_epf_exec_iod_work() therefore fixing the edge cases where
double completions occurred.
Fixes: 0faa0fe ("nvmet: New NVMe PCI endpoint function target driver")
Signed-off-by: Rick Wertenbroek <[email protected]>
Reviewed-by: Damien Le Moal <[email protected]>
Reviewed-by: Chaitanya Kulkarni <[email protected]>
Signed-off-by: Christoph Hellwig <[email protected]>1 parent 5a58ac9 commit 746d0ac
1 file changed
Lines changed: 16 additions & 7 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1242 | 1242 | | |
1243 | 1243 | | |
1244 | 1244 | | |
1245 | | - | |
1246 | | - | |
| 1245 | + | |
| 1246 | + | |
| 1247 | + | |
| 1248 | + | |
| 1249 | + | |
1247 | 1250 | | |
1248 | 1251 | | |
1249 | 1252 | | |
| |||
1604 | 1607 | | |
1605 | 1608 | | |
1606 | 1609 | | |
| 1610 | + | |
| 1611 | + | |
| 1612 | + | |
| 1613 | + | |
| 1614 | + | |
1607 | 1615 | | |
1608 | | - | |
| 1616 | + | |
1609 | 1617 | | |
1610 | 1618 | | |
1611 | 1619 | | |
| |||
1643 | 1651 | | |
1644 | 1652 | | |
1645 | 1653 | | |
1646 | | - | |
1647 | | - | |
1648 | | - | |
1649 | | - | |
| 1654 | + | |
| 1655 | + | |
| 1656 | + | |
| 1657 | + | |
| 1658 | + | |
1650 | 1659 | | |
1651 | 1660 | | |
1652 | 1661 | | |
| |||
0 commit comments