3.16.63-rc1 review patch.  If anyone has any objections, please let me know.

------------------

From: Parav Pandit <[email protected]>

commit 33f93e1ebcf5acfaef06cda2d3e373730519e33e upstream.

In case of LAP are used for RoCE, it can lead to a problem of sleeping a
context while spin lock is held in below flow.

cm_lap_handler
        ->spin_lock
        -> <..switch_case..>
        -> cm_init_av_for_response
                -> ib_init_ah_from_wc
                        -> rdma_addr_find_l2_eth_by_grh
                                wait_for_completion()

Therefore ah attribute initialization is done for incoming lap requests
outside of the lock context.

Signed-off-by: Parav Pandit <[email protected]>
Reviewed-by: Daniel Jurgens <[email protected]>
Signed-off-by: Leon Romanovsky <[email protected]>
Signed-off-by: Jason Gunthorpe <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>
---
 drivers/infiniband/core/cm.c | 11 ++++++-----
 1 file changed, 6 insertions(+), 5 deletions(-)

--- a/drivers/infiniband/core/cm.c
+++ b/drivers/infiniband/core/cm.c
@@ -2770,6 +2770,12 @@ static int cm_lap_handler(struct cm_work
        if (!cm_id_priv)
                return -EINVAL;
 
+       ret = cm_init_av_for_response(work->port, work->mad_recv_wc->wc,
+                                     work->mad_recv_wc->recv_buf.grh,
+                                     &cm_id_priv->av);
+       if (ret)
+               goto deref;
+
        param = &work->cm_event.param.lap_rcvd;
        param->alternate_path = &work->path[0];
        cm_format_path_from_lap(cm_id_priv, param->alternate_path, lap_msg);
@@ -2809,11 +2815,6 @@ static int cm_lap_handler(struct cm_work
 
        cm_id_priv->id.lap_state = IB_CM_LAP_RCVD;
        cm_id_priv->tid = lap_msg->hdr.tid;
-       ret = cm_init_av_for_response(work->port, work->mad_recv_wc->wc,
-                                     work->mad_recv_wc->recv_buf.grh,
-                                     &cm_id_priv->av);
-       if (ret)
-               goto unlock;
        cm_init_av_by_path(param->alternate_path, &cm_id_priv->alt_av,
                           cm_id_priv);
        ret = atomic_inc_and_test(&cm_id_priv->work_count);

Reply via email to