Re: [PATCH for-next v2] RDMA/rxe: Fix "RDMA/rxe: Cleanup rxe_mcast.c"

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

 



On Thu, May 5, 2022 at 4:28 AM Bob Pearson <rpearsonhpe@xxxxxxxxx> wrote:
>
> rxe_mcast.c currently uses _irqsave spinlocks for rxe->mcg_lock
> while rxe_recv.c uses _bh spinlocks for the same lock.
>
> Additionally the current code issues a warning that _irqrestore
> is restoring hardware interrupts while some interrupts are
> enabled. This is traced to calls to the calls to dev_mc_add/del().

Hi, Bob

As Jason commented, can you show us the warning? And how to reproduce
this problem?
Thanks,

Zhu Yanjun
>
> Change the locking of rxe->mcg_lock in rxe_mcast.c to use
> spin_(un)lock_bh() which matches that in rxe_recv.c. Also move
> the calls to dev_mc_add and dev_mc_del outside of spinlocks.
>
> Fixes: 6090a0c4c7c6 ("RDMA/rxe: Cleanup rxe_mcast.c")
> Signed-off-by: Bob Pearson <rpearsonhpe@xxxxxxxxx>
> ---
> v2
>   Addressed comments from Jason re not placing calls to dev_mc_add/del
>   inside of spinlocks.
>
>  drivers/infiniband/sw/rxe/rxe_mcast.c | 81 ++++++++++++---------------
>  1 file changed, 35 insertions(+), 46 deletions(-)
>
> diff --git a/drivers/infiniband/sw/rxe/rxe_mcast.c b/drivers/infiniband/sw/rxe/rxe_mcast.c
> index ae8f11cb704a..873a9b10307c 100644
> --- a/drivers/infiniband/sw/rxe/rxe_mcast.c
> +++ b/drivers/infiniband/sw/rxe/rxe_mcast.c
> @@ -38,13 +38,13 @@ static int rxe_mcast_add(struct rxe_dev *rxe, union ib_gid *mgid)
>  }
>
>  /**
> - * rxe_mcast_delete - delete multicast address from rxe device
> + * rxe_mcast_del - delete multicast address from rxe device
>   * @rxe: rxe device object
>   * @mgid: multicast address as a gid
>   *
>   * Returns 0 on success else an error
>   */
> -static int rxe_mcast_delete(struct rxe_dev *rxe, union ib_gid *mgid)
> +static int rxe_mcast_del(struct rxe_dev *rxe, union ib_gid *mgid)
>  {
>         unsigned char ll_addr[ETH_ALEN];
>
> @@ -143,11 +143,10 @@ static struct rxe_mcg *__rxe_lookup_mcg(struct rxe_dev *rxe,
>  struct rxe_mcg *rxe_lookup_mcg(struct rxe_dev *rxe, union ib_gid *mgid)
>  {
>         struct rxe_mcg *mcg;
> -       unsigned long flags;
>
> -       spin_lock_irqsave(&rxe->mcg_lock, flags);
> +       spin_lock_bh(&rxe->mcg_lock);
>         mcg = __rxe_lookup_mcg(rxe, mgid);
> -       spin_unlock_irqrestore(&rxe->mcg_lock, flags);
> +       spin_unlock_bh(&rxe->mcg_lock);
>
>         return mcg;
>  }
> @@ -159,17 +158,10 @@ struct rxe_mcg *rxe_lookup_mcg(struct rxe_dev *rxe, union ib_gid *mgid)
>   * @mcg: new mcg object
>   *
>   * Context: caller should hold rxe->mcg lock
> - * Returns: 0 on success else an error
>   */
> -static int __rxe_init_mcg(struct rxe_dev *rxe, union ib_gid *mgid,
> -                         struct rxe_mcg *mcg)
> +static void __rxe_init_mcg(struct rxe_dev *rxe, union ib_gid *mgid,
> +                          struct rxe_mcg *mcg)
>  {
> -       int err;
> -
> -       err = rxe_mcast_add(rxe, mgid);
> -       if (unlikely(err))
> -               return err;
> -
>         kref_init(&mcg->ref_cnt);
>         memcpy(&mcg->mgid, mgid, sizeof(mcg->mgid));
>         INIT_LIST_HEAD(&mcg->qp_list);
> @@ -184,8 +176,6 @@ static int __rxe_init_mcg(struct rxe_dev *rxe, union ib_gid *mgid,
>          */
>         kref_get(&mcg->ref_cnt);
>         __rxe_insert_mcg(mcg);
> -
> -       return 0;
>  }
>
>  /**
> @@ -198,7 +188,6 @@ static int __rxe_init_mcg(struct rxe_dev *rxe, union ib_gid *mgid,
>  static struct rxe_mcg *rxe_get_mcg(struct rxe_dev *rxe, union ib_gid *mgid)
>  {
>         struct rxe_mcg *mcg, *tmp;
> -       unsigned long flags;
>         int err;
>
>         if (rxe->attr.max_mcast_grp == 0)
> @@ -209,36 +198,38 @@ static struct rxe_mcg *rxe_get_mcg(struct rxe_dev *rxe, union ib_gid *mgid)
>         if (mcg)
>                 return mcg;
>
> +       /* check to see if we have reached limit */
> +       if (atomic_inc_return(&rxe->mcg_num) > rxe->attr.max_mcast_grp) {
> +               err = -ENOMEM;
> +               goto err_dec;
> +       }
> +
>         /* speculative alloc of new mcg */
>         mcg = kzalloc(sizeof(*mcg), GFP_KERNEL);
>         if (!mcg)
>                 return ERR_PTR(-ENOMEM);
>
> -       spin_lock_irqsave(&rxe->mcg_lock, flags);
> +       spin_lock_bh(&rxe->mcg_lock);
>         /* re-check to see if someone else just added it */
>         tmp = __rxe_lookup_mcg(rxe, mgid);
>         if (tmp) {
> +               spin_unlock_bh(&rxe->mcg_lock);
> +               atomic_dec(&rxe->mcg_num);
>                 kfree(mcg);
> -               mcg = tmp;
> -               goto out;
> +               return tmp;
>         }
>
> -       if (atomic_inc_return(&rxe->mcg_num) > rxe->attr.max_mcast_grp) {
> -               err = -ENOMEM;
> -               goto err_dec;
> -       }
> +       __rxe_init_mcg(rxe, mgid, mcg);
> +       spin_unlock_bh(&rxe->mcg_lock);
>
> -       err = __rxe_init_mcg(rxe, mgid, mcg);
> -       if (err)
> -               goto err_dec;
> -out:
> -       spin_unlock_irqrestore(&rxe->mcg_lock, flags);
> -       return mcg;
> +       /* add mcast address outside of lock */
> +       err = rxe_mcast_add(rxe, mgid);
> +       if (!err)
> +               return mcg;
>
> +       kfree(mcg);
>  err_dec:
>         atomic_dec(&rxe->mcg_num);
> -       spin_unlock_irqrestore(&rxe->mcg_lock, flags);
> -       kfree(mcg);
>         return ERR_PTR(err);
>  }
>
> @@ -268,7 +259,6 @@ static void __rxe_destroy_mcg(struct rxe_mcg *mcg)
>         __rxe_remove_mcg(mcg);
>         kref_put(&mcg->ref_cnt, rxe_cleanup_mcg);
>
> -       rxe_mcast_delete(mcg->rxe, &mcg->mgid);
>         atomic_dec(&rxe->mcg_num);
>  }
>
> @@ -280,11 +270,12 @@ static void __rxe_destroy_mcg(struct rxe_mcg *mcg)
>   */
>  static void rxe_destroy_mcg(struct rxe_mcg *mcg)
>  {
> -       unsigned long flags;
> +       /* delete mcast address outside of lock */
> +       rxe_mcast_del(mcg->rxe, &mcg->mgid);
>
> -       spin_lock_irqsave(&mcg->rxe->mcg_lock, flags);
> +       spin_lock_bh(&mcg->rxe->mcg_lock);
>         __rxe_destroy_mcg(mcg);
> -       spin_unlock_irqrestore(&mcg->rxe->mcg_lock, flags);
> +       spin_unlock_bh(&mcg->rxe->mcg_lock);
>  }
>
>  /**
> @@ -339,25 +330,24 @@ static int rxe_attach_mcg(struct rxe_mcg *mcg, struct rxe_qp *qp)
>  {
>         struct rxe_dev *rxe = mcg->rxe;
>         struct rxe_mca *mca, *tmp;
> -       unsigned long flags;
>         int err;
>
>         /* check to see if the qp is already a member of the group */
> -       spin_lock_irqsave(&rxe->mcg_lock, flags);
> +       spin_lock_bh(&rxe->mcg_lock);
>         list_for_each_entry(mca, &mcg->qp_list, qp_list) {
>                 if (mca->qp == qp) {
> -                       spin_unlock_irqrestore(&rxe->mcg_lock, flags);
> +                       spin_unlock_bh(&rxe->mcg_lock);
>                         return 0;
>                 }
>         }
> -       spin_unlock_irqrestore(&rxe->mcg_lock, flags);
> +       spin_unlock_bh(&rxe->mcg_lock);
>
>         /* speculative alloc new mca without using GFP_ATOMIC */
>         mca = kzalloc(sizeof(*mca), GFP_KERNEL);
>         if (!mca)
>                 return -ENOMEM;
>
> -       spin_lock_irqsave(&rxe->mcg_lock, flags);
> +       spin_lock_bh(&rxe->mcg_lock);
>         /* re-check to see if someone else just attached qp */
>         list_for_each_entry(tmp, &mcg->qp_list, qp_list) {
>                 if (tmp->qp == qp) {
> @@ -371,7 +361,7 @@ static int rxe_attach_mcg(struct rxe_mcg *mcg, struct rxe_qp *qp)
>         if (err)
>                 kfree(mca);
>  out:
> -       spin_unlock_irqrestore(&rxe->mcg_lock, flags);
> +       spin_unlock_bh(&rxe->mcg_lock);
>         return err;
>  }
>
> @@ -405,9 +395,8 @@ static int rxe_detach_mcg(struct rxe_mcg *mcg, struct rxe_qp *qp)
>  {
>         struct rxe_dev *rxe = mcg->rxe;
>         struct rxe_mca *mca, *tmp;
> -       unsigned long flags;
>
> -       spin_lock_irqsave(&rxe->mcg_lock, flags);
> +       spin_lock_bh(&rxe->mcg_lock);
>         list_for_each_entry_safe(mca, tmp, &mcg->qp_list, qp_list) {
>                 if (mca->qp == qp) {
>                         __rxe_cleanup_mca(mca, mcg);
> @@ -421,13 +410,13 @@ static int rxe_detach_mcg(struct rxe_mcg *mcg, struct rxe_qp *qp)
>                         if (atomic_read(&mcg->qp_num) <= 0)
>                                 __rxe_destroy_mcg(mcg);
>
> -                       spin_unlock_irqrestore(&rxe->mcg_lock, flags);
> +                       spin_unlock_bh(&rxe->mcg_lock);
>                         return 0;
>                 }
>         }
>
>         /* we didn't find the qp on the list */
> -       spin_unlock_irqrestore(&rxe->mcg_lock, flags);
> +       spin_unlock_bh(&rxe->mcg_lock);
>         return -EINVAL;
>  }
>
> --
> 2.34.1
>



[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Photo]     [Yosemite News]     [Yosemite Photos]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux