aboutsummaryrefslogtreecommitdiffstats
path: root/block
diff options
authorJens Axboe <axboe@kernel.dk>2026-05-27 08:37:52 -0600
committerJens Axboe <axboe@kernel.dk>2026-05-27 08:37:52 -0600
commit640c36aabd80a4bac72dd690e8792efc2f637198 (patch)
tree882a1928bf674906140e3ee265b27e40dfa2645b /block
parent072afc5d25354584a9888455c2fb3a8d21bdc754 (diff)
parent6235ea3f8b8ffca0333ade0863992f3cd69592ea (diff)
downloadlinux-next-history-640c36aabd80a4bac72dd690e8792efc2f637198.tar.gz
Merge branch 'for-7.2/block' into for-next
* for-7.2/block: blk-throttle: schedule parent dispatch in tg_flush_bios() rust: block: mq: align init_request numa_node arg with C signature block: partitions: replace __get_free_page() with kmalloc()
Diffstat (limited to 'block')
-rw-r--r--block/blk-throttle.c51
-rw-r--r--block/partitions/core.c6
2 files changed, 52 insertions, 5 deletions
diff --git a/block/blk-throttle.c b/block/blk-throttle.c
index cabf91f0d0dcb..88986dde1e183 100644
--- a/block/blk-throttle.c
+++ b/block/blk-throttle.c
@@ -1649,7 +1649,7 @@ static void tg_flush_bios(struct throtl_grp *tg)
*/
tg_update_disptime(tg);
- throtl_schedule_pending_timer(sq, jiffies + 1);
+ throtl_schedule_next_dispatch(sq->parent_sq, true);
}
static void throtl_pd_offline(struct blkg_policy_data *pd)
@@ -1668,11 +1668,52 @@ struct blkcg_policy blkcg_policy_throtl = {
.pd_free_fn = throtl_pd_free,
};
+static void tg_cancel_writeback_bios(struct throtl_grp *tg,
+ struct bio_list *cancel_bios)
+{
+ struct throtl_service_queue *sq = &tg->service_queue;
+ struct throtl_data *td = sq_to_td(sq);
+ int rw;
+
+ if (tg->flags & THROTL_TG_CANCELING)
+ return;
+ tg->flags |= THROTL_TG_CANCELING;
+
+ for (rw = READ; rw <= WRITE; rw++) {
+ struct throtl_qnode *qn, *tmp;
+ unsigned int nr_bios = 0;
+
+ list_for_each_entry_safe(qn, tmp, &sq->queued[rw], node) {
+ struct bio *bio;
+
+ while ((bio = bio_list_pop(&qn->bios_iops))) {
+ sq->nr_queued_iops[rw]--;
+ bio_list_add(&cancel_bios[rw], bio);
+ nr_bios++;
+ }
+ while ((bio = bio_list_pop(&qn->bios_bps))) {
+ sq->nr_queued_bps[rw]--;
+ bio_list_add(&cancel_bios[rw], bio);
+ nr_bios++;
+ }
+
+ list_del_init(&qn->node);
+ blkg_put(tg_to_blkg(qn->tg));
+ }
+
+ td->nr_queued[rw] -= nr_bios;
+ }
+
+ throtl_dequeue_tg(tg);
+}
+
void blk_throtl_cancel_bios(struct gendisk *disk)
{
struct request_queue *q = disk->queue;
struct cgroup_subsys_state *pos_css;
struct blkcg_gq *blkg;
+ struct bio_list cancel_bios[2] = { };
+ int rw;
if (!blk_throtl_activated(q))
return;
@@ -1693,10 +1734,16 @@ void blk_throtl_cancel_bios(struct gendisk *disk)
* Cancel bios here to ensure no bios are inflight after
* del_gendisk.
*/
- tg_flush_bios(blkg_to_tg(blkg));
+ tg_cancel_writeback_bios(blkg_to_tg(blkg), cancel_bios);
}
rcu_read_unlock();
spin_unlock_irq(&q->queue_lock);
+
+ for (rw = READ; rw <= WRITE; rw++) {
+ struct bio *bio;
+ while ((bio = bio_list_pop(&cancel_bios[rw])))
+ bio_io_error(bio);
+ }
}
static bool tg_within_limit(struct throtl_grp *tg, struct bio *bio, bool rw)
diff --git a/block/partitions/core.c b/block/partitions/core.c
index 5d5332ce586b6..b5c59b79ca7cb 100644
--- a/block/partitions/core.c
+++ b/block/partitions/core.c
@@ -124,7 +124,7 @@ static struct parsed_partitions *check_partition(struct gendisk *hd)
state = allocate_partitions(hd);
if (!state)
return NULL;
- state->pp_buf.buffer = (char *)__get_free_page(GFP_KERNEL);
+ state->pp_buf.buffer = kmalloc(PAGE_SIZE, GFP_KERNEL);
if (!state->pp_buf.buffer) {
free_partitions(state);
return NULL;
@@ -154,7 +154,7 @@ static struct parsed_partitions *check_partition(struct gendisk *hd)
if (res > 0) {
printk(KERN_INFO "%s", seq_buf_str(&state->pp_buf));
- free_page((unsigned long)state->pp_buf.buffer);
+ kfree(state->pp_buf.buffer);
return state;
}
if (state->access_beyond_eod)
@@ -170,7 +170,7 @@ static struct parsed_partitions *check_partition(struct gendisk *hd)
printk(KERN_INFO "%s", seq_buf_str(&state->pp_buf));
}
- free_page((unsigned long)state->pp_buf.buffer);
+ kfree(state->pp_buf.buffer);
free_partitions(state);
return ERR_PTR(res);
}