Re: [PATCH v2 3/7] s390/pci: Use dma-iommu layer

Niklas Schnelle
2022-12-19T15:18:23Z

On Mon, 2022-11-28 at 18:03 +0000, Robin Murphy wrote:
> On 2022-11-16 17:16, Niklas Schnelle wrote:
> [...]
> > diff --git a/drivers/iommu/Kconfig b/drivers/iommu/Kconfig
> > index dc5f7a156ff5..804fb8f42d61 100644
> > --- a/drivers/iommu/Kconfig
> > +++ b/drivers/iommu/Kconfig
> > @@ -93,7 +93,7 @@ config IOMMU_DEBUGFS
> > choice
> > prompt "IOMMU default domain type"
> > depends on IOMMU_API
> > - default IOMMU_DEFAULT_DMA_LAZY if X86 || IA64
> > + default IOMMU_DEFAULT_DMA_LAZY if X86 || IA64 || S390
> > default IOMMU_DEFAULT_DMA_STRICT
> > help
> > Choose the type of IOMMU domain used to manage DMA API usage by
> > @@ -412,6 +412,7 @@ config ARM_SMMU_V3_SVA
> > config S390_IOMMU
> > def_bool y if S390 && PCI
> > depends on S390 && PCI
> > + select IOMMU_DMA
>
> Please add S390 to the condition under config IOMMU_DMA instead.

Done, will be in v3

>
> > select IOMMU_API
> > help
> > Support for the IOMMU API for s390 PCI devices.
> [...]
> > @@ -45,9 +329,14 @@ static struct iommu_domain *s390_domain_alloc(unsigned domain_type)
> > {
> > struct s390_domain *s390_domain;
> >
> > - if (domain_type != IOMMU_DOMAIN_UNMANAGED)
> > + switch (domain_type) {
> > + case IOMMU_DOMAIN_DMA:
> > + case IOMMU_DOMAIN_DMA_FQ:
>
> I was about to question adding this without any visible treatment of
> iommu_iotlb_gather_queued() or domain->type == IOMMU_DOMAIN_DMA_FQ as a
> whole, but I guess if you never actually free any pagetables it does
> work out OK. Bit of a timebomb if there's a chance of that ever changing
> in future, though.

Yes, as we're not freeing pagetables they will be reused simply by
reusing same IOVA. Restricting the range of IOVAs is then what keeps
the translation table from growing unbounded. This also makes the
pagetable handling easier

It will definitely need handling if we ever add freeing pagestables
yes. I'd hope though that if we do add this functionality it will be
through common code reuse such as io-pgtable.h that will deal with this
naturally. I'm still pondering to add a comment here but I also fear
that this part is going to be refactored soon and such a comment will
get lost before it could matter.

>
> > + case IOMMU_DOMAIN_UNMANAGED:
> > + break;
> > + default:
> > return NULL;
> > -
> > + }
> > s390_domain = kzalloc(sizeof(*s390_domain), GFP_KERNEL);
> > if (!s390_domain)
> > return NULL;
> [...]
> > @@ -397,12 +678,29 @@ static size_t s390_iommu_unmap_pages(struct iommu_domain *domain,
> > return 0;
> >
> > iommu_iotlb_gather_add_range(gather, iova, size);
> > + atomic64_add(pgcount, &s390_domain->ctrs.unmapped_pages);
> >
> > return size;
> > }
> >
> > +static void s390_iommu_probe_finalize(struct device *dev)
> > +{
> > + struct iommu_domain *domain = iommu_get_domain_for_dev(dev);
> > +
> > + iommu_dma_forcedac = true;
> > + iommu_setup_dma_ops(dev, domain->geometry.aperture_start, domain->geometry.aperture_end);
>
> For consistency with all but one other caller now, just pass 0 and
> U64_MAX for base and size to make it clear that they're meaningless
> (they will eventually go away as part of a bigger refactoring).
>
> Thanks,
> Robin.

Done will be in v3.

Now I'm still trying to figure out how to prefer the proposed
IOMMU_DOMAIN_DMA_SQ when running with a hypervisor with expensive IOTLB
flush while IOMMU_DOMAIN_DMA and IOMMU_DOMAIN_DMA_FQ both work but are
slower. Jason's patch idea of adding a DMA_API_POLICY sounds like a
good start but is also a rather big change and doesn't yet allow for a
preference by the IOMMU driver. Will see, if I can come up with
something minimal for that.