Skip to content

Commit 0d4cafd

Browse files
committed
Merge tag 'for-linus-20180511' of git://git.kernel.dk/linux-block
Pull block fixes from Jens Axboe: "Just a few NVMe fixes this round - one fixing a use-after-free, one fixes the return value after controller reset, and the last one fixes an issue where some drives will spuriously EIO. We should get these into 4.17" * tag 'for-linus-20180511' of git://git.kernel.dk/linux-block: nvme: add quirk to force medium priority for SQ creation nvme: Fix sync controller reset return nvme: fix use-after-free in nvme_free_ns_head
2 parents f0ab773 + 9abd68e commit 0d4cafd

File tree

3 files changed

+23
-2
lines changed

3 files changed

+23
-2
lines changed

drivers/nvme/host/core.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ static struct class *nvme_subsys_class;
9999

100100
static void nvme_ns_remove(struct nvme_ns *ns);
101101
static int nvme_revalidate_disk(struct gendisk *disk);
102+
static void nvme_put_subsystem(struct nvme_subsystem *subsys);
102103

103104
int nvme_reset_ctrl(struct nvme_ctrl *ctrl)
104105
{
@@ -117,7 +118,8 @@ int nvme_reset_ctrl_sync(struct nvme_ctrl *ctrl)
117118
ret = nvme_reset_ctrl(ctrl);
118119
if (!ret) {
119120
flush_work(&ctrl->reset_work);
120-
if (ctrl->state != NVME_CTRL_LIVE)
121+
if (ctrl->state != NVME_CTRL_LIVE &&
122+
ctrl->state != NVME_CTRL_ADMIN_ONLY)
121123
ret = -ENETRESET;
122124
}
123125

@@ -350,6 +352,7 @@ static void nvme_free_ns_head(struct kref *ref)
350352
ida_simple_remove(&head->subsys->ns_ida, head->instance);
351353
list_del_init(&head->entry);
352354
cleanup_srcu_struct(&head->srcu);
355+
nvme_put_subsystem(head->subsys);
353356
kfree(head);
354357
}
355358

@@ -2861,6 +2864,9 @@ static struct nvme_ns_head *nvme_alloc_ns_head(struct nvme_ctrl *ctrl,
28612864
goto out_cleanup_srcu;
28622865

28632866
list_add_tail(&head->entry, &ctrl->subsys->nsheads);
2867+
2868+
kref_get(&ctrl->subsys->ref);
2869+
28642870
return head;
28652871
out_cleanup_srcu:
28662872
cleanup_srcu_struct(&head->srcu);

drivers/nvme/host/nvme.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,11 @@ enum nvme_quirks {
8484
* Supports the LighNVM command set if indicated in vs[1].
8585
*/
8686
NVME_QUIRK_LIGHTNVM = (1 << 6),
87+
88+
/*
89+
* Set MEDIUM priority on SQ creation
90+
*/
91+
NVME_QUIRK_MEDIUM_PRIO_SQ = (1 << 7),
8792
};
8893

8994
/*

drivers/nvme/host/pci.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1093,9 +1093,18 @@ static int adapter_alloc_cq(struct nvme_dev *dev, u16 qid,
10931093
static int adapter_alloc_sq(struct nvme_dev *dev, u16 qid,
10941094
struct nvme_queue *nvmeq)
10951095
{
1096+
struct nvme_ctrl *ctrl = &dev->ctrl;
10961097
struct nvme_command c;
10971098
int flags = NVME_QUEUE_PHYS_CONTIG;
10981099

1100+
/*
1101+
* Some drives have a bug that auto-enables WRRU if MEDIUM isn't
1102+
* set. Since URGENT priority is zeroes, it makes all queues
1103+
* URGENT.
1104+
*/
1105+
if (ctrl->quirks & NVME_QUIRK_MEDIUM_PRIO_SQ)
1106+
flags |= NVME_SQ_PRIO_MEDIUM;
1107+
10991108
/*
11001109
* Note: we (ab)use the fact that the prp fields survive if no data
11011110
* is attached to the request.
@@ -2701,7 +2710,8 @@ static const struct pci_device_id nvme_id_table[] = {
27012710
.driver_data = NVME_QUIRK_STRIPE_SIZE |
27022711
NVME_QUIRK_DEALLOCATE_ZEROES, },
27032712
{ PCI_VDEVICE(INTEL, 0xf1a5), /* Intel 600P/P3100 */
2704-
.driver_data = NVME_QUIRK_NO_DEEPEST_PS },
2713+
.driver_data = NVME_QUIRK_NO_DEEPEST_PS |
2714+
NVME_QUIRK_MEDIUM_PRIO_SQ },
27052715
{ PCI_VDEVICE(INTEL, 0x5845), /* Qemu emulated controller */
27062716
.driver_data = NVME_QUIRK_IDENTIFY_CNS, },
27072717
{ PCI_DEVICE(0x1c58, 0x0003), /* HGST adapter */

0 commit comments

Comments
 (0)