Commit 6462c247 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'block-6.15-20250515' of git://git.kernel.dk/linux

Pull block fixes from Jens Axboe:

 - NVMe pull request via Christoph:
      - fixes for atomic writes (Alan Adamson)
      - fixes for polled CQs in nvmet-epf (Damien Le Moal)
      - fix for polled CQs in nvme-pci (Keith Busch)
      - fix compile on odd configs that need to be forced to inline
        (Kees Cook)
      - one more quirk (Ilya Guterman)

 - Fix for missing allocation of an integrity buffer for some cases

 - Fix for a regression with ublk command cancelation

* tag 'block-6.15-20250515' of git://git.kernel.dk/linux:
  ublk: fix dead loop when canceling io command
  nvme-pci: add NVME_QUIRK_NO_DEEPEST_PS quirk for SOLIDIGM P44 Pro
  nvme: all namespaces in a subsystem must adhere to a common atomic write size
  nvme: multipath: enable BLK_FEAT_ATOMIC_WRITES for multipathing
  nvmet: pci-epf: remove NVMET_PCI_EPF_Q_IS_SQ
  nvmet: pci-epf: improve debug message
  nvmet: pci-epf: cleanup nvmet_pci_epf_raise_irq()
  nvmet: pci-epf: do not fall back to using INTX if not supported
  nvmet: pci-epf: clear completion queue IRQ flag on delete
  nvme-pci: acquire cq_poll_lock in nvme_poll_irqdisable
  nvme-pci: make nvme_pci_npages_prp() __always_inline
  block: always allocate integrity buffer when required
parents e2661da1 dd24f87f
Loading
Loading
Loading
Loading
+47 −15
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@
 * not aware of PI.
 */
#include <linux/blk-integrity.h>
#include <linux/t10-pi.h>
#include <linux/workqueue.h>
#include "blk.h"

@@ -43,6 +44,29 @@ static void bio_integrity_verify_fn(struct work_struct *work)
	bio_endio(bio);
}

#define BIP_CHECK_FLAGS (BIP_CHECK_GUARD | BIP_CHECK_REFTAG | BIP_CHECK_APPTAG)
static bool bip_should_check(struct bio_integrity_payload *bip)
{
	return bip->bip_flags & BIP_CHECK_FLAGS;
}

static bool bi_offload_capable(struct blk_integrity *bi)
{
	switch (bi->csum_type) {
	case BLK_INTEGRITY_CSUM_CRC64:
		return bi->tuple_size == sizeof(struct crc64_pi_tuple);
	case BLK_INTEGRITY_CSUM_CRC:
	case BLK_INTEGRITY_CSUM_IP:
		return bi->tuple_size == sizeof(struct t10_pi_tuple);
	default:
		pr_warn_once("%s: unknown integrity checksum type:%d\n",
			__func__, bi->csum_type);
		fallthrough;
	case BLK_INTEGRITY_CSUM_NONE:
		return false;
	}
}

/**
 * __bio_integrity_endio - Integrity I/O completion function
 * @bio:	Protected bio
@@ -54,12 +78,12 @@ static void bio_integrity_verify_fn(struct work_struct *work)
 */
