From: Keith Busch Date: Fri, 4 Mar 2016 20:15:17 +0000 (-0700) Subject: NVMe: Create discard zero quirk white list X-Git-Tag: v4.1.12-102.0.20170601_1400~68 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=e098e06b360a5137c3cb289a7cfae61cc01c7b70;p=users%2Fjedix%2Flinux-maple.git NVMe: Create discard zero quirk white list The NVMe specification does not require discarded blocks return zeroes on read, but provides that behavior as a possibility. Some applications more efficiently use an SSD if reads on discarded blocks were deterministically zero, based on the "discard_zeroes_data" queue attribute. There is no specification defined way to determine device behavior on discarded blocks, so the driver always left the queue setting disabled. We can only know behavior based on individual device models, so this patch adds a flag to the NVMe "quirk" list that vendors may set if they know their controller works that way. The patch also sets the new flag for one such known device. Signed-off-by: Keith Busch Suggested-by: Artur Paszkiewicz Reviewed-by: Christoph Hellwig Reviewed-by: Martin K. Petersen Reviewed-by: Johannes Thumshirn Reviewed-by: Sagi Grimberg Signed-off-by: Jens Axboe (cherry picked from commit 08095e70783f1d8296f858d37a9e1878f5da0623) Orabug: 25130845 Signed-off-by: Ashok Vairavan Reviewed-by: Martin K. Petersen --- diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index ad275f2f660f0..58573ffa2ae21 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -731,8 +731,14 @@ static void nvme_init_integrity(struct nvme_ns *ns) static void nvme_config_discard(struct nvme_ns *ns) { + struct nvme_ctrl *ctrl = ns->ctrl; u32 logical_block_size = queue_logical_block_size(ns->queue); - ns->queue->limits.discard_zeroes_data = 0; + + if (ctrl->quirks & NVME_QUIRK_DISCARD_ZEROES) + ns->queue->limits.discard_zeroes_data = 1; + else + ns->queue->limits.discard_zeroes_data = 0; + ns->queue->limits.discard_alignment = logical_block_size; ns->queue->limits.discard_granularity = logical_block_size; blk_queue_max_discard_sectors(ns->queue, UINT_MAX); diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h index 1a449283c858a..5e88b21b99d62 100644 --- a/drivers/nvme/host/nvme.h +++ b/drivers/nvme/host/nvme.h @@ -53,6 +53,17 @@ enum nvme_quirks { * specific Identify field. */ NVME_QUIRK_STRIPE_SIZE = (1 << 0), + /* + * The controller doesn't handle Identify value others than 0 or 1 + * correctly. + */ + NVME_QUIRK_IDENTIFY_CNS = (1 << 1), + + /* + * The controller deterministically returns O's on reads to discarded + * logical blocks. + */ + NVME_QUIRK_DISCARD_ZEROES = (1 << 2), }; enum nvme_ctrl_state {