Skip to content

Commit

Permalink
md/md-bitmap: add a new helper to unplug bitmap asynchrously
Browse files Browse the repository at this point in the history
If bitmap is enabled, bitmap must update before submitting write io, this
is why unplug callback must move these io to 'conf->pending_io_list' if
'current->bio_list' is not empty, which will suffer performance
degradation.

A new helper md_bitmap_unplug_async() is introduced to submit bitmap io
in a kworker, so that submit bitmap io in raid10_unplug() doesn't require
that 'current->bio_list' is empty.

This patch prepare to limit the number of plugged bio.

Signed-off-by: Yu Kuai <[email protected]>
Signed-off-by: Song Liu <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
  • Loading branch information
YuKuai-huawei authored and liu-song-6 committed Jun 13, 2023
1 parent 7db922b commit a022325
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 0 deletions.
29 changes: 29 additions & 0 deletions drivers/md/md-bitmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -1054,6 +1054,35 @@ void md_bitmap_unplug(struct bitmap *bitmap)
}
EXPORT_SYMBOL(md_bitmap_unplug);

struct bitmap_unplug_work {
struct work_struct work;
struct bitmap *bitmap;
struct completion *done;
};

static void md_bitmap_unplug_fn(struct work_struct *work)
{
struct bitmap_unplug_work *unplug_work =
container_of(work, struct bitmap_unplug_work, work);

md_bitmap_unplug(unplug_work->bitmap);
complete(unplug_work->done);
}

void md_bitmap_unplug_async(struct bitmap *bitmap)
{
DECLARE_COMPLETION_ONSTACK(done);
struct bitmap_unplug_work unplug_work;

INIT_WORK_ONSTACK(&unplug_work.work, md_bitmap_unplug_fn);
unplug_work.bitmap = bitmap;
unplug_work.done = &done;

queue_work(md_bitmap_wq, &unplug_work.work);
wait_for_completion(&done);
}
EXPORT_SYMBOL(md_bitmap_unplug_async);

static void md_bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int needed);
/* * bitmap_init_from_disk -- called at bitmap_create time to initialize
* the in-memory bitmap from the on-disk bitmap -- also, sets up the
Expand Down
1 change: 1 addition & 0 deletions drivers/md/md-bitmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@ void md_bitmap_sync_with_cluster(struct mddev *mddev,
sector_t new_lo, sector_t new_hi);

void md_bitmap_unplug(struct bitmap *bitmap);
void md_bitmap_unplug_async(struct bitmap *bitmap);
void md_bitmap_daemon_work(struct mddev *mddev);

int md_bitmap_resize(struct bitmap *bitmap, sector_t blocks,
Expand Down
9 changes: 9 additions & 0 deletions drivers/md/md.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ static struct module *md_cluster_mod;
static DECLARE_WAIT_QUEUE_HEAD(resync_wait);
static struct workqueue_struct *md_wq;
static struct workqueue_struct *md_misc_wq;
struct workqueue_struct *md_bitmap_wq;

static int remove_and_add_spares(struct mddev *mddev,
struct md_rdev *this);
Expand Down Expand Up @@ -9637,6 +9638,11 @@ static int __init md_init(void)
if (!md_misc_wq)
goto err_misc_wq;

md_bitmap_wq = alloc_workqueue("md_bitmap", WQ_MEM_RECLAIM | WQ_UNBOUND,
0);
if (!md_bitmap_wq)
goto err_bitmap_wq;

ret = __register_blkdev(MD_MAJOR, "md", md_probe);
if (ret < 0)
goto err_md;
Expand All @@ -9655,6 +9661,8 @@ static int __init md_init(void)
err_mdp:
unregister_blkdev(MD_MAJOR, "md");
err_md:
destroy_workqueue(md_bitmap_wq);
err_bitmap_wq:
destroy_workqueue(md_misc_wq);
err_misc_wq:
destroy_workqueue(md_wq);
Expand Down Expand Up @@ -9951,6 +9959,7 @@ static __exit void md_exit(void)
spin_unlock(&all_mddevs_lock);

destroy_workqueue(md_misc_wq);
destroy_workqueue(md_bitmap_wq);
destroy_workqueue(md_wq);
}

Expand Down
1 change: 1 addition & 0 deletions drivers/md/md.h
Original file line number Diff line number Diff line change
Expand Up @@ -852,6 +852,7 @@ struct mdu_array_info_s;
struct mdu_disk_info_s;

extern int mdp_major;
extern struct workqueue_struct *md_bitmap_wq;
void md_autostart_arrays(int part);
int md_set_array_info(struct mddev *mddev, struct mdu_array_info_s *info);
int md_add_new_disk(struct mddev *mddev, struct mdu_disk_info_s *info);
Expand Down

0 comments on commit a022325

Please sign in to comment.