From: Damien Le Moal <dlemoal@kernel.org>
To: Jens Axboe <axboe@kernel.dk>, linux-block@vger.kernel.org
Subject: [PATCH v2 2/2] block: use a per disk workqueue for zone write plugging
Date: Sat, 20 Apr 2024 16:58:11 +0900 [thread overview]
Message-ID: <20240420075811.1276893-3-dlemoal@kernel.org> (raw)
In-Reply-To: <20240420075811.1276893-1-dlemoal@kernel.org>
A zone write plug BIO work function blk_zone_wplug_bio_work() calls
submit_bio_noacct_nocheck() to execute the next unplugged BIO. This
function may block. So executing zone plugs BIO works using the block
layer global kblockd workqueue can potentially lead to preformance or
latency issues as the number of concurrent work for a workqueue is
limited to WQ_DFL_ACTIVE (256).
1) For a system with a large number of zoned disks, issuing write
requests to otherwise unused zones may be delayed wiating for a work
thread to become available.
2) Requeue operations which use kblockd but are independent of zone
write plugging may alsoi end up being delayed.
To avoid these potential performance issues, create a workqueue per
zoned device to execute zone plugs BIO work. The workqueue max active
parameter is set to the maximum number of zone write plugs allocated
with the zone write plug mempool. This limit is equal to the maximum
number of open zones of the disk and defaults to 128 for disks that do
not have a limit on the number of open zones.
Fixes: dd291d77cc90 ("block: Introduce zone write plugging")
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
---
block/blk-zoned.c | 32 ++++++++++++++++++++++++--------
include/linux/blkdev.h | 1 +
2 files changed, 25 insertions(+), 8 deletions(-)
diff --git a/block/blk-zoned.c b/block/blk-zoned.c
index 685f0b9159fd..4f5bf1c0a99f 100644
--- a/block/blk-zoned.c
+++ b/block/blk-zoned.c
@@ -1131,7 +1131,7 @@ static void disk_zone_wplug_unplug_bio(struct gendisk *disk,
/* Schedule submission of the next plugged BIO if we have one. */
if (!bio_list_empty(&zwplug->bio_list)) {
spin_unlock_irqrestore(&zwplug->lock, flags);
- kblockd_schedule_work(&zwplug->bio_work);
+ queue_work(disk->zone_wplugs_wq, &zwplug->bio_work);
return;
}
@@ -1334,7 +1334,7 @@ static void disk_zone_wplug_handle_error(struct gendisk *disk,
/* Restart BIO submission if we still have any BIO left. */
if (!bio_list_empty(&zwplug->bio_list)) {
WARN_ON_ONCE(!(zwplug->flags & BLK_ZONE_WPLUG_PLUGGED));
- kblockd_schedule_work(&zwplug->bio_work);
+ queue_work(disk->zone_wplugs_wq, &zwplug->bio_work);
goto unlock;
}
@@ -1411,14 +1411,25 @@ static int disk_alloc_zone_resources(struct gendisk *disk,
disk->zone_wplugs_pool = mempool_create_kmalloc_pool(pool_size,
sizeof(struct blk_zone_wplug));
- if (!disk->zone_wplugs_pool) {
- kfree(disk->zone_wplugs_hash);
- disk->zone_wplugs_hash = NULL;
- disk->zone_wplugs_hash_bits = 0;
- return -ENOMEM;
- }
+ if (!disk->zone_wplugs_pool)
+ goto free_hash;
+
+ disk->zone_wplugs_wq =
+ alloc_workqueue("%s_zwplugs", WQ_MEM_RECLAIM | WQ_HIGHPRI,
+ pool_size, disk->disk_name);
+ if (!disk->zone_wplugs_wq)
+ goto destroy_pool;
return 0;
+
+destroy_pool:
+ mempool_destroy(disk->zone_wplugs_pool);
+ disk->zone_wplugs_pool = NULL;
+free_hash:
+ kfree(disk->zone_wplugs_hash);
+ disk->zone_wplugs_hash = NULL;
+ disk->zone_wplugs_hash_bits = 0;
+ return -ENOMEM;
}
static void disk_destroy_zone_wplugs_hash_table(struct gendisk *disk)
@@ -1449,6 +1460,11 @@ void disk_free_zone_resources(struct gendisk *disk)
{
cancel_work_sync(&disk->zone_wplugs_work);
+ if (disk->zone_wplugs_wq) {
+ destroy_workqueue(disk->zone_wplugs_wq);
+ disk->zone_wplugs_wq = NULL;
+ }
+
disk_destroy_zone_wplugs_hash_table(disk);
/*
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index c62536c78a46..a2847f8e5f82 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -191,6 +191,7 @@ struct gendisk {
struct hlist_head *zone_wplugs_hash;
struct list_head zone_wplugs_err_list;
struct work_struct zone_wplugs_work;
+ struct workqueue_struct *zone_wplugs_wq;
#endif /* CONFIG_BLK_DEV_ZONED */
#if IS_ENABLED(CONFIG_CDROM)
--
2.44.0
next prev parent reply other threads:[~2024-04-20 7:58 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-04-20 7:58 [PATCH v2 0/2] Fixes for zone write plugging Damien Le Moal
2024-04-20 7:58 ` [PATCH v2 1/2] block: prevent freeing a zone write plug too early Damien Le Moal
2024-04-22 6:23 ` Christoph Hellwig
2024-04-23 6:12 ` Damien Le Moal
2024-04-23 14:21 ` Jens Axboe
2024-04-23 15:16 ` Damien Le Moal
2024-04-23 15:36 ` Jens Axboe
2024-04-23 18:19 ` Damien Le Moal
2024-04-24 13:58 ` Jens Axboe
2024-04-20 7:58 ` Damien Le Moal [this message]
2024-04-22 6:25 ` [PATCH v2 2/2] block: use a per disk workqueue for zone write plugging Christoph Hellwig
2024-04-23 6:01 ` Damien Le Moal
2024-04-23 15:46 ` (subset) [PATCH v2 0/2] Fixes " Jens Axboe
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240420075811.1276893-3-dlemoal@kernel.org \
--to=dlemoal@kernel.org \
--cc=axboe@kernel.dk \
--cc=linux-block@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox