| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (c) 2016 Mellanox Technologies Ltd. All rights reserved. |
|---|
| 3 | 4 | * Copyright (c) 2015 System Fabric Works, Inc. All rights reserved. |
|---|
| 4 | | - * |
|---|
| 5 | | - * This software is available to you under a choice of one of two |
|---|
| 6 | | - * licenses. You may choose to be licensed under the terms of the GNU |
|---|
| 7 | | - * General Public License (GPL) Version 2, available from the file |
|---|
| 8 | | - * COPYING in the main directory of this source tree, or the |
|---|
| 9 | | - * OpenIB.org BSD license below: |
|---|
| 10 | | - * |
|---|
| 11 | | - * Redistribution and use in source and binary forms, with or |
|---|
| 12 | | - * without modification, are permitted provided that the following |
|---|
| 13 | | - * conditions are met: |
|---|
| 14 | | - * |
|---|
| 15 | | - * - Redistributions of source code must retain the above |
|---|
| 16 | | - * copyright notice, this list of conditions and the following |
|---|
| 17 | | - * disclaimer. |
|---|
| 18 | | - * |
|---|
| 19 | | - * - Redistributions in binary form must reproduce the above |
|---|
| 20 | | - * copyright notice, this list of conditions and the following |
|---|
| 21 | | - * disclaimer in the documentation and/or other materials |
|---|
| 22 | | - * provided with the distribution. |
|---|
| 23 | | - * |
|---|
| 24 | | - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
|---|
| 25 | | - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
|---|
| 26 | | - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
|---|
| 27 | | - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS |
|---|
| 28 | | - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN |
|---|
| 29 | | - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
|---|
| 30 | | - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
|---|
| 31 | | - * SOFTWARE. |
|---|
| 32 | 5 | */ |
|---|
| 33 | 6 | |
|---|
| 34 | 7 | #include <linux/dma-mapping.h> |
|---|
| 35 | 8 | #include <net/addrconf.h> |
|---|
| 9 | +#include <rdma/uverbs_ioctl.h> |
|---|
| 36 | 10 | #include "rxe.h" |
|---|
| 37 | 11 | #include "rxe_loc.h" |
|---|
| 38 | 12 | #include "rxe_queue.h" |
|---|
| .. | .. |
|---|
| 56 | 30 | { |
|---|
| 57 | 31 | struct rxe_dev *rxe = to_rdev(dev); |
|---|
| 58 | 32 | struct rxe_port *port; |
|---|
| 59 | | - int rc = -EINVAL; |
|---|
| 60 | | - |
|---|
| 61 | | - if (unlikely(port_num != 1)) { |
|---|
| 62 | | - pr_warn("invalid port_number %d\n", port_num); |
|---|
| 63 | | - goto out; |
|---|
| 64 | | - } |
|---|
| 33 | + int rc; |
|---|
| 65 | 34 | |
|---|
| 66 | 35 | port = &rxe->port; |
|---|
| 67 | 36 | |
|---|
| .. | .. |
|---|
| 71 | 40 | mutex_lock(&rxe->usdev_lock); |
|---|
| 72 | 41 | rc = ib_get_eth_speed(dev, port_num, &attr->active_speed, |
|---|
| 73 | 42 | &attr->active_width); |
|---|
| 43 | + |
|---|
| 44 | + if (attr->state == IB_PORT_ACTIVE) |
|---|
| 45 | + attr->phys_state = IB_PORT_PHYS_STATE_LINK_UP; |
|---|
| 46 | + else if (dev_get_flags(rxe->ndev) & IFF_UP) |
|---|
| 47 | + attr->phys_state = IB_PORT_PHYS_STATE_POLLING; |
|---|
| 48 | + else |
|---|
| 49 | + attr->phys_state = IB_PORT_PHYS_STATE_DISABLED; |
|---|
| 50 | + |
|---|
| 74 | 51 | mutex_unlock(&rxe->usdev_lock); |
|---|
| 75 | 52 | |
|---|
| 76 | | -out: |
|---|
| 77 | 53 | return rc; |
|---|
| 78 | | -} |
|---|
| 79 | | - |
|---|
| 80 | | -static struct net_device *rxe_get_netdev(struct ib_device *device, |
|---|
| 81 | | - u8 port_num) |
|---|
| 82 | | -{ |
|---|
| 83 | | - struct rxe_dev *rxe = to_rdev(device); |
|---|
| 84 | | - |
|---|
| 85 | | - if (rxe->ndev) { |
|---|
| 86 | | - dev_hold(rxe->ndev); |
|---|
| 87 | | - return rxe->ndev; |
|---|
| 88 | | - } |
|---|
| 89 | | - |
|---|
| 90 | | - return NULL; |
|---|
| 91 | 54 | } |
|---|
| 92 | 55 | |
|---|
| 93 | 56 | static int rxe_query_pkey(struct ib_device *device, |
|---|
| 94 | 57 | u8 port_num, u16 index, u16 *pkey) |
|---|
| 95 | 58 | { |
|---|
| 96 | | - struct rxe_dev *rxe = to_rdev(device); |
|---|
| 97 | | - struct rxe_port *port; |
|---|
| 59 | + if (index > 0) |
|---|
| 60 | + return -EINVAL; |
|---|
| 98 | 61 | |
|---|
| 99 | | - if (unlikely(port_num != 1)) { |
|---|
| 100 | | - dev_warn(device->dev.parent, "invalid port_num = %d\n", |
|---|
| 101 | | - port_num); |
|---|
| 102 | | - goto err1; |
|---|
| 103 | | - } |
|---|
| 104 | | - |
|---|
| 105 | | - port = &rxe->port; |
|---|
| 106 | | - |
|---|
| 107 | | - if (unlikely(index >= port->attr.pkey_tbl_len)) { |
|---|
| 108 | | - dev_warn(device->dev.parent, "invalid index = %d\n", |
|---|
| 109 | | - index); |
|---|
| 110 | | - goto err1; |
|---|
| 111 | | - } |
|---|
| 112 | | - |
|---|
| 113 | | - *pkey = port->pkey_tbl[index]; |
|---|
| 62 | + *pkey = IB_DEFAULT_PKEY_FULL; |
|---|
| 114 | 63 | return 0; |
|---|
| 115 | | - |
|---|
| 116 | | -err1: |
|---|
| 117 | | - return -EINVAL; |
|---|
| 118 | 64 | } |
|---|
| 119 | 65 | |
|---|
| 120 | 66 | static int rxe_modify_device(struct ib_device *dev, |
|---|
| 121 | 67 | int mask, struct ib_device_modify *attr) |
|---|
| 122 | 68 | { |
|---|
| 123 | 69 | struct rxe_dev *rxe = to_rdev(dev); |
|---|
| 70 | + |
|---|
| 71 | + if (mask & ~(IB_DEVICE_MODIFY_SYS_IMAGE_GUID | |
|---|
| 72 | + IB_DEVICE_MODIFY_NODE_DESC)) |
|---|
| 73 | + return -EOPNOTSUPP; |
|---|
| 124 | 74 | |
|---|
| 125 | 75 | if (mask & IB_DEVICE_MODIFY_SYS_IMAGE_GUID) |
|---|
| 126 | 76 | rxe->attr.sys_image_guid = cpu_to_be64(attr->sys_image_guid); |
|---|
| .. | .. |
|---|
| 139 | 89 | struct rxe_dev *rxe = to_rdev(dev); |
|---|
| 140 | 90 | struct rxe_port *port; |
|---|
| 141 | 91 | |
|---|
| 142 | | - if (unlikely(port_num != 1)) { |
|---|
| 143 | | - pr_warn("invalid port_num = %d\n", port_num); |
|---|
| 144 | | - goto err1; |
|---|
| 145 | | - } |
|---|
| 146 | | - |
|---|
| 147 | 92 | port = &rxe->port; |
|---|
| 148 | 93 | |
|---|
| 149 | 94 | port->attr.port_cap_flags |= attr->set_port_cap_mask; |
|---|
| .. | .. |
|---|
| 153 | 98 | port->attr.qkey_viol_cntr = 0; |
|---|
| 154 | 99 | |
|---|
| 155 | 100 | return 0; |
|---|
| 156 | | - |
|---|
| 157 | | -err1: |
|---|
| 158 | | - return -EINVAL; |
|---|
| 159 | 101 | } |
|---|
| 160 | 102 | |
|---|
| 161 | 103 | static enum rdma_link_layer rxe_get_link_layer(struct ib_device *dev, |
|---|
| 162 | 104 | u8 port_num) |
|---|
| 163 | 105 | { |
|---|
| 164 | | - struct rxe_dev *rxe = to_rdev(dev); |
|---|
| 165 | | - |
|---|
| 166 | | - return rxe_link_layer(rxe, port_num); |
|---|
| 106 | + return IB_LINK_LAYER_ETHERNET; |
|---|
| 167 | 107 | } |
|---|
| 168 | 108 | |
|---|
| 169 | | -static struct ib_ucontext *rxe_alloc_ucontext(struct ib_device *dev, |
|---|
| 170 | | - struct ib_udata *udata) |
|---|
| 109 | +static int rxe_alloc_ucontext(struct ib_ucontext *uctx, struct ib_udata *udata) |
|---|
| 171 | 110 | { |
|---|
| 172 | | - struct rxe_dev *rxe = to_rdev(dev); |
|---|
| 173 | | - struct rxe_ucontext *uc; |
|---|
| 111 | + struct rxe_dev *rxe = to_rdev(uctx->device); |
|---|
| 112 | + struct rxe_ucontext *uc = to_ruc(uctx); |
|---|
| 174 | 113 | |
|---|
| 175 | | - uc = rxe_alloc(&rxe->uc_pool); |
|---|
| 176 | | - return uc ? &uc->ibuc : ERR_PTR(-ENOMEM); |
|---|
| 114 | + return rxe_add_to_pool(&rxe->uc_pool, &uc->pelem); |
|---|
| 177 | 115 | } |
|---|
| 178 | 116 | |
|---|
| 179 | | -static int rxe_dealloc_ucontext(struct ib_ucontext *ibuc) |
|---|
| 117 | +static void rxe_dealloc_ucontext(struct ib_ucontext *ibuc) |
|---|
| 180 | 118 | { |
|---|
| 181 | 119 | struct rxe_ucontext *uc = to_ruc(ibuc); |
|---|
| 182 | 120 | |
|---|
| 183 | 121 | rxe_drop_ref(uc); |
|---|
| 184 | | - return 0; |
|---|
| 185 | 122 | } |
|---|
| 186 | 123 | |
|---|
| 187 | 124 | static int rxe_port_immutable(struct ib_device *dev, u8 port_num, |
|---|
| .. | .. |
|---|
| 203 | 140 | return 0; |
|---|
| 204 | 141 | } |
|---|
| 205 | 142 | |
|---|
| 206 | | -static struct ib_pd *rxe_alloc_pd(struct ib_device *dev, |
|---|
| 207 | | - struct ib_ucontext *context, |
|---|
| 208 | | - struct ib_udata *udata) |
|---|
| 143 | +static int rxe_alloc_pd(struct ib_pd *ibpd, struct ib_udata *udata) |
|---|
| 209 | 144 | { |
|---|
| 210 | | - struct rxe_dev *rxe = to_rdev(dev); |
|---|
| 211 | | - struct rxe_pd *pd; |
|---|
| 145 | + struct rxe_dev *rxe = to_rdev(ibpd->device); |
|---|
| 146 | + struct rxe_pd *pd = to_rpd(ibpd); |
|---|
| 212 | 147 | |
|---|
| 213 | | - pd = rxe_alloc(&rxe->pd_pool); |
|---|
| 214 | | - return pd ? &pd->ibpd : ERR_PTR(-ENOMEM); |
|---|
| 148 | + return rxe_add_to_pool(&rxe->pd_pool, &pd->pelem); |
|---|
| 215 | 149 | } |
|---|
| 216 | 150 | |
|---|
| 217 | | -static int rxe_dealloc_pd(struct ib_pd *ibpd) |
|---|
| 151 | +static int rxe_dealloc_pd(struct ib_pd *ibpd, struct ib_udata *udata) |
|---|
| 218 | 152 | { |
|---|
| 219 | 153 | struct rxe_pd *pd = to_rpd(ibpd); |
|---|
| 220 | 154 | |
|---|
| .. | .. |
|---|
| 222 | 156 | return 0; |
|---|
| 223 | 157 | } |
|---|
| 224 | 158 | |
|---|
| 225 | | -static void rxe_init_av(struct rxe_dev *rxe, struct rdma_ah_attr *attr, |
|---|
| 226 | | - struct rxe_av *av) |
|---|
| 227 | | -{ |
|---|
| 228 | | - rxe_av_from_attr(rdma_ah_get_port_num(attr), av, attr); |
|---|
| 229 | | - rxe_av_fill_ip_info(av, attr); |
|---|
| 230 | | -} |
|---|
| 231 | | - |
|---|
| 232 | | -static struct ib_ah *rxe_create_ah(struct ib_pd *ibpd, |
|---|
| 233 | | - struct rdma_ah_attr *attr, |
|---|
| 234 | | - struct ib_udata *udata) |
|---|
| 159 | +static int rxe_create_ah(struct ib_ah *ibah, |
|---|
| 160 | + struct rdma_ah_init_attr *init_attr, |
|---|
| 161 | + struct ib_udata *udata) |
|---|
| 235 | 162 | |
|---|
| 236 | 163 | { |
|---|
| 237 | 164 | int err; |
|---|
| 238 | | - struct rxe_dev *rxe = to_rdev(ibpd->device); |
|---|
| 239 | | - struct rxe_pd *pd = to_rpd(ibpd); |
|---|
| 240 | | - struct rxe_ah *ah; |
|---|
| 165 | + struct rxe_dev *rxe = to_rdev(ibah->device); |
|---|
| 166 | + struct rxe_ah *ah = to_rah(ibah); |
|---|
| 241 | 167 | |
|---|
| 242 | | - err = rxe_av_chk_attr(rxe, attr); |
|---|
| 168 | + err = rxe_av_chk_attr(rxe, init_attr->ah_attr); |
|---|
| 243 | 169 | if (err) |
|---|
| 244 | | - return ERR_PTR(err); |
|---|
| 170 | + return err; |
|---|
| 245 | 171 | |
|---|
| 246 | | - ah = rxe_alloc(&rxe->ah_pool); |
|---|
| 247 | | - if (!ah) |
|---|
| 248 | | - return ERR_PTR(-ENOMEM); |
|---|
| 172 | + err = rxe_add_to_pool(&rxe->ah_pool, &ah->pelem); |
|---|
| 173 | + if (err) |
|---|
| 174 | + return err; |
|---|
| 249 | 175 | |
|---|
| 250 | | - rxe_add_ref(pd); |
|---|
| 251 | | - ah->pd = pd; |
|---|
| 252 | | - |
|---|
| 253 | | - rxe_init_av(rxe, attr, &ah->av); |
|---|
| 254 | | - return &ah->ibah; |
|---|
| 176 | + rxe_init_av(init_attr->ah_attr, &ah->av); |
|---|
| 177 | + return 0; |
|---|
| 255 | 178 | } |
|---|
| 256 | 179 | |
|---|
| 257 | 180 | static int rxe_modify_ah(struct ib_ah *ibah, struct rdma_ah_attr *attr) |
|---|
| .. | .. |
|---|
| 264 | 187 | if (err) |
|---|
| 265 | 188 | return err; |
|---|
| 266 | 189 | |
|---|
| 267 | | - rxe_init_av(rxe, attr, &ah->av); |
|---|
| 190 | + rxe_init_av(attr, &ah->av); |
|---|
| 268 | 191 | return 0; |
|---|
| 269 | 192 | } |
|---|
| 270 | 193 | |
|---|
| .. | .. |
|---|
| 278 | 201 | return 0; |
|---|
| 279 | 202 | } |
|---|
| 280 | 203 | |
|---|
| 281 | | -static int rxe_destroy_ah(struct ib_ah *ibah) |
|---|
| 204 | +static int rxe_destroy_ah(struct ib_ah *ibah, u32 flags) |
|---|
| 282 | 205 | { |
|---|
| 283 | 206 | struct rxe_ah *ah = to_rah(ibah); |
|---|
| 284 | 207 | |
|---|
| 285 | | - rxe_drop_ref(ah->pd); |
|---|
| 286 | 208 | rxe_drop_ref(ah); |
|---|
| 287 | 209 | return 0; |
|---|
| 288 | 210 | } |
|---|
| .. | .. |
|---|
| 334 | 256 | return err; |
|---|
| 335 | 257 | } |
|---|
| 336 | 258 | |
|---|
| 337 | | -static struct ib_srq *rxe_create_srq(struct ib_pd *ibpd, |
|---|
| 338 | | - struct ib_srq_init_attr *init, |
|---|
| 339 | | - struct ib_udata *udata) |
|---|
| 259 | +static int rxe_create_srq(struct ib_srq *ibsrq, struct ib_srq_init_attr *init, |
|---|
| 260 | + struct ib_udata *udata) |
|---|
| 340 | 261 | { |
|---|
| 341 | 262 | int err; |
|---|
| 342 | | - struct rxe_dev *rxe = to_rdev(ibpd->device); |
|---|
| 343 | | - struct rxe_pd *pd = to_rpd(ibpd); |
|---|
| 344 | | - struct rxe_srq *srq; |
|---|
| 345 | | - struct ib_ucontext *context = udata ? ibpd->uobject->context : NULL; |
|---|
| 263 | + struct rxe_dev *rxe = to_rdev(ibsrq->device); |
|---|
| 264 | + struct rxe_pd *pd = to_rpd(ibsrq->pd); |
|---|
| 265 | + struct rxe_srq *srq = to_rsrq(ibsrq); |
|---|
| 346 | 266 | struct rxe_create_srq_resp __user *uresp = NULL; |
|---|
| 347 | 267 | |
|---|
| 348 | 268 | if (udata) { |
|---|
| 349 | 269 | if (udata->outlen < sizeof(*uresp)) |
|---|
| 350 | | - return ERR_PTR(-EINVAL); |
|---|
| 270 | + return -EINVAL; |
|---|
| 351 | 271 | uresp = udata->outbuf; |
|---|
| 352 | 272 | } |
|---|
| 353 | 273 | |
|---|
| .. | .. |
|---|
| 355 | 275 | if (err) |
|---|
| 356 | 276 | goto err1; |
|---|
| 357 | 277 | |
|---|
| 358 | | - srq = rxe_alloc(&rxe->srq_pool); |
|---|
| 359 | | - if (!srq) { |
|---|
| 360 | | - err = -ENOMEM; |
|---|
| 278 | + err = rxe_add_to_pool(&rxe->srq_pool, &srq->pelem); |
|---|
| 279 | + if (err) |
|---|
| 361 | 280 | goto err1; |
|---|
| 362 | | - } |
|---|
| 363 | 281 | |
|---|
| 364 | | - rxe_add_index(srq); |
|---|
| 365 | 282 | rxe_add_ref(pd); |
|---|
| 366 | 283 | srq->pd = pd; |
|---|
| 367 | 284 | |
|---|
| 368 | | - err = rxe_srq_from_init(rxe, srq, init, context, uresp); |
|---|
| 285 | + err = rxe_srq_from_init(rxe, srq, init, udata, uresp); |
|---|
| 369 | 286 | if (err) |
|---|
| 370 | 287 | goto err2; |
|---|
| 371 | 288 | |
|---|
| 372 | | - return &srq->ibsrq; |
|---|
| 289 | + return 0; |
|---|
| 373 | 290 | |
|---|
| 374 | 291 | err2: |
|---|
| 375 | 292 | rxe_drop_ref(pd); |
|---|
| 376 | | - rxe_drop_index(srq); |
|---|
| 377 | 293 | rxe_drop_ref(srq); |
|---|
| 378 | 294 | err1: |
|---|
| 379 | | - return ERR_PTR(err); |
|---|
| 295 | + return err; |
|---|
| 380 | 296 | } |
|---|
| 381 | 297 | |
|---|
| 382 | 298 | static int rxe_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr, |
|---|
| .. | .. |
|---|
| 401 | 317 | if (err) |
|---|
| 402 | 318 | goto err1; |
|---|
| 403 | 319 | |
|---|
| 404 | | - err = rxe_srq_from_attr(rxe, srq, attr, mask, &ucmd); |
|---|
| 320 | + err = rxe_srq_from_attr(rxe, srq, attr, mask, &ucmd, udata); |
|---|
| 405 | 321 | if (err) |
|---|
| 406 | 322 | goto err1; |
|---|
| 407 | 323 | |
|---|
| .. | .. |
|---|
| 424 | 340 | return 0; |
|---|
| 425 | 341 | } |
|---|
| 426 | 342 | |
|---|
| 427 | | -static int rxe_destroy_srq(struct ib_srq *ibsrq) |
|---|
| 343 | +static int rxe_destroy_srq(struct ib_srq *ibsrq, struct ib_udata *udata) |
|---|
| 428 | 344 | { |
|---|
| 429 | 345 | struct rxe_srq *srq = to_rsrq(ibsrq); |
|---|
| 430 | 346 | |
|---|
| .. | .. |
|---|
| 432 | 348 | rxe_queue_cleanup(srq->rq.queue); |
|---|
| 433 | 349 | |
|---|
| 434 | 350 | rxe_drop_ref(srq->pd); |
|---|
| 435 | | - rxe_drop_index(srq); |
|---|
| 436 | 351 | rxe_drop_ref(srq); |
|---|
| 437 | | - |
|---|
| 438 | 352 | return 0; |
|---|
| 439 | 353 | } |
|---|
| 440 | 354 | |
|---|
| .. | .. |
|---|
| 498 | 412 | |
|---|
| 499 | 413 | rxe_add_index(qp); |
|---|
| 500 | 414 | |
|---|
| 501 | | - err = rxe_qp_from_init(rxe, qp, pd, init, uresp, ibpd); |
|---|
| 415 | + err = rxe_qp_from_init(rxe, qp, pd, init, uresp, ibpd, udata); |
|---|
| 502 | 416 | if (err) |
|---|
| 503 | 417 | goto err3; |
|---|
| 504 | 418 | |
|---|
| .. | .. |
|---|
| 544 | 458 | return 0; |
|---|
| 545 | 459 | } |
|---|
| 546 | 460 | |
|---|
| 547 | | -static int rxe_destroy_qp(struct ib_qp *ibqp) |
|---|
| 461 | +static int rxe_destroy_qp(struct ib_qp *ibqp, struct ib_udata *udata) |
|---|
| 548 | 462 | { |
|---|
| 549 | 463 | struct rxe_qp *qp = to_rqp(ibqp); |
|---|
| 550 | 464 | |
|---|
| .. | .. |
|---|
| 602 | 516 | switch (wr->opcode) { |
|---|
| 603 | 517 | case IB_WR_RDMA_WRITE_WITH_IMM: |
|---|
| 604 | 518 | wr->ex.imm_data = ibwr->ex.imm_data; |
|---|
| 605 | | - /* fall through */ |
|---|
| 519 | + fallthrough; |
|---|
| 606 | 520 | case IB_WR_RDMA_READ: |
|---|
| 607 | 521 | case IB_WR_RDMA_WRITE: |
|---|
| 608 | 522 | wr->wr.rdma.remote_addr = rdma_wr(ibwr)->remote_addr; |
|---|
| .. | .. |
|---|
| 835 | 749 | return err; |
|---|
| 836 | 750 | } |
|---|
| 837 | 751 | |
|---|
| 838 | | -static struct ib_cq *rxe_create_cq(struct ib_device *dev, |
|---|
| 839 | | - const struct ib_cq_init_attr *attr, |
|---|
| 840 | | - struct ib_ucontext *context, |
|---|
| 841 | | - struct ib_udata *udata) |
|---|
| 752 | +static int rxe_create_cq(struct ib_cq *ibcq, const struct ib_cq_init_attr *attr, |
|---|
| 753 | + struct ib_udata *udata) |
|---|
| 842 | 754 | { |
|---|
| 843 | 755 | int err; |
|---|
| 756 | + struct ib_device *dev = ibcq->device; |
|---|
| 844 | 757 | struct rxe_dev *rxe = to_rdev(dev); |
|---|
| 845 | | - struct rxe_cq *cq; |
|---|
| 758 | + struct rxe_cq *cq = to_rcq(ibcq); |
|---|
| 846 | 759 | struct rxe_create_cq_resp __user *uresp = NULL; |
|---|
| 847 | 760 | |
|---|
| 848 | 761 | if (udata) { |
|---|
| 849 | 762 | if (udata->outlen < sizeof(*uresp)) |
|---|
| 850 | | - return ERR_PTR(-EINVAL); |
|---|
| 763 | + return -EINVAL; |
|---|
| 851 | 764 | uresp = udata->outbuf; |
|---|
| 852 | 765 | } |
|---|
| 853 | 766 | |
|---|
| 854 | 767 | if (attr->flags) |
|---|
| 855 | | - return ERR_PTR(-EINVAL); |
|---|
| 768 | + return -EINVAL; |
|---|
| 856 | 769 | |
|---|
| 857 | 770 | err = rxe_cq_chk_attr(rxe, NULL, attr->cqe, attr->comp_vector); |
|---|
| 858 | 771 | if (err) |
|---|
| 859 | | - goto err1; |
|---|
| 772 | + return err; |
|---|
| 860 | 773 | |
|---|
| 861 | | - cq = rxe_alloc(&rxe->cq_pool); |
|---|
| 862 | | - if (!cq) { |
|---|
| 863 | | - err = -ENOMEM; |
|---|
| 864 | | - goto err1; |
|---|
| 865 | | - } |
|---|
| 866 | | - |
|---|
| 867 | | - err = rxe_cq_from_init(rxe, cq, attr->cqe, attr->comp_vector, |
|---|
| 868 | | - context, uresp); |
|---|
| 774 | + err = rxe_cq_from_init(rxe, cq, attr->cqe, attr->comp_vector, udata, |
|---|
| 775 | + uresp); |
|---|
| 869 | 776 | if (err) |
|---|
| 870 | | - goto err2; |
|---|
| 777 | + return err; |
|---|
| 871 | 778 | |
|---|
| 872 | | - return &cq->ibcq; |
|---|
| 873 | | - |
|---|
| 874 | | -err2: |
|---|
| 875 | | - rxe_drop_ref(cq); |
|---|
| 876 | | -err1: |
|---|
| 877 | | - return ERR_PTR(err); |
|---|
| 779 | + return rxe_add_to_pool(&rxe->cq_pool, &cq->pelem); |
|---|
| 878 | 780 | } |
|---|
| 879 | 781 | |
|---|
| 880 | | -static int rxe_destroy_cq(struct ib_cq *ibcq) |
|---|
| 782 | +static int rxe_destroy_cq(struct ib_cq *ibcq, struct ib_udata *udata) |
|---|
| 881 | 783 | { |
|---|
| 882 | 784 | struct rxe_cq *cq = to_rcq(ibcq); |
|---|
| 883 | 785 | |
|---|
| .. | .. |
|---|
| 904 | 806 | if (err) |
|---|
| 905 | 807 | goto err1; |
|---|
| 906 | 808 | |
|---|
| 907 | | - err = rxe_cq_resize_queue(cq, cqe, uresp); |
|---|
| 809 | + err = rxe_cq_resize_queue(cq, cqe, uresp, udata); |
|---|
| 908 | 810 | if (err) |
|---|
| 909 | 811 | goto err1; |
|---|
| 910 | 812 | |
|---|
| .. | .. |
|---|
| 966 | 868 | struct rxe_dev *rxe = to_rdev(ibpd->device); |
|---|
| 967 | 869 | struct rxe_pd *pd = to_rpd(ibpd); |
|---|
| 968 | 870 | struct rxe_mem *mr; |
|---|
| 969 | | - int err; |
|---|
| 970 | 871 | |
|---|
| 971 | 872 | mr = rxe_alloc(&rxe->mr_pool); |
|---|
| 972 | | - if (!mr) { |
|---|
| 973 | | - err = -ENOMEM; |
|---|
| 974 | | - goto err1; |
|---|
| 975 | | - } |
|---|
| 873 | + if (!mr) |
|---|
| 874 | + return ERR_PTR(-ENOMEM); |
|---|
| 976 | 875 | |
|---|
| 977 | 876 | rxe_add_index(mr); |
|---|
| 978 | | - |
|---|
| 979 | 877 | rxe_add_ref(pd); |
|---|
| 980 | | - |
|---|
| 981 | | - err = rxe_mem_init_dma(pd, access, mr); |
|---|
| 982 | | - if (err) |
|---|
| 983 | | - goto err2; |
|---|
| 878 | + rxe_mem_init_dma(pd, access, mr); |
|---|
| 984 | 879 | |
|---|
| 985 | 880 | return &mr->ibmr; |
|---|
| 986 | | - |
|---|
| 987 | | -err2: |
|---|
| 988 | | - rxe_drop_ref(pd); |
|---|
| 989 | | - rxe_drop_index(mr); |
|---|
| 990 | | - rxe_drop_ref(mr); |
|---|
| 991 | | -err1: |
|---|
| 992 | | - return ERR_PTR(err); |
|---|
| 993 | 881 | } |
|---|
| 994 | 882 | |
|---|
| 995 | 883 | static struct ib_mr *rxe_reg_user_mr(struct ib_pd *ibpd, |
|---|
| .. | .. |
|---|
| 1028 | 916 | return ERR_PTR(err); |
|---|
| 1029 | 917 | } |
|---|
| 1030 | 918 | |
|---|
| 1031 | | -static int rxe_dereg_mr(struct ib_mr *ibmr) |
|---|
| 919 | +static int rxe_dereg_mr(struct ib_mr *ibmr, struct ib_udata *udata) |
|---|
| 1032 | 920 | { |
|---|
| 1033 | 921 | struct rxe_mem *mr = to_rmr(ibmr); |
|---|
| 1034 | 922 | |
|---|
| 1035 | 923 | mr->state = RXE_MEM_STATE_ZOMBIE; |
|---|
| 1036 | | - rxe_drop_ref(mr->pd); |
|---|
| 924 | + rxe_drop_ref(mr_pd(mr)); |
|---|
| 1037 | 925 | rxe_drop_index(mr); |
|---|
| 1038 | 926 | rxe_drop_ref(mr); |
|---|
| 1039 | 927 | return 0; |
|---|
| 1040 | 928 | } |
|---|
| 1041 | 929 | |
|---|
| 1042 | | -static struct ib_mr *rxe_alloc_mr(struct ib_pd *ibpd, |
|---|
| 1043 | | - enum ib_mr_type mr_type, |
|---|
| 930 | +static struct ib_mr *rxe_alloc_mr(struct ib_pd *ibpd, enum ib_mr_type mr_type, |
|---|
| 1044 | 931 | u32 max_num_sg) |
|---|
| 1045 | 932 | { |
|---|
| 1046 | 933 | struct rxe_dev *rxe = to_rdev(ibpd->device); |
|---|
| .. | .. |
|---|
| 1143 | 1030 | static ssize_t parent_show(struct device *device, |
|---|
| 1144 | 1031 | struct device_attribute *attr, char *buf) |
|---|
| 1145 | 1032 | { |
|---|
| 1146 | | - struct rxe_dev *rxe = container_of(device, struct rxe_dev, |
|---|
| 1147 | | - ib_dev.dev); |
|---|
| 1033 | + struct rxe_dev *rxe = |
|---|
| 1034 | + rdma_device_to_drv_device(device, struct rxe_dev, ib_dev); |
|---|
| 1148 | 1035 | |
|---|
| 1149 | 1036 | return scnprintf(buf, PAGE_SIZE, "%s\n", rxe_parent_name(rxe, 1)); |
|---|
| 1150 | 1037 | } |
|---|
| 1151 | 1038 | |
|---|
| 1152 | 1039 | static DEVICE_ATTR_RO(parent); |
|---|
| 1153 | 1040 | |
|---|
| 1154 | | -static struct device_attribute *rxe_dev_attributes[] = { |
|---|
| 1155 | | - &dev_attr_parent, |
|---|
| 1041 | +static struct attribute *rxe_dev_attributes[] = { |
|---|
| 1042 | + &dev_attr_parent.attr, |
|---|
| 1043 | + NULL |
|---|
| 1156 | 1044 | }; |
|---|
| 1157 | 1045 | |
|---|
| 1158 | | -int rxe_register_device(struct rxe_dev *rxe) |
|---|
| 1046 | +static const struct attribute_group rxe_attr_group = { |
|---|
| 1047 | + .attrs = rxe_dev_attributes, |
|---|
| 1048 | +}; |
|---|
| 1049 | + |
|---|
| 1050 | +static int rxe_enable_driver(struct ib_device *ib_dev) |
|---|
| 1051 | +{ |
|---|
| 1052 | + struct rxe_dev *rxe = container_of(ib_dev, struct rxe_dev, ib_dev); |
|---|
| 1053 | + |
|---|
| 1054 | + rxe_set_port_state(rxe); |
|---|
| 1055 | + dev_info(&rxe->ib_dev.dev, "added %s\n", netdev_name(rxe->ndev)); |
|---|
| 1056 | + return 0; |
|---|
| 1057 | +} |
|---|
| 1058 | + |
|---|
| 1059 | +static const struct ib_device_ops rxe_dev_ops = { |
|---|
| 1060 | + .owner = THIS_MODULE, |
|---|
| 1061 | + .driver_id = RDMA_DRIVER_RXE, |
|---|
| 1062 | + .uverbs_abi_ver = RXE_UVERBS_ABI_VERSION, |
|---|
| 1063 | + |
|---|
| 1064 | + .alloc_hw_stats = rxe_ib_alloc_hw_stats, |
|---|
| 1065 | + .alloc_mr = rxe_alloc_mr, |
|---|
| 1066 | + .alloc_pd = rxe_alloc_pd, |
|---|
| 1067 | + .alloc_ucontext = rxe_alloc_ucontext, |
|---|
| 1068 | + .attach_mcast = rxe_attach_mcast, |
|---|
| 1069 | + .create_ah = rxe_create_ah, |
|---|
| 1070 | + .create_cq = rxe_create_cq, |
|---|
| 1071 | + .create_qp = rxe_create_qp, |
|---|
| 1072 | + .create_srq = rxe_create_srq, |
|---|
| 1073 | + .dealloc_driver = rxe_dealloc, |
|---|
| 1074 | + .dealloc_pd = rxe_dealloc_pd, |
|---|
| 1075 | + .dealloc_ucontext = rxe_dealloc_ucontext, |
|---|
| 1076 | + .dereg_mr = rxe_dereg_mr, |
|---|
| 1077 | + .destroy_ah = rxe_destroy_ah, |
|---|
| 1078 | + .destroy_cq = rxe_destroy_cq, |
|---|
| 1079 | + .destroy_qp = rxe_destroy_qp, |
|---|
| 1080 | + .destroy_srq = rxe_destroy_srq, |
|---|
| 1081 | + .detach_mcast = rxe_detach_mcast, |
|---|
| 1082 | + .enable_driver = rxe_enable_driver, |
|---|
| 1083 | + .get_dma_mr = rxe_get_dma_mr, |
|---|
| 1084 | + .get_hw_stats = rxe_ib_get_hw_stats, |
|---|
| 1085 | + .get_link_layer = rxe_get_link_layer, |
|---|
| 1086 | + .get_port_immutable = rxe_port_immutable, |
|---|
| 1087 | + .map_mr_sg = rxe_map_mr_sg, |
|---|
| 1088 | + .mmap = rxe_mmap, |
|---|
| 1089 | + .modify_ah = rxe_modify_ah, |
|---|
| 1090 | + .modify_device = rxe_modify_device, |
|---|
| 1091 | + .modify_port = rxe_modify_port, |
|---|
| 1092 | + .modify_qp = rxe_modify_qp, |
|---|
| 1093 | + .modify_srq = rxe_modify_srq, |
|---|
| 1094 | + .peek_cq = rxe_peek_cq, |
|---|
| 1095 | + .poll_cq = rxe_poll_cq, |
|---|
| 1096 | + .post_recv = rxe_post_recv, |
|---|
| 1097 | + .post_send = rxe_post_send, |
|---|
| 1098 | + .post_srq_recv = rxe_post_srq_recv, |
|---|
| 1099 | + .query_ah = rxe_query_ah, |
|---|
| 1100 | + .query_device = rxe_query_device, |
|---|
| 1101 | + .query_pkey = rxe_query_pkey, |
|---|
| 1102 | + .query_port = rxe_query_port, |
|---|
| 1103 | + .query_qp = rxe_query_qp, |
|---|
| 1104 | + .query_srq = rxe_query_srq, |
|---|
| 1105 | + .reg_user_mr = rxe_reg_user_mr, |
|---|
| 1106 | + .req_notify_cq = rxe_req_notify_cq, |
|---|
| 1107 | + .resize_cq = rxe_resize_cq, |
|---|
| 1108 | + |
|---|
| 1109 | + INIT_RDMA_OBJ_SIZE(ib_ah, rxe_ah, ibah), |
|---|
| 1110 | + INIT_RDMA_OBJ_SIZE(ib_cq, rxe_cq, ibcq), |
|---|
| 1111 | + INIT_RDMA_OBJ_SIZE(ib_pd, rxe_pd, ibpd), |
|---|
| 1112 | + INIT_RDMA_OBJ_SIZE(ib_srq, rxe_srq, ibsrq), |
|---|
| 1113 | + INIT_RDMA_OBJ_SIZE(ib_ucontext, rxe_ucontext, ibuc), |
|---|
| 1114 | +}; |
|---|
| 1115 | + |
|---|
| 1116 | +int rxe_register_device(struct rxe_dev *rxe, const char *ibdev_name) |
|---|
| 1159 | 1117 | { |
|---|
| 1160 | 1118 | int err; |
|---|
| 1161 | | - int i; |
|---|
| 1162 | 1119 | struct ib_device *dev = &rxe->ib_dev; |
|---|
| 1163 | 1120 | struct crypto_shash *tfm; |
|---|
| 1164 | 1121 | |
|---|
| 1165 | | - strlcpy(dev->name, "rxe%d", IB_DEVICE_NAME_MAX); |
|---|
| 1166 | 1122 | strlcpy(dev->node_desc, "rxe", sizeof(dev->node_desc)); |
|---|
| 1167 | 1123 | |
|---|
| 1168 | | - dev->owner = THIS_MODULE; |
|---|
| 1169 | 1124 | dev->node_type = RDMA_NODE_IB_CA; |
|---|
| 1170 | 1125 | dev->phys_port_cnt = 1; |
|---|
| 1171 | 1126 | dev->num_comp_vectors = num_possible_cpus(); |
|---|
| 1172 | | - dev->dev.parent = rxe_dma_device(rxe); |
|---|
| 1173 | 1127 | dev->local_dma_lkey = 0; |
|---|
| 1174 | 1128 | addrconf_addr_eui48((unsigned char *)&dev->node_guid, |
|---|
| 1175 | 1129 | rxe->ndev->dev_addr); |
|---|
| 1176 | | - dev->dev.dma_ops = &dma_virt_ops; |
|---|
| 1177 | | - dma_coerce_mask_and_coherent(&dev->dev, |
|---|
| 1178 | | - dma_get_required_mask(&dev->dev)); |
|---|
| 1179 | 1130 | |
|---|
| 1180 | | - dev->uverbs_abi_ver = RXE_UVERBS_ABI_VERSION; |
|---|
| 1181 | 1131 | dev->uverbs_cmd_mask = BIT_ULL(IB_USER_VERBS_CMD_GET_CONTEXT) |
|---|
| 1182 | 1132 | | BIT_ULL(IB_USER_VERBS_CMD_CREATE_COMP_CHANNEL) |
|---|
| 1183 | 1133 | | BIT_ULL(IB_USER_VERBS_CMD_QUERY_DEVICE) |
|---|
| .. | .. |
|---|
| 1211 | 1161 | | BIT_ULL(IB_USER_VERBS_CMD_DETACH_MCAST) |
|---|
| 1212 | 1162 | ; |
|---|
| 1213 | 1163 | |
|---|
| 1214 | | - dev->query_device = rxe_query_device; |
|---|
| 1215 | | - dev->modify_device = rxe_modify_device; |
|---|
| 1216 | | - dev->query_port = rxe_query_port; |
|---|
| 1217 | | - dev->modify_port = rxe_modify_port; |
|---|
| 1218 | | - dev->get_link_layer = rxe_get_link_layer; |
|---|
| 1219 | | - dev->get_netdev = rxe_get_netdev; |
|---|
| 1220 | | - dev->query_pkey = rxe_query_pkey; |
|---|
| 1221 | | - dev->alloc_ucontext = rxe_alloc_ucontext; |
|---|
| 1222 | | - dev->dealloc_ucontext = rxe_dealloc_ucontext; |
|---|
| 1223 | | - dev->mmap = rxe_mmap; |
|---|
| 1224 | | - dev->get_port_immutable = rxe_port_immutable; |
|---|
| 1225 | | - dev->alloc_pd = rxe_alloc_pd; |
|---|
| 1226 | | - dev->dealloc_pd = rxe_dealloc_pd; |
|---|
| 1227 | | - dev->create_ah = rxe_create_ah; |
|---|
| 1228 | | - dev->modify_ah = rxe_modify_ah; |
|---|
| 1229 | | - dev->query_ah = rxe_query_ah; |
|---|
| 1230 | | - dev->destroy_ah = rxe_destroy_ah; |
|---|
| 1231 | | - dev->create_srq = rxe_create_srq; |
|---|
| 1232 | | - dev->modify_srq = rxe_modify_srq; |
|---|
| 1233 | | - dev->query_srq = rxe_query_srq; |
|---|
| 1234 | | - dev->destroy_srq = rxe_destroy_srq; |
|---|
| 1235 | | - dev->post_srq_recv = rxe_post_srq_recv; |
|---|
| 1236 | | - dev->create_qp = rxe_create_qp; |
|---|
| 1237 | | - dev->modify_qp = rxe_modify_qp; |
|---|
| 1238 | | - dev->query_qp = rxe_query_qp; |
|---|
| 1239 | | - dev->destroy_qp = rxe_destroy_qp; |
|---|
| 1240 | | - dev->post_send = rxe_post_send; |
|---|
| 1241 | | - dev->post_recv = rxe_post_recv; |
|---|
| 1242 | | - dev->create_cq = rxe_create_cq; |
|---|
| 1243 | | - dev->destroy_cq = rxe_destroy_cq; |
|---|
| 1244 | | - dev->resize_cq = rxe_resize_cq; |
|---|
| 1245 | | - dev->poll_cq = rxe_poll_cq; |
|---|
| 1246 | | - dev->peek_cq = rxe_peek_cq; |
|---|
| 1247 | | - dev->req_notify_cq = rxe_req_notify_cq; |
|---|
| 1248 | | - dev->get_dma_mr = rxe_get_dma_mr; |
|---|
| 1249 | | - dev->reg_user_mr = rxe_reg_user_mr; |
|---|
| 1250 | | - dev->dereg_mr = rxe_dereg_mr; |
|---|
| 1251 | | - dev->alloc_mr = rxe_alloc_mr; |
|---|
| 1252 | | - dev->map_mr_sg = rxe_map_mr_sg; |
|---|
| 1253 | | - dev->attach_mcast = rxe_attach_mcast; |
|---|
| 1254 | | - dev->detach_mcast = rxe_detach_mcast; |
|---|
| 1255 | | - dev->get_hw_stats = rxe_ib_get_hw_stats; |
|---|
| 1256 | | - dev->alloc_hw_stats = rxe_ib_alloc_hw_stats; |
|---|
| 1164 | + ib_set_device_ops(dev, &rxe_dev_ops); |
|---|
| 1165 | + err = ib_device_set_netdev(&rxe->ib_dev, rxe->ndev, 1); |
|---|
| 1166 | + if (err) |
|---|
| 1167 | + return err; |
|---|
| 1257 | 1168 | |
|---|
| 1258 | 1169 | tfm = crypto_alloc_shash("crc32", 0, 0); |
|---|
| 1259 | 1170 | if (IS_ERR(tfm)) { |
|---|
| .. | .. |
|---|
| 1263 | 1174 | } |
|---|
| 1264 | 1175 | rxe->tfm = tfm; |
|---|
| 1265 | 1176 | |
|---|
| 1266 | | - dev->driver_id = RDMA_DRIVER_RXE; |
|---|
| 1267 | | - err = ib_register_device(dev, NULL); |
|---|
| 1268 | | - if (err) { |
|---|
| 1177 | + rdma_set_device_sysfs_group(dev, &rxe_attr_group); |
|---|
| 1178 | + err = ib_register_device(dev, ibdev_name, NULL); |
|---|
| 1179 | + if (err) |
|---|
| 1269 | 1180 | pr_warn("%s failed with error %d\n", __func__, err); |
|---|
| 1270 | | - goto err1; |
|---|
| 1271 | | - } |
|---|
| 1272 | 1181 | |
|---|
| 1273 | | - for (i = 0; i < ARRAY_SIZE(rxe_dev_attributes); ++i) { |
|---|
| 1274 | | - err = device_create_file(&dev->dev, rxe_dev_attributes[i]); |
|---|
| 1275 | | - if (err) { |
|---|
| 1276 | | - pr_warn("%s failed with error %d for attr number %d\n", |
|---|
| 1277 | | - __func__, err, i); |
|---|
| 1278 | | - goto err2; |
|---|
| 1279 | | - } |
|---|
| 1280 | | - } |
|---|
| 1281 | | - |
|---|
| 1282 | | - return 0; |
|---|
| 1283 | | - |
|---|
| 1284 | | -err2: |
|---|
| 1285 | | - ib_unregister_device(dev); |
|---|
| 1286 | | -err1: |
|---|
| 1287 | | - crypto_free_shash(rxe->tfm); |
|---|
| 1288 | | - |
|---|
| 1182 | + /* |
|---|
| 1183 | + * Note that rxe may be invalid at this point if another thread |
|---|
| 1184 | + * unregistered it. |
|---|
| 1185 | + */ |
|---|
| 1289 | 1186 | return err; |
|---|
| 1290 | | -} |
|---|
| 1291 | | - |
|---|
| 1292 | | -int rxe_unregister_device(struct rxe_dev *rxe) |
|---|
| 1293 | | -{ |
|---|
| 1294 | | - int i; |
|---|
| 1295 | | - struct ib_device *dev = &rxe->ib_dev; |
|---|
| 1296 | | - |
|---|
| 1297 | | - for (i = 0; i < ARRAY_SIZE(rxe_dev_attributes); ++i) |
|---|
| 1298 | | - device_remove_file(&dev->dev, rxe_dev_attributes[i]); |
|---|
| 1299 | | - |
|---|
| 1300 | | - ib_unregister_device(dev); |
|---|
| 1301 | | - |
|---|
| 1302 | | - return 0; |
|---|
| 1303 | 1187 | } |
|---|