From: Bang Nguyen Date: Fri, 19 Jul 2013 17:28:26 +0000 (-0700) Subject: RDS: Fix a bug in QoS protocol negotiation X-Git-Tag: v4.1.12-92~293^2^2~53 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=93d77cb23ffa4cf100d2262c8314634ea7bbe457;p=users%2Fjedix%2Flinux-maple.git RDS: Fix a bug in QoS protocol negotiation Fix bug that may cause the connection to downgrade to lower protocol. Also, don't negotiate protocol on reconnect. Orabug: 17079972 Signed-off-by: Giri adari (cherry picked from commit 4962a6def99ce1b80212198ebc96700a51dee694) --- diff --git a/net/rds/connection.c b/net/rds/connection.c index e21fc5f0a9dc..069ffcf1002b 100644 --- a/net/rds/connection.c +++ b/net/rds/connection.c @@ -589,11 +589,20 @@ void rds_conn_drop(struct rds_connection *conn) conn->c_reconnect_warn = 1; conn->c_reconnect_drops = 0; conn->c_reconnect_err = 0; + printk(KERN_INFO "RDS/IB: connection " + "<%u.%u.%u.%u,%u.%u.%u.%u,%d> dropped\n", + NIPQUAD(conn->c_laddr), + NIPQUAD(conn->c_faddr), + conn->c_tos); } else if ((conn->c_reconnect_warn) && (now - conn->c_reconnect_start > 60)) { - printk(KERN_INFO "RDS/IB: re-connect to %u.%u.%u.%u is " - "stalling for more than 1 min...(drops=%u err=%d)\n", - NIPQUAD(conn->c_faddr), conn->c_reconnect_drops, + printk(KERN_INFO "RDS/IB: re-connect " + "<%u.%u.%u.%u,%u.%u.%u.%u,%d> stalling " + "for more than 1 min...(drops=%u err=%d)\n", + NIPQUAD(conn->c_laddr), + NIPQUAD(conn->c_faddr), + conn->c_tos, + conn->c_reconnect_drops, conn->c_reconnect_err); conn->c_reconnect_warn = 0; } diff --git a/net/rds/ib_cm.c b/net/rds/ib_cm.c index 8ef5e4498b0a..ccb5d7f1791c 100644 --- a/net/rds/ib_cm.c +++ b/net/rds/ib_cm.c @@ -728,6 +728,22 @@ int rds_ib_cm_handle_connect(struct rdma_cm_id *cm_id, goto out; } + if (conn->c_reconnect && (conn->c_version != version)) { + printk(KERN_WARNING "RDS/IB: connection " + "<%u.%u.%u.%u,%u.%u.%u.%u,%d,%u.%u> rejecting version " + "(%u/%u)\n", + NIPQUAD(conn->c_laddr), + NIPQUAD(conn->c_faddr), + conn->c_tos, + RDS_PROTOCOL_MAJOR(conn->c_version), + RDS_PROTOCOL_MINOR(conn->c_version), + RDS_PROTOCOL_MAJOR(version), + RDS_PROTOCOL_MINOR(version)); + + conn = NULL; + goto out; + } + /* * The connection request may occur while the * previous connection exist, e.g. in case of failover. @@ -759,9 +775,12 @@ int rds_ib_cm_handle_connect(struct rdma_cm_id *cm_id, */ if (now > conn->c_connection_start && now - conn->c_connection_start > 15) { - printk(KERN_CRIT "rds connection racing for 15s, forcing reset " - "connection %u.%u.%u.%u->%u.%u.%u.%u\n", - NIPQUAD(conn->c_laddr), NIPQUAD(conn->c_faddr)); + printk(KERN_CRIT "RDS/IB: connection " + "<%u.%u.%u.%u,%u.%u.%u.%u,%d> " + "racing for 15s, forcing reset ", + NIPQUAD(conn->c_laddr), + NIPQUAD(conn->c_faddr), + conn->c_tos); rds_conn_drop(conn); rds_ib_stats_inc(s_ib_listen_closed_stale); } else { @@ -851,7 +870,7 @@ int rds_ib_cm_initiate_connect(struct rdma_cm_id *cm_id) /* If the peer doesn't do protocol negotiation, we must * default to RDSv3.0 */ - rds_ib_set_protocol(conn, RDS_PROTOCOL_4_0); + rds_ib_set_protocol(conn, RDS_PROTOCOL_4_1); ic->i_flowctl = rds_ib_sysctl_flow_control; /* advertise flow control */ ret = rds_ib_setup_qp(conn); diff --git a/net/rds/rdma_transport.c b/net/rds/rdma_transport.c index f7f87bb83b16..407e13166deb 100644 --- a/net/rds/rdma_transport.c +++ b/net/rds/rdma_transport.c @@ -40,7 +40,7 @@ #include #include -#define RDS_IB_REJ_CONSUMER_DEFINED 28 +#define RDS_REJ_CONSUMER_DEFINED 28 static struct rdma_cm_id *rds_iw_listen_id; @@ -186,18 +186,22 @@ int rds_rdma_cm_event_handler(struct rdma_cm_id *cm_id, case RDMA_CM_EVENT_REJECTED: err = (int *)event->param.conn.private_data; if (conn) { - if ((*err) == 0 && - event->status == RDS_IB_REJ_CONSUMER_DEFINED) { - /* rejection from 3.x protocol */ - if (!conn->c_tos) { - /* retry the connect with a - * lower compatible protocol */ + if (!conn->c_reconnect) { + if ((*err) == 0 && + event->status == RDS_REJ_CONSUMER_DEFINED) { + /* rejection from 3.x protocol */ + if (!conn->c_tos) { + /* retry the connect with a + lower compatible protocol */ + conn->c_proposed_version = + RDS_PROTOCOL_COMPAT_VERSION; + } + } else { conn->c_proposed_version = - RDS_PROTOCOL_COMPAT_VERSION; - rds_conn_drop(conn); + RDS_PROTOCOL_VERSION; } - } else - rds_conn_drop(conn); + } + rds_conn_drop(conn); } break;