Skip to content

Commit a9aa190

Browse files
committed
Merge branch 'for-linus' of git://git.kernel.dk/linux-block
Pull block layer fixes from Jens Axboe: "A couple of last minute fixes for regressions in this cycle. More specifically: - Two patches from Andy, adjusting the NVMe APST quirks to avoid some issues specific to one Toshiba drive, and some variant of Samsung on two specific Dell laptops. - A fix for mtip32xx, turning off mq scheduling on that device. We have a real fix for this, but it's too late in the cycle. Thankfully we already have a NO_SCHED flag we can apply here. A prep patch for this is ensuring that we honor the NO_SCHED flag when attempting to online switch schedulers, previsouly we only did so for drive load time. From Ming. - Fixing an oops in blk-mq polling with scheduling attached. This one is easily reproducible, it would be a shame to release 4.11 with that issue. From me. I'd prefer not having to send in patches at this point in time, but the above are all things that have regressed in this cycle and the fixes are relatively straight forward" * 'for-linus' of git://git.kernel.dk/linux-block: blk-mq: fix potential oops with polling and blk-mq scheduler nvme: Quirk APST off on "THNSF5256GPUK TOSHIBA" nvme: Adjust the Samsung APST quirk mtip32xx: pass BLK_MQ_F_NO_SCHED block: respect BLK_MQ_F_NO_SCHED
2 parents 4664e32 + 3a07bb1 commit a9aa190

File tree

6 files changed

+66
-13
lines changed

6 files changed

+66
-13
lines changed

block/blk-mq.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2928,8 +2928,17 @@ bool blk_mq_poll(struct request_queue *q, blk_qc_t cookie)
29282928
hctx = q->queue_hw_ctx[blk_qc_t_to_queue_num(cookie)];
29292929
if (!blk_qc_t_is_internal(cookie))
29302930
rq = blk_mq_tag_to_rq(hctx->tags, blk_qc_t_to_tag(cookie));
2931-
else
2931+
else {
29322932
rq = blk_mq_tag_to_rq(hctx->sched_tags, blk_qc_t_to_tag(cookie));
2933+
/*
2934+
* With scheduling, if the request has completed, we'll
2935+
* get a NULL return here, as we clear the sched tag when
2936+
* that happens. The request still remains valid, like always,
2937+
* so we should be safe with just the NULL check.
2938+
*/
2939+
if (!rq)
2940+
return false;
2941+
}
29332942

29342943
return __blk_mq_poll(hctx, rq);
29352944
}

block/elevator.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1098,12 +1098,20 @@ int elevator_change(struct request_queue *q, const char *name)
10981098
}
10991099
EXPORT_SYMBOL(elevator_change);
11001100

1101+
static inline bool elv_support_iosched(struct request_queue *q)
1102+
{
1103+
if (q->mq_ops && q->tag_set && (q->tag_set->flags &
1104+
BLK_MQ_F_NO_SCHED))
1105+
return false;
1106+
return true;
1107+
}
1108+
11011109
ssize_t elv_iosched_store(struct request_queue *q, const char *name,
11021110
size_t count)
11031111
{
11041112
int ret;
11051113

1106-
if (!(q->mq_ops || q->request_fn))
1114+
if (!(q->mq_ops || q->request_fn) || !elv_support_iosched(q))
11071115
return count;
11081116

11091117
ret = __elevator_change(q, name);
@@ -1135,7 +1143,7 @@ ssize_t elv_iosched_show(struct request_queue *q, char *name)
11351143
len += sprintf(name+len, "[%s] ", elv->elevator_name);
11361144
continue;
11371145
}
1138-
if (__e->uses_mq && q->mq_ops)
1146+
if (__e->uses_mq && q->mq_ops && elv_support_iosched(q))
11391147
len += sprintf(name+len, "%s ", __e->elevator_name);
11401148
else if (!__e->uses_mq && !q->mq_ops)
11411149
len += sprintf(name+len, "%s ", __e->elevator_name);

drivers/block/mtip32xx/mtip32xx.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3969,7 +3969,7 @@ static int mtip_block_initialize(struct driver_data *dd)
39693969
dd->tags.reserved_tags = 1;
39703970
dd->tags.cmd_size = sizeof(struct mtip_cmd);
39713971
dd->tags.numa_node = dd->numa_node;
3972-
dd->tags.flags = BLK_MQ_F_SHOULD_MERGE;
3972+
dd->tags.flags = BLK_MQ_F_SHOULD_MERGE | BLK_MQ_F_NO_SCHED;
39733973
dd->tags.driver_data = dd;
39743974
dd->tags.timeout = MTIP_NCQ_CMD_TIMEOUT_MS;
39753975

