Skip to content

Commit d5d885f

Browse files
liu-song-6shligit
authored andcommitted
md: introduce new personality funciton start()
In do_md_run(), md threads should not wake up until the array is fully initialized in md_run(). However, in raid5_run(), raid5-cache may wake up mddev->thread to flush stripes that need to be written back. This design doesn't break badly right now. But it could lead to bad bug in the future. This patch tries to resolve this problem by splitting start up work into two personality functions, run() and start(). Tasks that do not require the md threads should go into run(), while task that require the md threads go into start(). r5l_load_log() is moved to raid5_start(), so it is not called until the md threads are started in do_md_run(). Signed-off-by: Song Liu <[email protected]> Signed-off-by: Shaohua Li <[email protected]>
1 parent 50c4c4e commit d5d885f

File tree

6 files changed

+65
-11
lines changed

6 files changed

+65
-11
lines changed

drivers/md/dm-raid.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3151,6 +3151,14 @@ static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv)
31513151
goto bad;
31523152
}
31533153

3154+
r = md_start(&rs->md);
3155+
3156+
if (r) {
3157+
ti->error = "Failed to start raid array";
3158+
mddev_unlock(&rs->md);
3159+
goto bad_md_start;
3160+
}
3161+
31543162
rs->callbacks.congested_fn = raid_is_congested;
31553163
dm_table_add_target_callbacks(ti->table, &rs->callbacks);
31563164

@@ -3198,6 +3206,7 @@ static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv)
31983206
mddev_unlock(&rs->md);
31993207
return 0;
32003208

3209+
bad_md_start:
32013210
bad_journal_mode_set:
32023211
bad_stripe_cache:
32033212
bad_check_reshape:

drivers/md/md.c

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5560,11 +5560,6 @@ int md_run(struct mddev *mddev)
55605560
if (start_readonly && mddev->ro == 0)
55615561
mddev->ro = 2; /* read-only, but switch on first write */
55625562

5563-
/*
5564-
* NOTE: some pers->run(), for example r5l_recovery_log(), wakes
5565-
* up mddev->thread. It is important to initialize critical
5566-
* resources for mddev->thread BEFORE calling pers->run().
5567-
*/
55685563
err = pers->run(mddev);
55695564
if (err)
55705565
pr_warn("md: pers->run() failed ...\n");
@@ -5678,6 +5673,9 @@ static int do_md_run(struct mddev *mddev)
56785673
if (mddev_is_clustered(mddev))
56795674
md_allow_write(mddev);
56805675

5676+
/* run start up tasks that require md_thread */
5677+
md_start(mddev);
5678+
56815679
md_wakeup_thread(mddev->thread);
56825680
md_wakeup_thread(mddev->sync_thread); /* possibly kick off a reshape */
56835681

@@ -5689,6 +5687,21 @@ static int do_md_run(struct mddev *mddev)
56895687
return err;
56905688
}
56915689

