.. | .. |
---|
1 | 1 | /* |
---|
2 | | - * Copyright (c) 2006, 2018 Oracle and/or its affiliates. All rights reserved. |
---|
| 2 | + * Copyright (c) 2006, 2019 Oracle and/or its affiliates. All rights reserved. |
---|
3 | 3 | * |
---|
4 | 4 | * This software is available to you under a choice of one of two |
---|
5 | 5 | * licenses. You may choose to be licensed under the terms of the GNU |
---|
.. | .. |
---|
87 | 87 | |
---|
88 | 88 | spin_lock_irqsave(&rds_ibdev->spinlock, flags); |
---|
89 | 89 | list_for_each_entry(ic, &rds_ibdev->conn_list, ib_node) |
---|
90 | | - rds_conn_drop(ic->conn); |
---|
| 90 | + rds_conn_path_drop(&ic->conn->c_path[0], true); |
---|
91 | 91 | spin_unlock_irqrestore(&rds_ibdev->spinlock, flags); |
---|
92 | 92 | } |
---|
93 | 93 | |
---|
.. | .. |
---|
125 | 125 | queue_work(rds_wq, &rds_ibdev->free_work); |
---|
126 | 126 | } |
---|
127 | 127 | |
---|
128 | | -static void rds_ib_add_one(struct ib_device *device) |
---|
| 128 | +static int rds_ib_add_one(struct ib_device *device) |
---|
129 | 129 | { |
---|
130 | 130 | struct rds_ib_device *rds_ibdev; |
---|
131 | | - bool has_fr, has_fmr; |
---|
| 131 | + int ret; |
---|
132 | 132 | |
---|
133 | 133 | /* Only handle IB (no iWARP) devices */ |
---|
134 | 134 | if (device->node_type != RDMA_NODE_IB_CA) |
---|
135 | | - return; |
---|
| 135 | + return -EOPNOTSUPP; |
---|
| 136 | + |
---|
| 137 | + /* Device must support FRWR */ |
---|
| 138 | + if (!(device->attrs.device_cap_flags & IB_DEVICE_MEM_MGT_EXTENSIONS)) |
---|
| 139 | + return -EOPNOTSUPP; |
---|
136 | 140 | |
---|
137 | 141 | rds_ibdev = kzalloc_node(sizeof(struct rds_ib_device), GFP_KERNEL, |
---|
138 | 142 | ibdev_to_node(device)); |
---|
139 | 143 | if (!rds_ibdev) |
---|
140 | | - return; |
---|
| 144 | + return -ENOMEM; |
---|
141 | 145 | |
---|
142 | 146 | spin_lock_init(&rds_ibdev->spinlock); |
---|
143 | 147 | refcount_set(&rds_ibdev->refcount, 1); |
---|
.. | .. |
---|
149 | 153 | rds_ibdev->max_wrs = device->attrs.max_qp_wr; |
---|
150 | 154 | rds_ibdev->max_sge = min(device->attrs.max_send_sge, RDS_IB_MAX_SGE); |
---|
151 | 155 | |
---|
152 | | - has_fr = (device->attrs.device_cap_flags & |
---|
153 | | - IB_DEVICE_MEM_MGT_EXTENSIONS); |
---|
154 | | - has_fmr = (device->alloc_fmr && device->dealloc_fmr && |
---|
155 | | - device->map_phys_fmr && device->unmap_fmr); |
---|
156 | | - rds_ibdev->use_fastreg = (has_fr && !has_fmr); |
---|
| 156 | + rds_ibdev->odp_capable = |
---|
| 157 | + !!(device->attrs.device_cap_flags & |
---|
| 158 | + IB_DEVICE_ON_DEMAND_PAGING) && |
---|
| 159 | + !!(device->attrs.odp_caps.per_transport_caps.rc_odp_caps & |
---|
| 160 | + IB_ODP_SUPPORT_WRITE) && |
---|
| 161 | + !!(device->attrs.odp_caps.per_transport_caps.rc_odp_caps & |
---|
| 162 | + IB_ODP_SUPPORT_READ); |
---|
157 | 163 | |
---|
158 | | - rds_ibdev->fmr_max_remaps = device->attrs.max_map_per_fmr?: 32; |
---|
159 | 164 | rds_ibdev->max_1m_mrs = device->attrs.max_mr ? |
---|
160 | 165 | min_t(unsigned int, (device->attrs.max_mr / 2), |
---|
161 | 166 | rds_ib_mr_1m_pool_size) : rds_ib_mr_1m_pool_size; |
---|
.. | .. |
---|
173 | 178 | if (!rds_ibdev->vector_load) { |
---|
174 | 179 | pr_err("RDS/IB: %s failed to allocate vector memory\n", |
---|
175 | 180 | __func__); |
---|
| 181 | + ret = -ENOMEM; |
---|
176 | 182 | goto put_dev; |
---|
177 | 183 | } |
---|
178 | 184 | |
---|
179 | 185 | rds_ibdev->dev = device; |
---|
180 | 186 | rds_ibdev->pd = ib_alloc_pd(device, 0); |
---|
181 | 187 | if (IS_ERR(rds_ibdev->pd)) { |
---|
| 188 | + ret = PTR_ERR(rds_ibdev->pd); |
---|
182 | 189 | rds_ibdev->pd = NULL; |
---|
183 | 190 | goto put_dev; |
---|
184 | 191 | } |
---|
.. | .. |
---|
186 | 193 | rds_ibdev->mr_1m_pool = |
---|
187 | 194 | rds_ib_create_mr_pool(rds_ibdev, RDS_IB_MR_1M_POOL); |
---|
188 | 195 | if (IS_ERR(rds_ibdev->mr_1m_pool)) { |
---|
| 196 | + ret = PTR_ERR(rds_ibdev->mr_1m_pool); |
---|
189 | 197 | rds_ibdev->mr_1m_pool = NULL; |
---|
190 | 198 | goto put_dev; |
---|
191 | 199 | } |
---|
.. | .. |
---|
193 | 201 | rds_ibdev->mr_8k_pool = |
---|
194 | 202 | rds_ib_create_mr_pool(rds_ibdev, RDS_IB_MR_8K_POOL); |
---|
195 | 203 | if (IS_ERR(rds_ibdev->mr_8k_pool)) { |
---|
| 204 | + ret = PTR_ERR(rds_ibdev->mr_8k_pool); |
---|
196 | 205 | rds_ibdev->mr_8k_pool = NULL; |
---|
197 | 206 | goto put_dev; |
---|
198 | 207 | } |
---|
199 | 208 | |
---|
200 | | - rdsdebug("RDS/IB: max_mr = %d, max_wrs = %d, max_sge = %d, fmr_max_remaps = %d, max_1m_mrs = %d, max_8k_mrs = %d\n", |
---|
201 | | - device->attrs.max_fmr, rds_ibdev->max_wrs, rds_ibdev->max_sge, |
---|
202 | | - rds_ibdev->fmr_max_remaps, rds_ibdev->max_1m_mrs, |
---|
203 | | - rds_ibdev->max_8k_mrs); |
---|
| 209 | + rdsdebug("RDS/IB: max_mr = %d, max_wrs = %d, max_sge = %d, max_1m_mrs = %d, max_8k_mrs = %d\n", |
---|
| 210 | + device->attrs.max_mr, rds_ibdev->max_wrs, rds_ibdev->max_sge, |
---|
| 211 | + rds_ibdev->max_1m_mrs, rds_ibdev->max_8k_mrs); |
---|
204 | 212 | |
---|
205 | | - pr_info("RDS/IB: %s: %s supported and preferred\n", |
---|
206 | | - device->name, |
---|
207 | | - rds_ibdev->use_fastreg ? "FRMR" : "FMR"); |
---|
| 213 | + pr_info("RDS/IB: %s: added\n", device->name); |
---|
208 | 214 | |
---|
209 | 215 | down_write(&rds_ib_devices_lock); |
---|
210 | 216 | list_add_tail_rcu(&rds_ibdev->list, &rds_ib_devices); |
---|
.. | .. |
---|
212 | 218 | refcount_inc(&rds_ibdev->refcount); |
---|
213 | 219 | |
---|
214 | 220 | ib_set_client_data(device, &rds_ib_client, rds_ibdev); |
---|
215 | | - refcount_inc(&rds_ibdev->refcount); |
---|
216 | 221 | |
---|
217 | 222 | rds_ib_nodev_connect(); |
---|
| 223 | + return 0; |
---|
218 | 224 | |
---|
219 | 225 | put_dev: |
---|
220 | 226 | rds_ib_dev_put(rds_ibdev); |
---|
| 227 | + return ret; |
---|
221 | 228 | } |
---|
222 | 229 | |
---|
223 | 230 | /* |
---|
.. | .. |
---|
259 | 266 | { |
---|
260 | 267 | struct rds_ib_device *rds_ibdev = client_data; |
---|
261 | 268 | |
---|
262 | | - if (!rds_ibdev) |
---|
263 | | - return; |
---|
264 | | - |
---|
265 | 269 | rds_ib_dev_shutdown(rds_ibdev); |
---|
266 | 270 | |
---|
267 | 271 | /* stop connection attempts from getting a reference to this device. */ |
---|
.. | .. |
---|
291 | 295 | void *buffer) |
---|
292 | 296 | { |
---|
293 | 297 | struct rds_info_rdma_connection *iinfo = buffer; |
---|
294 | | - struct rds_ib_connection *ic; |
---|
| 298 | + struct rds_ib_connection *ic = conn->c_transport_data; |
---|
295 | 299 | |
---|
296 | 300 | /* We will only ever look at IB transports */ |
---|
297 | 301 | if (conn->c_trans != &rds_ib_transport) |
---|
.. | .. |
---|
301 | 305 | |
---|
302 | 306 | iinfo->src_addr = conn->c_laddr.s6_addr32[3]; |
---|
303 | 307 | iinfo->dst_addr = conn->c_faddr.s6_addr32[3]; |
---|
| 308 | + if (ic) { |
---|
| 309 | + iinfo->tos = conn->c_tos; |
---|
| 310 | + iinfo->sl = ic->i_sl; |
---|
| 311 | + } |
---|
304 | 312 | |
---|
305 | 313 | memset(&iinfo->src_gid, 0, sizeof(iinfo->src_gid)); |
---|
306 | 314 | memset(&iinfo->dst_gid, 0, sizeof(iinfo->dst_gid)); |
---|
307 | 315 | if (rds_conn_state(conn) == RDS_CONN_UP) { |
---|
308 | 316 | struct rds_ib_device *rds_ibdev; |
---|
309 | | - |
---|
310 | | - ic = conn->c_transport_data; |
---|
311 | 317 | |
---|
312 | 318 | rdma_read_gids(ic->i_cm_id, (union ib_gid *)&iinfo->src_gid, |
---|
313 | 319 | (union ib_gid *)&iinfo->dst_gid); |
---|
.. | .. |
---|
317 | 323 | iinfo->max_recv_wr = ic->i_recv_ring.w_nr; |
---|
318 | 324 | iinfo->max_send_sge = rds_ibdev->max_sge; |
---|
319 | 325 | rds_ib_get_mr_info(rds_ibdev, iinfo); |
---|
| 326 | + iinfo->cache_allocs = atomic_read(&ic->i_cache_allocs); |
---|
320 | 327 | } |
---|
321 | 328 | return 1; |
---|
322 | 329 | } |
---|
.. | .. |
---|
327 | 334 | void *buffer) |
---|
328 | 335 | { |
---|
329 | 336 | struct rds6_info_rdma_connection *iinfo6 = buffer; |
---|
330 | | - struct rds_ib_connection *ic; |
---|
| 337 | + struct rds_ib_connection *ic = conn->c_transport_data; |
---|
331 | 338 | |
---|
332 | 339 | /* We will only ever look at IB transports */ |
---|
333 | 340 | if (conn->c_trans != &rds_ib_transport) |
---|
.. | .. |
---|
335 | 342 | |
---|
336 | 343 | iinfo6->src_addr = conn->c_laddr; |
---|
337 | 344 | iinfo6->dst_addr = conn->c_faddr; |
---|
| 345 | + if (ic) { |
---|
| 346 | + iinfo6->tos = conn->c_tos; |
---|
| 347 | + iinfo6->sl = ic->i_sl; |
---|
| 348 | + } |
---|
338 | 349 | |
---|
339 | 350 | memset(&iinfo6->src_gid, 0, sizeof(iinfo6->src_gid)); |
---|
340 | 351 | memset(&iinfo6->dst_gid, 0, sizeof(iinfo6->dst_gid)); |
---|
.. | .. |
---|
342 | 353 | if (rds_conn_state(conn) == RDS_CONN_UP) { |
---|
343 | 354 | struct rds_ib_device *rds_ibdev; |
---|
344 | 355 | |
---|
345 | | - ic = conn->c_transport_data; |
---|
346 | 356 | rdma_read_gids(ic->i_cm_id, (union ib_gid *)&iinfo6->src_gid, |
---|
347 | 357 | (union ib_gid *)&iinfo6->dst_gid); |
---|
348 | 358 | rds_ibdev = ic->rds_ibdev; |
---|
.. | .. |
---|
350 | 360 | iinfo6->max_recv_wr = ic->i_recv_ring.w_nr; |
---|
351 | 361 | iinfo6->max_send_sge = rds_ibdev->max_sge; |
---|
352 | 362 | rds6_ib_get_mr_info(rds_ibdev, iinfo6); |
---|
| 363 | + iinfo6->cache_allocs = atomic_read(&ic->i_cache_allocs); |
---|
353 | 364 | } |
---|
354 | 365 | return 1; |
---|
355 | 366 | } |
---|
.. | .. |
---|
514 | 525 | rds_ib_mr_exit(); |
---|
515 | 526 | } |
---|
516 | 527 | |
---|
| 528 | +static u8 rds_ib_get_tos_map(u8 tos) |
---|
| 529 | +{ |
---|
| 530 | + /* 1:1 user to transport map for RDMA transport. |
---|
| 531 | + * In future, if custom map is desired, hook can export |
---|
| 532 | + * user configurable map. |
---|
| 533 | + */ |
---|
| 534 | + return tos; |
---|
| 535 | +} |
---|
| 536 | + |
---|
517 | 537 | struct rds_transport rds_ib_transport = { |
---|
518 | 538 | .laddr_check = rds_ib_laddr_check, |
---|
519 | 539 | .xmit_path_complete = rds_ib_xmit_path_complete, |
---|
.. | .. |
---|
536 | 556 | .sync_mr = rds_ib_sync_mr, |
---|
537 | 557 | .free_mr = rds_ib_free_mr, |
---|
538 | 558 | .flush_mrs = rds_ib_flush_mrs, |
---|
| 559 | + .get_tos_map = rds_ib_get_tos_map, |
---|
539 | 560 | .t_owner = THIS_MODULE, |
---|
540 | 561 | .t_name = "infiniband", |
---|
541 | 562 | .t_unloading = rds_ib_is_unloading, |
---|