Skip to content

Commit 6070131

Browse files
committed
Merge tag 'md-next-20230613' of https://git.kernel.org/pub/scm/linux/kernel/git/song/md into for-6.5/block
Pull MD updates from Song: "The major changes are: 1. Protect md_thread with rcu, by Yu Kuai; 2. Various non-urgent raid5 and raid1/10 fixes, by Yu Kuai; 3. Non-urgent raid10 fixes, by Li Nan." * tag 'md-next-20230613' of https://git.kernel.org/pub/scm/linux/kernel/git/song/md: (29 commits) md/raid1-10: limit the number of plugged bio md/raid1-10: don't handle pluged bio by daemon thread md/md-bitmap: add a new helper to unplug bitmap asynchrously md/raid1-10: submit write io directly if bitmap is not enabled md/raid1-10: factor out a helper to submit normal write md/raid1-10: factor out a helper to add bio to plug md/raid10: prevent soft lockup while flush writes md/raid10: fix io loss while replacement replace rdev md/raid10: Do not add spare disk when recovery fails md/raid10: clean up md_add_new_disk() md/raid10: prioritize adding disk to 'removed' mirror md/raid10: improve code of mrdev in raid10_sync_request md/raid10: fix null-ptr-deref of mreplace in raid10_sync_request md/raid5: don't start reshape when recovery or replace is in progress md: protect md_thread with rcu md/bitmap: factor out a helper to set timeout md/bitmap: always wake up md_thread in timeout_store dm-raid: remove useless checking in raid_message() md: factor out a helper to wake up md_thread directly md: fix duplicate filename for rdev ...
2 parents d44c404 + 460af1f commit 6070131

19 files changed

+508
-287
lines changed

drivers/md/dm-raid.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3750,11 +3750,11 @@ static int raid_message(struct dm_target *ti, unsigned int argc, char **argv,
37503750
* canceling read-auto mode
37513751
*/
37523752
mddev->ro = 0;
3753-
if (!mddev->suspended && mddev->sync_thread)
3753+
if (!mddev->suspended)
37543754
md_wakeup_thread(mddev->sync_thread);
37553755
}
37563756
set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
3757-
if (!mddev->suspended && mddev->thread)
3757+
if (!mddev->suspended)
37583758
md_wakeup_thread(mddev->thread);
37593759

37603760
return 0;

drivers/md/md-bitmap.c

Lines changed: 65 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,7 @@ __acquires(bitmap->lock)
5454
{
5555
unsigned char *mappage;
5656

57-
if (page >= bitmap->pages) {
58-
/* This can happen if bitmap_start_sync goes beyond
59-
* End-of-device while looking for a whole page.
60-
* It is harmless.
61-
*/
62-
return -EINVAL;
63-
}
64-
57+
WARN_ON_ONCE(page >= bitmap->pages);
6558
if (bitmap->bp[page].hijacked) /* it's hijacked, don't try to alloc */
6659
return 0;
6760

@@ -1023,7 +1016,6 @@ static int md_bitmap_file_test_bit(struct bitmap *bitmap, sector_t block)
10231016
return set;
10241017
}
10251018

1026-
10271019
/* this gets called when the md device is ready to unplug its underlying
10281020
* (slave) device queues -- before we let any writes go down, we need to
10291021
* sync the dirty pages of the bitmap file to disk */
@@ -1033,8 +1025,7 @@ void md_bitmap_unplug(struct bitmap *bitmap)
10331025
int dirty, need_write;
10341026
int writing = 0;
10351027

1036-
if (!bitmap || !bitmap->storage.filemap ||
1037-
test_bit(BITMAP_STALE, &bitmap->flags))
1028+
if (!md_bitmap_enabled(bitmap))
10381029
return;
10391030

