Skip to content

Commit 72adae2

Browse files
XiaoNi87liu-song-6
authored andcommitted
md: Change active_io to percpu
Now the type of active_io is atomic. It's used to count how many ios are in the submitting process and it's added and decreased very time. But it only needs to check if it's zero when suspending the raid. So we can switch atomic to percpu to improve the performance. After switching active_io to percpu type, we use the state of active_io to judge if the raid device is suspended. And we don't need to wake up ->sb_wait in md_handle_request anymore. It's done in the callback function which is registered when initing active_io. The argument mddev->suspended is only used to count how many users are trying to set raid to suspend state. Signed-off-by: Xiao Ni <[email protected]> Signed-off-by: Song Liu <[email protected]>
1 parent d193291 commit 72adae2

File tree

2 files changed

+25
-20
lines changed

2 files changed

+25
-20
lines changed

drivers/md/md.c

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -382,10 +382,7 @@ static DEFINE_SPINLOCK(all_mddevs_lock);
382382

383383
static bool is_md_suspended(struct mddev *mddev)
384384
{
385-
if (mddev->suspended)
386-
return true;
387-
else
388-
return false;
385+
return percpu_ref_is_dying(&mddev->active_io);
389386
}
390387
/* Rather than calling directly into the personality make_request function,
391388
* IO requests come here first so that we can check if the device is
@@ -412,12 +409,10 @@ static bool is_suspended(struct mddev *mddev, struct bio *bio)
412409
void md_handle_request(struct mddev *mddev, struct bio *bio)
413410
{
414411
check_suspended:
415-
rcu_read_lock();
416412
if (is_suspended(mddev, bio)) {
417413
DEFINE_WAIT(__wait);
418414
/* Bail out if REQ_NOWAIT is set for the bio */
419415
if (bio->bi_opf & REQ_NOWAIT) {
420-
rcu_read_unlock();
421416
bio_wouldblock_error(bio);
422417
return;
423418
}
@@ -426,23 +421,19 @@ void md_handle_request(struct mddev *mddev, struct bio *bio)
426421
TASK_UNINTERRUPTIBLE);
427422
if (!is_suspended(mddev, bio))
428423
break;
429-
rcu_read_unlock();
430424
schedule();
431-
rcu_read_lock();
432425
}
433426
finish_wait(&mddev->sb_wait, &__wait);
434427
}
435-
atomic_inc(&mddev->active_io);
436-
rcu_read_unlock();
428+
if (!percpu_ref_tryget_live(&mddev->active_io))
429+
goto check_suspended;
437430

438431
if (!mddev->pers->make_request(mddev, bio)) {
439-
atomic_dec(&mddev->active_io);
440-
wake_up(&mddev->sb_wait);
432+
percpu_ref_put(&mddev->active_io);
441433
goto check_suspended;
442434
}
443435

444-
if (atomic_dec_and_test(&mddev->active_io) && is_md_suspended(mddev))
445-
wake_up(&mddev->sb_wait);
436+
percpu_ref_put(&mddev->active_io);
446437
}
447438
EXPORT_SYMBOL(md_handle_request);
448439

@@ -490,11 +481,10 @@ void mddev_suspend(struct mddev *mddev)
490481
lockdep_assert_held(&mddev->reconfig_mutex);
491482
if (mddev->suspended++)
492483
return;
493-
synchronize_rcu();
494484
wake_up(&mddev->sb_wait);
495485
set_bit(MD_ALLOW_SB_UPDATE, &mddev->flags);
496-
smp_mb__after_atomic();
497-
wait_event(mddev->sb_wait, atomic_read(&mddev->active_io) == 0);
486+
percpu_ref_kill(&mddev->active_io);
487+
wait_event(mddev->sb_wait, percpu_ref_is_zero(&mddev->active_io));
498488
mddev->pers->quiesce(mddev, 1);
499489
clear_bit_unlock(MD_ALLOW_SB_UPDATE, &mddev->flags);
500490
wait_event(mddev->sb_wait, !test_bit(MD_UPDATING_SB, &mddev->flags));
@@ -512,6 +502,7 @@ void mddev_resume(struct mddev *mddev)
512502
lockdep_assert_held(&mddev->reconfig_mutex);
513503
if (--mddev->suspended)
514504
return;
505+
percpu_ref_resurrect(&mddev->active_io);
515506
wake_up(&mddev->sb_wait);
516507
mddev->pers->quiesce(mddev, 0);
517508