bool __bio_integrity_endio(struct bio *bio)
{
	struct blk_integrity *bi = blk_get_integrity(bio->bi_bdev->bd_disk);
	struct bio_integrity_payload *bip = bio_integrity(bio);
	struct bio_integrity_data *bid =
		container_of(bip, struct bio_integrity_data, bip);

	if (bio_op(bio) == REQ_OP_READ && !bio->bi_status && bi->csum_type) {
	if (bio_op(bio) == REQ_OP_READ && !bio->bi_status &&
	    bip_should_check(bip)) {
		INIT_WORK(&bid->work, bio_integrity_verify_fn);
		queue_work(kintegrityd_wq, &bid->work);
		return false;
@@ -84,6 +108,7 @@ bool bio_integrity_prep(struct bio *bio)
{
	struct blk_integrity *bi = blk_get_integrity(bio->bi_bdev->bd_disk);
	struct bio_integrity_data *bid;
	bool set_flags = true;
	gfp_t gfp = GFP_NOIO;
	unsigned int len;
	void *buf;
@@ -100,19 +125,24 @@ bool bio_integrity_prep(struct bio *bio)

	switch (bio_op(bio)) {
	case REQ_OP_READ:
		if (bi->flags & BLK_INTEGRITY_NOVERIFY)
		if (bi->flags & BLK_INTEGRITY_NOVERIFY) {
			if (bi_offload_capable(bi))
				return true;
			set_flags = false;
		}
		break;
	case REQ_OP_WRITE:
		if (bi->flags & BLK_INTEGRITY_NOGENERATE)
			return true;

		/*
		 * Zero the memory allocated to not leak uninitialized kernel
		 * memory to disk for non-integrity metadata where nothing else
		 * initializes the memory.
		 */
		if (bi->csum_type == BLK_INTEGRITY_CSUM_NONE)
		if (bi->flags & BLK_INTEGRITY_NOGENERATE) {
			if (bi_offload_capable(bi))
				return true;
			set_flags = false;
			gfp |= __GFP_ZERO;
		} else if (bi->csum_type == BLK_INTEGRITY_CSUM_NONE)
			gfp |= __GFP_ZERO;
		break;
	default:
@@ -137,19 +167,21 @@ bool bio_integrity_prep(struct bio *bio)
	bid->bip.bip_flags |= BIP_BLOCK_INTEGRITY;
	bip_set_seed(&bid->bip, bio->bi_iter.bi_sector);

	if (set_flags) {
		if (bi->csum_type == BLK_INTEGRITY_CSUM_IP)
			bid->bip.bip_flags |= BIP_IP_CHECKSUM;
		if (bi->csum_type)
			bid->bip.bip_flags |= BIP_CHECK_GUARD;
		if (bi->flags & BLK_INTEGRITY_REF_TAG)
			bid->bip.bip_flags |= BIP_CHECK_REFTAG;
	}

	if (bio_integrity_add_page(bio, virt_to_page(buf), len,
			offset_in_page(buf)) < len)
		goto err_end_io;

	/* Auto-generate integrity metadata if this is a write */
	if (bio_data_dir(bio) == WRITE)
	if (bio_data_dir(bio) == WRITE && bip_should_check(&bid->bip))
		blk_integrity_generate(bio);
	else
		bid->saved_bio_iter = bio->bi_iter;
+1 −1
Original line number Diff line number Diff line
@@ -1708,7 +1708,7 @@ static void ublk_cancel_cmd(struct ublk_queue *ubq, unsigned tag,
	 * that ublk_dispatch_req() is always called
	 */
	req = blk_mq_tag_to_rq(ub->tag_set.tags[ubq->q_id], tag);
	if (req && blk_mq_request_started(req))
	if (req && blk_mq_request_started(req) && req->tag == tag)
		return;

	spin_lock(&ubq->cancel_lock);
+27 −3
Original line number Diff line number Diff line
@@ -2059,7 +2059,21 @@ static bool nvme_update_disk_info(struct nvme_ns *ns, struct nvme_id_ns *id,
		if (id->nsfeat & NVME_NS_FEAT_ATOMICS && id->nawupf)
			atomic_bs = (1 + le16_to_cpu(id->nawupf)) * bs;
		else
			atomic_bs = (1 + ns->ctrl->subsys->awupf) * bs;
			atomic_bs = (1 + ns->ctrl->awupf) * bs;

		/*
		 * Set subsystem atomic bs.
		 */
		if (ns->ctrl->subsys->atomic_bs) {
			if (atomic_bs != ns->ctrl->subsys->atomic_bs) {
				dev_err_ratelimited(ns->ctrl->device,
					"%s: Inconsistent Atomic Write Size, Namespace will not be added: Subsystem=%d bytes, Controller/Namespace=%d bytes\n",
					ns->disk ? ns->disk->disk_name : "?",
					ns->ctrl->subsys->atomic_bs,
					atomic_bs);
			}
		} else
			ns->ctrl->subsys->atomic_bs = atomic_bs;

		nvme_update_atomic_write_disk_info(ns, id, lim, bs, atomic_bs);
	}
@@ -2201,6 +2215,17 @@ static int nvme_update_ns_info_block(struct nvme_ns *ns,
	nvme_set_chunk_sectors(ns, id, &lim);
	if (!nvme_update_disk_info(ns, id, &lim))
		capacity = 0;

	/*
	 * Validate the max atomic write size fits within the subsystem's
	 * atomic write capabilities.
	 */
	if (lim.atomic_write_hw_max > ns->ctrl->subsys->atomic_bs) {
		blk_mq_unfreeze_queue(ns->disk->queue, memflags);
		ret = -ENXIO;
		goto out;
	}

	nvme_config_discard(ns, &lim);
	if (IS_ENABLED(CONFIG_BLK_DEV_ZONED) &&
	    ns->head->ids.csi == NVME_CSI_ZNS)
@@ -3031,7 +3056,6 @@ static int nvme_init_subsystem(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id)
		kfree(subsys);
		return -EINVAL;
	}
	subsys->awupf = le16_to_cpu(id->awupf);
	nvme_mpath_default_iopolicy(subsys);

	subsys->dev.class = &nvme_subsys_class;
@@ -3441,7 +3465,7 @@ static int nvme_init_identify(struct nvme_ctrl *ctrl)
		dev_pm_qos_expose_latency_tolerance(ctrl->device);
	else if (!ctrl->apst_enabled && prev_apst_enabled)
		dev_pm_qos_hide_latency_tolerance(ctrl->device);

	ctrl->awupf = le16_to_cpu(id->awupf);
out_free:
	kfree(id);
	return ret;
+2 −1
Original line number Diff line number Diff line
@@ -638,7 +638,8 @@ int nvme_mpath_alloc_disk(struct nvme_ctrl *ctrl, struct nvme_ns_head *head)

	blk_set_stacking_limits(&lim);
	lim.dma_alignment = 3;
	lim.features |= BLK_FEAT_IO_STAT | BLK_FEAT_NOWAIT | BLK_FEAT_POLL;
	lim.features |= BLK_FEAT_IO_STAT | BLK_FEAT_NOWAIT |
		BLK_FEAT_POLL | BLK_FEAT_ATOMIC_WRITES;
	if (head->ids.csi == NVME_CSI_ZNS)
		lim.features |= BLK_FEAT_ZONED;

+2 −1
Original line number Diff line number Diff line
@@ -410,6 +410,7 @@ struct nvme_ctrl {

	enum nvme_ctrl_type cntrltype;
	enum nvme_dctype dctype;
	u16 awupf; /* 0's based value. */
};

static inline enum nvme_ctrl_state nvme_ctrl_state(struct nvme_ctrl *ctrl)
@@ -442,11 +443,11 @@ struct nvme_subsystem {
	u8			cmic;
	enum nvme_subsys_type	subtype;
	u16			vendor_id;
	u16			awupf;	/* 0's based awupf value. */
	struct ida		ns_ida;
#ifdef CONFIG_NVME_MULTIPATH
	enum nvme_iopolicy	iopolicy;
#endif
	u32			atomic_bs;
};

/*
Loading