mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-03 15:47:36 +00:00
md/raid5-cache: clear MD_SB_CHANGE_PENDING before flushing stripes
In recovery, if we process too much data, raid5-cache may set MD_SB_CHANGE_PENDING, which causes spinning in handle_stripe(). Fix this issue by clearing the bit before flushing data only stripes. This issue was initially discussed in [1]. [1] https://www.spinics.net/lists/raid/msg64409.html Signed-off-by: Song Liu <songliubraving@fb.com>
This commit is contained in:
parent
e1a86dbbbd
commit
c9020e64cf
1 changed files with 7 additions and 0 deletions
|
@ -2430,10 +2430,15 @@ static void r5c_recovery_flush_data_only_stripes(struct r5l_log *log,
|
||||||
struct mddev *mddev = log->rdev->mddev;
|
struct mddev *mddev = log->rdev->mddev;
|
||||||
struct r5conf *conf = mddev->private;
|
struct r5conf *conf = mddev->private;
|
||||||
struct stripe_head *sh, *next;
|
struct stripe_head *sh, *next;
|
||||||
|
bool cleared_pending = false;
|
||||||
|
|
||||||
if (ctx->data_only_stripes == 0)
|
if (ctx->data_only_stripes == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (test_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags)) {
|
||||||
|
cleared_pending = true;
|
||||||
|
clear_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags);
|
||||||
|
}
|
||||||
log->r5c_journal_mode = R5C_JOURNAL_MODE_WRITE_BACK;
|
log->r5c_journal_mode = R5C_JOURNAL_MODE_WRITE_BACK;
|
||||||
|
|
||||||
list_for_each_entry_safe(sh, next, &ctx->cached_list, lru) {
|
list_for_each_entry_safe(sh, next, &ctx->cached_list, lru) {
|
||||||
|
@ -2448,6 +2453,8 @@ static void r5c_recovery_flush_data_only_stripes(struct r5l_log *log,
|
||||||
atomic_read(&conf->active_stripes) == 0);
|
atomic_read(&conf->active_stripes) == 0);
|
||||||
|
|
||||||
log->r5c_journal_mode = R5C_JOURNAL_MODE_WRITE_THROUGH;
|
log->r5c_journal_mode = R5C_JOURNAL_MODE_WRITE_THROUGH;
|
||||||
|
if (cleared_pending)
|
||||||
|
set_bit(MD_SB_CHANGE_PENDING, &mddev->sb_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int r5l_recovery_log(struct r5l_log *log)
|
static int r5l_recovery_log(struct r5l_log *log)
|
||||||
|
|
Loading…
Reference in a new issue