Commit 7503345a authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'block-6.13-20241207' of git://git.kernel.dk/linux

Pull block fixes from Jens Axboe:

 - NVMe pull request via Keith:
      - Target fix using incorrect zero buffer (Nilay)
      - Device specifc deallocate quirk fixes (Christoph, Keith)
      - Fabrics fix for handling max command target bugs (Maurizio)
      - Cocci fix usage for kzalloc (Yu-Chen)
      - DMA size fix for host memory buffer feature (Christoph)
      - Fabrics queue cleanup fixes (Chunguang)

 - CPU hotplug ordering fixes

 - Add missing MODULE_DESCRIPTION for rnull

 - bcache error value fix

 - virtio-blk queue freeze fix

* tag 'block-6.13-20241207' of git://git.kernel.dk/linux:
  blk-mq: move cpuhp callback registering out of q->sysfs_lock
  blk-mq: register cpuhp callback after hctx is added to xarray table
  virtio-blk: don't keep queue frozen during system suspend
  nvme-tcp: simplify nvme_tcp_teardown_io_queues()
  nvme-tcp: no need to quiesce admin_q in nvme_tcp_teardown_io_queues()
  nvme-rdma: unquiesce admin_q before destroy it
  nvme-tcp: fix the memleak while create new ctrl failed
  nvme-pci: don't use dma_alloc_noncontiguous with 0 merge boundary
  nvmet: replace kmalloc + memset with kzalloc for data allocation
  nvme-fabrics: handle zero MAXCMD without closing the connection
  bcache: revert replacing IS_ERR_OR_NULL with IS_ERR again
  nvme-pci: remove two deallocate zeroes quirks
  block: rnull: add missing MODULE_DESCRIPTION
  nvme: don't apply NVME_QUIRK_DEALLOCATE_ZEROES when DSM is not supported
  nvmet: use kzalloc instead of ZERO_PAGE in nvme_execute_identify_ns_nvm()
parents aa0274d2 22465bba
Loading
Loading
Loading
Loading
+94 −14
Original line number Diff line number Diff line
@@ -43,6 +43,7 @@

static DEFINE_PER_CPU(struct llist_head, blk_cpu_done);
static DEFINE_PER_CPU(call_single_data_t, blk_cpu_csd);
static DEFINE_MUTEX(blk_mq_cpuhp_lock);

static void blk_mq_insert_request(struct request *rq, blk_insert_t flags);
static void blk_mq_request_bypass_insert(struct request *rq,
@@ -3739,13 +3740,91 @@ static int blk_mq_hctx_notify_dead(unsigned int cpu, struct hlist_node *node)
	return 0;
}

static void blk_mq_remove_cpuhp(struct blk_mq_hw_ctx *hctx)
static void __blk_mq_remove_cpuhp(struct blk_mq_hw_ctx *hctx)
{
	if (!(hctx->flags & BLK_MQ_F_STACKING))
	lockdep_assert_held(&blk_mq_cpuhp_lock);

	if (!(hctx->flags & BLK_MQ_F_STACKING) &&
	    !hlist_unhashed(&hctx->cpuhp_online)) {
		cpuhp_state_remove_instance_nocalls(CPUHP_AP_BLK_MQ_ONLINE,
						    &hctx->cpuhp_online);
		INIT_HLIST_NODE(&hctx->cpuhp_online);
	}

	if (!hlist_unhashed(&hctx->cpuhp_dead)) {
		cpuhp_state_remove_instance_nocalls(CPUHP_BLK_MQ_DEAD,
						    &hctx->cpuhp_dead);
		INIT_HLIST_NODE(&hctx->cpuhp_dead);
	}
}

static void blk_mq_remove_cpuhp(struct blk_mq_hw_ctx *hctx)
{
	mutex_lock(&blk_mq_cpuhp_lock);
	__blk_mq_remove_cpuhp(hctx);
	mutex_unlock(&blk_mq_cpuhp_lock);
}