drivers/nvme/host/core.c

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1315,6 +1315,14 @@ static void nvme_configure_apst(struct nvme_ctrl *ctrl)
13151315
if (target)
13161316
table->entries[state] = target;
13171317

1318+
/*
1319+
* Don't allow transitions to the deepest state
1320+
* if it's quirked off.
1321+
*/
1322+
if (state == ctrl->npss &&
1323+
(ctrl->quirks & NVME_QUIRK_NO_DEEPEST_PS))
1324+
continue;
1325+
13181326
/*
13191327
* Is this state a useful non-operational state for
13201328
* higher-power states to autonomously transition to?
@@ -1387,16 +1395,15 @@ struct nvme_core_quirk_entry {
13871395
};
13881396

13891397
static const struct nvme_core_quirk_entry core_quirks[] = {
1390-
/*
1391-
* Seen on a Samsung "SM951 NVMe SAMSUNG 256GB": using APST causes
1392-
* the controller to go out to lunch. It dies when the watchdog
1393-
* timer reads CSTS and gets 0xffffffff.
1394-
*/
13951398
{
1396-
.vid = 0x144d,
1397-
.fr = "BXW75D0Q",
1399+
/*
1400+
* This Toshiba device seems to die using any APST states. See:
1401+
* https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1678184/comments/11
1402+
*/
1403+
.vid = 0x1179,
1404+
.mn = "THNSF5256GPUK TOSHIBA",
13981405
.quirks = NVME_QUIRK_NO_APST,
1399-
},
1406+
}
14001407
};
14011408

14021409
/* match is null-terminated but idstr is space-padded. */

drivers/nvme/host/nvme.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,11 @@ enum nvme_quirks {
8383
* APST should not be used.
8484
*/
8585
NVME_QUIRK_NO_APST = (1 << 4),
86+
87+
/*
88+
* The deepest sleep state should not be used.
89+
*/
90+
NVME_QUIRK_NO_DEEPEST_PS = (1 << 5),
8691
};
8792

8893
/*

drivers/nvme/host/pci.c

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <linux/blk-mq-pci.h>
2020
#include <linux/cpu.h>
2121
#include <linux/delay.h>
22+
#include <linux/dmi.h>
2223
#include <linux/errno.h>
2324
#include <linux/fs.h>
2425
#include <linux/genhd.h>
@@ -1943,10 +1944,31 @@ static int nvme_dev_map(struct nvme_dev *dev)
19431944
return -ENODEV;
19441945
}
19451946

1947+
static unsigned long check_dell_samsung_bug(struct pci_dev *pdev)
1948+
{
1949+
if (pdev->vendor == 0x144d && pdev->device == 0xa802) {
1950+
/*
1951+
* Several Samsung devices seem to drop off the PCIe bus
1952+
* randomly when APST is on and uses the deepest sleep state.
1953+
* This has been observed on a Samsung "SM951 NVMe SAMSUNG
1954+
* 256GB", a "PM951 NVMe SAMSUNG 512GB", and a "Samsung SSD
1955+
* 950 PRO 256GB", but it seems to be restricted to two Dell
1956+
* laptops.
1957+
*/
1958+
if (dmi_match(DMI_SYS_VENDOR, "Dell Inc.") &&
1959+
(dmi_match(DMI_PRODUCT_NAME, "XPS 15 9550") ||
1960+
dmi_match(DMI_PRODUCT_NAME, "Precision 5510")))
1961+
return NVME_QUIRK_NO_DEEPEST_PS;
1962+
}
1963+
1964+
return 0;
1965+
}
1966+
19461967
static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)
19471968
{
19481969
int node, result = -ENOMEM;
19491970
struct nvme_dev *dev;
1971+
unsigned long quirks = id->driver_data;
19501972

19511973
node = dev_to_node(&pdev->dev);
19521974
if (node == NUMA_NO_NODE)
@@ -1978,8 +2000,10 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)
19782000
if (result)
19792001
goto put_pci;
19802002

2003+
quirks |= check_dell_samsung_bug(pdev);
2004+
19812005
result = nvme_init_ctrl(&dev->ctrl, &pdev->dev, &nvme_pci_ctrl_ops,
1982-
id->driver_data);
2006+
quirks);
19832007
if (result)
19842008
goto release_pools;
19852009

0 commit comments

Comments
 (0)