mirror of
https://github.com/fail0verflow/switch-linux.git
synced 2025-05-04 02:34:21 -04:00
md/raid5-cache: exclude reclaiming stripes in reclaim check
stripes which are being reclaimed are still accounted into cached stripes. The reclaim takes time. r5c_do_reclaim isn't aware of the stripes and does unnecessary stripe reclaim. In practice, I saw one stripe is reclaimed one time. This will cause bad IO pattern. Fixing this by excluding the reclaing stripes in the check. Cc: Song Liu <songliubraving@fb.com> Signed-off-by: Shaohua Li <shli@fb.com>
This commit is contained in:
parent
e8fd52eec2
commit
e33fbb9cc7
3 changed files with 16 additions and 2 deletions
|
@ -1327,6 +1327,10 @@ static void r5c_flush_stripe(struct r5conf *conf, struct stripe_head *sh)
|
||||||
atomic_inc(&conf->active_stripes);
|
atomic_inc(&conf->active_stripes);
|
||||||
r5c_make_stripe_write_out(sh);
|
r5c_make_stripe_write_out(sh);
|
||||||
|
|
||||||
|
if (test_bit(STRIPE_R5C_PARTIAL_STRIPE, &sh->state))
|
||||||
|
atomic_inc(&conf->r5c_flushing_partial_stripes);
|
||||||
|
else
|
||||||
|
atomic_inc(&conf->r5c_flushing_full_stripes);
|
||||||
raid5_release_stripe(sh);
|
raid5_release_stripe(sh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1369,12 +1373,16 @@ static void r5c_do_reclaim(struct r5conf *conf)
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
int total_cached;
|
int total_cached;
|
||||||
int stripes_to_flush;
|
int stripes_to_flush;
|
||||||
|
int flushing_partial, flushing_full;
|
||||||
|
|
||||||
if (!r5c_is_writeback(log))
|
if (!r5c_is_writeback(log))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
flushing_partial = atomic_read(&conf->r5c_flushing_partial_stripes);
|
||||||
|
flushing_full = atomic_read(&conf->r5c_flushing_full_stripes);
|
||||||
total_cached = atomic_read(&conf->r5c_cached_partial_stripes) +
|
total_cached = atomic_read(&conf->r5c_cached_partial_stripes) +
|
||||||
atomic_read(&conf->r5c_cached_full_stripes);
|
atomic_read(&conf->r5c_cached_full_stripes) -
|
||||||
|
flushing_full - flushing_partial;
|
||||||
|
|
||||||
if (total_cached > conf->min_nr_stripes * 3 / 4 ||
|
if (total_cached > conf->min_nr_stripes * 3 / 4 ||
|
||||||
atomic_read(&conf->empty_inactive_list_nr) > 0)
|
atomic_read(&conf->empty_inactive_list_nr) > 0)
|
||||||
|
@ -1384,7 +1392,7 @@ static void r5c_do_reclaim(struct r5conf *conf)
|
||||||
*/
|
*/
|
||||||
stripes_to_flush = R5C_RECLAIM_STRIPE_GROUP;
|
stripes_to_flush = R5C_RECLAIM_STRIPE_GROUP;
|
||||||
else if (total_cached > conf->min_nr_stripes * 1 / 2 ||
|
else if (total_cached > conf->min_nr_stripes * 1 / 2 ||
|
||||||
atomic_read(&conf->r5c_cached_full_stripes) >
|
atomic_read(&conf->r5c_cached_full_stripes) - flushing_full >
|
||||||
R5C_FULL_STRIPE_FLUSH_BATCH)
|
R5C_FULL_STRIPE_FLUSH_BATCH)
|
||||||
/*
|
/*
|
||||||
* if stripe cache pressure moderate, or if there is many full
|
* if stripe cache pressure moderate, or if there is many full
|
||||||
|
@ -2601,11 +2609,13 @@ void r5c_finish_stripe_write_out(struct r5conf *conf,
|
||||||
|
|
||||||
if (test_and_clear_bit(STRIPE_R5C_PARTIAL_STRIPE, &sh->state)) {
|
if (test_and_clear_bit(STRIPE_R5C_PARTIAL_STRIPE, &sh->state)) {
|
||||||
BUG_ON(atomic_read(&conf->r5c_cached_partial_stripes) == 0);
|
BUG_ON(atomic_read(&conf->r5c_cached_partial_stripes) == 0);
|
||||||
|
atomic_dec(&conf->r5c_flushing_partial_stripes);
|
||||||
atomic_dec(&conf->r5c_cached_partial_stripes);
|
atomic_dec(&conf->r5c_cached_partial_stripes);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (test_and_clear_bit(STRIPE_R5C_FULL_STRIPE, &sh->state)) {
|
if (test_and_clear_bit(STRIPE_R5C_FULL_STRIPE, &sh->state)) {
|
||||||
BUG_ON(atomic_read(&conf->r5c_cached_full_stripes) == 0);
|
BUG_ON(atomic_read(&conf->r5c_cached_full_stripes) == 0);
|
||||||
|
atomic_dec(&conf->r5c_flushing_full_stripes);
|
||||||
atomic_dec(&conf->r5c_cached_full_stripes);
|
atomic_dec(&conf->r5c_cached_full_stripes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6838,6 +6838,8 @@ static struct r5conf *setup_conf(struct mddev *mddev)
|
||||||
INIT_LIST_HEAD(&conf->r5c_full_stripe_list);
|
INIT_LIST_HEAD(&conf->r5c_full_stripe_list);
|
||||||
atomic_set(&conf->r5c_cached_partial_stripes, 0);
|
atomic_set(&conf->r5c_cached_partial_stripes, 0);
|
||||||
INIT_LIST_HEAD(&conf->r5c_partial_stripe_list);
|
INIT_LIST_HEAD(&conf->r5c_partial_stripe_list);
|
||||||
|
atomic_set(&conf->r5c_flushing_full_stripes, 0);
|
||||||
|
atomic_set(&conf->r5c_flushing_partial_stripes, 0);
|
||||||
|
|
||||||
conf->level = mddev->new_level;
|
conf->level = mddev->new_level;
|
||||||
conf->chunk_sectors = mddev->new_chunk_sectors;
|
conf->chunk_sectors = mddev->new_chunk_sectors;
|
||||||
|
|
|
@ -663,6 +663,8 @@ struct r5conf {
|
||||||
struct list_head r5c_full_stripe_list;
|
struct list_head r5c_full_stripe_list;
|
||||||
atomic_t r5c_cached_partial_stripes;
|
atomic_t r5c_cached_partial_stripes;
|
||||||
struct list_head r5c_partial_stripe_list;
|
struct list_head r5c_partial_stripe_list;
|
||||||
|
atomic_t r5c_flushing_full_stripes;
|
||||||
|
atomic_t r5c_flushing_partial_stripes;
|
||||||
|
|
||||||
atomic_t empty_inactive_list_nr;
|
atomic_t empty_inactive_list_nr;
|
||||||
struct llist_head released_stripes;
|
struct llist_head released_stripes;
|
||||||
|
|
Loading…
Add table
Reference in a new issue