lkml.org 
[lkml]   [2019]   [Feb]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Date
    Subject[PATCH 3.16 088/305] IB/{cm, umad}: Handle av init error
    3.16.63-rc1 review patch.  If anyone has any objections, please let me know.

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

    From: Parav Pandit <parav@mellanox.com>

    commit 0c4386ec77cfcd0ccbdbe8c2e67dd3a49b2a4c7f upstream.

    cm_init_av_for_response depends on ib_init_ah_from_wc() whose return
    status is ignored.
    ib_init_ah_from_wc() can fail and its return status should be handled as
    done in this patch.

    Signed-off-by: Parav Pandit <parav@mellanox.com>
    Reviewed-by: Daniel Jurgens <danielj@mellanox.com>
    Signed-off-by: Leon Romanovsky <leon@kernel.org>
    Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
    [bwh: Backported to 3.16: adjust context]
    Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
    ---
    drivers/infiniband/core/cm.c | 34 ++++++++++++++++++------------
    drivers/infiniband/core/user_mad.c | 10 ++++++---
    2 files changed, 28 insertions(+), 16 deletions(-)

    --- a/drivers/infiniband/core/cm.c
    +++ b/drivers/infiniband/core/cm.c
    @@ -380,13 +380,13 @@ static void cm_set_private_data(struct c
    cm_id_priv->private_data_len = private_data_len;
    }

    -static void cm_init_av_for_response(struct cm_port *port, struct ib_wc *wc,
    - struct ib_grh *grh, struct cm_av *av)
    +static int cm_init_av_for_response(struct cm_port *port, struct ib_wc *wc,
    + struct ib_grh *grh, struct cm_av *av)
    {
    av->port = port;
    av->pkey_index = wc->pkey_index;
    - ib_init_ah_from_wc(port->cm_dev->ib_device, port->port_num, wc,
    - grh, &av->ah_attr);
    + return ib_init_ah_from_wc(port->cm_dev->ib_device, port->port_num, wc,
    + grh, &av->ah_attr);
    }

    static int cm_init_av_by_path(struct ib_sa_path_rec *path, struct cm_av *av,
    @@ -1601,9 +1601,11 @@ static int cm_req_handler(struct cm_work

    cm_id_priv = container_of(cm_id, struct cm_id_private, id);
    cm_id_priv->id.remote_id = req_msg->local_comm_id;
    - cm_init_av_for_response(work->port, work->mad_recv_wc->wc,
    - work->mad_recv_wc->recv_buf.grh,
    - &cm_id_priv->av);
    + 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 destroy;
    cm_id_priv->timewait_info = cm_create_timewait_info(cm_id_priv->
    id.local_id);
    if (IS_ERR(cm_id_priv->timewait_info)) {
    @@ -2807,9 +2809,11 @@ 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;
    - cm_init_av_for_response(work->port, work->mad_recv_wc->wc,
    - work->mad_recv_wc->recv_buf.grh,
    - &cm_id_priv->av);
    + 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);
    @@ -3060,6 +3064,7 @@ static int cm_sidr_req_handler(struct cm
    struct cm_id_private *cm_id_priv, *cur_cm_id_priv;
    struct cm_sidr_req_msg *sidr_req_msg;
    struct ib_wc *wc;
    + int ret;

    cm_id = ib_create_cm_id(work->port->cm_dev->ib_device, NULL, NULL);
    if (IS_ERR(cm_id))
    @@ -3072,9 +3077,12 @@ static int cm_sidr_req_handler(struct cm
    wc = work->mad_recv_wc->wc;
    cm_id_priv->av.dgid.global.subnet_prefix = cpu_to_be64(wc->slid);
    cm_id_priv->av.dgid.global.interface_id = 0;
    - cm_init_av_for_response(work->port, work->mad_recv_wc->wc,
    - work->mad_recv_wc->recv_buf.grh,
    - &cm_id_priv->av);
    + 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 out;
    +
    cm_id_priv->id.remote_id = sidr_req_msg->request_id;
    cm_id_priv->tid = sidr_req_msg->hdr.tid;
    atomic_inc(&cm_id_priv->work_count);
    --- a/drivers/infiniband/core/user_mad.c
    +++ b/drivers/infiniband/core/user_mad.c
    @@ -234,10 +234,14 @@ static void recv_handler(struct ib_mad_a
    packet->mad.hdr.grh_present = !!(mad_recv_wc->wc->wc_flags & IB_WC_GRH);
    if (packet->mad.hdr.grh_present) {
    struct ib_ah_attr ah_attr;
    + int ret;

    - ib_init_ah_from_wc(agent->device, agent->port_num,
    - mad_recv_wc->wc, mad_recv_wc->recv_buf.grh,
    - &ah_attr);
    + ret = ib_init_ah_from_wc(agent->device, agent->port_num,
    + mad_recv_wc->wc,
    + mad_recv_wc->recv_buf.grh,
    + &ah_attr);
    + if (ret)
    + goto err2;

    packet->mad.hdr.gid_index = ah_attr.grh.sgid_index;
    packet->mad.hdr.hop_limit = ah_attr.grh.hop_limit;
    \
     
     \ /
      Last update: 2019-02-03 15:02    [W:3.274 / U:0.736 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site