10401031
/* look at each page to see if there are any set bits that need to be
@@ -1063,6 +1054,35 @@ void md_bitmap_unplug(struct bitmap *bitmap)
10631054
}
10641055
EXPORT_SYMBOL(md_bitmap_unplug);
10651056

1057+
struct bitmap_unplug_work {
1058+
struct work_struct work;
1059+
struct bitmap *bitmap;
1060+
struct completion *done;
1061+
};
1062+
1063+
static void md_bitmap_unplug_fn(struct work_struct *work)
1064+
{
1065+
struct bitmap_unplug_work *unplug_work =
1066+
container_of(work, struct bitmap_unplug_work, work);
1067+
1068+
md_bitmap_unplug(unplug_work->bitmap);
1069+
complete(unplug_work->done);
1070+
}
1071+
1072+
void md_bitmap_unplug_async(struct bitmap *bitmap)
1073+
{
1074+
DECLARE_COMPLETION_ONSTACK(done);
1075+
struct bitmap_unplug_work unplug_work;
1076+
1077+
INIT_WORK_ONSTACK(&unplug_work.work, md_bitmap_unplug_fn);
1078+
unplug_work.bitmap = bitmap;
1079+
unplug_work.done = &done;
1080+
1081+
queue_work(md_bitmap_wq, &unplug_work.work);
1082+
wait_for_completion(&done);
1083+
}
1084+
EXPORT_SYMBOL(md_bitmap_unplug_async);
1085+
10661086
static void md_bitmap_set_memory_bits(struct bitmap *bitmap, sector_t offset, int needed);
10671087
/* * bitmap_init_from_disk -- called at bitmap_create time to initialize
10681088
* the in-memory bitmap from the on-disk bitmap -- also, sets up the
@@ -1241,11 +1261,28 @@ static bitmap_counter_t *md_bitmap_get_counter(struct bitmap_counts *bitmap,
12411261
sector_t offset, sector_t *blocks,
12421262
int create);
12431263

1264+
static void mddev_set_timeout(struct mddev *mddev, unsigned long timeout,
1265+
bool force)
1266+
{
1267+
struct md_thread *thread;
1268+
1269+
rcu_read_lock();
1270+
thread = rcu_dereference(mddev->thread);
1271+
1272+
if (!thread)
1273+
goto out;
1274+
1275+
if (force || thread->timeout < MAX_SCHEDULE_TIMEOUT)
1276+
thread->timeout = timeout;
1277+
1278+
out:
1279+
rcu_read_unlock();
1280+
}
1281+
12441282
/*
12451283
* bitmap daemon -- periodically wakes up to clean bits and flush pages
12461284
* out to disk
12471285
*/
1248-
12491286
void md_bitmap_daemon_work(struct mddev *mddev)
12501287
{
12511288
struct bitmap *bitmap;
@@ -1269,7 +1306,7 @@ void md_bitmap_daemon_work(struct mddev *mddev)
12691306

12701307
bitmap->daemon_lastrun = jiffies;
12711308
if (bitmap->allclean) {
1272-
mddev->thread->timeout = MAX_SCHEDULE_TIMEOUT;
1309+
mddev_set_timeout(mddev, MAX_SCHEDULE_TIMEOUT, true);
12731310
goto done;
12741311
}
12751312
bitmap->allclean = 1;
@@ -1366,8 +1403,7 @@ void md_bitmap_daemon_work(struct mddev *mddev)
13661403

13671404
done:
13681405
if (bitmap->allclean == 0)
1369-
mddev->thread->timeout =
1370-
mddev->bitmap_info.daemon_sleep;
1406+
mddev_set_timeout(mddev, mddev->bitmap_info.daemon_sleep, true);
13711407
mutex_unlock(&mddev->bitmap_info.mutex);
13721408
}
13731409

@@ -1387,6 +1423,14 @@ __acquires(bitmap->lock)
13871423
sector_t csize;
13881424
int err;
13891425

1426+
if (page >= bitmap->pages) {
1427+
/*
1428+
* This can happen if bitmap_start_sync goes beyond
1429+
* End-of-device while looking for a whole page or
1430+
* user set a huge number to sysfs bitmap_set_bits.
1431+
*/
1432+
return NULL;
1433+
}
13901434
err = md_bitmap_checkpage(bitmap, page, create, 0);
13911435

13921436
if (bitmap->bp[page].hijacked ||
@@ -1820,8 +1864,7 @@ void md_bitmap_destroy(struct mddev *mddev)
18201864
mddev->bitmap = NULL; /* disconnect from the md device */
18211865
spin_unlock(&mddev->lock);
18221866
mutex_unlock(&mddev->bitmap_info.mutex);
1823-
if (mddev->thread)
1824-
mddev->thread->timeout = MAX_SCHEDULE_TIMEOUT;
1867+
mddev_set_timeout(mddev, MAX_SCHEDULE_TIMEOUT, true);
18251868

18261869
md_bitmap_free(bitmap);
18271870
}
@@ -1964,7 +2007,7 @@ int md_bitmap_load(struct mddev *mddev)
19642007
/* Kick recovery in case any bits were set */
19652008
set_bit(MD_RECOVERY_NEEDED, &bitmap->mddev->recovery);
19662009

1967-
mddev->thread->timeout = mddev->bitmap_info.daemon_sleep;
2010+
mddev_set_timeout(mddev, mddev->bitmap_info.daemon_sleep, true);
19682011
md_wakeup_thread(mddev->thread);
19692012

19702013
md_bitmap_update_sb(bitmap);
@@ -2469,17 +2512,11 @@ timeout_store(struct mddev *mddev, const char *buf, size_t len)
24692512
timeout = MAX_SCHEDULE_TIMEOUT-1;
24702513
if (timeout < 1)
24712514
timeout = 1;
2515+
24722516
mddev->bitmap_info.daemon_sleep = timeout;
2473-
if (mddev->thread) {
2474-
/* if thread->timeout is MAX_SCHEDULE_TIMEOUT, then
2475-
* the bitmap is all clean and we don't need to
2476-
* adjust the timeout right now
2477-
*/
2478-
if (mddev->thread->timeout < MAX_SCHEDULE_TIMEOUT) {
2479-
mddev->thread->timeout = timeout;
2480-
md_wakeup_thread(mddev->thread);
2481-
}
2482-
}
2517+
mddev_set_timeout(mddev, timeout, false);
2518+
md_wakeup_thread(mddev->thread);
2519+
24832520
return len;
24842521
}
24852522

