From mboxrd@z Thu Jan 1 00:00:00 1970 Date: Thu, 14 Feb 2019 05:44:40 -0800 (PST) From: lravich@gmail.com Message-Id: <4bddaad3-14e2-4ceb-90d0-2955ea76b442@googlegroups.com> In-Reply-To: <20190119001001.13087-1-logang@deltatee.com> References: <20190119001001.13087-1-logang@deltatee.com> Subject: Re: [PATCH] NTB: ntb_transport: Ensure the destination buffer is mapped for TX DMA MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_Part_301_1326305677.1550151880472" To: linux-ntb List-ID: ------=_Part_301_1326305677.1550151880472 Content-Type: multipart/alternative; boundary="----=_Part_302_1173821174.1550151880472" ------=_Part_302_1173821174.1550151880472 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit Hi Logan , I took a look on the dma_map_resource() you used in this patch , looks like ops->map_resource not implemented for intel if I see it right, this will not fix the issue for Intel NTB . Please let me know if I am right Thanks. Leonid Ravich On Saturday, January 19, 2019 at 2:10:12 AM UTC+2, Logan Gunthorpe wrote: > > Presently, when ntb_transport is used with DMA and the IOMMU turned on, > it fails with errors from the IOMMU such as: > > DMAR: DRHD: handling fault status reg 202 > DMAR: [DMA Write] Request device [00:04.0] fault addr > 381fc0340000 [fault reason 05] PTE Write access is not set > > This is because ntb_transport does not map the BAR space with the IOMMU. > > To fix this, we map the entire MW region for each QP after we assign > the DMA channel. This prevents needing an extra DMA map in the fast > path. > > Link: https://lore.kernel.org/linux-pci/499934e7-3734-1aee-37dd-b42a5d2a2608@intel.com/ > > Signed-off-by > : > Logan Gunthorpe > > Cc: Jon Mason > > Cc: Dave Jiang > > Cc: Allen Hubbe > > --- > drivers/ntb/ntb_transport.c | 28 ++++++++++++++++++++++++++-- > 1 file changed, 26 insertions(+), 2 deletions(-) > > diff --git a/drivers/ntb/ntb_transport.c b/drivers/ntb/ntb_transport.c > index 3bfdb4562408..526b65afc16a 100644 > --- a/drivers/ntb/ntb_transport.c > +++ b/drivers/ntb/ntb_transport.c > @@ -144,7 +144,9 @@ struct ntb_transport_qp { > struct list_head tx_free_q; > spinlock_t ntb_tx_free_q_lock; > void __iomem *tx_mw; > - dma_addr_t tx_mw_phys; > + phys_addr_t tx_mw_phys; > + size_t tx_mw_size; > + dma_addr_t tx_mw_dma_addr; > unsigned int tx_index; > unsigned int tx_max_entry; > unsigned int tx_max_frame; > @@ -1049,6 +1051,7 @@ static int ntb_transport_init_queue(struct > ntb_transport_ctx *nt, > tx_size = (unsigned int)mw_size / num_qps_mw; > qp_offset = tx_size * (qp_num / mw_count); > > + qp->tx_mw_size = tx_size; > qp->tx_mw = nt->mw_vec[mw_num].vbase + qp_offset; > if (!qp->tx_mw) > return -EINVAL; > @@ -1644,7 +1647,7 @@ static int ntb_async_tx_submit(struct > ntb_transport_qp *qp, > dma_cookie_t cookie; > > device = chan->device; > - dest = qp->tx_mw_phys + qp->tx_max_frame * entry->tx_index; > + dest = qp->tx_mw_dma_addr + qp->tx_max_frame * entry->tx_index; > buff_off = (size_t)buf & ~PAGE_MASK; > dest_off = (size_t)dest & ~PAGE_MASK; > > @@ -1863,6 +1866,18 @@ ntb_transport_create_queue(void *data, struct > device *client_dev, > qp->rx_dma_chan = NULL; > } > > + if (qp->tx_dma_chan) { > + qp->tx_mw_dma_addr = > + dma_map_resource(qp->tx_dma_chan->device->dev, > + qp->tx_mw_phys, qp->tx_mw_size, > + DMA_FROM_DEVICE, 0); > + if (dma_mapping_error(qp->tx_dma_chan->device->dev, > + qp->tx_mw_dma_addr)) { > + qp->tx_mw_dma_addr = 0; > + goto err1; > + } > + } > + > dev_dbg(&pdev->dev, "Using %s memcpy for TX\n", > qp->tx_dma_chan ? "DMA" : "CPU"); > > @@ -1904,6 +1919,10 @@ ntb_transport_create_queue(void *data, struct > device *client_dev, > qp->rx_alloc_entry = 0; > while ((entry = ntb_list_rm(&qp->ntb_rx_q_lock, &qp->rx_free_q))) > kfree(entry); > + if (qp->tx_mw_dma_addr) > + dma_unmap_resource(qp->tx_dma_chan->device->dev, > + qp->tx_mw_dma_addr, qp->tx_mw_size, > + DMA_FROM_DEVICE, 0); > if (qp->tx_dma_chan) > dma_release_channel(qp->tx_dma_chan); > if (qp->rx_dma_chan) > @@ -1945,6 +1964,11 @@ void ntb_transport_free_queue(struct > ntb_transport_qp *qp) > */ > dma_sync_wait(chan, qp->last_cookie); > dmaengine_terminate_all(chan); > + > + dma_unmap_resource(chan->device->dev, > + qp->tx_mw_dma_addr, qp->tx_mw_size, > + DMA_FROM_DEVICE, 0); > + > dma_release_channel(chan); > } > > -- > 2.19.0 > > ------=_Part_302_1173821174.1550151880472 Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable
Hi Logan ,=C2=A0
I took a look on the=C2=A0dma_map_res= ource() you used in this patch , looks like=C2=A0ops->map_resource not i= mplemented for intel=C2=A0
if I see it right, this will not fix t= he issue for Intel NTB .

