Re: [PATCH V3 10/10] md/raid1: introduce wait_for_serialization

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Dec 23, 2019 at 1:49 AM <jgq516@xxxxxxxxx> wrote:
>
> From: Guoqing Jiang <guoqing.jiang@xxxxxxxxxxxxxxx>
>
> Previously, we call check_and_add_serial when serialization is
> enabled for write IO, but it could allocate and free memory
> back and forth.
>
> Now, let's just get an element from memory pool with the new
> function, then insert node to rb tree if no collision happens.
>
> Signed-off-by: Guoqing Jiang <guoqing.jiang@xxxxxxxxxxxxxxx>
> ---
>  drivers/md/raid1.c | 41 ++++++++++++++++++++++-------------------
>  1 file changed, 22 insertions(+), 19 deletions(-)
>
> diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
> index 48d553d7989a..cd810e195086 100644
> --- a/drivers/md/raid1.c
> +++ b/drivers/md/raid1.c
> @@ -56,32 +56,43 @@ static void lower_barrier(struct r1conf *conf, sector_t sector_nr);
>  INTERVAL_TREE_DEFINE(struct serial_info, node, sector_t, _subtree_last,
>                      START, LAST, static inline, raid1_rb);
>
> -static int check_and_add_serial(struct md_rdev *rdev, sector_t lo, sector_t hi)
> +static int check_and_add_serial(struct md_rdev *rdev, struct r1bio *r1_bio,
> +                               struct serial_info *si, int idx)
>  {
> -       struct serial_info *si;
>         unsigned long flags;
>         int ret = 0;
> -       struct mddev *mddev = rdev->mddev;
> -       int idx = sector_to_idx(lo);
> +       sector_t lo = r1_bio->sector;
> +       sector_t hi = lo + r1_bio->sectors;
>         struct serial_in_rdev *serial = &rdev->serial[idx];
>
> -       si = mempool_alloc(mddev->serial_info_pool, GFP_NOIO);
> -
>         spin_lock_irqsave(&serial->serial_lock, flags);
>         /* collision happened */
>         if (raid1_rb_iter_first(&serial->serial_rb, lo, hi))
>                 ret = -EBUSY;
> -       if (!ret) {
> +       else {
>                 si->start = lo;
>                 si->last = hi;
>                 raid1_rb_insert(si, &serial->serial_rb);
> -       } else
> -               mempool_free(si, mddev->serial_info_pool);
> +       }
>         spin_unlock_irqrestore(&serial->serial_lock, flags);
>
>         return ret;
>  }
>
> +static void wait_for_serialization(struct md_rdev *rdev, struct r1bio *r1_bio)
> +{
> +       struct mddev *mddev = rdev->mddev;
> +       struct serial_info *si;
> +       int idx = sector_to_idx(r1_bio->sector);
> +       struct serial_in_rdev *serial = &rdev->serial[idx];
> +
> +       if (WARN_ON(!mddev->serial_info_pool))
> +               return;
> +       si = mempool_alloc(mddev->serial_info_pool, GFP_NOIO);
> +       wait_event(serial->serial_io_wait,
> +                  check_and_add_serial(rdev, r1_bio, si, idx) == 0);

Are we leaking si when raid1_rb_iter_first() failed?



[Index of Archives]     [Linux RAID Wiki]     [ATA RAID]     [Linux SCSI Target Infrastructure]     [Linux Block]     [Linux IDE]     [Linux SCSI]     [Linux Hams]     [Device Mapper]     [Device Mapper Cryptographics]     [Kernel]     [Linux Admin]     [Linux Net]     [GFS]     [RPM]     [git]     [Yosemite Forum]


  Powered by Linux