Skip to content

Commit a772178

Browse files
committed
Merge tag 'nvme-6.9-2024-05-09' of git://git.infradead.org/nvme into block-6.9
Pull NVMe fixes from Keith: "nvme fixes for Linux 6.9 - nvme target fixes (Sagi, Dan, Maurizo) - new vendor quirk for broken MSI (Sean)" * tag 'nvme-6.9-2024-05-09' of git://git.infradead.org/nvme: nvmet-rdma: fix possible bad dereference when freeing rsps nvmet: prevent sprintf() overflow in nvmet_subsys_nsid_exists() nvmet: make nvmet_wq unbound nvmet-auth: return the error code to the nvmet_auth_ctrl_hash() callers nvme-pci: Add quirk for broken MSIs
2 parents ffd379c + 73964c1 commit a772178

File tree

6 files changed

+25
-20
lines changed

6 files changed

+25
-20
lines changed

drivers/nvme/host/nvme.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,11 @@ enum nvme_quirks {
162162
* Disables simple suspend/resume path.
163163
*/
164164
NVME_QUIRK_FORCE_NO_SIMPLE_SUSPEND = (1 << 20),
165+
166+
/*
167+
* MSI (but not MSI-X) interrupts are broken and never fire.
168+
*/
169+
NVME_QUIRK_BROKEN_MSI = (1 << 21),
165170
};
166171

167172
/*

drivers/nvme/host/pci.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2224,6 +2224,7 @@ static int nvme_setup_irqs(struct nvme_dev *dev, unsigned int nr_io_queues)
22242224
.priv = dev,
22252225
};
22262226
unsigned int irq_queues, poll_queues;
2227+
unsigned int flags = PCI_IRQ_ALL_TYPES | PCI_IRQ_AFFINITY;
22272228

22282229
/*
22292230
* Poll queues don't need interrupts, but we need at least one I/O queue
@@ -2247,8 +2248,10 @@ static int nvme_setup_irqs(struct nvme_dev *dev, unsigned int nr_io_queues)
22472248
irq_queues = 1;
22482249
if (!(dev->ctrl.quirks & NVME_QUIRK_SINGLE_VECTOR))
22492250
irq_queues += (nr_io_queues - poll_queues);
2250-
return pci_alloc_irq_vectors_affinity(pdev, 1, irq_queues,
2251-
PCI_IRQ_ALL_TYPES | PCI_IRQ_AFFINITY, &affd);
2251+
if (dev->ctrl.quirks & NVME_QUIRK_BROKEN_MSI)
2252+
flags &= ~PCI_IRQ_MSI;
2253+
return pci_alloc_irq_vectors_affinity(pdev, 1, irq_queues, flags,
2254+
&affd);
22522255
}
22532256

22542257
static unsigned int nvme_max_io_queues(struct nvme_dev *dev)
@@ -2477,6 +2480,7 @@ static int nvme_pci_enable(struct nvme_dev *dev)
24772480
{
24782481
int result = -ENOMEM;
24792482
struct pci_dev *pdev = to_pci_dev(dev->dev);
2483+
unsigned int flags = PCI_IRQ_ALL_TYPES;
24802484

24812485
if (pci_enable_device_mem(pdev))
24822486
return result;
@@ -2493,7 +2497,9 @@ static int nvme_pci_enable(struct nvme_dev *dev)
24932497
* interrupts. Pre-enable a single MSIX or MSI vec for setup. We'll
24942498
* adjust this later.
24952499
*/
2496-
result = pci_alloc_irq_vectors(pdev, 1, 1, PCI_IRQ_ALL_TYPES);
2500+
if (dev->ctrl.quirks & NVME_QUIRK_BROKEN_MSI)
2501+
flags &= ~PCI_IRQ_MSI;
2502+
result = pci_alloc_irq_vectors(pdev, 1, 1, flags);
24972503
if (result < 0)
24982504
goto disable;
24992505