Please let me know if I a= m right=C2=A0

Thanks.
Leonid Ravich
<= br>On Saturday, January 19, 2019 at 2:10:12 AM UTC+2, Logan Gunthorpe wrote= :
Presently, when ntb_transport= is used with DMA and the IOMMU turned on,
it fails with errors from the IOMMU such as:

=C2=A0 DMAR: DRHD: handling fault status reg 202
=C2=A0 DMAR: [DMA Write] Request device [00:04.0] fault addr
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0381fc0340000 [fault rea= son 05] PTE Write access is not set

This is because ntb_transport does not map the BAR space with the IOMMU= .

To fix this, we map the entire MW region for each QP after we assign
the DMA channel. This prevents needing an extra DMA map in the fast
path.

Link: https= ://lore.kernel.org/linux-pci/499934e7-3734-1aee-37dd-b42a5d2a2608= @intel.com/
Signed-off-by
: Logan Gunthorpe <log...@deltatee.com>
Cc: Jon Mason <jdm...@kudzu.us>
Cc: Dave Jiang <dave....@intel.com>
Cc: Allen Hubbe <all...@gmail.com>
---
=C2=A0drivers/ntb/ntb_transport.c | 28 ++++++++++++++++++++++++++--
=C2=A01 file changed, 26 insertions(+), 2 deletions(-)