static void __blk_mq_add_cpuhp(struct blk_mq_hw_ctx *hctx)
{
	lockdep_assert_held(&blk_mq_cpuhp_lock);

	if (!(hctx->flags & BLK_MQ_F_STACKING) &&
	    hlist_unhashed(&hctx->cpuhp_online))
		cpuhp_state_add_instance_nocalls(CPUHP_AP_BLK_MQ_ONLINE,
				&hctx->cpuhp_online);

	if (hlist_unhashed(&hctx->cpuhp_dead))
		cpuhp_state_add_instance_nocalls(CPUHP_BLK_MQ_DEAD,
				&hctx->cpuhp_dead);
}

static void __blk_mq_remove_cpuhp_list(struct list_head *head)
{
	struct blk_mq_hw_ctx *hctx;

	lockdep_assert_held(&blk_mq_cpuhp_lock);

	list_for_each_entry(hctx, head, hctx_list)
		__blk_mq_remove_cpuhp(hctx);
}

/*
 * Unregister cpuhp callbacks from exited hw queues
 *
 * Safe to call if this `request_queue` is live
 */
static void blk_mq_remove_hw_queues_cpuhp(struct request_queue *q)
{
	LIST_HEAD(hctx_list);

	spin_lock(&q->unused_hctx_lock);
	list_splice_init(&q->unused_hctx_list, &hctx_list);
	spin_unlock(&q->unused_hctx_lock);

	mutex_lock(&blk_mq_cpuhp_lock);
	__blk_mq_remove_cpuhp_list(&hctx_list);
	mutex_unlock(&blk_mq_cpuhp_lock);

	spin_lock(&q->unused_hctx_lock);
	list_splice(&hctx_list, &q->unused_hctx_list);
	spin_unlock(&q->unused_hctx_lock);
}

/*
 * Register cpuhp callbacks from all hw queues
 *
 * Safe to call if this `request_queue` is live
 */
static void blk_mq_add_hw_queues_cpuhp(struct request_queue *q)
{
	struct blk_mq_hw_ctx *hctx;
	unsigned long i;

	mutex_lock(&blk_mq_cpuhp_lock);
	queue_for_each_hw_ctx(q, hctx, i)
		__blk_mq_add_cpuhp(hctx);
	mutex_unlock(&blk_mq_cpuhp_lock);
}

/*
@@ -3796,8 +3875,6 @@ static void blk_mq_exit_hctx(struct request_queue *q,
	if (set->ops->exit_hctx)
		set->ops->exit_hctx(hctx, hctx_idx);

	blk_mq_remove_cpuhp(hctx);

	xa_erase(&q->hctx_table, hctx_idx);

	spin_lock(&q->unused_hctx_lock);
@@ -3814,6 +3891,7 @@ static void blk_mq_exit_hw_queues(struct request_queue *q,
	queue_for_each_hw_ctx(q, hctx, i) {
		if (i == nr_queue)
			break;
		blk_mq_remove_cpuhp(hctx);
		blk_mq_exit_hctx(q, set, hctx, i);
	}
}
@@ -3824,16 +3902,11 @@ static int blk_mq_init_hctx(struct request_queue *q,
{
	hctx->queue_num = hctx_idx;

	if (!(hctx->flags & BLK_MQ_F_STACKING))
		cpuhp_state_add_instance_nocalls(CPUHP_AP_BLK_MQ_ONLINE,
				&hctx->cpuhp_online);
	cpuhp_state_add_instance_nocalls(CPUHP_BLK_MQ_DEAD, &hctx->cpuhp_dead);

	hctx->tags = set->tags[hctx_idx];

	if (set->ops->init_hctx &&
	    set->ops->init_hctx(hctx, set->driver_data, hctx_idx))
		goto unregister_cpu_notifier;
		goto fail;

	if (blk_mq_init_request(set, hctx->fq->flush_rq, hctx_idx,
				hctx->numa_node))
@@ -3850,8 +3923,7 @@ static int blk_mq_init_hctx(struct request_queue *q,
 exit_hctx:
	if (set->ops->exit_hctx)
		set->ops->exit_hctx(hctx, hctx_idx);
 unregister_cpu_notifier:
	blk_mq_remove_cpuhp(hctx);
 fail:
	return -1;
}

@@ -3877,6 +3949,8 @@ blk_mq_alloc_hctx(struct request_queue *q, struct blk_mq_tag_set *set,
	INIT_DELAYED_WORK(&hctx->run_work, blk_mq_run_work_fn);
	spin_lock_init(&hctx->lock);
	INIT_LIST_HEAD(&hctx->dispatch);
	INIT_HLIST_NODE(&hctx->cpuhp_dead);
	INIT_HLIST_NODE(&hctx->cpuhp_online);
	hctx->queue = q;
	hctx->flags = set->flags & ~BLK_MQ_F_TAG_QUEUE_SHARED;

@@ -4415,6 +4489,12 @@ 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);
	mutex_unlock(&q->sysfs_lock);

	/* unregister cpuhp callbacks for exited hctxs */
	blk_mq_remove_hw_queues_cpuhp(q);

	/* register cpuhp for new initialized hctxs */
	blk_mq_add_hw_queues_cpuhp(q);
}

