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>
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,
* 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);
&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);
}
"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;
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;
int c_to_index;
unsigned int c_reconnect;
-
/* Qos support */
u8 c_tos;
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);