]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
net/rds: prevent RDS connections using stale ARP entries
authorWei Lin Guay <wei.lin.guay@oracle.com>
Mon, 19 Mar 2018 13:26:34 +0000 (14:26 +0100)
committerBrian Maly <brian.maly@oracle.com>
Tue, 12 Jun 2018 00:39:10 +0000 (20:39 -0400)
Active bonding fallback is an asynchronous event in the cluster. Thus,
there is a potential race where a host has sent out a CM REQ, using a
wrong remote gid, before IP migration happens at the remote end. The
side effect of this issue causes RDS connections only use one physical
IB port. When that particular IB port goes down, it causes send
completion error on those RDS connections and eventually increases the
brownout time.

To avoid this phenomenon, RDS has to reject all incoming CM REQ after
RDMA_CM_EVENT_DISCONNECTED or RDMA_CM_EVENT_ADDR_CHANGE events until
route resolution has been performed locally. By doing so, we can
ensure that the gratituos ARPs are sent to the remote end and RDS
connections are established based on the correct ARP entries.

Orabug: 28149101

Signed-off-by: Wei Lin Guay <wei.lin.guay@oracle.com>
Tested-by: Dib Chatterjee <dib.chatterjee@oracle.com>
(cherry picked from commit d7f00e2a0d30b0f14a763d96e6c8ae2ddb40a281
repo https://linux-git.us.oracle.com/UEK/linux-wguay-public)

Signed-off-by: Brian Maly <brian.maly@oracle.com>
Conflicts:
net/rds/rds.h
net/rds/ib_cm.c

Fixed checkpatch issues.

Signed-off-by: HÃ¥kon Bugge <haakon.bugge@oracle.com>
Reviewed-by: Shannon Nelson <shannon.nelson@oracle.com>
Reviewed-by: Zhu Yanjun <yanjun.zhu@oracle.com>
Signed-off-by: Brian Maly <brian.maly@oracle.com>
net/rds/ib_cm.c
net/rds/rdma_transport.c
net/rds/rds.h
net/rds/threads.c

index 54a5d3d58461961c891970a52b0af2e1d7a766ae..53debab967c83337bc3300ff0922d6da6034818e 100644 (file)
@@ -1066,6 +1066,18 @@ int rds_ib_cm_handle_connect(struct rdma_cm_id *cm_id,
        mutex_lock(&conn->c_cm_lock);
        ic = conn->c_transport_data;
 
+       if (conn->c_route && !rds_conn_self_loopback_passive(conn)) {
+               rds_rtd_ptr(RDS_RTD_CM,
+                           "no route resolution saddr %pI4 daddr %pI4 RDSv%u.%u lguid 0x%llx fguid 0x%llx tos %d\n",
+                           saddr6, daddr6,
+                           RDS_PROTOCOL_MAJOR(version),
+                           RDS_PROTOCOL_MINOR(version),
+                           (unsigned long long)be64_to_cpu(lguid),
+                           (unsigned long long)be64_to_cpu(fguid),
+                           dp_cmn->ricpc_tos);
+               goto out;
+       }
+
        if (ic && cm_seq_check_enable) {
                if (cm_req_seq != ic->i_prev_seq) {
                        rds_rtd(RDS_RTD_CM_EXT_P,
index 6ae9aa0670f64c31be2359a1fe7862f8cc33920f..5d86ab12553fa9f11232b744a0d5319e34c2de04 100644 (file)
@@ -164,6 +164,7 @@ int rds_rdma_cm_event_handler_cmn(struct rdma_cm_id *cm_id,
                                 * needs to update the sl manually. As for now, RDS is assuming
                                 * that it is a 1:1 in tos to sl mapping.
                                 */
+                               conn->c_route = 0;
                                cm_id->route.path_rec[0].sl = TOS_TO_SL(conn->c_tos);
                                cm_id->route.path_rec[0].qos_class = conn->c_tos;
                                ret = trans->cm_initiate_connect(cm_id, isv6);
@@ -291,6 +292,8 @@ int rds_rdma_cm_event_handler_cmn(struct rdma_cm_id *cm_id,
                                    &conn->c_laddr, &conn->c_faddr,
                                    conn->c_tos);
                        conn->c_reconnect_racing = 0;
+                       /* reset route resolution flag */
+                       conn->c_route = 1;
                        if (!rds_conn_self_loopback_passive(conn))
                                rds_conn_drop(conn, DR_IB_ADDR_CHANGE);
                }
@@ -301,6 +304,8 @@ int rds_rdma_cm_event_handler_cmn(struct rdma_cm_id *cm_id,
                            "DISCONNECT event - dropping connection %pI6c->%pI6c tos %d\n",
                            &conn->c_laddr, &conn->c_faddr, conn->c_tos);
                conn->c_reconnect_racing = 0;
+               /* reset route resolution flag */
+               conn->c_route = 1;
                rds_conn_drop(conn, DR_IB_DISCONNECTED_EVENT);
                break;
 
index 59f6063c3032b5abf6c3c258eee78dcb1ac3ff0d..efd4e2532bddc414a86a9d3c234ca793a6549f16 100644 (file)
@@ -286,7 +286,7 @@ struct rds_conn_path {
        unsigned int            cp_rdsinfo_pending;
 
        unsigned int            cp_reconnect_racing;
-
+       unsigned int            cp_route_resolved;
        enum rds_conn_drop_src  cp_drop_source;
 
        unsigned char           cp_acl_init;
@@ -327,7 +327,6 @@ struct rds_connection {
        int                     c_to_index;
 
        unsigned int            c_reconnect;
-
        /* Qos support */
        u8                      c_tos;
 
index cc58563c6ba97b23bf1f69c044f24dd6b15cee4f..5a81e321d13cc4dea816f758e5f632f816b50278 100644 (file)
@@ -102,6 +102,8 @@ void rds_connect_path_complete(struct rds_conn_path *cp, int curr)
 
        cp->cp_connection_start = get_seconds();
        cp->cp_reconnect = 1;
+       /* reset route resolution flag */
+       cp->cp_route_resolved = 0;
        conn->c_proposed_version = RDS_PROTOCOL_VERSION;
 }
 EXPORT_SYMBOL_GPL(rds_connect_path_complete);