From 7b991b2324239f9a026b47518fdc1e4a6e127aad Mon Sep 17 00:00:00 2001 From: Ferry Meng Date: Tue, 14 Apr 2026 14:33:25 +0800 Subject: [PATCH 1/2] anolis: nvme: add support for passing I/O flags to backend ANBZ: #33094 This patch adds support for NVMe block devices to pass I/O request flags to the backend storage, enabling performance optimization in certain scenarios. Changes include: - Add CONFIG_NVME_PASS_REQFLAG boolean configuration option - Add pass_reqflag_enabled flag to nvme_ctrl structure - Enable flag passing for Alibaba vendor devices (checked via PCI_VENDOR_ID_ALIBABA in identify controller) - Pack request flags into cdw3 high 16 bits for write operations The flags are encoded as follows: - Bit 0: Feature enabled indicator - Bit 1: REQ_SYNC - Bit 2: REQ_META - Bit 3: REQ_PRIO - Bit 4: REQ_IDLE - Bit 5: REQ_PREFLUSH - Bit 6: REQ_RAHEAD - Bit 7: REQ_BACKGROUND This allows the backend storage to optimize I/O scheduling based on the request characteristics. Signed-off-by: Ferry Meng --- .../default/CONFIG_NVME_PASS_REQFLAG | 1 + drivers/nvme/host/Kconfig | 18 ++++++++++++++++++ drivers/nvme/host/core.c | 4 ++++ drivers/nvme/host/nvme.h | 3 +++ drivers/nvme/host/pci.c | 16 ++++++++++++++++ include/linux/blk-mq.h | 14 ++++++++++++++ 6 files changed, 56 insertions(+) create mode 100644 anolis/configs/L0-MANDATORY/default/CONFIG_NVME_PASS_REQFLAG diff --git a/anolis/configs/L0-MANDATORY/default/CONFIG_NVME_PASS_REQFLAG b/anolis/configs/L0-MANDATORY/default/CONFIG_NVME_PASS_REQFLAG new file mode 100644 index 000000000000..a42eec8ec004 --- /dev/null +++ b/anolis/configs/L0-MANDATORY/default/CONFIG_NVME_PASS_REQFLAG @@ -0,0 +1 @@ +CONFIG_NVME_PASS_REQFLAG=y diff --git a/drivers/nvme/host/Kconfig b/drivers/nvme/host/Kconfig index 494675aeaaad..7ef13c83adc4 100644 --- a/drivers/nvme/host/Kconfig +++ b/drivers/nvme/host/Kconfig @@ -85,3 +85,21 @@ config NVME_TCP from https://github.com/linux-nvme/nvme-cli. If unsure, say N. + +config NVME_PASS_REQFLAG + bool "NVM Express block device pass I/O flags" + depends on BLK_DEV_NVME + help + Enable support for NVMe devices to pass I/O block flags + (such as REQ_META, REQ_BACKGROUND, etc.) to the backend storage. + + When enabled, the NVMe driver forwards per-request I/O flags + to the backend device, allowing backend to do specific + optimizations. + + Note that this feature requires both guest and backend to support + the corresponding I/O flag protocol. If the backend does not + understand the flags, they are silently ignored and there is no + functional change compared to disabling this option. + + If unsure, say N. \ No newline at end of file diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c index 1ff34199efe7..6866655a1a62 100644 --- a/drivers/nvme/host/core.c +++ b/drivers/nvme/host/core.c @@ -2852,6 +2852,10 @@ int nvme_init_identify(struct nvme_ctrl *ctrl) dev_err(ctrl->device, "Identify Controller failed (%d)\n", ret); return -EIO; } +#ifdef CONFIG_NVME_PASS_REQFLAG + if (le16_to_cpu(id->vid) == PCI_VENDOR_ID_ALIBABA) + ctrl->pass_reqflag_enabled = true; +#endif if (id->lpa & NVME_CTRL_LPA_CMD_EFFECTS_LOG) { ret = nvme_get_effects_log(ctrl, NVME_CSI_NVM, &ctrl->effects); diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h index c6425e7f5ba3..f9ac9aae6ac2 100644 --- a/drivers/nvme/host/nvme.h +++ b/drivers/nvme/host/nvme.h @@ -362,6 +362,9 @@ struct nvme_ctrl { unsigned long discard_page_busy; struct nvme_fault_inject fault_inject; +#ifdef CONFIG_NVME_PASS_REQFLAG + bool pass_reqflag_enabled; +#endif }; static inline enum nvme_ctrl_state nvme_ctrl_state(struct nvme_ctrl *ctrl) diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c index 90162bfc5922..e769b579c920 100644 --- a/drivers/nvme/host/pci.c +++ b/drivers/nvme/host/pci.c @@ -962,6 +962,9 @@ static blk_status_t nvme_queue_rq(struct blk_mq_hw_ctx *hctx, struct nvme_iod *iod = blk_mq_rq_to_pdu(req); struct nvme_command *cmnd = &iod->cmd; blk_status_t ret; +#ifdef CONFIG_NVME_PASS_REQFLAG + u16 reqflag = 0; +#endif iod->aborted = 0; iod->npages = -1; @@ -985,6 +988,19 @@ static blk_status_t nvme_queue_rq(struct blk_mq_hw_ctx *hctx, ret = nvme_map_data(dev, req, cmnd); if (ret) goto out_free_cmd; +#ifdef CONFIG_NVME_PASS_REQFLAG + if (dev->ctrl.pass_reqflag_enabled && + (req_op(req) == REQ_OP_WRITE || req_op(req) == REQ_OP_READ)) { + /* Extract and pack request flags into reqflag from low to high bit, + * bit-0 informs backend that feature is enabled + */ + reqflag = get_and_pack_req_cmd_flags(req); + + /* Set reqflag to the high 16 bits of cdw3 */ + cmnd->common.cdw2[1] = (cmnd->common.cdw2[1] & cpu_to_le32(0xFFFF)) + | cpu_to_le32((u32)reqflag << 16); + } +#endif } if (blk_integrity_rq(req)) { diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h index 04f4119be6ed..d914e6d5d4a1 100644 --- a/include/linux/blk-mq.h +++ b/include/linux/blk-mq.h @@ -671,4 +671,18 @@ static inline void blk_mq_cleanup_rq(struct request *rq) rq->q->mq_ops->cleanup_rq(rq); } +static inline u16 get_and_pack_req_cmd_flags(struct request *rq) +{ + /* Extract and pack request flags into uint16_t, + * bit-0 indicates that the value is valid + */ + return 1 << 0 | + ((rq->cmd_flags & REQ_SYNC) ? (1 << 1) : 0) | + ((rq->cmd_flags & REQ_META) ? (1 << 2) : 0) | + ((rq->cmd_flags & REQ_PRIO) ? (1 << 3) : 0) | + ((rq->cmd_flags & REQ_IDLE) ? (1 << 4) : 0) | + ((rq->cmd_flags & REQ_PREFLUSH) ? (1 << 5) : 0) | + ((rq->cmd_flags & REQ_RAHEAD) ? (1 << 6) : 0) | + ((rq->cmd_flags & REQ_BACKGROUND) ? (1 << 7) : 0); +} #endif -- Gitee From 94ecb70c64f9cac96a9d041cb2bf0a7a3fc022ce Mon Sep 17 00:00:00 2001 From: Ferry Meng Date: Tue, 14 Apr 2026 14:33:42 +0800 Subject: [PATCH 2/2] anolis: virtio-blk: add support for passing I/O flags to backend ANBZ: #33094 This patch modifies virtio-blk driver to pass I/O request flags to the backend. Changes include: - Add CONFIG_VIRTIO_BLK_PASS_REQFLAG Kconfig option to control the feature - Modify ioprio assignment to use rpair.ioprio (16-bit) instead of the original 32-bit field when CONFIG_VIRTIO_BLK_PASS_REQFLAG is enabled - Add tag field (rpair.tag) with packed request flags for write/read operations - Fall back to original ioprio assignment when CONFIG_VIRTIO_BLK_PASS_REQFLAG is disabled The flags are encoded as follows: - Bit 0: Feature enabled indicator - Bit 1: REQ_SYNC - Bit 2: REQ_META - Bit 3: REQ_PRIO - Bit 4: REQ_IDLE - Bit 5: REQ_PREFLUSH - Bit 6: REQ_RAHEAD - Bit 7: REQ_BACKGROUND This enables the backend to optimize I/O scheduling based on request characteristics, improving performance in certain scenarios. Signed-off-by: Ferry Meng --- .../default/CONFIG_VIRTIO_BLK_PASS_REQFLAG | 1 + drivers/block/Kconfig | 18 ++++++++++++++++++ drivers/block/virtio_blk.c | 12 ++++++++++++ 3 files changed, 31 insertions(+) create mode 100644 anolis/configs/L0-MANDATORY/default/CONFIG_VIRTIO_BLK_PASS_REQFLAG diff --git a/anolis/configs/L0-MANDATORY/default/CONFIG_VIRTIO_BLK_PASS_REQFLAG b/anolis/configs/L0-MANDATORY/default/CONFIG_VIRTIO_BLK_PASS_REQFLAG new file mode 100644 index 000000000000..c0a932a9521e --- /dev/null +++ b/anolis/configs/L0-MANDATORY/default/CONFIG_VIRTIO_BLK_PASS_REQFLAG @@ -0,0 +1 @@ +CONFIG_VIRTIO_BLK_PASS_REQFLAG=y diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index 9195938f67ae..a4cf6a1615c1 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -452,6 +452,24 @@ config VIRTIO_BLK_RING_PAIR If unsure, say N. +config VIRTIO_BLK_PASS_REQFLAG + bool "Virtio block device pass I/O flags" + depends on VIRTIO_BLK + help + Enable support for virtio-blk devices to pass I/O block flags + (such as REQ_META, REQ_BACKGROUND, etc.) to the backend storage. + + When enabled, the virtio-blk driver forwards per-request I/O + flags to the backend device, allowing backend to do specific + optimizations. + + Note that this feature requires both guest and backend to support + the corresponding I/O flag protocol. If the backend does not + understand the flags, they are silently ignored and there is no + functional change compared to disabling this option. + + If unsure, say N. + config BLK_DEV_RBD tristate "Rados block device (RBD)" depends on INET && BLOCK diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c index 17ce47c185da..8bd9025b922d 100644 --- a/drivers/block/virtio_blk.c +++ b/drivers/block/virtio_blk.c @@ -841,7 +841,19 @@ static blk_status_t virtblk_setup_cmd(struct virtio_device *vdev, vbr->out_hdr.type = cpu_to_virtio32(vdev, type); vbr->out_hdr.sector = cpu_to_virtio64(vdev, sector); +#ifdef CONFIG_VIRTIO_BLK_PASS_REQFLAG + vbr->out_hdr.rpair.ioprio = cpu_to_virtio16(vdev, (u16)req_get_ioprio(req)); + if (req_op(req) == REQ_OP_WRITE || req_op(req) == REQ_OP_READ) + /* Extract and pack request flags into ioprio high 16bit, + * bit-0 informs backend that feature is enabled + */ + vbr->out_hdr.rpair.tag = cpu_to_virtio16(vdev, + get_and_pack_req_cmd_flags(req)); + else + vbr->out_hdr.rpair.tag = cpu_to_virtio16(vdev, 0); +#else vbr->out_hdr.ioprio = cpu_to_virtio32(vdev, req_get_ioprio(req)); +#endif if (type == VIRTIO_BLK_T_DISCARD || type == VIRTIO_BLK_T_WRITE_ZEROES) { if (virtblk_setup_discard_write_zeroes(req, unmap)) -- Gitee