]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
IB/mlx4: Fix CM REQ retries in paravirt mode
authorHåkon Bugge <Haakon.Bugge@oracle.com>
Mon, 19 Jun 2017 10:23:03 +0000 (12:23 +0200)
committerChuck Anderson <chuck.anderson@oracle.com>
Fri, 23 Jun 2017 04:20:00 +0000 (21:20 -0700)
CM REQs cannot be successfully retried, because a new pv_cm_id is
created for each request, without checking if one already exists.

This commit fixes this, by checking if an id exists before creating
one.

This bug can be provoked by running an RDMA CM user-land application,
but inserting a five seconds delay before the rdma_accept() call on
the passive side. This delay is larger than the default CMA timeout,
and triggers a retry from the active side. The retried REQ will use
another pv_cm_id (the cm_id on the wire). This confuses the CM
protocol and two REJs are sent from the passive side.

This commit is required to achieve the reduced HA Brownout time,
needed by Exadata. The Brownout issue is tracked by orabug 25521901.

Orabug: 26287667

Suggested-by: Venkat Venkatsubra <venkat.x.venkatsubra@oracle.com>
Signed-off-by: Håkon Bugge <haakon.bugge@oracle.com>
Reported-by: Wei Lin Guay <wei.lin.guay@oracle.com>
Tested-by: Wei Lin Guay <wei.lin.guay@oracle.com>
Reviewed-by: Yuval Shaia <yuval.shaia@oracle.com>
drivers/infiniband/hw/mlx4/cm.c

index a21b5ddcbaf6eb8d46d7159d66eee02c89cac47d..160c1326f547c980b87812ed18f6d9650f76e204 100644 (file)
@@ -325,6 +325,9 @@ int mlx4_ib_multiplex_cm_handler(struct ib_device *ibdev, int port, int slave_id
                        mad->mad_hdr.attr_id == CM_REP_ATTR_ID ||
                        mad->mad_hdr.attr_id == CM_SIDR_REQ_ATTR_ID) {
                sl_cm_id = get_local_comm_id(mad);
+               id = id_map_get(ibdev, &pv_cm_id, slave_id, sl_cm_id);
+               if (id)
+                       goto cont;
                id = id_map_alloc(ibdev, slave_id, sl_cm_id);
                if (IS_ERR(id)) {
                        mlx4_ib_warn(ibdev, "%s: id{slave: %d, sl_cm_id: 0x%x} Failed to id_map_alloc\n",
@@ -345,6 +348,7 @@ int mlx4_ib_multiplex_cm_handler(struct ib_device *ibdev, int port, int slave_id
                return -EINVAL;
        }
 
+cont:
        set_local_comm_id(mad, id->pv_cm_id);
 
        if (mad->mad_hdr.attr_id == CM_DREQ_ATTR_ID)