[PATCH] nvme: add NO_FUA quirk for ADATA XPG GAMMIX S70 BLADE

Christoph Hellwig hch at lst.de
Mon Nov 2 23:56:17 PST 2026


On Thu, Oct 22, 2026 at 08:21:25AM -0700, Hugo Deco wrote:
> On the ADATA XPG GAMMIX S70 BLADE (PCI 1cc1:5370, firmware 03020P5E)
> every Write with the FUA bit set takes 200, 400 or 600 ms to complete,
> always a multiple of ~200 ms, while a plain Write completes in
> 0.0-0.4 ms and a Flush in ~1.3 ms. Tracing nvme_setup_cmd and
> nvme_complete_rq shows the whole delay is between submission and
> completion, i.e. inside the device (e.g. FUA write, control 0x4000:
> 598.3 ms).
> 
> Because ext4/jbd2 issue FUA for every journal commit, fsync() on this
> drive stalls for 250-890 ms and desktop applications freeze.
> 
> Add NVME_QUIRK_NO_FUA, which stops advertising BLK_FEAT_FUA while
> keeping the volatile write cache enabled, so the block layer emulates
> FUA with a Write followed by a Flush. Durability semantics are
> unchanged.
> 
> With the quirk applied, 4 KiB O_DIRECT|O_DSYNC writes and
> create+write+fsync drop from 250-890 ms to a 0.82-0.85 ms median
> (30 samples, two partitions on the same drive).

No a huge fan of adding these quirks, but the results are pretty massiv.
Andres also saw FUA slowdowns on various Samsung devices, which got
lost.  Maybe we should add those as well?

> 
> Signed-off-by: Hugo Deco <hugodeco at sufficit.com.br>
> ---
>  drivers/nvme/host/core.c | 11 +++++++++++
>  drivers/nvme/host/nvme.h |  8 ++++++++
>  2 files changed, 19 insertions(+)
> 
> diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
> index 7eb0f9f..5c0d74d 100644
> --- a/drivers/nvme/host/core.c
> +++ b/drivers/nvme/host/core.c
> @@ -2477,6 +2477,8 @@ static int nvme_update_ns_info_block(struct nvme_ns *ns,
>  		lim.features |= BLK_FEAT_WRITE_CACHE | BLK_FEAT_FUA;
>  	else
>  		lim.features &= ~(BLK_FEAT_WRITE_CACHE | BLK_FEAT_FUA);
> +	if (ns->ctrl->quirks & NVME_QUIRK_NO_FUA)
> +		lim.features &= ~BLK_FEAT_FUA;
> 
>  	if (info->is_rotational)
>  		lim.features |= BLK_FEAT_ROTATIONAL;
> @@ -3090,6 +3092,15 @@ struct nvme_core_quirk_entry {
>  };
> 
>  static const struct nvme_core_quirk_entry core_quirks[] = {
> +	{
> +		/*
> +		 * ADATA XPG GAMMIX S70 BLADE (fw 03020P5E) takes 200-600 ms
> +		 * to complete FUA writes while Flush takes ~1.3 ms.
> +		 */
> +		.vid = 0x1cc1,
> +		.mn = "XPG GAMMIX S70 BLADE",
> +		.quirks = NVME_QUIRK_NO_FUA,
> +	},
>  	{
>  		/*
>  		 * This Toshiba device seems to die using any APST states.  See:
> diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
> index a643c47..2128b40 100644
> --- a/drivers/nvme/host/nvme.h
> +++ b/drivers/nvme/host/nvme.h
> @@ -183,6 +183,12 @@ enum nvme_quirks {
>  	 * Admin queue DMA buffers must be page aligned
>  	 */
>  	NVME_QUIRK_ADMIN_PAGE_ALIGN		= (1 << 23),
> +
> +	/*
> +	 * The device is extremely slow on FUA writes but fast on Flush;
> +	 * do not advertise FUA so the block layer emulates it.
> +	 */
> +	NVME_QUIRK_NO_FUA			= (1 << 24),
>  };
> 
>  static inline char *nvme_quirk_name(enum nvme_quirks q)
> @@ -236,6 +242,8 @@ static inline char *nvme_quirk_name(enum nvme_quirks q)
>  		return "dmapool_align_512";
>  	case NVME_QUIRK_ADMIN_PAGE_ALIGN:
>  		return "admin_page_align";
> +	case NVME_QUIRK_NO_FUA:
> +		return "no_fua";
>  	}
> 
>  	return "unknown";
> -- 
> 2.53.0
---end quoted text---



More information about the Linux-nvme mailing list