Skip to content

Commit

Permalink
Merge tag 'block-6.14-20250131' of git://git.kernel.dk/linux
Browse files Browse the repository at this point in the history
Pull more block updates from Jens Axboe:

 - MD pull request via Song:
      - Fix a md-cluster regression introduced

 - More sysfs race fixes

 - Mark anything inside queue freezing as not being able to do IO for
   memory allocations

 - Fix for a regression introduced in loop in this merge window

 - Fix for a regression in queue mapping setups introduced in this merge
   window

 - Fix for the block dio fops attempting an iov_iter revert upton
   getting -EIOCBQUEUED on the read side. This one is going to stable as
   well

* tag 'block-6.14-20250131' of git://git.kernel.dk/linux:
  block: force noio scope in blk_mq_freeze_queue
  block: fix nr_hw_queue update racing with disk addition/removal
  block: get rid of request queue ->sysfs_dir_lock
  loop: don't clear LO_FLAGS_PARTSCAN on LOOP_SET_STATUS{,64}
  md/md-bitmap: Synchronize bitmap_get_stats() with bitmap lifetime
  blk-mq: create correct map for fallback case
  block: don't revert iter for -EIOCBQUEUED
  • Loading branch information
torvalds committed Jan 31, 2025
2 parents c82da38 + 1e1a9ce commit 9755ffd
Show file tree
Hide file tree
Showing 34 changed files with 164 additions and 130 deletions.
10 changes: 6 additions & 4 deletions block/blk-cgroup.c
Original file line number Diff line number Diff line change
Expand Up @@ -1546,6 +1546,7 @@ int blkcg_activate_policy(struct gendisk *disk, const struct blkcg_policy *pol)
struct request_queue *q = disk->queue;
struct blkg_policy_data *pd_prealloc = NULL;
struct blkcg_gq *blkg, *pinned_blkg = NULL;
unsigned int memflags;
int ret;

if (blkcg_policy_enabled(q, pol))
Expand All @@ -1560,7 +1561,7 @@ int blkcg_activate_policy(struct gendisk *disk, const struct blkcg_policy *pol)
return -EINVAL;

if (queue_is_mq(q))
blk_mq_freeze_queue(q);
memflags = blk_mq_freeze_queue(q);
retry:
spin_lock_irq(&q->queue_lock);

