Message ID | 0-v1-789ba72d2950+2e-ib_virt_page_jgg@nvidia.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | RDMA: Add ib_virt_dma_to_page() | expand |
On Thu, Mar 30, 2023 at 4:26 PM Jason Gunthorpe <jgg@nvidia.com> wrote: > Make it clearer what is going on by adding a function to go back from the > "virtual" dma_addr to a struct page. This is used in the > ib_uses_virt_dma() style drivers (siw, rxe, hfi, qib). > > Call it instead of a naked virt_to_page() when working with dma_addr > values encoded by the various ib_map functions. > > This also fixes the vir_to_page() casting problem Linus Walleij has been > chasing. > > Cc: Linus Walleij <linus.walleij@linaro.org> > Signed-off-by: Jason Gunthorpe <jgg@nvidia.com> Excellent, thanks Jason! Reviewed-by: Linus Walleij <linus.walleij@linaro.org> Yours, Linus Walleij
Hi Jason,
I love your patch! Perhaps something to improve:
[auto build test WARNING on 78b26a335310a097d6b22581b706050db42f196c]
url: https://github.com/intel-lab-lkp/linux/commits/Jason-Gunthorpe/RDMA-Add-ib_virt_dma_to_page/20230330-222848
base: 78b26a335310a097d6b22581b706050db42f196c
patch link: https://lore.kernel.org/r/0-v1-789ba72d2950%2B2e-ib_virt_page_jgg%40nvidia.com
patch subject: [PATCH] RDMA: Add ib_virt_dma_to_page()
config: m68k-randconfig-r014-20230329 (https://download.01.org/0day-ci/archive/20230331/202303310254.tmWyQaZG-lkp@intel.com/config)
compiler: m68k-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/a10308d393288ba62a1aa7c24a7f6df484c2892a
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Jason-Gunthorpe/RDMA-Add-ib_virt_dma_to_page/20230330-222848
git checkout a10308d393288ba62a1aa7c24a7f6df484c2892a
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=m68k olddefconfig
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=m68k SHELL=/bin/bash drivers/infiniband/sw/siw/
If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <lkp@intel.com>
| Link: https://lore.kernel.org/oe-kbuild-all/202303310254.tmWyQaZG-lkp@intel.com/
All warnings (new ones prefixed by >>):
drivers/infiniband/sw/siw/siw_qp_tx.c: In function 'siw_tx_hdt':
>> drivers/infiniband/sw/siw/siw_qp_tx.c:546:49: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
546 | (void *)va,
| ^
vim +546 drivers/infiniband/sw/siw/siw_qp_tx.c
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 426
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 427 /*
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 428 * Write out iov referencing hdr, data and trailer of current FPDU.
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 429 * Update transmit state dependent on write return status
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 430 */
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 431 static int siw_tx_hdt(struct siw_iwarp_tx *c_tx, struct socket *s)
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 432 {
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 433 struct siw_wqe *wqe = &c_tx->wqe_active;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 434 struct siw_sge *sge = &wqe->sqe.sge[c_tx->sge_idx];
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 435 struct kvec iov[MAX_ARRAY];
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 436 struct page *page_array[MAX_ARRAY];
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 437 struct msghdr msg = { .msg_flags = MSG_DONTWAIT | MSG_EOR };
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 438
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 439 int seg = 0, do_crc = c_tx->do_crc, is_kva = 0, rv;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 440 unsigned int data_len = c_tx->bytes_unsent, hdr_len = 0, trl_len = 0,
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 441 sge_off = c_tx->sge_off, sge_idx = c_tx->sge_idx,
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 442 pbl_idx = c_tx->pbl_idx;
fab4f97e1fe33c Bernard Metzler 2019-08-22 443 unsigned long kmap_mask = 0L;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 444
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 445 if (c_tx->state == SIW_SEND_HDR) {
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 446 if (c_tx->use_sendpage) {
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 447 rv = siw_tx_ctrl(c_tx, s, MSG_DONTWAIT | MSG_MORE);
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 448 if (rv)
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 449 goto done;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 450
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 451 c_tx->state = SIW_SEND_DATA;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 452 } else {
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 453 iov[0].iov_base =
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 454 (char *)&c_tx->pkt.ctrl + c_tx->ctrl_sent;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 455 iov[0].iov_len = hdr_len =
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 456 c_tx->ctrl_len - c_tx->ctrl_sent;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 457 seg = 1;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 458 }
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 459 }
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 460
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 461 wqe->processed += data_len;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 462
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 463 while (data_len) { /* walk the list of SGE's */
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 464 unsigned int sge_len = min(sge->length - sge_off, data_len);
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 465 unsigned int fp_off = (sge->laddr + sge_off) & ~PAGE_MASK;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 466 struct siw_mem *mem;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 467
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 468 if (!(tx_flags(wqe) & SIW_WQE_INLINE)) {
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 469 mem = wqe->mem[sge_idx];
fab4f97e1fe33c Bernard Metzler 2019-08-22 470 is_kva = mem->mem_obj == NULL ? 1 : 0;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 471 } else {
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 472 is_kva = 1;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 473 }
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 474 if (is_kva && !c_tx->use_sendpage) {
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 475 /*
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 476 * tx from kernel virtual address: either inline data
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 477 * or memory region with assigned kernel buffer
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 478 */
c536277e0db1ad Bernard Metzler 2019-08-22 479 iov[seg].iov_base =
c536277e0db1ad Bernard Metzler 2019-08-22 480 (void *)(uintptr_t)(sge->laddr + sge_off);
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 481 iov[seg].iov_len = sge_len;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 482
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 483 if (do_crc)
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 484 crypto_shash_update(c_tx->mpa_crc_hd,
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 485 iov[seg].iov_base,
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 486 sge_len);
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 487 sge_off += sge_len;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 488 data_len -= sge_len;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 489 seg++;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 490 goto sge_done;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 491 }
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 492
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 493 while (sge_len) {
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 494 size_t plen = min((int)PAGE_SIZE - fp_off, sge_len);
1ec50dd12a4347 Ira Weiny 2021-06-21 495 void *kaddr;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 496
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 497 if (!is_kva) {
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 498 struct page *p;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 499
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 500 if (mem->is_pbl)
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 501 p = siw_get_pblpage(
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 502 mem, sge->laddr + sge_off,
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 503 &pbl_idx);
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 504 else
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 505 p = siw_get_upage(mem->umem,
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 506 sge->laddr + sge_off);
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 507 if (unlikely(!p)) {
9d649d594f3965 Ira Weiny 2021-06-24 508 siw_unmap_pages(iov, kmap_mask, seg);
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 509 wqe->processed -= c_tx->bytes_unsent;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 510 rv = -EFAULT;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 511 goto done_crc;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 512 }
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 513 page_array[seg] = p;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 514
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 515 if (!c_tx->use_sendpage) {
9d649d594f3965 Ira Weiny 2021-06-24 516 void *kaddr = kmap_local_page(p);
fab4f97e1fe33c Bernard Metzler 2019-08-22 517
fab4f97e1fe33c Bernard Metzler 2019-08-22 518 /* Remember for later kunmap() */
fab4f97e1fe33c Bernard Metzler 2019-08-22 519 kmap_mask |= BIT(seg);
9d649d594f3965 Ira Weiny 2021-06-24 520 iov[seg].iov_base = kaddr + fp_off;
9d649d594f3965 Ira Weiny 2021-06-24 521 iov[seg].iov_len = plen;
fab4f97e1fe33c Bernard Metzler 2019-08-22 522
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 523 if (do_crc)
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 524 crypto_shash_update(
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 525 c_tx->mpa_crc_hd,
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 526 iov[seg].iov_base,
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 527 plen);
0404bd629fd4d0 Bernard Metzler 2019-09-09 528 } else if (do_crc) {
1ec50dd12a4347 Ira Weiny 2021-06-21 529 kaddr = kmap_local_page(p);
0404bd629fd4d0 Bernard Metzler 2019-09-09 530 crypto_shash_update(c_tx->mpa_crc_hd,
1ec50dd12a4347 Ira Weiny 2021-06-21 531 kaddr + fp_off,
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 532 plen);
1ec50dd12a4347 Ira Weiny 2021-06-21 533 kunmap_local(kaddr);
0404bd629fd4d0 Bernard Metzler 2019-09-09 534 }
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 535 } else {
0d1b756acf60da Linus Walleij 2022-09-02 536 /*
0d1b756acf60da Linus Walleij 2022-09-02 537 * Cast to an uintptr_t to preserve all 64 bits
0d1b756acf60da Linus Walleij 2022-09-02 538 * in sge->laddr.
0d1b756acf60da Linus Walleij 2022-09-02 539 */
a10308d393288b Jason Gunthorpe 2023-03-30 540 u64 va = (uintptr_t)(sge->laddr + sge_off);
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 541
a10308d393288b Jason Gunthorpe 2023-03-30 542 page_array[seg] = ib_virt_dma_to_page(va);
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 543 if (do_crc)
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 544 crypto_shash_update(
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 545 c_tx->mpa_crc_hd,
0d1b756acf60da Linus Walleij 2022-09-02 @546 (void *)va,
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 547 plen);
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 548 }
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 549
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 550 sge_len -= plen;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 551 sge_off += plen;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 552 data_len -= plen;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 553 fp_off = 0;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 554
271bfcfb83a9f7 Daniil Dulov 2023-02-27 555 if (++seg >= (int)MAX_ARRAY) {
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 556 siw_dbg_qp(tx_qp(c_tx), "to many fragments\n");
9d649d594f3965 Ira Weiny 2021-06-24 557 siw_unmap_pages(iov, kmap_mask, seg-1);
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 558 wqe->processed -= c_tx->bytes_unsent;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 559 rv = -EMSGSIZE;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 560 goto done_crc;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 561 }
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 562 }
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 563 sge_done:
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 564 /* Update SGE variables at end of SGE */
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 565 if (sge_off == sge->length &&
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 566 (data_len != 0 || wqe->processed < wqe->bytes)) {
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 567 sge_idx++;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 568 sge++;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 569 sge_off = 0;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 570 }
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 571 }
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 572 /* trailer */
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 573 if (likely(c_tx->state != SIW_SEND_TRAILER)) {
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 574 iov[seg].iov_base = &c_tx->trailer.pad[4 - c_tx->pad];
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 575 iov[seg].iov_len = trl_len = MAX_TRAILER - (4 - c_tx->pad);
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 576 } else {
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 577 iov[seg].iov_base = &c_tx->trailer.pad[c_tx->ctrl_sent];
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 578 iov[seg].iov_len = trl_len = MAX_TRAILER - c_tx->ctrl_sent;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 579 }
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 580
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 581 if (c_tx->pad) {
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 582 *(u32 *)c_tx->trailer.pad = 0;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 583 if (do_crc)
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 584 crypto_shash_update(c_tx->mpa_crc_hd,
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 585 (u8 *)&c_tx->trailer.crc - c_tx->pad,
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 586 c_tx->pad);
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 587 }
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 588 if (!c_tx->mpa_crc_hd)
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 589 c_tx->trailer.crc = 0;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 590 else if (do_crc)
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 591 crypto_shash_final(c_tx->mpa_crc_hd, (u8 *)&c_tx->trailer.crc);
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 592
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 593 data_len = c_tx->bytes_unsent;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 594
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 595 if (c_tx->use_sendpage) {
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 596 rv = siw_0copy_tx(s, page_array, &wqe->sqe.sge[c_tx->sge_idx],
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 597 c_tx->sge_off, data_len);
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 598 if (rv == data_len) {
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 599 rv = kernel_sendmsg(s, &msg, &iov[seg], 1, trl_len);
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 600 if (rv > 0)
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 601 rv += data_len;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 602 else
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 603 rv = data_len;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 604 }
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 605 } else {
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 606 rv = kernel_sendmsg(s, &msg, iov, seg + 1,
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 607 hdr_len + data_len + trl_len);
9d649d594f3965 Ira Weiny 2021-06-24 608 siw_unmap_pages(iov, kmap_mask, seg);
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 609 }
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 610 if (rv < (int)hdr_len) {
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 611 /* Not even complete hdr pushed or negative rv */
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 612 wqe->processed -= data_len;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 613 if (rv >= 0) {
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 614 c_tx->ctrl_sent += rv;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 615 rv = -EAGAIN;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 616 }
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 617 goto done_crc;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 618 }
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 619 rv -= hdr_len;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 620
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 621 if (rv >= (int)data_len) {
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 622 /* all user data pushed to TCP or no data to push */
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 623 if (data_len > 0 && wqe->processed < wqe->bytes) {
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 624 /* Save the current state for next tx */
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 625 c_tx->sge_idx = sge_idx;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 626 c_tx->sge_off = sge_off;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 627 c_tx->pbl_idx = pbl_idx;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 628 }
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 629 rv -= data_len;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 630
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 631 if (rv == trl_len) /* all pushed */
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 632 rv = 0;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 633 else {
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 634 c_tx->state = SIW_SEND_TRAILER;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 635 c_tx->ctrl_len = MAX_TRAILER;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 636 c_tx->ctrl_sent = rv + 4 - c_tx->pad;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 637 c_tx->bytes_unsent = 0;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 638 rv = -EAGAIN;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 639 }
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 640
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 641 } else if (data_len > 0) {
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 642 /* Maybe some user data pushed to TCP */
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 643 c_tx->state = SIW_SEND_DATA;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 644 wqe->processed -= data_len - rv;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 645
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 646 if (rv) {
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 647 /*
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 648 * Some bytes out. Recompute tx state based
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 649 * on old state and bytes pushed
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 650 */
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 651 unsigned int sge_unsent;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 652
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 653 c_tx->bytes_unsent -= rv;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 654 sge = &wqe->sqe.sge[c_tx->sge_idx];
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 655 sge_unsent = sge->length - c_tx->sge_off;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 656
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 657 while (sge_unsent <= rv) {
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 658 rv -= sge_unsent;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 659 c_tx->sge_idx++;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 660 c_tx->sge_off = 0;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 661 sge++;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 662 sge_unsent = sge->length;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 663 }
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 664 c_tx->sge_off += rv;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 665 }
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 666 rv = -EAGAIN;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 667 }
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 668 done_crc:
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 669 c_tx->do_crc = 0;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 670 done:
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 671 return rv;
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 672 }
b9be6f18cf9ed0 Bernard Metzler 2019-06-20 673
On Thu, Mar 30, 2023 at 9:02 PM kernel test robot <lkp@intel.com> wrote: > 0d1b756acf60da Linus Walleij 2022-09-02 536 /* > 0d1b756acf60da Linus Walleij 2022-09-02 537 * Cast to an uintptr_t to preserve all 64 bits > 0d1b756acf60da Linus Walleij 2022-09-02 538 * in sge->laddr. > 0d1b756acf60da Linus Walleij 2022-09-02 539 */ > a10308d393288b Jason Gunthorpe 2023-03-30 540 u64 va = (uintptr_t)(sge->laddr + sge_off); Oh now that becomes an u64 > b9be6f18cf9ed0 Bernard Metzler 2019-06-20 541 > a10308d393288b Jason Gunthorpe 2023-03-30 542 page_array[seg] = ib_virt_dma_to_page(va); > b9be6f18cf9ed0 Bernard Metzler 2019-06-20 543 if (do_crc) > b9be6f18cf9ed0 Bernard Metzler 2019-06-20 544 crypto_shash_update( > b9be6f18cf9ed0 Bernard Metzler 2019-06-20 545 c_tx->mpa_crc_hd, > 0d1b756acf60da Linus Walleij 2022-09-02 @546 (void *)va, Then this cast needs to be (void *)(uintptr_t) again. Not very elegant, possibly something more smooth can be done. Yours, Linus Walleij
On Thu, Mar 30, 2023 at 11:53:52PM +0200, Linus Walleij wrote: > On Thu, Mar 30, 2023 at 9:02 PM kernel test robot <lkp@intel.com> wrote: > > > 0d1b756acf60da Linus Walleij 2022-09-02 536 /* > > 0d1b756acf60da Linus Walleij 2022-09-02 537 * Cast to an uintptr_t to preserve all 64 bits > > 0d1b756acf60da Linus Walleij 2022-09-02 538 * in sge->laddr. > > 0d1b756acf60da Linus Walleij 2022-09-02 539 */ > > a10308d393288b Jason Gunthorpe 2023-03-30 540 u64 va = (uintptr_t)(sge->laddr + sge_off); > > Oh now that becomes an u64 > > > b9be6f18cf9ed0 Bernard Metzler 2019-06-20 541 > > a10308d393288b Jason Gunthorpe 2023-03-30 542 page_array[seg] = ib_virt_dma_to_page(va); > > b9be6f18cf9ed0 Bernard Metzler 2019-06-20 543 if (do_crc) > > b9be6f18cf9ed0 Bernard Metzler 2019-06-20 544 crypto_shash_update( > > b9be6f18cf9ed0 Bernard Metzler 2019-06-20 545 c_tx->mpa_crc_hd, > > 0d1b756acf60da Linus Walleij 2022-09-02 @546 (void *)va, > > Then this cast needs to be (void *)(uintptr_t) again. > > Not very elegant, possibly something more smooth can be done. It needs another similar helper function to from dma_addr to kva void * Jason
diff --git a/drivers/infiniband/sw/rxe/rxe_mr.c b/drivers/infiniband/sw/rxe/rxe_mr.c index 1e17f8086d59a8..0e538fafcc20ff 100644 --- a/drivers/infiniband/sw/rxe/rxe_mr.c +++ b/drivers/infiniband/sw/rxe/rxe_mr.c @@ -210,10 +210,10 @@ int rxe_mr_init_fast(int max_pages, struct rxe_mr *mr) return err; } -static int rxe_set_page(struct ib_mr *ibmr, u64 iova) +static int rxe_set_page(struct ib_mr *ibmr, u64 dma_addr) { struct rxe_mr *mr = to_rmr(ibmr); - struct page *page = virt_to_page(iova & mr->page_mask); + struct page *page = ib_virt_dma_to_page(dma_addr); bool persistent = !!(mr->access & IB_ACCESS_FLUSH_PERSISTENT); int err; @@ -279,16 +279,16 @@ static int rxe_mr_copy_xarray(struct rxe_mr *mr, u64 iova, void *addr, return 0; } -static void rxe_mr_copy_dma(struct rxe_mr *mr, u64 iova, void *addr, +static void rxe_mr_copy_dma(struct rxe_mr *mr, u64 dma_addr, void *addr, unsigned int length, enum rxe_mr_copy_dir dir) { - unsigned int page_offset = iova & (PAGE_SIZE - 1); + unsigned int page_offset = dma_addr & (PAGE_SIZE - 1); unsigned int bytes; struct page *page; u8 *va; while (length) { - page = virt_to_page(iova & mr->page_mask); + page = ib_virt_dma_to_page(dma_addr); bytes = min_t(unsigned int, length, PAGE_SIZE - page_offset); va = kmap_local_page(page); @@ -300,7 +300,7 @@ static void rxe_mr_copy_dma(struct rxe_mr *mr, u64 iova, void *addr, kunmap_local(va); page_offset = 0; - iova += bytes; + dma_addr += bytes; addr += bytes; length -= bytes; } @@ -488,7 +488,7 @@ int rxe_mr_do_atomic_op(struct rxe_mr *mr, u64 iova, int opcode, if (mr->ibmr.type == IB_MR_TYPE_DMA) { page_offset = iova & (PAGE_SIZE - 1); - page = virt_to_page(iova & PAGE_MASK); + page = ib_virt_dma_to_page(iova); } else { unsigned long index; int err; @@ -545,7 +545,7 @@ int rxe_mr_do_atomic_write(struct rxe_mr *mr, u64 iova, u64 value) if (mr->ibmr.type == IB_MR_TYPE_DMA) { page_offset = iova & (PAGE_SIZE - 1); - page = virt_to_page(iova & PAGE_MASK); + page = ib_virt_dma_to_page(iova); } else { unsigned long index; int err; diff --git a/drivers/infiniband/sw/siw/siw_qp_tx.c b/drivers/infiniband/sw/siw/siw_qp_tx.c index 6bb9e9e81ff4ca..108985af49723b 100644 --- a/drivers/infiniband/sw/siw/siw_qp_tx.c +++ b/drivers/infiniband/sw/siw/siw_qp_tx.c @@ -29,7 +29,7 @@ static struct page *siw_get_pblpage(struct siw_mem *mem, u64 addr, int *idx) dma_addr_t paddr = siw_pbl_get_buffer(pbl, offset, NULL, idx); if (paddr) - return virt_to_page((void *)(uintptr_t)paddr); + return ib_virt_dma_to_page(paddr); return NULL; } @@ -537,15 +537,9 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx, struct socket *s) * Cast to an uintptr_t to preserve all 64 bits * in sge->laddr. */ - uintptr_t va = (uintptr_t)(sge->laddr + sge_off); + u64 va = (uintptr_t)(sge->laddr + sge_off); - /* - * virt_to_page() takes a (void *) pointer - * so cast to a (void *) meaning it will be 64 - * bits on a 64 bit platform and 32 bits on a - * 32 bit platform. - */ - page_array[seg] = virt_to_page((void *)(va & PAGE_MASK)); + page_array[seg] = ib_virt_dma_to_page(va); if (do_crc) crypto_shash_update( c_tx->mpa_crc_hd, diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index 949cf4ffc536c5..4e8868171de68c 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h @@ -4035,6 +4035,19 @@ static inline bool ib_dma_pci_p2p_dma_supported(struct ib_device *dev) return dma_pci_p2pdma_supported(dev->dma_device); } +/** + * ib_virt_dma_to_page - Convert a dma_addr to a struct page + * @dma_addr: The DMA address to check + * + * Used by ib_uses_virt_dma() to get back to the struct page after + * going through the dma_addr marshalling. + */ +static inline struct page *ib_virt_dma_to_page(u64 dma_addr) +{ + /* virt_dma mode maps the kvs's directly into the dma addr */ + return virt_to_page((void *)(uintptr_t)dma_addr); +} + /** * ib_dma_mapping_error - check a DMA addr for error * @dev: The device for which the dma_addr was created
Make it clearer what is going on by adding a function to go back from the "virtual" dma_addr to a struct page. This is used in the ib_uses_virt_dma() style drivers (siw, rxe, hfi, qib). Call it instead of a naked virt_to_page() when working with dma_addr values encoded by the various ib_map functions. This also fixes the vir_to_page() casting problem Linus Walleij has been chasing. Cc: Linus Walleij <linus.walleij@linaro.org> Signed-off-by: Jason Gunthorpe <jgg@nvidia.com> --- drivers/infiniband/sw/rxe/rxe_mr.c | 16 ++++++++-------- drivers/infiniband/sw/siw/siw_qp_tx.c | 12 +++--------- include/rdma/ib_verbs.h | 13 +++++++++++++ 3 files changed, 24 insertions(+), 17 deletions(-) Maybe this will be clearer overall base-commit: 78b26a335310a097d6b22581b706050db42f196c