| .. | .. |
|---|
| 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 "rxe.h" |
|---|
| .. | .. |
|---|
| 79 | 52 | u32 lkey = mem->pelem.index << 8 | rxe_get_key(); |
|---|
| 80 | 53 | u32 rkey = (access & IB_ACCESS_REMOTE) ? lkey : 0; |
|---|
| 81 | 54 | |
|---|
| 82 | | - if (mem->pelem.pool->type == RXE_TYPE_MR) { |
|---|
| 83 | | - mem->ibmr.lkey = lkey; |
|---|
| 84 | | - mem->ibmr.rkey = rkey; |
|---|
| 85 | | - } |
|---|
| 86 | | - |
|---|
| 87 | | - mem->lkey = lkey; |
|---|
| 88 | | - mem->rkey = rkey; |
|---|
| 55 | + mem->ibmr.lkey = lkey; |
|---|
| 56 | + mem->ibmr.rkey = rkey; |
|---|
| 89 | 57 | mem->state = RXE_MEM_STATE_INVALID; |
|---|
| 90 | 58 | mem->type = RXE_MEM_TYPE_NONE; |
|---|
| 91 | 59 | mem->map_shift = ilog2(RXE_BUF_PER_MAP); |
|---|
| .. | .. |
|---|
| 96 | 64 | struct rxe_mem *mem = container_of(arg, typeof(*mem), pelem); |
|---|
| 97 | 65 | int i; |
|---|
| 98 | 66 | |
|---|
| 99 | | - if (mem->umem) |
|---|
| 100 | | - ib_umem_release(mem->umem); |
|---|
| 67 | + ib_umem_release(mem->umem); |
|---|
| 101 | 68 | |
|---|
| 102 | 69 | if (mem->map) { |
|---|
| 103 | 70 | for (i = 0; i < mem->num_map; i++) |
|---|
| .. | .. |
|---|
| 145 | 112 | return -ENOMEM; |
|---|
| 146 | 113 | } |
|---|
| 147 | 114 | |
|---|
| 148 | | -int rxe_mem_init_dma(struct rxe_pd *pd, |
|---|
| 149 | | - int access, struct rxe_mem *mem) |
|---|
| 115 | +void rxe_mem_init_dma(struct rxe_pd *pd, |
|---|
| 116 | + int access, struct rxe_mem *mem) |
|---|
| 150 | 117 | { |
|---|
| 151 | 118 | rxe_mem_init(access, mem); |
|---|
| 152 | 119 | |
|---|
| 153 | | - mem->pd = pd; |
|---|
| 120 | + mem->ibmr.pd = &pd->ibpd; |
|---|
| 154 | 121 | mem->access = access; |
|---|
| 155 | 122 | mem->state = RXE_MEM_STATE_VALID; |
|---|
| 156 | 123 | mem->type = RXE_MEM_TYPE_DMA; |
|---|
| 157 | | - |
|---|
| 158 | | - return 0; |
|---|
| 159 | 124 | } |
|---|
| 160 | 125 | |
|---|
| 161 | 126 | int rxe_mem_init_user(struct rxe_pd *pd, u64 start, |
|---|
| 162 | 127 | u64 length, u64 iova, int access, struct ib_udata *udata, |
|---|
| 163 | 128 | struct rxe_mem *mem) |
|---|
| 164 | 129 | { |
|---|
| 165 | | - int entry; |
|---|
| 166 | 130 | struct rxe_map **map; |
|---|
| 167 | 131 | struct rxe_phys_buf *buf = NULL; |
|---|
| 168 | 132 | struct ib_umem *umem; |
|---|
| 169 | | - struct scatterlist *sg; |
|---|
| 133 | + struct sg_page_iter sg_iter; |
|---|
| 170 | 134 | int num_buf; |
|---|
| 171 | 135 | void *vaddr; |
|---|
| 172 | 136 | int err; |
|---|
| 173 | 137 | |
|---|
| 174 | | - umem = ib_umem_get(pd->ibpd.uobject->context, start, length, access, 0); |
|---|
| 138 | + umem = ib_umem_get(pd->ibpd.device, start, length, access); |
|---|
| 175 | 139 | if (IS_ERR(umem)) { |
|---|
| 176 | 140 | pr_warn("err %d from rxe_umem_get\n", |
|---|
| 177 | 141 | (int)PTR_ERR(umem)); |
|---|
| .. | .. |
|---|
| 180 | 144 | } |
|---|
| 181 | 145 | |
|---|
| 182 | 146 | mem->umem = umem; |
|---|
| 183 | | - num_buf = umem->nmap; |
|---|
| 147 | + num_buf = ib_umem_num_pages(umem); |
|---|
| 184 | 148 | |
|---|
| 185 | 149 | rxe_mem_init(access, mem); |
|---|
| 186 | 150 | |
|---|
| .. | .. |
|---|
| 191 | 155 | goto err1; |
|---|
| 192 | 156 | } |
|---|
| 193 | 157 | |
|---|
| 194 | | - mem->page_shift = umem->page_shift; |
|---|
| 195 | | - mem->page_mask = BIT(umem->page_shift) - 1; |
|---|
| 158 | + mem->page_shift = PAGE_SHIFT; |
|---|
| 159 | + mem->page_mask = PAGE_SIZE - 1; |
|---|
| 196 | 160 | |
|---|
| 197 | 161 | num_buf = 0; |
|---|
| 198 | 162 | map = mem->map; |
|---|
| 199 | 163 | if (length > 0) { |
|---|
| 200 | 164 | buf = map[0]->buf; |
|---|
| 201 | 165 | |
|---|
| 202 | | - for_each_sg(umem->sg_head.sgl, sg, umem->nmap, entry) { |
|---|
| 203 | | - vaddr = page_address(sg_page(sg)); |
|---|
| 166 | + for_each_sg_page(umem->sg_head.sgl, &sg_iter, umem->nmap, 0) { |
|---|
| 167 | + if (num_buf >= RXE_BUF_PER_MAP) { |
|---|
| 168 | + map++; |
|---|
| 169 | + buf = map[0]->buf; |
|---|
| 170 | + num_buf = 0; |
|---|
| 171 | + } |
|---|
| 172 | + |
|---|
| 173 | + vaddr = page_address(sg_page_iter_page(&sg_iter)); |
|---|
| 204 | 174 | if (!vaddr) { |
|---|
| 205 | 175 | pr_warn("null vaddr\n"); |
|---|
| 206 | 176 | ib_umem_release(umem); |
|---|
| .. | .. |
|---|
| 209 | 179 | } |
|---|
| 210 | 180 | |
|---|
| 211 | 181 | buf->addr = (uintptr_t)vaddr; |
|---|
| 212 | | - buf->size = BIT(umem->page_shift); |
|---|
| 182 | + buf->size = PAGE_SIZE; |
|---|
| 213 | 183 | num_buf++; |
|---|
| 214 | 184 | buf++; |
|---|
| 215 | 185 | |
|---|
| 216 | | - if (num_buf >= RXE_BUF_PER_MAP) { |
|---|
| 217 | | - map++; |
|---|
| 218 | | - buf = map[0]->buf; |
|---|
| 219 | | - num_buf = 0; |
|---|
| 220 | | - } |
|---|
| 221 | 186 | } |
|---|
| 222 | 187 | } |
|---|
| 223 | 188 | |
|---|
| 224 | | - mem->pd = pd; |
|---|
| 189 | + mem->ibmr.pd = &pd->ibpd; |
|---|
| 225 | 190 | mem->umem = umem; |
|---|
| 226 | 191 | mem->access = access; |
|---|
| 227 | 192 | mem->length = length; |
|---|
| .. | .. |
|---|
| 251 | 216 | if (err) |
|---|
| 252 | 217 | goto err1; |
|---|
| 253 | 218 | |
|---|
| 254 | | - mem->pd = pd; |
|---|
| 219 | + mem->ibmr.pd = &pd->ibpd; |
|---|
| 255 | 220 | mem->max_buf = max_pages; |
|---|
| 256 | 221 | mem->state = RXE_MEM_STATE_FREE; |
|---|
| 257 | 222 | mem->type = RXE_MEM_TYPE_MR; |
|---|
| .. | .. |
|---|
| 371 | 336 | memcpy(dest, src, length); |
|---|
| 372 | 337 | |
|---|
| 373 | 338 | if (crcp) |
|---|
| 374 | | - *crcp = rxe_crc32(to_rdev(mem->pd->ibpd.device), |
|---|
| 339 | + *crcp = rxe_crc32(to_rdev(mem->ibmr.device), |
|---|
| 375 | 340 | *crcp, dest, length); |
|---|
| 376 | 341 | |
|---|
| 377 | 342 | return 0; |
|---|
| .. | .. |
|---|
| 405 | 370 | memcpy(dest, src, bytes); |
|---|
| 406 | 371 | |
|---|
| 407 | 372 | if (crcp) |
|---|
| 408 | | - crc = rxe_crc32(to_rdev(mem->pd->ibpd.device), |
|---|
| 373 | + crc = rxe_crc32(to_rdev(mem->ibmr.device), |
|---|
| 409 | 374 | crc, dest, bytes); |
|---|
| 410 | 375 | |
|---|
| 411 | 376 | length -= bytes; |
|---|
| .. | .. |
|---|
| 574 | 539 | struct rxe_dev *rxe = to_rdev(pd->ibpd.device); |
|---|
| 575 | 540 | int index = key >> 8; |
|---|
| 576 | 541 | |
|---|
| 577 | | - if (index >= RXE_MIN_MR_INDEX && index <= RXE_MAX_MR_INDEX) { |
|---|
| 578 | | - mem = rxe_pool_get_index(&rxe->mr_pool, index); |
|---|
| 579 | | - if (!mem) |
|---|
| 580 | | - goto err1; |
|---|
| 581 | | - } else { |
|---|
| 582 | | - goto err1; |
|---|
| 542 | + mem = rxe_pool_get_index(&rxe->mr_pool, index); |
|---|
| 543 | + if (!mem) |
|---|
| 544 | + return NULL; |
|---|
| 545 | + |
|---|
| 546 | + if (unlikely((type == lookup_local && mr_lkey(mem) != key) || |
|---|
| 547 | + (type == lookup_remote && mr_rkey(mem) != key) || |
|---|
| 548 | + mr_pd(mem) != pd || |
|---|
| 549 | + (access && !(access & mem->access)) || |
|---|
| 550 | + mem->state != RXE_MEM_STATE_VALID)) { |
|---|
| 551 | + rxe_drop_ref(mem); |
|---|
| 552 | + mem = NULL; |
|---|
| 583 | 553 | } |
|---|
| 584 | | - |
|---|
| 585 | | - if ((type == lookup_local && mem->lkey != key) || |
|---|
| 586 | | - (type == lookup_remote && mem->rkey != key)) |
|---|
| 587 | | - goto err2; |
|---|
| 588 | | - |
|---|
| 589 | | - if (mem->pd != pd) |
|---|
| 590 | | - goto err2; |
|---|
| 591 | | - |
|---|
| 592 | | - if (access && !(access & mem->access)) |
|---|
| 593 | | - goto err2; |
|---|
| 594 | | - |
|---|
| 595 | | - if (mem->state != RXE_MEM_STATE_VALID) |
|---|
| 596 | | - goto err2; |
|---|
| 597 | 554 | |
|---|
| 598 | 555 | return mem; |
|---|
| 599 | | - |
|---|
| 600 | | -err2: |
|---|
| 601 | | - rxe_drop_ref(mem); |
|---|
| 602 | | -err1: |
|---|
| 603 | | - return NULL; |
|---|
| 604 | | -} |
|---|
| 605 | | - |
|---|
| 606 | | -int rxe_mem_map_pages(struct rxe_dev *rxe, struct rxe_mem *mem, |
|---|
| 607 | | - u64 *page, int num_pages, u64 iova) |
|---|
| 608 | | -{ |
|---|
| 609 | | - int i; |
|---|
| 610 | | - int num_buf; |
|---|
| 611 | | - int err; |
|---|
| 612 | | - struct rxe_map **map; |
|---|
| 613 | | - struct rxe_phys_buf *buf; |
|---|
| 614 | | - int page_size; |
|---|
| 615 | | - |
|---|
| 616 | | - if (num_pages > mem->max_buf) { |
|---|
| 617 | | - err = -EINVAL; |
|---|
| 618 | | - goto err1; |
|---|
| 619 | | - } |
|---|
| 620 | | - |
|---|
| 621 | | - num_buf = 0; |
|---|
| 622 | | - page_size = 1 << mem->page_shift; |
|---|
| 623 | | - map = mem->map; |
|---|
| 624 | | - buf = map[0]->buf; |
|---|
| 625 | | - |
|---|
| 626 | | - for (i = 0; i < num_pages; i++) { |
|---|
| 627 | | - buf->addr = *page++; |
|---|
| 628 | | - buf->size = page_size; |
|---|
| 629 | | - buf++; |
|---|
| 630 | | - num_buf++; |
|---|
| 631 | | - |
|---|
| 632 | | - if (num_buf == RXE_BUF_PER_MAP) { |
|---|
| 633 | | - map++; |
|---|
| 634 | | - buf = map[0]->buf; |
|---|
| 635 | | - num_buf = 0; |
|---|
| 636 | | - } |
|---|
| 637 | | - } |
|---|
| 638 | | - |
|---|
| 639 | | - mem->iova = iova; |
|---|
| 640 | | - mem->va = iova; |
|---|
| 641 | | - mem->length = num_pages << mem->page_shift; |
|---|
| 642 | | - mem->state = RXE_MEM_STATE_VALID; |
|---|
| 643 | | - |
|---|
| 644 | | - return 0; |
|---|
| 645 | | - |
|---|
| 646 | | -err1: |
|---|
| 647 | | - return err; |
|---|
| 648 | 556 | } |
|---|