int blk_mq_init_allocated_queue(struct blk_mq_tag_set *set,
+1 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@
    type: NullBlkModule,
    name: "rnull_mod",
    author: "Andreas Hindborg",
    description: "Rust implementation of the C null block driver",
    license: "GPL v2",
}

+5 −2
Original line number Diff line number Diff line
@@ -1586,9 +1586,12 @@ static void virtblk_remove(struct virtio_device *vdev)
static int virtblk_freeze(struct virtio_device *vdev)
{
	struct virtio_blk *vblk = vdev->priv;
	struct request_queue *q = vblk->disk->queue;

	/* Ensure no requests in virtqueues before deleting vqs. */
	blk_mq_freeze_queue(vblk->disk->queue);
	blk_mq_freeze_queue(q);
	blk_mq_quiesce_queue_nowait(q);
	blk_mq_unfreeze_queue(q);

	/* Ensure we don't receive any more interrupts */
	virtio_reset_device(vdev);
@@ -1612,8 +1615,8 @@ static int virtblk_restore(struct virtio_device *vdev)
		return ret;

	virtio_device_ready(vdev);
	blk_mq_unquiesce_queue(vblk->disk->queue);

	blk_mq_unfreeze_queue(vblk->disk->queue);
	return 0;
}
#endif
+1 −1
Original line number Diff line number Diff line
@@ -1718,7 +1718,7 @@ static CLOSURE_CALLBACK(cache_set_flush)
	if (!IS_ERR_OR_NULL(c->gc_thread))
		kthread_stop(c->gc_thread);

	if (!IS_ERR(c->root))
	if (!IS_ERR_OR_NULL(c->root))
		list_add(&c->root->list, &c->btree_cache);

	/*
+5 −3
Original line number Diff line number Diff line
@@ -2071,7 +2071,8 @@ static bool nvme_update_disk_info(struct nvme_ns *ns, struct nvme_id_ns *id,
	lim->physical_block_size = min(phys_bs, atomic_bs);
	lim->io_min = phys_bs;
	lim->io_opt = io_opt;
	if (ns->ctrl->quirks & NVME_QUIRK_DEALLOCATE_ZEROES)
	if ((ns->ctrl->quirks & NVME_QUIRK_DEALLOCATE_ZEROES) &&
	    (ns->ctrl->oncs & NVME_CTRL_ONCS_DSM))
		lim->max_write_zeroes_sectors = UINT_MAX;
	else
		lim->max_write_zeroes_sectors = ns->ctrl->max_zeroes_sectors;
@@ -3260,8 +3261,9 @@ static int nvme_check_ctrl_fabric_info(struct nvme_ctrl *ctrl, struct nvme_id_ct
	}

	if (!ctrl->maxcmd) {
		dev_err(ctrl->device, "Maximum outstanding commands is 0\n");
		return -EINVAL;
		dev_warn(ctrl->device,
			"Firmware bug: maximum outstanding commands is 0\n");
		ctrl->maxcmd = ctrl->sqsize + 1;
	}

	return 0;
Loading