@@ -690,7 +681,6 @@ void mddev_init(struct mddev *mddev)
690681
timer_setup(&mddev->safemode_timer, md_safemode_timeout, 0);
691682
atomic_set(&mddev->active, 1);
692683
atomic_set(&mddev->openers, 0);
693-
atomic_set(&mddev->active_io, 0);
694684
spin_lock_init(&mddev->lock);
695685
atomic_set(&mddev->flush_pending, 0);
696686
init_waitqueue_head(&mddev->sb_wait);
@@ -5767,6 +5757,12 @@ static void md_safemode_timeout(struct timer_list *t)
57675757
}
57685758

57695759
static int start_dirty_degraded;
5760+
static void active_io_release(struct percpu_ref *ref)
5761+
{
5762+
struct mddev *mddev = container_of(ref, struct mddev, active_io);
5763+
5764+
wake_up(&mddev->sb_wait);
5765+
}
57705766

57715767
int md_run(struct mddev *mddev)
57725768
{
@@ -5847,10 +5843,15 @@ int md_run(struct mddev *mddev)
58475843
nowait = nowait && bdev_nowait(rdev->bdev);
58485844
}
58495845

5846+
err = percpu_ref_init(&mddev->active_io, active_io_release,
5847+
PERCPU_REF_ALLOW_REINIT, GFP_KERNEL);
5848+
if (err)
5849+
return err;
5850+
58505851
if (!bioset_initialized(&mddev->bio_set)) {
58515852
err = bioset_init(&mddev->bio_set, BIO_POOL_SIZE, 0, BIOSET_NEED_BVECS);
58525853
if (err)
5853-
return err;
5854+
goto exit_active_io;
58545855
}
58555856
if (!bioset_initialized(&mddev->sync_set)) {
58565857
err = bioset_init(&mddev->sync_set, BIO_POOL_SIZE, 0, BIOSET_NEED_BVECS);
@@ -6038,6 +6039,8 @@ int md_run(struct mddev *mddev)
60386039
bioset_exit(&mddev->sync_set);
60396040
exit_bio_set:
60406041
bioset_exit(&mddev->bio_set);
6042+
exit_active_io:
6043+
percpu_ref_exit(&mddev->active_io);
60416044
return err;
60426045
}
60436046
EXPORT_SYMBOL_GPL(md_run);
@@ -6262,6 +6265,7 @@ void md_stop(struct mddev *mddev)
62626265
*/
62636266
__md_stop_writes(mddev);
62646267
__md_stop(mddev);
6268+
percpu_ref_exit(&mddev->active_io);
62656269
bioset_exit(&mddev->bio_set);
62666270
bioset_exit(&mddev->sync_set);
62676271
}
@@ -7835,6 +7839,7 @@ static void md_free_disk(struct gendisk *disk)
78357839
struct mddev *mddev = disk->private_data;
78367840

78377841
percpu_ref_exit(&mddev->writes_pending);
7842+
percpu_ref_exit(&mddev->active_io);
78387843
bioset_exit(&mddev->bio_set);
78397844
bioset_exit(&mddev->sync_set);
78407845

drivers/md/md.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,7 @@ struct mddev {
315315
unsigned long sb_flags;
316316

317317
int suspended;
318-
atomic_t active_io;
318+
struct percpu_ref active_io;
319319
int ro;
320320
int sysfs_active; /* set when sysfs deletes
321321
* are happening, so run/

0 commit comments

Comments
 (0)