[PATCH] nvme: implement the DEAC bit for the Write Zeroes command

Guixin Liu kanie at linux.alibaba.com
Mon Oct 31 02:01:47 PDT 2022


在 2022/10/31 00:29, Christoph Hellwig 写道:
> While the specification allows devices to either deallocate data
> or to actually write zeroes on any Write Zeroes command, many SSDs
> only do the sensible thing and deallocate data when the DEAC bit
> is specific.  Set it when it is suppored and the caller doesn't
> explicitly opt out of deallocation.
>
> Signed-off-by: Christoph Hellwig <hch at lst.de>
> ---
>
> BTW, I'm tempted to slap a
>
> Fixes: 6e02318eaea5 ("nvme: add support for the Write Zeroes command")
>
> onto this.  While it doesn't fix the Write Zeroes support per se,
> it should help us with a lot of the devices timing out on Write Zeroes.
>
>   drivers/nvme/host/core.c | 6 +++++-
>   drivers/nvme/host/nvme.h | 1 +
>   include/linux/nvme.h     | 1 +
>   3 files changed, 7 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
> index 0090dc0b3ae6f..14568ae308fba 100644
> --- a/drivers/nvme/host/core.c
> +++ b/drivers/nvme/host/core.c
> @@ -850,8 +850,11 @@ static inline blk_status_t nvme_setup_write_zeroes(struct nvme_ns *ns,
>   	cmnd->write_zeroes.length =
>   		cpu_to_le16((blk_rq_bytes(req) >> ns->lba_shift) - 1);
>   
> +	if (!(req->cmd_flags & REQ_NOUNMAP) && ns->dlfeat & (1 << 3))

Maybe we can add a series of macros to make the code easier to read.

Best regards,

Guixin Liu

> +		cmnd->write_zeroes.control |= cpu_to_le16(NVME_WZ_DEAC);
> +
>   	if (nvme_ns_has_pi(ns)) {
> -		cmnd->write_zeroes.control = cpu_to_le16(NVME_RW_PRINFO_PRACT);
> +		cmnd->write_zeroes.control |= cpu_to_le16(NVME_RW_PRINFO_PRACT);
>   
>   		switch (ns->pi_type) {
>   		case NVME_NS_DPS_PI_TYPE1:
> @@ -2004,6 +2007,7 @@ static int nvme_update_ns_info_block(struct nvme_ns *ns,
>   		}
>   	}
>   
> +	ns->dlfeat = id->dlfeat;
>   	set_disk_ro(ns->disk, nvme_ns_is_readonly(ns, info));
>   	set_bit(NVME_NS_READY, &ns->flags);
>   	blk_mq_unfreeze_queue(ns->disk->queue);
> diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
> index a29877217ee65..00d3b438efe3f 100644
> --- a/drivers/nvme/host/nvme.h
> +++ b/drivers/nvme/host/nvme.h
> @@ -477,6 +477,7 @@ struct nvme_ns {
>   	u32 sws;
>   	u8 pi_type;
>   	u8 guard_type;
> +	u8 dlfeat;
>   #ifdef CONFIG_BLK_DEV_ZONED
>   	u64 zsze;
>   #endif
> diff --git a/include/linux/nvme.h b/include/linux/nvme.h
> index 050d7d0cd81b0..c96930b2c28fe 100644
> --- a/include/linux/nvme.h
> +++ b/include/linux/nvme.h
> @@ -963,6 +963,7 @@ enum {
>   	NVME_RW_PRINFO_PRCHK_GUARD	= 1 << 12,
>   	NVME_RW_PRINFO_PRACT		= 1 << 13,
>   	NVME_RW_DTYPE_STREAMS		= 1 << 4,
> +	NVME_WZ_DEAC			= 1 << 9,
>   };
>   
>   struct nvme_dsm_cmd {



More information about the Linux-nvme mailing list