diff --git a/drivers/ntb/ntb_transport.c b/drivers/ntb/ntb_transport.c
index 3bfdb4562408..526b65afc16a 100644
--- a/drivers/ntb/ntb_transport.c
+++ b/drivers/ntb/ntb_transport.c
@@ -144,7 +144,9 @@ struct ntb_transport_qp {
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0struct list_head = tx_free_q;
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0spinlock_t ntb_tx= _free_q_lock;
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0void __iomem *tx_= mw;
-=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0dma_addr_t tx_mw_phys;
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0phys_addr_t tx_mw_phys= ;
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0size_t tx_mw_size;
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0dma_addr_t tx_mw_dma_a= ddr;
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0unsigned int tx_i= ndex;
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0unsigned int tx_m= ax_entry;
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0unsigned int tx_m= ax_frame;
@@ -1049,6 +1051,7 @@ static int ntb_transport_init_queue(struct n= tb_transport_ctx *nt,
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0tx_size =3D (unsi= gned int)mw_size / num_qps_mw;
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0qp_offset =3D tx_= size * (qp_num / mw_count);
=C2=A0
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0qp->tx_mw_size =3D = tx_size;
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0qp->tx_mw =3D = nt->mw_vec[mw_num].vbase + qp_offset;
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0if (!qp->tx_mw= )
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0return -EINVAL;
@@ -1644,7 +1647,7 @@ static int ntb_async_tx_submit(struct ntb_transpo= rt_qp *qp,
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0dma_cookie_t cook= ie;
=C2=A0
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0device =3D chan-&= gt;device;
-=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0dest =3D qp->tx_mw_= phys + qp->tx_max_frame * entry->tx_index;
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0dest =3D qp->tx_mw_= dma_addr + qp->tx_max_frame * entry->tx_index;
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0buff_off =3D (siz= e_t)buf & ~PAGE_MASK;
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0dest_off =3D (siz= e_t)dest & ~PAGE_MASK;
=C2=A0
@@ -1863,6 +1866,18 @@ ntb_transport_create_queue(void *data, stru= ct device *client_dev,
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0qp->rx_dma_chan =3D NULL;
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0}
=C2=A0
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0if (qp->tx_dma_chan= ) {
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0qp->tx_mw_dma_addr =3D
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= dma_map_resource(qp->tx_dma_chan->device->dev,
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 qp->tx_mw_phys, qp->tx_mw_size,
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0 DMA_FROM_DEVICE, 0);
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0if (dma_mapping_error(qp->tx_dma_chan-&g= t;device->dev,
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 =C2=A0 =C2=A0 =C2=A0q= p->tx_mw_dma_addr)) {
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= qp->tx_mw_dma_addr =3D 0;
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= goto err1;
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0}
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0}
+
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0dev_dbg(&pdev= ->dev, "Using %s memcpy for TX\n",
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0qp->tx_dma_chan ? "DMA" = : "CPU");
=C2=A0
@@ -1904,6 +1919,10 @@ ntb_transport_create_queue(void *data, stru= ct device *client_dev,
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0qp->rx_alloc_e= ntry =3D 0;
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0while ((entry =3D= ntb_list_rm(&qp->ntb_rx_q_lock, &qp->rx_free_q)))
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0kfree(entry);
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0if (qp->tx_mw_dma_a= ddr)
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0dma_unmap_resource(qp->tx_dma_chan-><= wbr>device->dev,
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 =C2=A0 qp->tx_mw_d= ma_addr, qp->tx_mw_size,
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 =C2=A0 DMA_FROM_DEVIC= E, 0);
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0if (qp->tx_dma= _chan)
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0dma_release_channel(qp->tx_dma_cha= n);
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0if (qp->rx_dma= _chan)
@@ -1945,6 +1964,11 @@ void ntb_transport_free_queue(struct ntb_tr= ansport_qp *qp)
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 */
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0dma_sync_wait(chan, qp->last_cooki= e);
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0dmaengine_terminate_all(chan);
+
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0dma_unmap_resource(chan->device->dev,
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 =C2=A0 qp->tx_mw_d= ma_addr, qp->tx_mw_size,
+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 =C2=A0 DMA_FROM_DEVIC= E, 0);
+
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0dma_release_channel(chan);
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0}
=C2=A0
--=20
2.19.0

------=_Part_302_1173821174.1550151880472-- ------=_Part_301_1326305677.1550151880472--