Re: [PATCH v10 5/7] PCI: endpoint: pci-epf-vntb: Reuse pre-exposed doorbells and IRQ flags
Frank Li <[email protected]> Mon, 23 Mar 2026 14:39:01 -0400
| Newsgroups | dev.linux.lists.ntb,org.kernel.vger.linux-kernel,org.kernel.vger.linux-pci |
|---|---|
| Message-ID | <acGIxaIRUoaAjFM1@lizhi-Precision-Tower-5810> |
On Mon, Mar 02, 2026 at 04:14:25PM +0900, Koichiro Den wrote: > Support doorbell backends where the doorbell target is already exposed > via a platform-owned fixed BAR mapping and/or where the doorbell IRQ > must be requested with specific flags. > > When pci_epf_alloc_doorbell() provides db_msg[].bar/offset, reuse the > pre-exposed BAR window and skip programming a new inbound mapping. Also > honor db_msg[].irq_flags when requesting the doorbell IRQ. > > Multiple doorbells may share the same Linux IRQ. Avoid duplicate > request_irq() calls by requesting each unique virq once. > > Make pci-epf-vntb work with platform-defined or embedded doorbell > backends without exposing backend-specific details to the consumer > layer. > > Tested-by: Niklas Cassel <[email protected]> > Signed-off-by: Koichiro Den <[email protected]> > --- Reviewed-by: Frank Li <[email protected]> > drivers/pci/endpoint/functions/pci-epf-vntb.c | 61 ++++++++++++++++++- > 1 file changed, 58 insertions(+), 3 deletions(-) > > diff --git a/drivers/pci/endpoint/functions/pci-epf-vntb.c b/drivers/pci/endpoint/functions/pci-epf-vntb.c > index 148a3b160812..8e9a3048c2e5 100644 > --- a/drivers/pci/endpoint/functions/pci-epf-vntb.c > +++ b/drivers/pci/endpoint/functions/pci-epf-vntb.c > @@ -134,6 +134,11 @@ struct epf_ntb { > u16 vntb_vid; > > bool linkup; > + > + /* > + * True when doorbells are interrupt-driven (MSI or embedded), false > + * when polled. > + */ > bool msi_doorbell; > u32 spad_size; > > @@ -517,6 +522,17 @@ static int epf_ntb_configure_interrupt(struct epf_ntb *ntb) > return 0; > } > > +static bool epf_ntb_db_irq_is_duplicated(const struct pci_epf *epf, unsigned int idx) > +{ > + unsigned int i; > + > + for (i = 0; i < idx; i++) > + if (epf->db_msg[i].virq == epf->db_msg[idx].virq) > + return true; > + > + return false; > +} > + > static int epf_ntb_db_bar_init_msi_doorbell(struct epf_ntb *ntb, > struct pci_epf_bar *db_bar, > const struct pci_epc_features *epc_features, > @@ -533,9 +549,24 @@ static int epf_ntb_db_bar_init_msi_doorbell(struct epf_ntb *ntb, > if (ret) > return ret; > > + /* > + * The doorbell target may already be exposed by a platform-owned fixed > + * BAR. In that case, we must reuse it and the requested db_bar must > + * match. > + */ > + if (epf->db_msg[0].bar != NO_BAR && epf->db_msg[0].bar != barno) { > + ret = -EINVAL; > + goto err_free_doorbell; > + } > + > for (req = 0; req < ntb->db_count; req++) { > + /* Avoid requesting duplicate handlers */ > + if (epf_ntb_db_irq_is_duplicated(epf, req)) > + continue; > + > ret = request_irq(epf->db_msg[req].virq, epf_ntb_doorbell_handler, > - 0, "pci_epf_vntb_db", ntb); > + epf->db_msg[req].irq_flags, "pci_epf_vntb_db", > + ntb); > > if (ret) { > dev_err(&epf->dev, > @@ -545,6 +576,22 @@ static int epf_ntb_db_bar_init_msi_doorbell(struct epf_ntb *ntb, > } > } > > + if (epf->db_msg[0].bar != NO_BAR) { > + for (i = 0; i < ntb->db_count; i++) { > + msg = &epf->db_msg[i].msg; > + > + if (epf->db_msg[i].bar != barno) { > + ret = -EINVAL; > + goto err_free_irq; > + } > + > + ntb->reg->db_data[i] = msg->data; > + ntb->reg->db_offset[i] = epf->db_msg[i].offset; > + } > + goto out; > + } > + > + /* Program inbound mapping for the doorbell */ > msg = &epf->db_msg[0].msg; > > high = 0; > @@ -591,6 +638,7 @@ static int epf_ntb_db_bar_init_msi_doorbell(struct epf_ntb *ntb, > ntb->reg->db_offset[i] = offset; > } > > +out: > ntb->reg->db_entry_size = 0; > > ntb->msi_doorbell = true; > @@ -598,9 +646,13 @@ static int epf_ntb_db_bar_init_msi_doorbell(struct epf_ntb *ntb, > return 0; > > err_free_irq: > - for (req--; req >= 0; req--) > + for (req--; req >= 0; req--) { > + if (epf_ntb_db_irq_is_duplicated(epf, req)) > + continue; > free_irq(epf->db_msg[req].virq, ntb); > + } > > +err_free_doorbell: > pci_epf_free_doorbell(ntb->epf); > return ret; > } > @@ -666,8 +718,11 @@ static void epf_ntb_db_bar_clear(struct epf_ntb *ntb) > if (ntb->msi_doorbell) { > int i; > > - for (i = 0; i < ntb->db_count; i++) > + for (i = 0; i < ntb->db_count; i++) { > + if (epf_ntb_db_irq_is_duplicated(ntb->epf, i)) > + continue; > free_irq(ntb->epf->db_msg[i].virq, ntb); > + } > } > > if (ntb->epf->db_msg) > -- > 2.51.0 >