From: Frank Li <Frank.li@oss.nxp.com>
To: Koichiro Den <den@valinux.co.jp>
Cc: "Frank Li" <Frank.Li@kernel.org>,
"Manivannan Sadhasivam" <mani@kernel.org>,
"Krzysztof Wilczyński" <kwilczynski@kernel.org>,
"Kishon Vijay Abraham I" <kishon@kernel.org>,
"Jon Mason" <jdmason@kudzu.us>,
"Dave Jiang" <dave.jiang@intel.com>,
"Allen Hubbe" <allenbh@gmail.com>,
"Niklas Cassel" <cassel@kernel.org>,
"Bjorn Helgaas" <bhelgaas@google.com>,
"Jonathan Corbet" <corbet@lwn.net>,
"Shuah Khan" <skhan@linuxfoundation.org>,
"Randy Dunlap" <rdunlap@infradead.org>,
"Jingoo Han" <jingoohan1@gmail.com>,
"Lorenzo Pieralisi" <lpieralisi@kernel.org>,
"Rob Herring" <robh@kernel.org>,
"Jerome Brunet" <jbrunet@baylibre.com>,
linux-pci@vger.kernel.org, linux-doc@vger.kernel.org,
linux-kernel@vger.kernel.org, ntb@lists.linux.dev
Subject: Re: [PATCH v7 06/10] PCI: endpoint: pci-epf-vntb: Allow DMA and MW to share a BAR
Date: Wed, 21 Oct 2026 14:00:17 -0500 [thread overview]
Message-ID: <atkLwWs1uufsGkRV@SMW015318> (raw)
In-Reply-To: <fmnltbvuo6nm2sddmoqmpb6ema345rdqgavhf6xhrggnj7twpa@nlwyqy7zjppk>
On Thu, Oct 22, 2026 at 01:35:18AM +0900, Koichiro Den wrote:
> On Wed, Oct 21, 2026 at 10:52:32AM -0500, Frank Li wrote:
> > On Wed, Oct 21, 2026 at 01:22:25PM +0900, Koichiro Den wrote:
> > > Some endpoint configurations have no spare BAR for DMA resources. Allow
> > > dma_bar to select an MW BAR and place the DMA ranges after that MW.
> > >
> > > DMA submaps have fixed BAR offsets, so a shared MW translation must
> > > cover its configured size. Report that size as the translation alignment
> > > and require it to be a power of two.
> > >
> > > Older hosts treat the whole BAR as an MW. Require the host to advertise
> > > MW/DMA boundary support in LINK_UP before enabling a shared-BAR link.
> > >
> > > Signed-off-by: Koichiro Den <den@valinux.co.jp>
> > > ---
> > > Changes since v6:
> > > - Split out the host-side changes. (Frank)
> > > - Require MW/DMA BAR boundary support in LINK_UP for shared BARs.
> > >
> > > drivers/pci/endpoint/functions/pci-epf-vntb.c | 154 ++++++++++++++----
> > > include/linux/pci-epf-ntb.h | 3 +
> > > 2 files changed, 122 insertions(+), 35 deletions(-)
> > >
> > > diff --git a/drivers/pci/endpoint/functions/pci-epf-vntb.c b/drivers/pci/endpoint/functions/pci-epf-vntb.c
> > > index ac83af54122f..721cd841a1dd 100644
> > > --- a/drivers/pci/endpoint/functions/pci-epf-vntb.c
> > > +++ b/drivers/pci/endpoint/functions/pci-epf-vntb.c
> > > @@ -84,12 +84,13 @@ enum epf_irq_slot {
> > > #define MIN_DB_COUNT (EPF_IRQ_DB_START + 1)
> > >
> > > struct epf_ntb_dma {
> > > + struct mutex lock; /* Serialize DMA submap and MW updates */
> > > struct epf_ntb_dma_ctrl ctrl;
> > > struct dma_chan *dchan[EDMA_MAX_RD_CH];
> > > void *bar_scratch;
> > > dma_addr_t bar_scratch_phys;
> > > size_t bar_scratch_size;
> > > - struct pci_epf_bar_submap submap[EDMA_MAX_RD_CH + 2];
> > > + struct pci_epf_bar_submap submap[EDMA_MAX_RD_CH + 3];
> > > struct pci_epf_bar_submap *reg_submap;
> > > unsigned int num_submap;
> > > u16 rd_ch_cnt;
> > > @@ -229,6 +230,22 @@ static bool epf_ntb_is_bar_used(struct epf_ntb *ntb,
> > > return false;
> > > }
> > >
> > > +static u64 epf_ntb_dma_bar_offset(struct epf_ntb *ntb, enum pci_barno barno)
> > > +{
> > > + unsigned int i;
> > > +
> > > + for (i = 0; i < ntb->num_mws; i++)
> > > + if (ntb->epf_ntb_bar[BAR_MW1 + i] == barno)
> > > + return ntb->mws_size[i];
> > > +
> > > + return 0;
> > > +}
> > > +
> > > +static bool epf_ntb_dma_shares_bar(struct epf_ntb *ntb, enum pci_barno barno)
> > > +{
> > > + return ntb->dma && ntb->epf_ntb_bar[BAR_DMA] == barno;
> > > +}
> > > +
> > > struct epf_ntb_dma_filter {
> > > struct device *dev;
> > > int chan_id;
> > > @@ -353,6 +370,7 @@ static int epf_ntb_dw_edma_collect(struct epf_ntb *ntb,
> > > unsigned int i;
> > > size_t align;
> > > u32 next = 0;
> > > + u64 offset;
> > > int ret;
> > >
> > > if (ctrl->u.dma_ctrl.reg_layout_data != EDMA_MF_EDMA_UNROLL)
> > > @@ -371,9 +389,30 @@ static int epf_ntb_dw_edma_collect(struct epf_ntb *ntb,
> > > if (!is_power_of_2(align))
> > > return -EINVAL;
> > >
> > > - if (epf_ntb_is_bar_used(ntb, barno) ||
> > > - pci_epc_get_next_free_bar(features, barno) != barno)
> > > + if (barno == ntb->epf_ntb_bar[BAR_CONFIG] ||
> > > + barno == ntb->epf_ntb_bar[BAR_DB])
> > > + return -EINVAL;
> > > +
> > > + offset = epf_ntb_dma_bar_offset(ntb, barno);
> > > + if (!offset &&
> > > + (epf_ntb_is_bar_used(ntb, barno) ||
> > > + pci_epc_get_next_free_bar(features, barno) != barno))
> > > + return -EINVAL;
> > > + if (offset > U32_MAX)
> > > + return -EOVERFLOW;
> > > + if (offset && !is_power_of_2(offset))
> > > return -EINVAL;
> > > + dma->ctrl.submap.offset = offset;
> > > + next = offset;
> > > + if (next) {
> > > + /*
> > > + * submap[0] covers the MW prefix. Keep its temporary
> > > + * target at address 0 until the MW translation is
> > > + * installed.
> > > + */
> > > + dma->submap[0].size = next;
> > > + dma->num_submap = 1;
> > > + }
> > >
> > > dma->ctrl.magic = EPF_NTB_DMA_MAGIC;
> > > dma->ctrl.revision = EPF_NTB_DMA_REVISION;
> > > @@ -408,7 +447,7 @@ static int epf_ntb_dw_edma_collect(struct epf_ntb *ntb,
> > > chan->desc_addr_lo = lower_32_bits(dma_addr);
> > > chan->desc_addr_hi = upper_32_bits(dma_addr);
> > > }
> > > - dma->ctrl.submap.size = next;
> > > + dma->ctrl.submap.size = next - dma->ctrl.submap.offset;
> > >
> > > dma_dev = ntb->epf->epc->dev.parent;
> > > for (i = 0; i < dma->rd_ch_cnt; i++) {
> > > @@ -481,6 +520,8 @@ static int epf_ntb_dma_collect(struct epf_ntb *ntb)
> > > if (!dma)
> > > return -ENOMEM;
> > >
> > > + mutex_init(&dma->lock);
> > > +
> > > switch (ctrl->u.dma_ctrl.reg_layout) {
> > > case PCI_EPC_AUX_DMA_REG_LAYOUT_DW_EDMA:
> > > ret = epf_ntb_dw_edma_collect(ntb, dma, ctrl, resources, count);
> > > @@ -551,7 +592,7 @@ static int epf_ntb_dma_bar_init(struct epf_ntb *ntb)
> > > return -EOPNOTSUPP;
> > >
> > > barno = ntb->epf_ntb_bar[BAR_DMA];
> > > - mapped_size = dma->ctrl.submap.size;
> > > + mapped_size = dma->ctrl.submap.offset + dma->ctrl.submap.size;
> > > /*
> > > * Submaps cannot be installed until the host assigns the BAR address.
> > > * Use address 0 for the temporary BAR Match Mode mapping, as is done
> > > @@ -607,21 +648,25 @@ static void epf_ntb_dma_bar_clear(struct epf_ntb *ntb)
> > > memset(bar, 0, sizeof(*bar));
> > > }
> > >
> > > -static int epf_ntb_dma_set_bar(struct epf_ntb *ntb)
> > > +static int epf_ntb_dma_set_bar_locked(struct epf_ntb *ntb,
> > > + const dma_addr_t *mw_addr)
> > > {
> > > struct pci_epf_bar_submap *old_submap;
> > > struct epf_ntb_dma *dma = ntb->dma;
> > > unsigned int old_num_submap;
> > > struct pci_epf_bar *bar;
> > > + dma_addr_t old_mw_addr;
> > > int restore, ret;
> > > -
> > > - if (!dma)
> > > - return 0;
> > > + lockdep_assert_held(&dma->lock);
> > >
> > > bar = &ntb->epf->bar[ntb->epf_ntb_bar[BAR_DMA]];
> > >
> > > old_submap = bar->submap;
> > > old_num_submap = bar->num_submap;
> > > + if (mw_addr) {
> > > + old_mw_addr = dma->submap[0].phys_addr;
> > > + dma->submap[0].phys_addr = *mw_addr;
> > > + }
> > > bar->submap = dma->submap;
> > > bar->num_submap = dma->num_submap;
> > >
> > > @@ -631,6 +676,8 @@ static int epf_ntb_dma_set_bar(struct epf_ntb *ntb)
> > > return 0;
> > >
> > > /* A failed dynamic update may have already removed the old mapping. */
> > > + if (mw_addr)
> > > + dma->submap[0].phys_addr = old_mw_addr;
> > > bar->submap = old_submap;
> > > bar->num_submap = old_num_submap;
> > > restore = pci_epc_set_bar(ntb->epf->epc, ntb->epf->func_no,
> > > @@ -642,6 +689,18 @@ static int epf_ntb_dma_set_bar(struct epf_ntb *ntb)
> > > return ret;
> > > }
> > >
> > > +static int epf_ntb_dma_set_bar(struct epf_ntb *ntb)
> > > +{
> > > + struct epf_ntb_dma *dma = ntb->dma;
> > > +
> > > + if (!dma)
> > > + return 0;
> > > +
> > > + guard(mutex)(&dma->lock);
> > > +
> > > + return epf_ntb_dma_set_bar_locked(ntb, NULL);
> > > +}
> > > +
> > > /**
> > > * epf_ntb_configure_mw() - Configure the Outbound Address Space for VHOST
> > > * to access the memory window of HOST
> > > @@ -780,6 +839,13 @@ static void epf_ntb_cmd_handler(struct work_struct *work)
> > > EPF_NTB_COMMAND_STATUS_OK;
> > > break;
> > > case EPF_NTB_COMMAND_LINK_UP:
> > > + if (ntb->dma && ntb->dma->ctrl.submap.offset &&
> > > + !(argument & EPF_NTB_LINK_UP_DMA_MW_SUPPORTED)) {
> > > + epf_ntb_set_link_enabled(ntb, false);
> > > + dev_err(dev, "Host does not support MW/DMA BAR sharing\n");
> > > + ctrl->command_status = EPF_NTB_COMMAND_STATUS_ERROR;
> >
> > suppose it should be fallback to old method?
> > EPF_NTB_LINK_UP_DMA_MW_SUPPORTED is new feature.
>
> It's possible (by using the whole BAR as an MW), but I personally think the
> extra complexity would not really be worthwhile for this case.
>
> If a "New" endpoint is paired with an "Old" host whose kernel cannot be
> upgraded, the DMA feature cannot be used anyway. For that setup, I think
> disabling DMA export with dma_bar = -1 (the default) and rebinding the endpoint
> would be sufficient, with host re-enumeration as needed.
At least it should work without using DMA as previous version. Assume build
as PCIE card, which have already prebuild image, which may plug into any
host machine. You can't require user to rebinding endpoint software.
Many PCI card have not provided any console after production.
Frank
next prev parent reply other threads:[~2026-10-21 19:00 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-21 4:22 [PATCH v7 00/10] PCI: endpoint: Remote DMA support via vNTB Koichiro Den
2026-10-21 4:22 ` [PATCH v7 01/10] PCI: endpoint: Add DMA auxiliary resource metadata Koichiro Den
2026-10-21 4:22 ` [PATCH v7 02/10] PCI: dwc: Expose endpoint DMA resources Koichiro Den
2026-10-21 4:22 ` [PATCH v7 03/10] PCI: endpoint: pci-epf-vntb: Move epf_ntb_is_bar_used() up Koichiro Den
2026-10-21 4:22 ` [PATCH v7 04/10] PCI: endpoint: Add pci-epf-ntb.h for the shared NTB control layout Koichiro Den
2026-10-21 4:22 ` [PATCH v7 05/10] PCI: endpoint: pci-epf-vntb: Export endpoint DMA channels Koichiro Den
2026-10-21 4:22 ` [PATCH v7 06/10] PCI: endpoint: pci-epf-vntb: Allow DMA and MW to share a BAR Koichiro Den
2026-10-21 15:52 ` Frank Li
2026-10-21 16:35 ` Koichiro Den
2026-10-21 19:00 ` Frank Li [this message]
2026-10-21 4:22 ` [PATCH v7 07/10] Documentation: PCI: endpoint: Document vNTB DMA export Koichiro Den
2026-10-21 4:22 ` [PATCH v7 08/10] NTB: ntb_hw_epf: Use the shared NTB control layout Koichiro Den
2026-10-21 15:53 ` Frank Li
2026-10-21 4:22 ` [PATCH v7 09/10] NTB: ntb_hw_epf: Discover vNTB-embedded DMA Koichiro Den
2026-10-21 4:22 ` [PATCH v7 10/10] NTB: ntb_hw_epf: Support DMA and MW sharing a BAR Koichiro Den
2026-10-21 15:58 ` Frank Li
2026-10-21 16:57 ` Koichiro Den
2026-10-21 18:51 ` Frank Li
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=atkLwWs1uufsGkRV@SMW015318 \
--to=frank.li@oss.nxp.com \
--cc=Frank.Li@kernel.org \
--cc=allenbh@gmail.com \
--cc=bhelgaas@google.com \
--cc=cassel@kernel.org \
--cc=corbet@lwn.net \
--cc=dave.jiang@intel.com \
--cc=den@valinux.co.jp \
--cc=jbrunet@baylibre.com \
--cc=jdmason@kudzu.us \
--cc=jingoohan1@gmail.com \
--cc=kishon@kernel.org \
--cc=kwilczynski@kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=lpieralisi@kernel.org \
--cc=mani@kernel.org \
--cc=ntb@lists.linux.dev \
--cc=rdunlap@infradead.org \
--cc=robh@kernel.org \
--cc=skhan@linuxfoundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®