@@ -3390,6 +3396,8 @@ static const struct pci_device_id nvme_id_table[] = {
33903396
.driver_data = NVME_QUIRK_DELAY_BEFORE_CHK_RDY |
33913397
NVME_QUIRK_DISABLE_WRITE_ZEROES|
33923398
NVME_QUIRK_IGNORE_DEV_SUBNQN, },
3399+
{ PCI_DEVICE(0x15b7, 0x5008), /* Sandisk SN530 */
3400+
.driver_data = NVME_QUIRK_BROKEN_MSI },
33933401
{ PCI_DEVICE(0x1987, 0x5012), /* Phison E12 */
33943402
.driver_data = NVME_QUIRK_BOGUS_NID, },
33953403
{ PCI_DEVICE(0x1987, 0x5016), /* Phison E16 */

drivers/nvme/target/auth.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -480,7 +480,7 @@ int nvmet_auth_ctrl_hash(struct nvmet_req *req, u8 *response,
480480
nvme_auth_free_key(transformed_key);
481481
out_free_tfm:
482482
crypto_free_shash(shash_tfm);
483-
return 0;
483+
return ret;
484484
}
485485

486486
int nvmet_auth_ctrl_exponential(struct nvmet_req *req,

drivers/nvme/target/configfs.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -757,10 +757,9 @@ static struct configfs_attribute *nvmet_ns_attrs[] = {
757757
bool nvmet_subsys_nsid_exists(struct nvmet_subsys *subsys, u32 nsid)
758758
{
759759
struct config_item *ns_item;
760-
char name[4] = {};
760+
char name[12];
761761

762-
if (sprintf(name, "%u", nsid) <= 0)
763-
return false;
762+
snprintf(name, sizeof(name), "%u", nsid);
764763
mutex_lock(&subsys->namespaces_group.cg_subsys->su_mutex);
765764
ns_item = config_group_find_item(&subsys->namespaces_group, name);
766765
mutex_unlock(&subsys->namespaces_group.cg_subsys->su_mutex);

drivers/nvme/target/core.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1686,7 +1686,8 @@ static int __init nvmet_init(void)
16861686
if (!buffered_io_wq)
16871687
goto out_free_zbd_work_queue;
16881688

1689-
nvmet_wq = alloc_workqueue("nvmet-wq", WQ_MEM_RECLAIM, 0);
1689+
nvmet_wq = alloc_workqueue("nvmet-wq",
1690+
WQ_MEM_RECLAIM | WQ_UNBOUND, 0);
16901691
if (!nvmet_wq)
16911692
goto out_free_buffered_work_queue;
16921693

drivers/nvme/target/rdma.c

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -474,12 +474,8 @@ nvmet_rdma_alloc_rsps(struct nvmet_rdma_queue *queue)
474474
return 0;
475475

476476
out_free:
477-
while (--i >= 0) {
478-
struct nvmet_rdma_rsp *rsp = &queue->rsps[i];
479-
480-
list_del(&rsp->free_list);
481-
nvmet_rdma_free_rsp(ndev, rsp);
482-
}
477+
while (--i >= 0)
478+
nvmet_rdma_free_rsp(ndev, &queue->rsps[i]);
483479
kfree(queue->rsps);
484480
out:
485481
return ret;
@@ -490,12 +486,8 @@ static void nvmet_rdma_free_rsps(struct nvmet_rdma_queue *queue)
490486
struct nvmet_rdma_device *ndev = queue->dev;
491487
int i, nr_rsps = queue->recv_queue_size * 2;
492488

493-
for (i = 0; i < nr_rsps; i++) {
494-
struct nvmet_rdma_rsp *rsp = &queue->rsps[i];
495-
496-
list_del(&rsp->free_list);
497-
nvmet_rdma_free_rsp(ndev, rsp);
498-
}
489+
for (i = 0; i < nr_rsps; i++)
490+
nvmet_rdma_free_rsp(ndev, &queue->rsps[i]);
499491
kfree(queue->rsps);
500492
}
501493

0 commit comments

Comments
 (0)