mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-16 01:54:00 +00:00
block-6.13-20241220
-----BEGIN PGP SIGNATURE----- iQJEBAABCAAuFiEEwPw5LcreJtl1+l5K99NY+ylx4KYFAmdllisQHGF4Ym9lQGtl cm5lbC5kawAKCRD301j7KXHgpuq9D/9oe41A1qmeQ9PoiMpMh0wwBiY6hWQJLplk Z9R+vKuGYUjySkflax2JPQqlO+tJrF8f7ywEDnb9hfFHCFGVEelF3jNORhZIS2YT b1V76Tv0wnDenuXcSeF2HSqkUTjuyGO4uGLuLv51yj+Tfo6ZyPcZ3rWYXI3jev6e NVgHPxg4m0KCSDsCCxeNHfGV8en2VeMItZ0TIhqsYXfmIWrrSvVlMmIDxSQtIRyx tQGNS2oO5CH5B5CDOl9HtnEfJNVnbsfvM4j2VI6XNGOXINWYwabOLftpUzepWh32 MUX8kr1AdkgA0559+TI7KrUqNk5Y7wztKn30EvJD4AHS0hFapxP8w7BrbrPbmT2X C6mLAqHKfMeKrgVTnvGJL+SQZUJnGyVi++NCnZ4dsrUbdM3XTzwNw8YqneSnNXHO jFIql2eHvvPAb47xMk7UCdmObWbtOfWvGiK5qPH9kDirIQ3CllpTOadOBdK23mBg clxmhwoEVhOCdcOG8svT/0ai9ew8qhCtAE+dOnTE46qUumX1OJjDaYu8X7xvADzC YXYae6DbA46BjE0OWEwRxrNVS5lJIJzTiNBnVE6kc1Q9FLa1yv9SCqgxgnpTOCnY 7JEw+tgwbDt3fE1eilchyafC+/AoBlgR8pWUOEefEQMuv9OJCeUHlIESaSXgtCKi efHvwzAXiA== =0RHC -----END PGP SIGNATURE----- Merge tag 'block-6.13-20241220' of git://git.kernel.dk/linux Pull block fixes from Jens Axboe: - Minor cleanups for bdev/nvme using the helpers introduced - Revert of a deadlock fix that still needs more work - Fix a UAF of hctx in the cpu hotplug code * tag 'block-6.13-20241220' of git://git.kernel.dk/linux: block: avoid to reuse `hctx` not removed from cpuhp callback list block: Revert "block: Fix potential deadlock while freezing queue and acquiring sysfs_lock" nvme: use blk_validate_block_size() for max LBA check block/bdev: use helper for max block size check
This commit is contained in:
commit
11167b29e5
@ -155,8 +155,7 @@ int set_blocksize(struct file *file, int size)
|
||||
struct inode *inode = file->f_mapping->host;
|
||||
struct block_device *bdev = I_BDEV(inode);
|
||||
|
||||
/* Size must be a power of two, and between 512 and PAGE_SIZE */
|
||||
if (size > PAGE_SIZE || size < 512 || !is_power_of_2(size))
|
||||
if (blk_validate_block_size(size))
|
||||
return -EINVAL;
|
||||
|
||||
/* Size cannot be smaller than the size supported by the device */
|
||||
|
@ -275,13 +275,15 @@ void blk_mq_sysfs_unregister_hctxs(struct request_queue *q)
|
||||
struct blk_mq_hw_ctx *hctx;
|
||||
unsigned long i;
|
||||
|
||||
lockdep_assert_held(&q->sysfs_dir_lock);
|
||||
|
||||
mutex_lock(&q->sysfs_dir_lock);
|
||||
if (!q->mq_sysfs_init_done)
|
||||
return;
|
||||
goto unlock;
|
||||
|
||||
queue_for_each_hw_ctx(q, hctx, i)
|
||||
blk_mq_unregister_hctx(hctx);
|
||||
|
||||
unlock:
|
||||
mutex_unlock(&q->sysfs_dir_lock);
|
||||
}
|
||||
|
||||
int blk_mq_sysfs_register_hctxs(struct request_queue *q)
|
||||
@ -290,10 +292,9 @@ int blk_mq_sysfs_register_hctxs(struct request_queue *q)
|
||||
unsigned long i;
|
||||
int ret = 0;
|
||||
|
||||
lockdep_assert_held(&q->sysfs_dir_lock);
|
||||
|
||||
mutex_lock(&q->sysfs_dir_lock);
|
||||
if (!q->mq_sysfs_init_done)
|
||||
return ret;
|
||||
goto unlock;
|
||||
|
||||
queue_for_each_hw_ctx(q, hctx, i) {
|
||||
ret = blk_mq_register_hctx(hctx);
|
||||
@ -301,5 +302,8 @@ int blk_mq_sysfs_register_hctxs(struct request_queue *q)
|
||||
break;
|
||||
}
|
||||
|
||||
unlock:
|
||||
mutex_unlock(&q->sysfs_dir_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -4412,6 +4412,15 @@ struct gendisk *blk_mq_alloc_disk_for_queue(struct request_queue *q,
|
||||
}
|
||||
EXPORT_SYMBOL(blk_mq_alloc_disk_for_queue);
|
||||
|
||||
/*
|
||||
* Only hctx removed from cpuhp list can be reused
|
||||
*/
|
||||
static bool blk_mq_hctx_is_reusable(struct blk_mq_hw_ctx *hctx)
|
||||
{
|
||||
return hlist_unhashed(&hctx->cpuhp_online) &&
|
||||
hlist_unhashed(&hctx->cpuhp_dead);
|
||||
}
|
||||
|
||||
static struct blk_mq_hw_ctx *blk_mq_alloc_and_init_hctx(
|
||||
struct blk_mq_tag_set *set, struct request_queue *q,
|
||||
int hctx_idx, int node)
|
||||
@ -4421,7 +4430,7 @@ static struct blk_mq_hw_ctx *blk_mq_alloc_and_init_hctx(
|
||||
/* reuse dead hctx first */
|
||||
spin_lock(&q->unused_hctx_lock);
|
||||
list_for_each_entry(tmp, &q->unused_hctx_list, hctx_list) {
|
||||
if (tmp->numa_node == node) {
|
||||
if (tmp->numa_node == node && blk_mq_hctx_is_reusable(tmp)) {
|
||||
hctx = tmp;
|
||||
break;
|
||||
}
|
||||
@ -4453,8 +4462,7 @@ static void blk_mq_realloc_hw_ctxs(struct blk_mq_tag_set *set,
|
||||
unsigned long i, j;
|
||||
|
||||
/* protect against switching io scheduler */
|
||||
lockdep_assert_held(&q->sysfs_lock);
|
||||
|
||||
mutex_lock(&q->sysfs_lock);
|
||||
for (i = 0; i < set->nr_hw_queues; i++) {
|
||||
int old_node;
|
||||
int node = blk_mq_get_hctx_node(set, i);
|
||||
@ -4487,6 +4495,7 @@ 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);
|
||||
@ -4518,14 +4527,10 @@ int blk_mq_init_allocated_queue(struct blk_mq_tag_set *set,
|
||||
|
||||
xa_init(&q->hctx_table);
|
||||
|
||||
mutex_lock(&q->sysfs_lock);
|
||||
|
||||
blk_mq_realloc_hw_ctxs(set, q);
|
||||
if (!q->nr_hw_queues)
|
||||
goto err_hctxs;
|
||||
|
||||
mutex_unlock(&q->sysfs_lock);
|
||||
|
||||
INIT_WORK(&q->timeout_work, blk_mq_timeout_work);
|
||||
blk_queue_rq_timeout(q, set->timeout ? set->timeout : 30 * HZ);
|
||||
|
||||
@ -4544,7 +4549,6 @@ int blk_mq_init_allocated_queue(struct blk_mq_tag_set *set,
|
||||
return 0;
|
||||
|
||||
err_hctxs:
|
||||
mutex_unlock(&q->sysfs_lock);
|
||||
blk_mq_release(q);
|
||||
err_exit:
|
||||
q->mq_ops = NULL;
|
||||
@ -4925,12 +4929,12 @@ static bool blk_mq_elv_switch_none(struct list_head *head,
|
||||
return false;
|
||||
|
||||
/* q->elevator needs protection from ->sysfs_lock */
|
||||
lockdep_assert_held(&q->sysfs_lock);
|
||||
mutex_lock(&q->sysfs_lock);
|
||||
|
||||
/* the check has to be done with holding sysfs_lock */
|
||||
if (!q->elevator) {
|
||||
kfree(qe);
|
||||
goto out;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&qe->node);
|
||||
@ -4940,7 +4944,9 @@ static bool blk_mq_elv_switch_none(struct list_head *head,
|
||||
__elevator_get(qe->type);
|
||||
list_add(&qe->node, head);
|
||||
elevator_disable(q);
|
||||
out:
|
||||
unlock:
|
||||
mutex_unlock(&q->sysfs_lock);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -4969,9 +4975,11 @@ static void blk_mq_elv_switch_back(struct list_head *head,
|
||||
list_del(&qe->node);
|
||||
kfree(qe);
|
||||
|
||||
mutex_lock(&q->sysfs_lock);
|
||||
elevator_switch(q, t);
|
||||
/* drop the reference acquired in blk_mq_elv_switch_none */
|
||||
elevator_put(t);
|
||||
mutex_unlock(&q->sysfs_lock);
|
||||
}
|
||||
|
||||
static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set,
|
||||
@ -4991,11 +4999,8 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set,
|
||||
if (set->nr_maps == 1 && nr_hw_queues == set->nr_hw_queues)
|
||||
return;
|
||||
|
||||
list_for_each_entry(q, &set->tag_list, tag_set_list) {
|
||||
mutex_lock(&q->sysfs_dir_lock);
|
||||
mutex_lock(&q->sysfs_lock);
|
||||
list_for_each_entry(q, &set->tag_list, tag_set_list)
|
||||
blk_mq_freeze_queue(q);
|
||||
}
|
||||
/*
|
||||
* Switch IO scheduler to 'none', cleaning up the data associated
|
||||
* with the previous scheduler. We will switch back once we are done
|
||||
@ -5051,11 +5056,8 @@ switch_back:
|
||||
list_for_each_entry(q, &set->tag_list, tag_set_list)
|
||||
blk_mq_elv_switch_back(&head, q);
|
||||
|
||||
list_for_each_entry(q, &set->tag_list, tag_set_list) {
|
||||
list_for_each_entry(q, &set->tag_list, tag_set_list)
|
||||
blk_mq_unfreeze_queue(q);
|
||||
mutex_unlock(&q->sysfs_lock);
|
||||
mutex_unlock(&q->sysfs_dir_lock);
|
||||
}
|
||||
|
||||
/* Free the excess tags when nr_hw_queues shrink. */
|
||||
for (i = set->nr_hw_queues; i < prev_nr_hw_queues; i++)
|
||||
|
@ -706,11 +706,11 @@ queue_attr_store(struct kobject *kobj, struct attribute *attr,
|
||||
if (entry->load_module)
|
||||
entry->load_module(disk, page, length);
|
||||
|
||||
mutex_lock(&q->sysfs_lock);
|
||||
blk_mq_freeze_queue(q);
|
||||
mutex_lock(&q->sysfs_lock);
|
||||
res = entry->store(disk, page, length);
|
||||
blk_mq_unfreeze_queue(q);
|
||||
mutex_unlock(&q->sysfs_lock);
|
||||
blk_mq_unfreeze_queue(q);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -2034,7 +2034,7 @@ static bool nvme_update_disk_info(struct nvme_ns *ns, struct nvme_id_ns *id,
|
||||
* or smaller than a sector size yet, so catch this early and don't
|
||||
* allow block I/O.
|
||||
*/
|
||||
if (head->lba_shift > PAGE_SHIFT || head->lba_shift < SECTOR_SHIFT) {
|
||||
if (blk_validate_block_size(bs)) {
|
||||
bs = (1 << 9);
|
||||
valid = false;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user