Commit 949dd321 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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

Pull more block updates from Jens Axboe:

 - NVMe pull request via Keith:
      - PCI endpoint target cleanup (Damien)
      - Early import for uring_cmd fixed buffer (Caleb)
      - Multipath documentation and notification improvements (John)
      - Invalid pci sq doorbell write fix (Maurizio)

 - Queue init locking fix

 - Remove dead nsegs parameter from blk_mq_get_new_requests()

* tag 'block-6.15-20250403' of git://git.kernel.dk/linux:
  block: don't grab elevator lock during queue initialization
  nvme-pci: skip nvme_write_sq_db on empty rqlist
  nvme-multipath: change the NVME_MULTIPATH config option
  nvme: update the multipath warning in nvme_init_ns_head
  nvme/ioctl: move fixed buffer lookup to nvme_uring_cmd_io()
  nvme/ioctl: move blk_mq_free_request() out of nvme_map_user_request()
  nvme/ioctl: don't warn on vectorized uring_cmd with fixed buffer
  nvmet: pci-epf: Keep completion queues mapped
  block: remove unused nseg parameter
parents 7930edcc 01b91bf1
Loading
Loading
Loading
Loading
+19 −10
Original line number Diff line number Diff line
@@ -2965,8 +2965,7 @@ static bool blk_mq_attempt_bio_merge(struct request_queue *q,

static struct request *blk_mq_get_new_requests(struct request_queue *q,
					       struct blk_plug *plug,
					       struct bio *bio,
					       unsigned int nsegs)
					       struct bio *bio)
{
	struct blk_mq_alloc_data data = {
		.q		= q,
@@ -3125,7 +3124,7 @@ void blk_mq_submit_bio(struct bio *bio)
	if (rq) {
		blk_mq_use_cached_rq(rq, plug, bio);
	} else {
		rq = blk_mq_get_new_requests(q, plug, bio, nr_segs);
		rq = blk_mq_get_new_requests(q, plug, bio);
		if (unlikely(!rq)) {
			if (bio->bi_opf & REQ_NOWAIT)
				bio_wouldblock_error(bio);
@@ -4465,14 +4464,12 @@ static struct blk_mq_hw_ctx *blk_mq_alloc_and_init_hctx(
	return NULL;
}

static void blk_mq_realloc_hw_ctxs(struct blk_mq_tag_set *set,
static void __blk_mq_realloc_hw_ctxs(struct blk_mq_tag_set *set,
				     struct request_queue *q)
{
	struct blk_mq_hw_ctx *hctx;
	unsigned long i, j;

	/* protect against switching io scheduler  */
	mutex_lock(&q->elevator_lock);
	for (i = 0; i < set->nr_hw_queues; i++) {
		int old_node;
		int node = blk_mq_get_hctx_node(set, i);
@@ -4505,7 +4502,19 @@ static void blk_mq_realloc_hw_ctxs(struct blk_mq_tag_set *set,

	xa_for_each_start(&q->hctx_table, j, hctx, j)
		blk_mq_exit_hctx(q, set, hctx, j);
}

static void blk_mq_realloc_hw_ctxs(struct blk_mq_tag_set *set,
				   struct request_queue *q, bool lock)
{
	if (lock) {
		/* protect against switching io scheduler  */
		mutex_lock(&q->elevator_lock);
		__blk_mq_realloc_hw_ctxs(set, q);
		mutex_unlock(&q->elevator_lock);
	} else {
		__blk_mq_realloc_hw_ctxs(set, q);
	}

	/* unregister cpuhp callbacks for exited hctxs */
	blk_mq_remove_hw_queues_cpuhp(q);
@@ -4537,7 +4546,7 @@ int blk_mq_init_allocated_queue(struct blk_mq_tag_set *set,

	xa_init(&q->hctx_table);

	blk_mq_realloc_hw_ctxs(set, q);
	blk_mq_realloc_hw_ctxs(set, q, false);
	if (!q->nr_hw_queues)
		goto err_hctxs;

@@ -5033,7 +5042,7 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set,
fallback:
	blk_mq_update_queue_map(set);
	list_for_each_entry(q, &set->tag_list, tag_set_list) {
		blk_mq_realloc_hw_ctxs(set, q);
		blk_mq_realloc_hw_ctxs(set, q, true);

		if (q->nr_hw_queues != set->nr_hw_queues) {
			int i = prev_nr_hw_queues;
+9 −4
Original line number Diff line number Diff line
@@ -18,10 +18,15 @@ config NVME_MULTIPATH
	bool "NVMe multipath support"
	depends on NVME_CORE
	help
	   This option enables support for multipath access to NVMe
	   subsystems.  If this option is enabled only a single
	   /dev/nvmeXnY device will show up for each NVMe namespace,
	   even if it is accessible through multiple controllers.
	  This option controls support for multipath access to NVMe
	  subsystems. If this option is enabled support for NVMe multipath
	  access is included in the kernel. If this option is disabled support
	  for NVMe multipath access is excluded from the kernel. When this
	  option is disabled each controller/namespace receives its
	  own /dev/nvmeXnY device entry and NVMe multipath access is
	  not supported.

	  If unsure, say Y.

config NVME_VERBOSE_ERRORS
	bool "NVMe verbose error reporting"
+1 −1
Original line number Diff line number Diff line
@@ -3822,7 +3822,7 @@ static int nvme_init_ns_head(struct nvme_ns *ns, struct nvme_ns_info *info)
				"Found shared namespace %d, but multipathing not supported.\n",
				info->nsid);
			dev_warn_once(ctrl->device,
				"Support for shared namespaces without CONFIG_NVME_MULTIPATH is deprecated and will be removed in Linux 6.0.\n");
				"Shared namespace support requires core_nvme.multipath=Y.\n");
		}
	}

+37 −31
Original line number Diff line number Diff line
@@ -114,8 +114,7 @@ static struct request *nvme_alloc_user_request(struct request_queue *q,

static int nvme_map_user_request(struct request *req, u64 ubuffer,
		unsigned bufflen, void __user *meta_buffer, unsigned meta_len,
		struct io_uring_cmd *ioucmd, unsigned int flags,
		unsigned int iou_issue_flags)
		struct iov_iter *iter, unsigned int flags)
{
	struct request_queue *q = req->q;
	struct nvme_ns *ns = q->queuedata;
@@ -129,37 +128,23 @@ static int nvme_map_user_request(struct request *req, u64 ubuffer,
	if (!nvme_ctrl_sgl_supported(ctrl))
		dev_warn_once(ctrl->device, "using unchecked data buffer\n");
	if (has_metadata) {
		if (!supports_metadata) {
			ret = -EINVAL;
			goto out;
		}
		if (!supports_metadata)
			return -EINVAL;

		if (!nvme_ctrl_meta_sgl_supported(ctrl))
			dev_warn_once(ctrl->device,
				      "using unchecked metadata buffer\n");
	}

	if (ioucmd && (ioucmd->flags & IORING_URING_CMD_FIXED)) {
		struct iov_iter iter;

		/* fixedbufs is only for non-vectored io */
		if (WARN_ON_ONCE(flags & NVME_IOCTL_VEC)) {
			ret = -EINVAL;
			goto out;
		}
		ret = io_uring_cmd_import_fixed(ubuffer, bufflen,
				rq_data_dir(req), &iter, ioucmd,
				iou_issue_flags);
		if (ret < 0)
			goto out;
		ret = blk_rq_map_user_iov(q, req, NULL, &iter, GFP_KERNEL);
	} else {
	if (iter)
		ret = blk_rq_map_user_iov(q, req, NULL, iter, GFP_KERNEL);
	else
		ret = blk_rq_map_user_io(req, NULL, nvme_to_user_ptr(ubuffer),
				bufflen, GFP_KERNEL, flags & NVME_IOCTL_VEC, 0,
				0, rq_data_dir(req));
	}

	if (ret)
		goto out;
		return ret;

	bio = req->bio;
	if (bdev)
@@ -176,8 +161,6 @@ static int nvme_map_user_request(struct request *req, u64 ubuffer,
out_unmap:
	if (bio)
		blk_rq_unmap_user(bio);
out:
	blk_mq_free_request(req);
	return ret;
}

@@ -200,9 +183,9 @@ static int nvme_submit_user_cmd(struct request_queue *q,
	req->timeout = timeout;
	if (ubuffer && bufflen) {
		ret = nvme_map_user_request(req, ubuffer, bufflen, meta_buffer,
				meta_len, NULL, flags, 0);
				meta_len, NULL, flags);
		if (ret)
			return ret;
			goto out_free_req;
	}

	bio = req->bio;
@@ -218,7 +201,10 @@ static int nvme_submit_user_cmd(struct request_queue *q,

	if (effects)
		nvme_passthru_end(ctrl, ns, effects, cmd, ret);
	return ret;

out_free_req:
	blk_mq_free_request(req);
	return ret;
}

@@ -469,6 +455,8 @@ static int nvme_uring_cmd_io(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
	struct request_queue *q = ns ? ns->queue : ctrl->admin_q;
	struct nvme_uring_data d;
	struct nvme_command c;
	struct iov_iter iter;
	struct iov_iter *map_iter = NULL;
	struct request *req;
	blk_opf_t rq_flags = REQ_ALLOC_CACHE;
	blk_mq_req_flags_t blk_flags = 0;
@@ -504,6 +492,20 @@ static int nvme_uring_cmd_io(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
	d.metadata_len = READ_ONCE(cmd->metadata_len);
	d.timeout_ms = READ_ONCE(cmd->timeout_ms);

	if (d.data_len && (ioucmd->flags & IORING_URING_CMD_FIXED)) {
		/* fixedbufs is only for non-vectored io */
		if (vec)
			return -EINVAL;

		ret = io_uring_cmd_import_fixed(d.addr, d.data_len,
			nvme_is_write(&c) ? WRITE : READ, &iter, ioucmd,
			issue_flags);
		if (ret < 0)
			return ret;

		map_iter = &iter;
	}

	if (issue_flags & IO_URING_F_NONBLOCK) {
		rq_flags |= REQ_NOWAIT;
		blk_flags = BLK_MQ_REQ_NOWAIT;
@@ -517,11 +519,11 @@ static int nvme_uring_cmd_io(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
	req->timeout = d.timeout_ms ? msecs_to_jiffies(d.timeout_ms) : 0;

	if (d.data_len) {
		ret = nvme_map_user_request(req, d.addr,
			d.data_len, nvme_to_user_ptr(d.metadata),
			d.metadata_len, ioucmd, vec, issue_flags);
		ret = nvme_map_user_request(req, d.addr, d.data_len,
			nvme_to_user_ptr(d.metadata), d.metadata_len,
			map_iter, vec);
		if (ret)
			return ret;
			goto out_free_req;
	}

	/* to free bio on completion, as req->bio will be null at that time */
@@ -531,6 +533,10 @@ static int nvme_uring_cmd_io(struct nvme_ctrl *ctrl, struct nvme_ns *ns,
	req->end_io = nvme_uring_cmd_end_io;
	blk_execute_rq_nowait(req, false);
	return -EIOCBQUEUED;

out_free_req:
	blk_mq_free_request(req);
	return ret;
}

static bool is_ctrl_ioctl(unsigned int cmd)
+3 −0
Original line number Diff line number Diff line
@@ -986,6 +986,9 @@ static void nvme_submit_cmds(struct nvme_queue *nvmeq, struct rq_list *rqlist)
{
	struct request *req;

	if (rq_list_empty(rqlist))
		return;

	spin_lock(&nvmeq->sq_lock);
	while ((req = rq_list_pop(rqlist))) {
		struct nvme_iod *iod = blk_mq_rq_to_pdu(req);
Loading