5690+
int md_start(struct mddev *mddev)
5691+
{
5692+
int ret = 0;
5693+
5694+
if (mddev->pers->start) {
5695+
set_bit(MD_RECOVERY_WAIT, &mddev->recovery);
5696+
md_wakeup_thread(mddev->thread);
5697+
ret = mddev->pers->start(mddev);
5698+
clear_bit(MD_RECOVERY_WAIT, &mddev->recovery);
5699+
md_wakeup_thread(mddev->sync_thread);
5700+
}
5701+
return ret;
5702+
}
5703+
EXPORT_SYMBOL_GPL(md_start);
5704+
56925705
static int restart_array(struct mddev *mddev)
56935706
{
56945707
struct gendisk *disk = mddev->gendisk;
@@ -8169,7 +8182,8 @@ void md_do_sync(struct md_thread *thread)
81698182
int ret;
81708183

81718184
/* just incase thread restarts... */
8172-
if (test_bit(MD_RECOVERY_DONE, &mddev->recovery))
8185+
if (test_bit(MD_RECOVERY_DONE, &mddev->recovery) ||
8186+
test_bit(MD_RECOVERY_WAIT, &mddev->recovery))
81738187
return;
81748188
if (mddev->ro) {/* never try to sync a read-only array */
81758189
set_bit(MD_RECOVERY_INTR, &mddev->recovery);

drivers/md/md.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,7 @@ enum recovery_flags {
485485
MD_RECOVERY_RESHAPE, /* A reshape is happening */
486486
MD_RECOVERY_FROZEN, /* User request to abort, and not restart, any action */
487487
MD_RECOVERY_ERROR, /* sync-action interrupted because io-error */
488+
MD_RECOVERY_WAIT, /* waiting for pers->start() to finish */
488489
};
489490

490491
static inline int __must_check mddev_lock(struct mddev *mddev)
@@ -523,7 +524,13 @@ struct md_personality
523524
struct list_head list;
524525
struct module *owner;
525526
bool (*make_request)(struct mddev *mddev, struct bio *bio);
527+
/*
528+
* start up works that do NOT require md_thread. tasks that
529+
* requires md_thread should go into start()
530+
*/
526531
int (*run)(struct mddev *mddev);
532+
/* start up works that require md threads */
533+
int (*start)(struct mddev *mddev);
527534
void (*free)(struct mddev *mddev, void *priv);
528535
void (*status)(struct seq_file *seq, struct mddev *mddev);
529536
/* error_handler must set ->faulty and clear ->in_sync
@@ -687,6 +694,7 @@ extern int strict_strtoul_scaled(const char *cp, unsigned long *res, int scale);
687694

688695
extern void mddev_init(struct mddev *mddev);
689696
extern int md_run(struct mddev *mddev);
697+
extern int md_start(struct mddev *mddev);
690698
extern void md_stop(struct mddev *mddev);
691699
extern void md_stop_writes(struct mddev *mddev);
692700
extern int md_rdev_init(struct md_rdev *rdev);

drivers/md/raid5-cache.c

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2448,7 +2448,6 @@ static void r5c_recovery_flush_data_only_stripes(struct r5l_log *log,
24482448
raid5_release_stripe(sh);
24492449
}
24502450

2451-
md_wakeup_thread(conf->mddev->thread);
24522451
/* reuse conf->wait_for_quiescent in recovery */
24532452
wait_event(conf->wait_for_quiescent,
24542453
atomic_read(&conf->active_stripes) == 0);
@@ -3036,6 +3035,23 @@ static int r5l_load_log(struct r5l_log *log)
30363035
return ret;
30373036
}
30383037

3038+
int r5l_start(struct r5l_log *log)
3039+
{
3040+
int ret;
3041+
3042+
if (!log)
3043+
return 0;
3044+
3045+
ret = r5l_load_log(log);
3046+
if (ret) {
3047+
struct mddev *mddev = log->rdev->mddev;
3048+
struct r5conf *conf = mddev->private;
3049+
3050+
r5l_exit_log(conf);
3051+
}
3052+
return ret;
3053+
}
3054+
30393055
void r5c_update_on_rdev_error(struct mddev *mddev, struct md_rdev *rdev)
30403056
{
30413057
struct r5conf *conf = mddev->private;
@@ -3138,13 +3154,9 @@ int r5l_init_log(struct r5conf *conf, struct md_rdev *rdev)
31383154

31393155
rcu_assign_pointer(conf->log, log);
31403156

3141-
if (r5l_load_log(log))
3142-
goto error;
3143-
31443157
set_bit(MD_HAS_JOURNAL, &conf->mddev->flags);
31453158
return 0;
31463159

3147-
error:
31483160
rcu_assign_pointer(conf->log, NULL);
31493161
md_unregister_thread(&log->reclaim_thread);
31503162
reclaim_thread:

drivers/md/raid5-log.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ extern struct md_sysfs_entry r5c_journal_mode;
3232
extern void r5c_update_on_rdev_error(struct mddev *mddev,
3333
struct md_rdev *rdev);
3434
extern bool r5c_big_stripe_cached(struct r5conf *conf, sector_t sect);
35+
extern int r5l_start(struct r5l_log *log);
3536

3637
extern struct dma_async_tx_descriptor *
3738
ops_run_partial_parity(struct stripe_head *sh, struct raid5_percpu *percpu,

drivers/md/raid5.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8364,13 +8364,21 @@ static int raid5_change_consistency_policy(struct mddev *mddev, const char *buf)
83648364
return err;
83658365
}
83668366

8367+
static int raid5_start(struct mddev *mddev)
8368+
{
8369+
struct r5conf *conf = mddev->private;
8370+
8371+
return r5l_start(conf->log);
8372+
}
8373+
83678374
static struct md_personality raid6_personality =
83688375
{
83698376
.name = "raid6",
83708377
.level = 6,
83718378
.owner = THIS_MODULE,
83728379
.make_request = raid5_make_request,
83738380
.run = raid5_run,
8381+
.start = raid5_start,
83748382
.free = raid5_free,
83758383
.status = raid5_status,
83768384
.error_handler = raid5_error,
@@ -8395,6 +8403,7 @@ static struct md_personality raid5_personality =
83958403
.owner = THIS_MODULE,
83968404
.make_request = raid5_make_request,
83978405
.run = raid5_run,
8406+
.start = raid5_start,
83988407
.free = raid5_free,
83998408
.status = raid5_status,
84008409
.error_handler = raid5_error,
@@ -8420,6 +8429,7 @@ static struct md_personality raid4_personality =
84208429
.owner = THIS_MODULE,
84218430
.make_request = raid5_make_request,
84228431
.run = raid5_run,
8432+
.start = raid5_start,
84238433
.free = raid5_free,
84248434
.status = raid5_status,
84258435
.error_handler = raid5_error,

0 commit comments

Comments
 (0)