Skip to content

Commit 9755ffd

Browse files
committed
Merge tag 'block-6.14-20250131' of git://git.kernel.dk/linux
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
2 parents c82da38 + 1e1a9ce commit 9755ffd

34 files changed

+164
-130
lines changed

Diff for: block/blk-cgroup.c

+6-4
Original file line numberDiff line numberDiff line change
@@ -1546,6 +1546,7 @@ int blkcg_activate_policy(struct gendisk *disk, const struct blkcg_policy *pol)
15461546
struct request_queue *q = disk->queue;
15471547
struct blkg_policy_data *pd_prealloc = NULL;
15481548
struct blkcg_gq *blkg, *pinned_blkg = NULL;
1549+
unsigned int memflags;
15491550
int ret;
15501551

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

15621563
if (queue_is_mq(q))
1563-
blk_mq_freeze_queue(q);
1564+
memflags = blk_mq_freeze_queue(q);
15641565
retry:
15651566
spin_lock_irq(&q->queue_lock);
15661567

@@ -1624,7 +1625,7 @@ int blkcg_activate_policy(struct gendisk *disk, const struct blkcg_policy *pol)
16241625
spin_unlock_irq(&q->queue_lock);
16251626
out:
16261627
if (queue_is_mq(q))
1627-
blk_mq_unfreeze_queue(q);
1628+
blk_mq_unfreeze_queue(q, memflags);
16281629
if (pinned_blkg)
16291630
blkg_put(pinned_blkg);
16301631
if (pd_prealloc)
@@ -1668,12 +1669,13 @@ void blkcg_deactivate_policy(struct gendisk *disk,
16681669
{
16691670
struct request_queue *q = disk->queue;
16701671
struct blkcg_gq *blkg;
1672+
unsigned int memflags;
16711673

16721674
if (!blkcg_policy_enabled(q, pol))
16731675
return;
16741676

16751677
if (queue_is_mq(q))
1676-
blk_mq_freeze_queue(q);
1678+
memflags = blk_mq_freeze_queue(q);
16771679

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

16991701
if (queue_is_mq(q))
1700-
blk_mq_unfreeze_queue(q);
1702+
blk_mq_unfreeze_queue(q, memflags);
17011703
}
17021704
EXPORT_SYMBOL_GPL(blkcg_deactivate_policy);
17031705

Diff for: block/blk-core.c

-1
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,6 @@ struct request_queue *blk_alloc_queue(struct queue_limits *lim, int node_id)
430430
refcount_set(&q->refs, 1);
431431
mutex_init(&q->debugfs_mutex);
432432
mutex_init(&q->sysfs_lock);
433-
mutex_init(&q->sysfs_dir_lock);
434433
mutex_init(&q->limits_lock);
435434
mutex_init(&q->rq_qos_mutex);
436435
spin_lock_init(&q->queue_lock);

Diff for: block/blk-ia-ranges.c

-4
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,6 @@ int disk_register_independent_access_ranges(struct gendisk *disk)
111111
struct request_queue *q = disk->queue;
112112
int i, ret;
113113

114-
lockdep_assert_held(&q->sysfs_dir_lock);
115114
lockdep_assert_held(&q->sysfs_lock);
116115

117116
if (!iars)
@@ -155,7 +154,6 @@ void disk_unregister_independent_access_ranges(struct gendisk *disk)
155154
struct blk_independent_access_ranges *iars = disk->ia_ranges;
156155
int i;
157156

158-
lockdep_assert_held(&q->sysfs_dir_lock);
159157
lockdep_assert_held(&q->sysfs_lock);
160158

161159
if (!iars)
@@ -289,7 +287,6 @@ void disk_set_independent_access_ranges(struct gendisk *disk,
289287
{
290288
struct request_queue *q = disk->queue;
291289

292-
mutex_lock(&q->sysfs_dir_lock);
293290
mutex_lock(&q->sysfs_lock);
294291
if (iars && !disk_check_ia_ranges(disk, iars)) {
295292
kfree(iars);
@@ -313,6 +310,5 @@ void disk_set_independent_access_ranges(struct gendisk *disk,
313310
disk_register_independent_access_ranges(disk);
314311
unlock:
315312
mutex_unlock(&q->sysfs_lock);
316-
mutex_unlock(&q->sysfs_dir_lock);
317313
}
318314
EXPORT_SYMBOL_GPL(disk_set_independent_access_ranges);

Diff for: block/blk-iocost.c

+8-6
Original file line numberDiff line numberDiff line change
@@ -3224,6 +3224,7 @@ static ssize_t ioc_qos_write(struct kernfs_open_file *of, char *input,
32243224
u32 qos[NR_QOS_PARAMS];
32253225
bool enable, user;
32263226
char *body, *p;
3227+
unsigned int memflags;
32273228
int ret;
32283229

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

3250-
blk_mq_freeze_queue(disk->queue);
3251+
memflags = blk_mq_freeze_queue(disk->queue);
32513252
blk_mq_quiesce_queue(disk->queue);
32523253

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

33493350
blk_mq_unquiesce_queue(disk->queue);
3350-
blk_mq_unfreeze_queue(disk->queue);
3351+
blk_mq_unfreeze_queue(disk->queue, memflags);
33513352

33523353
blkg_conf_exit(&ctx);
33533354
return nbytes;
33543355
einval:
33553356
spin_unlock_irq(&ioc->lock);
33563357

33573358
blk_mq_unquiesce_queue(disk->queue);
3358-
blk_mq_unfreeze_queue(disk->queue);
3359+
blk_mq_unfreeze_queue(disk->queue, memflags);
33593360

33603361
ret = -EINVAL;
33613362
err:
@@ -3414,6 +3415,7 @@ static ssize_t ioc_cost_model_write(struct kernfs_open_file *of, char *input,
34143415
{
34153416
struct blkg_conf_ctx ctx;
34163417
struct request_queue *q;
3418+
unsigned int memflags;
34173419
struct ioc *ioc;
34183420
u64 u[NR_I_LCOEFS];
34193421
bool user;
@@ -3441,7 +3443,7 @@ static ssize_t ioc_cost_model_write(struct kernfs_open_file *of, char *input,
34413443
ioc = q_to_ioc(q);
34423444
}
34433445

3444-
blk_mq_freeze_queue(q);
3446+
memflags = blk_mq_freeze_queue(q);
34453447
blk_mq_quiesce_queue(q);
34463448

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

34953497
blk_mq_unquiesce_queue(q);
3496-
blk_mq_unfreeze_queue(q);
3498+
blk_mq_unfreeze_queue(q, memflags);
34973499

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

35043506
blk_mq_unquiesce_queue(q);
3505-
blk_mq_unfreeze_queue(q);
3507+
blk_mq_unfreeze_queue(q, memflags);
35063508

35073509
ret = -EINVAL;
35083510
err:

Diff for: block/blk-iolatency.c

+4-2
Original file line numberDiff line numberDiff line change
@@ -749,9 +749,11 @@ static void blkiolatency_enable_work_fn(struct work_struct *work)
749749
*/
750750
enabled = atomic_read(&blkiolat->enable_cnt);
751751
if (enabled != blkiolat->enabled) {
752-
blk_mq_freeze_queue(blkiolat->rqos.disk->queue);
752+
unsigned int memflags;
753+
754+
memflags = blk_mq_freeze_queue(blkiolat->rqos.disk->queue);
753755
blkiolat->enabled = enabled;
754-
blk_mq_unfreeze_queue(blkiolat->rqos.disk->queue);
756+
blk_mq_unfreeze_queue(blkiolat->rqos.disk->queue, memflags);
755757
}
756758
}
757759

Diff for: block/blk-mq-cpumap.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ void blk_mq_map_hw_queues(struct blk_mq_queue_map *qmap,
8787
return;
8888

8989
fallback:
90-
WARN_ON_ONCE(qmap->nr_queues > 1);
91-
blk_mq_clear_mq_map(qmap);
90+
blk_mq_map_queues(qmap);
9291
}
9392
EXPORT_SYMBOL_GPL(blk_mq_map_hw_queues);

Diff for: block/blk-mq-sysfs.c

+14-26
Original file line numberDiff line numberDiff line change
@@ -223,30 +223,27 @@ int blk_mq_sysfs_register(struct gendisk *disk)
223223
unsigned long i, j;
224224
int ret;
225225

226-
lockdep_assert_held(&q->sysfs_dir_lock);
227-
228226
ret = kobject_add(q->mq_kobj, &disk_to_dev(disk)->kobj, "mq");
229227
if (ret < 0)
230-
goto out;
228+
return ret;
231229

232230
kobject_uevent(q->mq_kobj, KOBJ_ADD);
233231

232+
mutex_lock(&q->tag_set->tag_list_lock);
234233
queue_for_each_hw_ctx(q, hctx, i) {
235234
ret = blk_mq_register_hctx(hctx);
236235
if (ret)
237-
goto unreg;
236+
goto out_unreg;
238237
}
238+
mutex_unlock(&q->tag_set->tag_list_lock);
239+
return 0;
239240

240-
q->mq_sysfs_init_done = true;
241-
242-
out:
243-
return ret;
244-
245-
unreg:
241+
out_unreg:
246242
queue_for_each_hw_ctx(q, hctx, j) {
247243
if (j < i)
248244
blk_mq_unregister_hctx(hctx);
249245
}
246+
mutex_unlock(&q->tag_set->tag_list_lock);
250247

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

262-
lockdep_assert_held(&q->sysfs_dir_lock);
263-
259+
mutex_lock(&q->tag_set->tag_list_lock);
264260
queue_for_each_hw_ctx(q, hctx, i)
265261
blk_mq_unregister_hctx(hctx);
262+
mutex_unlock(&q->tag_set->tag_list_lock);
266263

267264
kobject_uevent(q->mq_kobj, KOBJ_REMOVE);
268265
kobject_del(q->mq_kobj);
269-
270-
q->mq_sysfs_init_done = false;
271266
}
272267

273268
void blk_mq_sysfs_unregister_hctxs(struct request_queue *q)
274269
{
275270
struct blk_mq_hw_ctx *hctx;
276271
unsigned long i;
277272

278-
mutex_lock(&q->sysfs_dir_lock);
279-
if (!q->mq_sysfs_init_done)
280-
goto unlock;
273+
if (!blk_queue_registered(q))
274+
return;
281275

282276
queue_for_each_hw_ctx(q, hctx, i)
283277
blk_mq_unregister_hctx(hctx);
284-
285-
unlock:
286-
mutex_unlock(&q->sysfs_dir_lock);
287278
}
288279

289280
int blk_mq_sysfs_register_hctxs(struct request_queue *q)
@@ -292,18 +283,15 @@ int blk_mq_sysfs_register_hctxs(struct request_queue *q)
292283
unsigned long i;
293284
int ret = 0;
294285

295-
mutex_lock(&q->sysfs_dir_lock);
296-
if (!q->mq_sysfs_init_done)
297-
goto unlock;
286+
if (!blk_queue_registered(q))
287+
goto out;
298288

299289
queue_for_each_hw_ctx(q, hctx, i) {
300290
ret = blk_mq_register_hctx(hctx);
301291
if (ret)
302292
break;
303293
}
304294

305-
unlock:
306-
mutex_unlock(&q->sysfs_dir_lock);
307-
295+
out:
308296
return ret;
309297
}

Diff for: block/blk-mq.c

+13-8
Original file line numberDiff line numberDiff line change
@@ -210,12 +210,12 @@ int blk_mq_freeze_queue_wait_timeout(struct request_queue *q,
210210
}
211211
EXPORT_SYMBOL_GPL(blk_mq_freeze_queue_wait_timeout);
212212

213-
void blk_mq_freeze_queue(struct request_queue *q)
213+
void blk_mq_freeze_queue_nomemsave(struct request_queue *q)
214214
{
215215
blk_freeze_queue_start(q);
216216
blk_mq_freeze_queue_wait(q);
217217
}
218-
EXPORT_SYMBOL_GPL(blk_mq_freeze_queue);
218+
EXPORT_SYMBOL_GPL(blk_mq_freeze_queue_nomemsave);
219219

220220
bool __blk_mq_unfreeze_queue(struct request_queue *q, bool force_atomic)
221221
{
@@ -236,12 +236,12 @@ bool __blk_mq_unfreeze_queue(struct request_queue *q, bool force_atomic)
236236
return unfreeze;
237237
}
238238

239-
void blk_mq_unfreeze_queue(struct request_queue *q)
239+
void blk_mq_unfreeze_queue_nomemrestore(struct request_queue *q)
240240
{
241241
if (__blk_mq_unfreeze_queue(q, false))
242242
blk_unfreeze_release_lock(q);
243243
}
244-
EXPORT_SYMBOL_GPL(blk_mq_unfreeze_queue);
244+
EXPORT_SYMBOL_GPL(blk_mq_unfreeze_queue_nomemrestore);
245245

246246
/*
247247
* non_owner variant of blk_freeze_queue_start
@@ -4223,13 +4223,14 @@ static void blk_mq_update_tag_set_shared(struct blk_mq_tag_set *set,
42234223
bool shared)
42244224
{
42254225
struct request_queue *q;
4226+
unsigned int memflags;
42264227

42274228
lockdep_assert_held(&set->tag_list_lock);
42284229

42294230
list_for_each_entry(q, &set->tag_list, tag_set_list) {
4230-
blk_mq_freeze_queue(q);
4231+
memflags = blk_mq_freeze_queue(q);
42314232
queue_set_hctx_shared(q, shared);
4232-
blk_mq_unfreeze_queue(q);
4233+
blk_mq_unfreeze_queue(q, memflags);
42334234
}
42344235
}
42354236

@@ -4992,6 +4993,7 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set,
49924993
struct request_queue *q;
49934994
LIST_HEAD(head);
49944995
int prev_nr_hw_queues = set->nr_hw_queues;
4996+
unsigned int memflags;
49954997
int i;
49964998

49974999
lockdep_assert_held(&set->tag_list_lock);
@@ -5003,8 +5005,10 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set,
50035005
if (set->nr_maps == 1 && nr_hw_queues == set->nr_hw_queues)
50045006
return;
50055007

5008+
memflags = memalloc_noio_save();
50065009
list_for_each_entry(q, &set->tag_list, tag_set_list)
5007-
blk_mq_freeze_queue(q);
5010+
blk_mq_freeze_queue_nomemsave(q);
5011+
50085012
/*
50095013
* Switch IO scheduler to 'none', cleaning up the data associated
50105014
* with the previous scheduler. We will switch back once we are done
@@ -5052,7 +5056,8 @@ static void __blk_mq_update_nr_hw_queues(struct blk_mq_tag_set *set,
50525056
blk_mq_elv_switch_back(&head, q);
50535057

50545058
list_for_each_entry(q, &set->tag_list, tag_set_list)
5055-
blk_mq_unfreeze_queue(q);
5059+
blk_mq_unfreeze_queue_nomemrestore(q);
5060+
memalloc_noio_restore(memflags);
50565061

50575062
/* Free the excess tags when nr_hw_queues shrink. */
50585063
for (i = set->nr_hw_queues; i < prev_nr_hw_queues; i++)

Diff for: block/blk-pm.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ int blk_pre_runtime_suspend(struct request_queue *q)
8989
if (percpu_ref_is_zero(&q->q_usage_counter))
9090
ret = 0;
9191
/* Switch q_usage_counter back to per-cpu mode. */
92-
blk_mq_unfreeze_queue(q);
92+
blk_mq_unfreeze_queue_nomemrestore(q);
9393

9494
if (ret < 0) {
9595
spin_lock_irq(&q->queue_lock);

0 commit comments

Comments
 (0)