drivers/md/md-bitmap.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@ void md_bitmap_sync_with_cluster(struct mddev *mddev,
264264
sector_t new_lo, sector_t new_hi);
265265

266266
void md_bitmap_unplug(struct bitmap *bitmap);
267+
void md_bitmap_unplug_async(struct bitmap *bitmap);
267268
void md_bitmap_daemon_work(struct mddev *mddev);
268269

269270
int md_bitmap_resize(struct bitmap *bitmap, sector_t blocks,
@@ -273,6 +274,13 @@ int md_bitmap_copy_from_slot(struct mddev *mddev, int slot,
273274
sector_t *lo, sector_t *hi, bool clear_bits);
274275
void md_bitmap_free(struct bitmap *bitmap);
275276
void md_bitmap_wait_behind_writes(struct mddev *mddev);
277+
278+
static inline bool md_bitmap_enabled(struct bitmap *bitmap)
279+
{
280+
return bitmap && bitmap->storage.filemap &&
281+
!test_bit(BITMAP_STALE, &bitmap->flags);
282+
}
283+
276284
#endif
277285

278286
#endif

drivers/md/md-cluster.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -75,14 +75,14 @@ struct md_cluster_info {
7575
sector_t suspend_hi;
7676
int suspend_from; /* the slot which broadcast suspend_lo/hi */
7777

78-
struct md_thread *recovery_thread;
78+
struct md_thread __rcu *recovery_thread;
7979
unsigned long recovery_map;
8080
/* communication loc resources */
8181
struct dlm_lock_resource *ack_lockres;
8282
struct dlm_lock_resource *message_lockres;
8383
struct dlm_lock_resource *token_lockres;
8484
struct dlm_lock_resource *no_new_dev_lockres;
85-
struct md_thread *recv_thread;
85+
struct md_thread __rcu *recv_thread;
8686
struct completion newdisk_completion;
8787
wait_queue_head_t wait;
8888
unsigned long state;
@@ -362,8 +362,8 @@ static void __recover_slot(struct mddev *mddev, int slot)
362362

363363
set_bit(slot, &cinfo->recovery_map);
364364
if (!cinfo->recovery_thread) {
365-
cinfo->recovery_thread = md_register_thread(recover_bitmaps,
366-
mddev, "recover");
365+
rcu_assign_pointer(cinfo->recovery_thread,
366+
md_register_thread(recover_bitmaps, mddev, "recover"));
367367
if (!cinfo->recovery_thread) {
368368
pr_warn("md-cluster: Could not create recovery thread\n");
369369
return;
@@ -526,11 +526,15 @@ static void process_add_new_disk(struct mddev *mddev, struct cluster_msg *cmsg)
526526
static void process_metadata_update(struct mddev *mddev, struct cluster_msg *msg)
527527
{
528528
int got_lock = 0;
529+
struct md_thread *thread;
529530
struct md_cluster_info *cinfo = mddev->cluster_info;
530531
mddev->good_device_nr = le32_to_cpu(msg->raid_slot);
531532

532533
dlm_lock_sync(cinfo->no_new_dev_lockres, DLM_LOCK_CR);
533-
wait_event(mddev->thread->wqueue,
534+
535+
/* daemaon thread must exist */
536+
thread = rcu_dereference_protected(mddev->thread, true);
537+
wait_event(thread->wqueue,
534538
(got_lock = mddev_trylock(mddev)) ||
535539
test_bit(MD_CLUSTER_HOLDING_MUTEX_FOR_RECVD, &cinfo->state));
536540
md_reload_sb(mddev, mddev->good_device_nr);
@@ -889,7 +893,8 @@ static int join(struct mddev *mddev, int nodes)
889893
}
890894
/* Initiate the communication resources */
891895
ret = -ENOMEM;
892-
cinfo->recv_thread = md_register_thread(recv_daemon, mddev, "cluster_recv");
896+
rcu_assign_pointer(cinfo->recv_thread,
897+
md_register_thread(recv_daemon, mddev, "cluster_recv"));
893898
if (!cinfo->recv_thread) {
894899
pr_err("md-cluster: cannot allocate memory for recv_thread!\n");
895900
goto err;

drivers/md/md-multipath.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -400,8 +400,8 @@ static int multipath_run (struct mddev *mddev)
400400
if (ret)
401401
goto out_free_conf;
402402

403-
mddev->thread = md_register_thread(multipathd, mddev,
404-
"multipath");
403+
rcu_assign_pointer(mddev->thread,
404+
md_register_thread(multipathd, mddev, "multipath"));
405405
if (!mddev->thread)
406406
goto out_free_conf;
407407

0 commit comments

Comments
 (0)