Expand Down Expand Up @@ -1624,7 +1625,7 @@ int blkcg_activate_policy(struct gendisk *disk, const struct blkcg_policy *pol)
spin_unlock_irq(&q->queue_lock);
out:
if (queue_is_mq(q))
blk_mq_unfreeze_queue(q);
blk_mq_unfreeze_queue(q, memflags);
if (pinned_blkg)
blkg_put(pinned_blkg);
if (pd_prealloc)
Expand Down Expand Up @@ -1668,12 +1669,13 @@ void blkcg_deactivate_policy(struct gendisk *disk,
{
struct request_queue *q = disk->queue;
struct blkcg_gq *blkg;
unsigned int memflags;

if (!blkcg_policy_enabled(q, pol))
return;

if (queue_is_mq(q))
blk_mq_freeze_queue(q);
memflags = blk_mq_freeze_queue(q);

mutex_lock(&q->blkcg_mutex);
spin_lock_irq(&q->queue_lock);
Expand All @@ -1697,7 +1699,7 @@ void blkcg_deactivate_policy(struct gendisk *disk,
mutex_unlock(&q->blkcg_mutex);

if (queue_is_mq(q))
blk_mq_unfreeze_queue(q);
blk_mq_unfreeze_queue(q, memflags);
}
EXPORT_SYMBOL_GPL(blkcg_deactivate_policy);

Expand Down
1 change: 0 additions & 1 deletion block/blk-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -430,7 +430,6 @@ struct request_queue *blk_alloc_queue(struct queue_limits *lim, int node_id)
refcount_set(&q->refs, 1);
mutex_init(&q->debugfs_mutex);
mutex_init(&q->sysfs_lock);
mutex_init(&q->sysfs_dir_lock);
mutex_init(&q->limits_lock);
mutex_init(&q->rq_qos_mutex);
spin_lock_init(&q->queue_lock);
Expand Down
4 changes: 0 additions & 4 deletions block/blk-ia-ranges.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,6 @@ int disk_register_independent_access_ranges(struct gendisk *disk)
struct request_queue *q = disk->queue;
int i, ret;

lockdep_assert_held(&q->sysfs_dir_lock);
lockdep_assert_held(&q->sysfs_lock);

if (!iars)
Expand Down Expand Up @@ -155,7 +154,6 @@ void disk_unregister_independent_access_ranges(struct gendisk *disk)
struct blk_independent_access_ranges *iars = disk->ia_ranges;
int i;

lockdep_assert_held(&q->sysfs_dir_lock);
lockdep_assert_held(&q->sysfs_lock);

if (!iars)
Expand Down Expand Up @@ -289,7 +287,6 @@ void disk_set_independent_access_ranges(struct gendisk *disk,
{
struct request_queue *q = disk->queue;

mutex_lock(&q->sysfs_dir_lock);
mutex_lock(&q->sysfs_lock);
if (iars && !disk_check_ia_ranges(disk, iars)) {
kfree(iars);
Expand All @@ -313,6 +310,5 @@ void disk_set_independent_access_ranges(struct gendisk *disk,
disk_register_independent_access_ranges(disk);
unlock:
mutex_unlock(&q->sysfs_lock);
mutex_unlock(&q->sysfs_dir_lock);
}
EXPORT_SYMBOL_GPL(disk_set_independent_access_ranges);
14 changes: 8 additions & 6 deletions block/blk-iocost.c
Original file line number Diff line number Diff line change
Expand Up @@ -3224,6 +3224,7 @@ static ssize_t ioc_qos_write(struct kernfs_open_file *of, char *input,
u32 qos[NR_QOS_PARAMS];
bool enable, user;
char *body, *p;
unsigned int memflags;
int ret;

blkg_conf_init(&ctx, input);
Expand All @@ -3247,7 +3248,7 @@ static ssize_t ioc_qos_write(struct kernfs_open_file *of, char *input,
ioc = q_to_ioc(disk->queue);
}

blk_mq_freeze_queue(disk->queue);
memflags = blk_mq_freeze_queue(disk->queue);
blk_mq_quiesce_queue(disk->queue);

spin_lock_irq(&ioc->lock);
Expand Down Expand Up @@ -3347,15 +3348,15 @@ static ssize_t ioc_qos_write(struct kernfs_open_file *of, char *input,
wbt_enable_default(disk);

blk_mq_unquiesce_queue(disk->queue);
blk_mq_unfreeze_queue(disk->queue);
blk_mq_unfreeze_queue(disk->queue, memflags);

blkg_conf_exit(&ctx);
return nbytes;
einval:
spin_unlock_irq(&ioc->lock);

blk_mq_unquiesce_queue(disk->queue);
blk_mq_unfreeze_queue(disk->queue);
blk_mq_unfreeze_queue(disk->queue, memflags);

ret = -EINVAL;
err:
Expand Down Expand Up @@ -3414,6 +3415,7 @@ static ssize_t ioc_cost_model_write(struct kernfs_open_file *of, char *input,
{
struct blkg_conf_ctx ctx;
struct request_queue *q;
unsigned int memflags;
struct ioc *ioc;
u64 u[NR_I_LCOEFS];
bool user;
Expand Down Expand Up @@ -3441,7 +3443,7 @@ static ssize_t ioc_cost_model_write(struct kernfs_open_file *of, char *input,
ioc = q_to_ioc(q);
}

blk_mq_freeze_queue(q);
memflags = blk_mq_freeze_queue(q);
blk_mq_quiesce_queue(q);

spin_lock_irq(&ioc->lock);
Expand Down Expand Up @@ -3493,7 +3495,7 @@ static ssize_t ioc_cost_model_write(struct kernfs_open_file *of, char *input,
spin_unlock_irq(&ioc->lock);

blk_mq_unquiesce_queue(q);
blk_mq_unfreeze_queue(q);
blk_mq_unfreeze_queue(q, memflags);

blkg_conf_exit(&ctx);
return nbytes;
Expand All @@ -3502,7 +3504,7 @@ static ssize_t ioc_cost_model_write(struct kernfs_open_file *of, char *input,
spin_unlock_irq(&ioc->lock);

blk_mq_unquiesce_queue(q);
blk_mq_unfreeze_queue(q);
blk_mq_unfreeze_queue(q, memflags);

ret = -EINVAL;
err:
Expand Down
6 changes: 4 additions & 2 deletions block/blk-iolatency.c
Original file line number Diff line number Diff line change
Expand Up @@ -749,9 +749,11 @@ static void blkiolatency_enable_work_fn(struct work_struct *work)
*/
enabled = atomic_read(&blkiolat->enable_cnt);
if (enabled != blkiolat->enabled) {
blk_mq_freeze_queue(blkiolat->rqos.disk->queue);
unsigned int memflags;

memflags = blk_mq_freeze_queue(blkiolat->rqos.disk->queue);
blkiolat->enabled = enabled;
blk_mq_unfreeze_queue(blkiolat->rqos.disk->queue);
blk_mq_unfreeze_queue(blkiolat->rqos.disk->queue, memflags);
}
}

Expand Down
3 changes: 1 addition & 2 deletions block/blk-mq-cpumap.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ void blk_mq_map_hw_queues(struct blk_mq_queue_map *qmap,
return;

fallback:
WARN_ON_ONCE(qmap->nr_queues > 1);
blk_mq_clear_mq_map(qmap);
blk_mq_map_queues(qmap);
}
EXPORT_SYMBOL_GPL(blk_mq_map_hw_queues);
40 changes: 14 additions & 26 deletions block/blk-mq-sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -223,30 +223,27 @@ int blk_mq_sysfs_register(struct gendisk *disk)
unsigned long i, j;
int ret;

lockdep_assert_held(&q->sysfs_dir_lock);

ret = kobject_add(q->mq_kobj, &disk_to_dev(disk)->kobj, "mq");
if (ret < 0)
goto out;
return ret;

kobject_uevent(q->mq_kobj, KOBJ_ADD);

mutex_lock(&q->tag_set->tag_list_lock);
queue_for_each_hw_ctx(q, hctx, i) {
ret = blk_mq_register_hctx(hctx);
if (ret)
goto unreg;
goto out_unreg;
}
mutex_unlock(&q->tag_set->tag_list_lock);
return 0;

q->mq_sysfs_init_done = true;

out:
return ret;

unreg:
out_unreg:
queue_for_each_hw_ctx(q, hctx, j) {
if (j < i)
blk_mq_unregister_hctx(hctx);
}
mutex_unlock(&q->tag_set->tag_list_lock);

kobject_uevent(q->mq_kobj, KOBJ_REMOVE);
kobject_del(q->mq_kobj);
Expand All @@ -259,31 +256,25 @@ void blk_mq_sysfs_unregister(struct gendisk *disk)
struct blk_mq_hw_ctx *hctx;
unsigned long i;

lockdep_assert_held(&q->sysfs_dir_lock);

mutex_lock(&q->tag_set->tag_list_lock);
queue_for_each_hw_ctx(q, hctx, i)
blk_mq_unregister_hctx(hctx);
mutex_unlock(&q->tag_set->tag_list_lock);

kobject_uevent(q->mq_kobj, KOBJ_REMOVE);
kobject_del(q->mq_kobj);

q->mq_sysfs_init_done = false;
}

void blk_mq_sysfs_unregister_hctxs(struct request_queue *q)
{
struct blk_mq_hw_ctx *hctx;
unsigned long i;

mutex_lock(&q->sysfs_dir_lock);
if (!q->mq_sysfs_init_done)
goto unlock;
if (!blk_queue_registered(q))
return;

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)
Expand All @@ -292,18 +283,15 @@ int blk_mq_sysfs_register_hctxs(struct request_queue *q)
unsigned long i;
int ret = 0;

mutex_lock(&q->sysfs_dir_lock);
if (!q->mq_sysfs_init_done)
goto unlock;
if (!blk_queue_registered(q))
goto out;

queue_for_each_hw_ctx(q, hctx, i) {
ret = blk_mq_register_hctx(hctx);
if (ret)
break;
}

unlock:
mutex_unlock(&q->sysfs_dir_lock);

out:
return ret;
}
21 changes: 13 additions & 8 deletions block/blk-mq.c
Original file line number Diff line number Diff line change
Expand Up @@ -210,12 +210,12 @@ int blk_mq_freeze_queue_wait_timeout(struct request_queue *q,
}
EXPORT_SYMBOL_GPL(blk_mq_freeze_queue_wait_timeout);

void blk_mq_freeze_queue(struct request_queue *q)
void blk_mq_freeze_queue_nomemsave(struct request_queue *q)
{
blk_freeze_queue_start(q);
blk_mq_freeze_queue_wait(q);
}
EXPORT_SYMBOL_GPL(blk_mq_freeze_queue);
EXPORT_SYMBOL_GPL(blk_mq_freeze_queue_nomemsave);

bool __blk_mq_unfreeze_queue(struct request_queue *q, bool force_atomic)
{
Expand All @@ -236,12 +236,12 @@ bool __blk_mq_unfreeze_queue(struct request_queue *q, bool force_atomic)
return unfreeze;
}

void blk_mq_unfreeze_queue(struct request_queue *q)
void blk_mq_unfreeze_queue_nomemrestore(struct request_queue *q)
{
if (__blk_mq_unfreeze_queue(q, false))
blk_unfreeze_release_lock(q);
}
EXPORT_SYMBOL_GPL(blk_mq_unfreeze_queue);
EXPORT_SYMBOL_GPL(blk_mq_unfreeze_queue_nomemrestore);

/*
* non_owner variant of blk_freeze_queue_start
Expand Down Expand Up @@ -4223,13 +4223,14 @@ static void blk_mq_update_tag_set_shared(struct blk_mq_tag_set *set,
bool shared)
{
struct request_queue *q;
unsigned int memflags;

lockdep_assert_held(&set->tag_list_lock);

list_for_each_entry(q, &set->tag_list, tag_set_list) {
blk_mq_freeze_queue(q);
memflags = blk_mq_freeze_queue(q);
queue_set_hctx_shared(q, shared);
blk_mq_unfreeze_queue(q);
blk_mq_unfreeze_queue(q, memflags);
}
}

Expand Down Expand Up @@ -4992,6 +4993,7 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set,
struct request_queue *q;
LIST_HEAD(head);
int prev_nr_hw_queues = set->nr_hw_queues;
unsigned int memflags;
int i;

lockdep_assert_held(&set->tag_list_lock);
Expand All @@ -5003,8 +5005,10 @@ 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;

memflags = memalloc_noio_save();
list_for_each_entry(q, &set->tag_list, tag_set_list)
blk_mq_freeze_queue(q);
blk_mq_freeze_queue_nomemsave(q);

/*
* Switch IO scheduler to 'none', cleaning up the data associated
* with the previous scheduler. We will switch back once we are done
Expand Down Expand Up @@ -5052,7 +5056,8 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set,
blk_mq_elv_switch_back(&head, q);

list_for_each_entry(q, &set->tag_list, tag_set_list)
blk_mq_unfreeze_queue(q);
blk_mq_unfreeze_queue_nomemrestore(q);
memalloc_noio_restore(memflags);

/* Free the excess tags when nr_hw_queues shrink. */
for (i = set->nr_hw_queues; i < prev_nr_hw_queues; i++)
Expand Down
2 changes: 1 addition & 1 deletion block/blk-pm.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ int blk_pre_runtime_suspend(struct request_queue *q)
if (percpu_ref_is_zero(&q->q_usage_counter))
ret = 0;
/* Switch q_usage_counter back to per-cpu mode. */
blk_mq_unfreeze_queue(q);
blk_mq_unfreeze_queue_nomemrestore(q);

if (ret < 0) {
spin_lock_irq(&q->queue_lock);
Expand Down
Loading

0 comments on commit 9755ffd

Please sign in to comment.