| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * linux/fs/9p/trans_rdma.c |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 8 | 9 | * Copyright (C) 2004-2005 by Latchesar Ionkov <lucho@ionkov.net> |
|---|
| 9 | 10 | * Copyright (C) 2004-2008 by Eric Van Hensbergen <ericvh@gmail.com> |
|---|
| 10 | 11 | * Copyright (C) 1997-2002 by Ron Minnich <rminnich@sarnoff.com> |
|---|
| 11 | | - * |
|---|
| 12 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 13 | | - * it under the terms of the GNU General Public License version 2 |
|---|
| 14 | | - * as published by the Free Software Foundation. |
|---|
| 15 | | - * |
|---|
| 16 | | - * This program is distributed in the hope that it will be useful, |
|---|
| 17 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 18 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 19 | | - * GNU General Public License for more details. |
|---|
| 20 | | - * |
|---|
| 21 | | - * You should have received a copy of the GNU General Public License |
|---|
| 22 | | - * along with this program; if not, write to: |
|---|
| 23 | | - * Free Software Foundation |
|---|
| 24 | | - * 51 Franklin Street, Fifth Floor |
|---|
| 25 | | - * Boston, MA 02111-1301 USA |
|---|
| 26 | | - * |
|---|
| 27 | 12 | */ |
|---|
| 28 | 13 | |
|---|
| 29 | 14 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
|---|
| .. | .. |
|---|
| 109 | 94 | struct completion cm_done; |
|---|
| 110 | 95 | }; |
|---|
| 111 | 96 | |
|---|
| 97 | +struct p9_rdma_req; |
|---|
| 98 | + |
|---|
| 112 | 99 | /** |
|---|
| 113 | | - * p9_rdma_context - Keeps track of in-process WR |
|---|
| 100 | + * struct p9_rdma_context - Keeps track of in-process WR |
|---|
| 114 | 101 | * |
|---|
| 115 | 102 | * @busa: Bus address to unmap when the WR completes |
|---|
| 116 | 103 | * @req: Keeps track of requests (send) |
|---|
| 117 | 104 | * @rc: Keepts track of replies (receive) |
|---|
| 118 | 105 | */ |
|---|
| 119 | | -struct p9_rdma_req; |
|---|
| 120 | 106 | struct p9_rdma_context { |
|---|
| 121 | 107 | struct ib_cqe cqe; |
|---|
| 122 | 108 | dma_addr_t busa; |
|---|
| .. | .. |
|---|
| 127 | 113 | }; |
|---|
| 128 | 114 | |
|---|
| 129 | 115 | /** |
|---|
| 130 | | - * p9_rdma_opts - Collection of mount options |
|---|
| 116 | + * struct p9_rdma_opts - Collection of mount options |
|---|
| 131 | 117 | * @port: port of connection |
|---|
| 132 | 118 | * @sq_depth: The requested depth of the SQ. This really doesn't need |
|---|
| 133 | 119 | * to be any deeper than the number of threads used in the client |
|---|
| .. | .. |
|---|
| 400 | 386 | struct p9_trans_rdma *rdma = client->trans; |
|---|
| 401 | 387 | struct ib_recv_wr wr; |
|---|
| 402 | 388 | struct ib_sge sge; |
|---|
| 389 | + int ret; |
|---|
| 403 | 390 | |
|---|
| 404 | 391 | c->busa = ib_dma_map_single(rdma->cm_id->device, |
|---|
| 405 | 392 | c->rc.sdata, client->msize, |
|---|
| .. | .. |
|---|
| 417 | 404 | wr.wr_cqe = &c->cqe; |
|---|
| 418 | 405 | wr.sg_list = &sge; |
|---|
| 419 | 406 | wr.num_sge = 1; |
|---|
| 420 | | - return ib_post_recv(rdma->qp, &wr, NULL); |
|---|
| 407 | + |
|---|
| 408 | + ret = ib_post_recv(rdma->qp, &wr, NULL); |
|---|
| 409 | + if (ret) |
|---|
| 410 | + ib_dma_unmap_single(rdma->cm_id->device, c->busa, |
|---|
| 411 | + client->msize, DMA_FROM_DEVICE); |
|---|
| 412 | + return ret; |
|---|
| 421 | 413 | |
|---|
| 422 | 414 | error: |
|---|
| 423 | 415 | p9_debug(P9_DEBUG_ERROR, "EIO\n"); |
|---|
| .. | .. |
|---|
| 514 | 506 | |
|---|
| 515 | 507 | if (down_interruptible(&rdma->sq_sem)) { |
|---|
| 516 | 508 | err = -EINTR; |
|---|
| 517 | | - goto send_error; |
|---|
| 509 | + goto dma_unmap; |
|---|
| 518 | 510 | } |
|---|
| 519 | 511 | |
|---|
| 520 | 512 | /* Mark request as `sent' *before* we actually send it, |
|---|
| .. | .. |
|---|
| 524 | 516 | req->status = REQ_STATUS_SENT; |
|---|
| 525 | 517 | err = ib_post_send(rdma->qp, &wr, NULL); |
|---|
| 526 | 518 | if (err) |
|---|
| 527 | | - goto send_error; |
|---|
| 519 | + goto dma_unmap; |
|---|
| 528 | 520 | |
|---|
| 529 | 521 | /* Success */ |
|---|
| 530 | 522 | return 0; |
|---|
| 531 | 523 | |
|---|
| 524 | +dma_unmap: |
|---|
| 525 | + ib_dma_unmap_single(rdma->cm_id->device, c->busa, |
|---|
| 526 | + c->req->tc.size, DMA_TO_DEVICE); |
|---|
| 532 | 527 | /* Handle errors that happened during or while preparing the send: */ |
|---|
| 533 | 528 | send_error: |
|---|
| 534 | 529 | req->status = REQ_STATUS_ERROR; |
|---|
| .. | .. |
|---|
| 700 | 695 | goto error; |
|---|
| 701 | 696 | |
|---|
| 702 | 697 | /* Create the Completion Queue */ |
|---|
| 703 | | - rdma->cq = ib_alloc_cq(rdma->cm_id->device, client, |
|---|
| 704 | | - opts.sq_depth + opts.rq_depth + 1, |
|---|
| 705 | | - 0, IB_POLL_SOFTIRQ); |
|---|
| 698 | + rdma->cq = ib_alloc_cq_any(rdma->cm_id->device, client, |
|---|
| 699 | + opts.sq_depth + opts.rq_depth + 1, |
|---|
| 700 | + IB_POLL_SOFTIRQ); |
|---|
| 706 | 701 | if (IS_ERR(rdma->cq)) |
|---|
| 707 | 702 | goto error; |
|---|
| 708 | 703 | |
|---|