hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/net/rds/rdma_transport.c
....@@ -43,6 +43,9 @@
4343 static struct rdma_cm_id *rds6_rdma_listen_id;
4444 #endif
4545
46
+/* Per IB specification 7.7.3, service level is a 4-bit field. */
47
+#define TOS_TO_SL(tos) ((tos) & 0xF)
48
+
4649 static int rds_rdma_cm_event_handler_cmn(struct rdma_cm_id *cm_id,
4750 struct rdma_cm_event *event,
4851 bool isv6)
....@@ -51,6 +54,8 @@
5154 struct rds_connection *conn = cm_id->context;
5255 struct rds_transport *trans;
5356 int ret = 0;
57
+ int *err;
58
+ u8 len;
5459
5560 rdsdebug("conn %p id %p handling event %u (%s)\n", conn, cm_id,
5661 event->event, rdma_event_msg(event->event));
....@@ -81,9 +86,12 @@
8186 break;
8287
8388 case RDMA_CM_EVENT_ADDR_RESOLVED:
84
- /* XXX do we need to clean up if this fails? */
85
- ret = rdma_resolve_route(cm_id,
89
+ if (conn) {
90
+ rdma_set_service_type(cm_id, conn->c_tos);
91
+ /* XXX do we need to clean up if this fails? */
92
+ ret = rdma_resolve_route(cm_id,
8693 RDS_RDMA_RESOLVE_TIMEOUT_MS);
94
+ }
8795 break;
8896
8997 case RDMA_CM_EVENT_ROUTE_RESOLVED:
....@@ -94,21 +102,39 @@
94102 struct rds_ib_connection *ibic;
95103
96104 ibic = conn->c_transport_data;
97
- if (ibic && ibic->i_cm_id == cm_id)
105
+ if (ibic && ibic->i_cm_id == cm_id) {
106
+ cm_id->route.path_rec[0].sl =
107
+ TOS_TO_SL(conn->c_tos);
98108 ret = trans->cm_initiate_connect(cm_id, isv6);
99
- else
109
+ } else {
100110 rds_conn_drop(conn);
111
+ }
101112 }
102113 break;
103114
104115 case RDMA_CM_EVENT_ESTABLISHED:
105
- trans->cm_connect_complete(conn, event);
116
+ if (conn)
117
+ trans->cm_connect_complete(conn, event);
106118 break;
107119
108120 case RDMA_CM_EVENT_REJECTED:
121
+ if (!conn)
122
+ break;
123
+ err = (int *)rdma_consumer_reject_data(cm_id, event, &len);
124
+ if (!err ||
125
+ (err && len >= sizeof(*err) &&
126
+ ((*err) <= RDS_RDMA_REJ_INCOMPAT))) {
127
+ pr_warn("RDS/RDMA: conn <%pI6c, %pI6c> rejected, dropping connection\n",
128
+ &conn->c_laddr, &conn->c_faddr);
129
+
130
+ if (!conn->c_tos)
131
+ conn->c_proposed_version = RDS_PROTOCOL_COMPAT_VERSION;
132
+
133
+ rds_conn_drop(conn);
134
+ }
109135 rdsdebug("Connection rejected: %s\n",
110136 rdma_reject_msg(cm_id, event->status));
111
- /* FALLTHROUGH */
137
+ break;
112138 case RDMA_CM_EVENT_ADDR_ERROR:
113139 case RDMA_CM_EVENT_ROUTE_ERROR:
114140 case RDMA_CM_EVENT_CONNECT_ERROR:
....@@ -120,6 +146,8 @@
120146 break;
121147
122148 case RDMA_CM_EVENT_DISCONNECTED:
149
+ if (!conn)
150
+ break;
123151 rdsdebug("DISCONNECT event - dropping connection "
124152 "%pI6c->%pI6c\n", &conn->c_laddr,
125153 &conn->c_faddr);