Re: [PATCH 1/2] iommu/vt-d: Fix PCI bus rescan device hot add
On Tue, Feb 01, 2022 at 11:19:18AM -0800, Jacob Pan wrote: > Do you mean having an IRQ remapping notifier regardless IOMMU-API is > enabled, right? > It make sense, I will give it a try. Yeah, that would be best. I really don't like to use two notifiers just to work around ordering issues. Regards, Joerg ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH v2] iommu/iova: Separate out rcache init
On Thu, Feb 03, 2022 at 05:59:20PM +0800, John Garry wrote: > Currently the rcache structures are allocated for all IOVA domains, even if > they do not use "fast" alloc+free interface. This is wasteful of memory. > > In addition, fails in init_iova_rcaches() are not handled safely, which is > less than ideal. > > Make "fast" users call a separate rcache init explicitly, which includes > error checking. > > Signed-off-by: John Garry virtio things: Acked-by: Michael S. Tsirkin > --- > Differences to v1: > - Drop stubs for iova_domain_init_rcaches() and iova_domain_free_rcaches() > - Use put_iova_domain() in vdpa code > > diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c > index d85d54f2b549..b22034975301 100644 > --- a/drivers/iommu/dma-iommu.c > +++ b/drivers/iommu/dma-iommu.c > @@ -525,6 +525,7 @@ static int iommu_dma_init_domain(struct iommu_domain > *domain, dma_addr_t base, > struct iommu_dma_cookie *cookie = domain->iova_cookie; > unsigned long order, base_pfn; > struct iova_domain *iovad; > + int ret; > > if (!cookie || cookie->type != IOMMU_DMA_IOVA_COOKIE) > return -EINVAL; > @@ -559,6 +560,9 @@ static int iommu_dma_init_domain(struct iommu_domain > *domain, dma_addr_t base, > } > > init_iova_domain(iovad, 1UL << order, base_pfn); > + ret = iova_domain_init_rcaches(iovad); > + if (ret) > + return ret; > > /* If the FQ fails we can simply fall back to strict mode */ > if (domain->type == IOMMU_DOMAIN_DMA_FQ && iommu_dma_init_fq(domain)) > diff --git a/drivers/iommu/iova.c b/drivers/iommu/iova.c > index b28c9435b898..7e9c3a97c040 100644 > --- a/drivers/iommu/iova.c > +++ b/drivers/iommu/iova.c > @@ -15,13 +15,14 @@ > /* The anchor node sits above the top of the usable address space */ > #define IOVA_ANCHOR ~0UL > > +#define IOVA_RANGE_CACHE_MAX_SIZE 6 /* log of max cached IOVA range size > (in pages) */ > + > static bool iova_rcache_insert(struct iova_domain *iovad, > unsigned long pfn, > unsigned long size); > static unsigned long iova_rcache_get(struct iova_domain *iovad, >unsigned long size, >unsigned long limit_pfn); > -static void init_iova_rcaches(struct iova_domain *iovad); > static void free_cpu_cached_iovas(unsigned int cpu, struct iova_domain > *iovad); > static void free_iova_rcaches(struct iova_domain *iovad); > > @@ -64,8 +65,6 @@ init_iova_domain(struct iova_domain *iovad, unsigned long > granule, > iovad->anchor.pfn_lo = iovad->anchor.pfn_hi = IOVA_ANCHOR; > rb_link_node(>anchor.node, NULL, >rbroot.rb_node); > rb_insert_color(>anchor.node, >rbroot); > - cpuhp_state_add_instance_nocalls(CPUHP_IOMMU_IOVA_DEAD, > >cpuhp_dead); > - init_iova_rcaches(iovad); > } > EXPORT_SYMBOL_GPL(init_iova_domain); > > @@ -488,6 +487,13 @@ free_iova_fast(struct iova_domain *iovad, unsigned long > pfn, unsigned long size) > } > EXPORT_SYMBOL_GPL(free_iova_fast); > > +static void iova_domain_free_rcaches(struct iova_domain *iovad) > +{ > + cpuhp_state_remove_instance_nocalls(CPUHP_IOMMU_IOVA_DEAD, > + >cpuhp_dead); > + free_iova_rcaches(iovad); > +} > + > /** > * put_iova_domain - destroys the iova domain > * @iovad: - iova domain in question. > @@ -497,9 +503,9 @@ void put_iova_domain(struct iova_domain *iovad) > { > struct iova *iova, *tmp; > > - cpuhp_state_remove_instance_nocalls(CPUHP_IOMMU_IOVA_DEAD, > - >cpuhp_dead); > - free_iova_rcaches(iovad); > + if (iovad->rcaches) > + iova_domain_free_rcaches(iovad); > + > rbtree_postorder_for_each_entry_safe(iova, tmp, >rbroot, node) > free_iova_mem(iova); > } > @@ -608,6 +614,7 @@ EXPORT_SYMBOL_GPL(reserve_iova); > */ > > #define IOVA_MAG_SIZE 128 > +#define MAX_GLOBAL_MAGS 32 /* magazines per bin */ > > struct iova_magazine { > unsigned long size; > @@ -620,6 +627,13 @@ struct iova_cpu_rcache { > struct iova_magazine *prev; > }; > > +struct iova_rcache { > + spinlock_t lock; > + unsigned long depot_size; > + struct iova_magazine *depot[MAX_GLOBAL_MAGS]; > + struct iova_cpu_rcache __percpu *cpu_rcaches; > +}; > + > static struct iova_magazine *iova_magazine_alloc(gfp_t flags) > { > return kzalloc(sizeof(struct iova_magazine), flags); > @@ -693,28 +707,54 @@ static void iova_magazine_push(struct iova_magazine > *mag, unsigned long pfn) > mag->pfns[mag->size++] = pfn; > } > > -static void init_iova_rcaches(struct iova_domain *iovad) > +int iova_domain_init_rcaches(struct iova_domain *iovad) > { > - struct iova_cpu_rcache *cpu_rcache; > - struct iova_rcache *rcache; > unsigned int cpu; > - int i; > + int i, ret; > + > + iovad->rcaches =
Re: [PATCH V7 4/5] scsi: storvsc: Add Isolation VM support for storvsc driver
On Mon, 13 Dec 2021 02:14:05 -0500 Tianyu Lan wrote: > @@ -2078,6 +2079,7 @@ struct hv_device *vmbus_device_create(const guid_t > *type, > return child_device_obj; > } > > +static u64 vmbus_dma_mask = DMA_BIT_MASK(64); This breaks the x86 clang allmodconfig build as I presume those involved know by now: ../drivers/hv/vmbus_drv.c:2082:29: error: shift count >= width of type [-Werror,-Wshift-count-overflow] static u64 vmbus_dma_mask = DMA_BIT_MASK(64); ^~~~ ../include/linux/dma-mapping.h:76:54: note: expanded from macro 'DMA_BIT_MASK' #define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1)) ^ ~~~ 1 error generated. Is there any ETA on getting the fix into Linus's tree? ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
Re: [PATCH V7 4/5] scsi: storvsc: Add Isolation VM support for storvsc driver
On Thu, 3 Feb 2022 15:53:51 -0800 Jakub Kicinski wrote: > On Mon, 13 Dec 2021 02:14:05 -0500 Tianyu Lan wrote: > > @@ -2078,6 +2079,7 @@ struct hv_device *vmbus_device_create(const guid_t > > *type, > > return child_device_obj; > > } > > > > +static u64 vmbus_dma_mask = DMA_BIT_MASK(64); > > This breaks the x86 clang allmodconfig build as I presume those > involved know by now: > > ../drivers/hv/vmbus_drv.c:2082:29: error: shift count >= width of type > [-Werror,-Wshift-count-overflow] > static u64 vmbus_dma_mask = DMA_BIT_MASK(64); > ^~~~ > ../include/linux/dma-mapping.h:76:54: note: expanded from macro 'DMA_BIT_MASK' > #define DMA_BIT_MASK(n) (((n) == 64) ? ~0ULL : ((1ULL<<(n))-1)) > ^ ~~~ > 1 error generated. Looks like a compiler issue actually, found the discussion now: https://lore.kernel.org/llvm/202112181827.o3x7gmhz-...@intel.com/ ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
iommu non-strict mode for arm64
Hi all, We've gotten significant slowdowns on arm64 with 4k pages compared to 64k. The slowdowns can be alleviated by setting iommu.strict=0 or iommu.passthrough=1. Is there a reason x86 defaults to lazy iommu, while arm64 does not? Are there security implications which are specific to arm64? -- Josh ___ iommu mailing list iommu@lists.linux-foundation.org https://lists.linuxfoundation.org/mailman/listinfo/iommu
[PATCH v2] iommu/iova: Separate out rcache init
Currently the rcache structures are allocated for all IOVA domains, even if they do not use "fast" alloc+free interface. This is wasteful of memory. In addition, fails in init_iova_rcaches() are not handled safely, which is less than ideal. Make "fast" users call a separate rcache init explicitly, which includes error checking. Signed-off-by: John Garry --- Differences to v1: - Drop stubs for iova_domain_init_rcaches() and iova_domain_free_rcaches() - Use put_iova_domain() in vdpa code diff --git a/drivers/iommu/dma-iommu.c b/drivers/iommu/dma-iommu.c index d85d54f2b549..b22034975301 100644 --- a/drivers/iommu/dma-iommu.c +++ b/drivers/iommu/dma-iommu.c @@ -525,6 +525,7 @@ static int iommu_dma_init_domain(struct iommu_domain *domain, dma_addr_t base, struct iommu_dma_cookie *cookie = domain->iova_cookie; unsigned long order, base_pfn; struct iova_domain *iovad; + int ret; if (!cookie || cookie->type != IOMMU_DMA_IOVA_COOKIE) return -EINVAL; @@ -559,6 +560,9 @@ static int iommu_dma_init_domain(struct iommu_domain *domain, dma_addr_t base, } init_iova_domain(iovad, 1UL << order, base_pfn); + ret = iova_domain_init_rcaches(iovad); + if (ret) + return ret; /* If the FQ fails we can simply fall back to strict mode */ if (domain->type == IOMMU_DOMAIN_DMA_FQ && iommu_dma_init_fq(domain)) diff --git a/drivers/iommu/iova.c b/drivers/iommu/iova.c index b28c9435b898..7e9c3a97c040 100644 --- a/drivers/iommu/iova.c +++ b/drivers/iommu/iova.c @@ -15,13 +15,14 @@ /* The anchor node sits above the top of the usable address space */ #define IOVA_ANCHOR~0UL +#define IOVA_RANGE_CACHE_MAX_SIZE 6/* log of max cached IOVA range size (in pages) */ + static bool iova_rcache_insert(struct iova_domain *iovad, unsigned long pfn, unsigned long size); static unsigned long iova_rcache_get(struct iova_domain *iovad, unsigned long size, unsigned long limit_pfn); -static void init_iova_rcaches(struct iova_domain *iovad); static void free_cpu_cached_iovas(unsigned int cpu, struct iova_domain *iovad); static void free_iova_rcaches(struct iova_domain *iovad); @@ -64,8 +65,6 @@ init_iova_domain(struct iova_domain *iovad, unsigned long granule, iovad->anchor.pfn_lo = iovad->anchor.pfn_hi = IOVA_ANCHOR; rb_link_node(>anchor.node, NULL, >rbroot.rb_node); rb_insert_color(>anchor.node, >rbroot); - cpuhp_state_add_instance_nocalls(CPUHP_IOMMU_IOVA_DEAD, >cpuhp_dead); - init_iova_rcaches(iovad); } EXPORT_SYMBOL_GPL(init_iova_domain); @@ -488,6 +487,13 @@ free_iova_fast(struct iova_domain *iovad, unsigned long pfn, unsigned long size) } EXPORT_SYMBOL_GPL(free_iova_fast); +static void iova_domain_free_rcaches(struct iova_domain *iovad) +{ + cpuhp_state_remove_instance_nocalls(CPUHP_IOMMU_IOVA_DEAD, + >cpuhp_dead); + free_iova_rcaches(iovad); +} + /** * put_iova_domain - destroys the iova domain * @iovad: - iova domain in question. @@ -497,9 +503,9 @@ void put_iova_domain(struct iova_domain *iovad) { struct iova *iova, *tmp; - cpuhp_state_remove_instance_nocalls(CPUHP_IOMMU_IOVA_DEAD, - >cpuhp_dead); - free_iova_rcaches(iovad); + if (iovad->rcaches) + iova_domain_free_rcaches(iovad); + rbtree_postorder_for_each_entry_safe(iova, tmp, >rbroot, node) free_iova_mem(iova); } @@ -608,6 +614,7 @@ EXPORT_SYMBOL_GPL(reserve_iova); */ #define IOVA_MAG_SIZE 128 +#define MAX_GLOBAL_MAGS 32 /* magazines per bin */ struct iova_magazine { unsigned long size; @@ -620,6 +627,13 @@ struct iova_cpu_rcache { struct iova_magazine *prev; }; +struct iova_rcache { + spinlock_t lock; + unsigned long depot_size; + struct iova_magazine *depot[MAX_GLOBAL_MAGS]; + struct iova_cpu_rcache __percpu *cpu_rcaches; +}; + static struct iova_magazine *iova_magazine_alloc(gfp_t flags) { return kzalloc(sizeof(struct iova_magazine), flags); @@ -693,28 +707,54 @@ static void iova_magazine_push(struct iova_magazine *mag, unsigned long pfn) mag->pfns[mag->size++] = pfn; } -static void init_iova_rcaches(struct iova_domain *iovad) +int iova_domain_init_rcaches(struct iova_domain *iovad) { - struct iova_cpu_rcache *cpu_rcache; - struct iova_rcache *rcache; unsigned int cpu; - int i; + int i, ret; + + iovad->rcaches = kcalloc(IOVA_RANGE_CACHE_MAX_SIZE, +sizeof(struct iova_rcache), +GFP_KERNEL); + if (!iovad->rcaches) + return -ENOMEM; for (i = 0; i < IOVA_RANGE_CACHE_MAX_SIZE; ++i) { +