Skip to content

Commit

Permalink
md/raid10: prevent unnecessary calls to wake_up() in fast path
Browse files Browse the repository at this point in the history
Currently, wake_up() is called unconditionally in fast path such as
raid10_make_request(), which will cause lock contention under high
concurrency:

raid10_make_request
 wake_up
  __wake_up_common_lock
   spin_lock_irqsave

Improve performance by only call wake_up() if waitqueue is not empty
in allow_barrier() and raid10_make_request().

Signed-off-by: Yu Kuai <yukuai3@huawei.com>
Reviewed-by: Logan Gunthorpe <logang@deltatee.com>
Acked-by: Guoqing Jiang <guoqing.jiang@linux.dev>
Signed-off-by: Song Liu <song@kernel.org>
  • Loading branch information
YuKuai-huawei authored and liu-song-6 committed Sep 22, 2022
1 parent 0de57e5 commit 0c0be98
Showing 1 changed file with 8 additions and 2 deletions.
10 changes: 8 additions & 2 deletions drivers/md/raid10.c
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,12 @@ static void put_buf(struct r10bio *r10_bio)
lower_barrier(conf);
}

static void wake_up_barrier(struct r10conf *conf)
{
if (wq_has_sleeper(&conf->wait_barrier))
wake_up(&conf->wait_barrier);
}

static void reschedule_retry(struct r10bio *r10_bio)
{
unsigned long flags;
Expand Down Expand Up @@ -1015,7 +1021,7 @@ static void allow_barrier(struct r10conf *conf)
{
if ((atomic_dec_and_test(&conf->nr_pending)) ||
(conf->array_freeze_pending))
wake_up(&conf->wait_barrier);
wake_up_barrier(conf);
}

static void freeze_array(struct r10conf *conf, int extra)
Expand Down Expand Up @@ -1891,7 +1897,7 @@ static bool raid10_make_request(struct mddev *mddev, struct bio *bio)
__make_request(mddev, bio, sectors);

/* In case raid10d snuck in to freeze_array */
wake_up(&conf->wait_barrier);
wake_up_barrier(conf);
return true;
}

Expand Down

0 comments on commit 0c0be98

Please sign in to comment.