lkml.org 
[lkml]   [2020]   [Mar]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.4 153/168] IB/hfi1, qib: Ensure RCU is locked when accessing list
    Date
    From: Dennis Dalessandro <dennis.dalessandro@intel.com>

    commit 817a68a6584aa08e323c64283fec5ded7be84759 upstream.

    The packet handling function, specifically the iteration of the qp list
    for mad packet processing misses locking RCU before running through the
    list. Not only is this incorrect, but the list_for_each_entry_rcu() call
    can not be called with a conditional check for lock dependency. Remedy
    this by invoking the rcu lock and unlock around the critical section.

    This brings MAD packet processing in line with what is done for non-MAD
    packets.

    Fixes: 7724105686e7 ("IB/hfi1: add driver files")
    Link: https://lore.kernel.org/r/20200225195445.140896.41873.stgit@awfm-01.aw.intel.com
    Reviewed-by: Mike Marciniszyn <mike.marciniszyn@intel.com>
    Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com>
    Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/infiniband/hw/hfi1/verbs.c | 4 +++-
    drivers/infiniband/hw/qib/qib_verbs.c | 2 ++
    2 files changed, 5 insertions(+), 1 deletion(-)

    --- a/drivers/infiniband/hw/hfi1/verbs.c
    +++ b/drivers/infiniband/hw/hfi1/verbs.c
    @@ -515,10 +515,11 @@ static inline void hfi1_handle_packet(st
    opa_get_lid(packet->dlid, 9B));
    if (!mcast)
    goto drop;
    + rcu_read_lock();
    list_for_each_entry_rcu(p, &mcast->qp_list, list) {
    packet->qp = p->qp;
    if (hfi1_do_pkey_check(packet))
    - goto drop;
    + goto unlock_drop;
    spin_lock_irqsave(&packet->qp->r_lock, flags);
    packet_handler = qp_ok(packet);
    if (likely(packet_handler))
    @@ -527,6 +528,7 @@ static inline void hfi1_handle_packet(st
    ibp->rvp.n_pkt_drops++;
    spin_unlock_irqrestore(&packet->qp->r_lock, flags);
    }
    + rcu_read_unlock();
    /*
    * Notify rvt_multicast_detach() if it is waiting for us
    * to finish.
    --- a/drivers/infiniband/hw/qib/qib_verbs.c
    +++ b/drivers/infiniband/hw/qib/qib_verbs.c
    @@ -329,8 +329,10 @@ void qib_ib_rcv(struct qib_ctxtdata *rcd
    if (mcast == NULL)
    goto drop;
    this_cpu_inc(ibp->pmastats->n_multicast_rcv);
    + rcu_read_lock();
    list_for_each_entry_rcu(p, &mcast->qp_list, list)
    qib_qp_rcv(rcd, hdr, 1, data, tlen, p->qp);
    + rcu_read_unlock();
    /*
    * Notify rvt_multicast_detach() if it is waiting for us
    * to finish.

    \
     
     \ /
      Last update: 2020-03-10 13:56    [W:4.113 / U:0.032 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site