diff mbox series

RDMA: Add ib_virt_dma_to_page()

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

Commit Message

Jason Gunthorpe March 30, 2023, 2:26 p.m. UTC
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

Comments

Linus Walleij March 30, 2023, 6:24 p.m. UTC | #1
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
kernel test robot March 30, 2023, 7:01 p.m. UTC | #2
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
Linus Walleij March 30, 2023, 9:53 p.m. UTC | #3
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
Jason Gunthorpe March 30, 2023, 10:37 p.m. UTC | #4
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 mbox series

Patch

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