Re: [Patch Part3 V1 19/22] iommu/vt-d: simplify intel_unmap_sg() and kill duplicated code
On 2014/4/22 15:38, David Woodhouse wrote: > On Tue, 2014-04-22 at 15:07 +0800, Jiang Liu wrote: >> + size_t size = 0; >> +#if 0 >> + /* current the third argument of intel_unmap_page is unsued */ >> + int i; >> + struct scatterlist *sg; >> >> - freelist = domain_unmap(domain, start_pfn, last_pfn); >> + for_each_sg(sglist, sg, nelems, i) >> + size += sg->length; >> +#endif > > Please don't do that. If you want to rely on the fact that > intel_unmap_page() currently just uses the size from the IOVA it finds, > then split it out into a separate function which explicitly does > precisely that. And call that new function from both intel_unmap_sg() > and intel_unmap_page(). Good suggestion, will change to follow that way in next version. -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [Patch Part3 V1 19/22] iommu/vt-d: simplify intel_unmap_sg() and kill duplicated code
On Tue, 2014-04-22 at 15:07 +0800, Jiang Liu wrote: > + size_t size = 0; > +#if 0 > + /* current the third argument of intel_unmap_page is unsued */ > + int i; > + struct scatterlist *sg; > > - freelist = domain_unmap(domain, start_pfn, last_pfn); > + for_each_sg(sglist, sg, nelems, i) > + size += sg->length; > +#endif Please don't do that. If you want to rely on the fact that intel_unmap_page() currently just uses the size from the IOVA it finds, then split it out into a separate function which explicitly does precisely that. And call that new function from both intel_unmap_sg() and intel_unmap_page(). -- David WoodhouseOpen Source Technology Centre david.woodho...@intel.com Intel Corporation smime.p7s Description: S/MIME cryptographic signature
[Patch Part3 V1 19/22] iommu/vt-d: simplify intel_unmap_sg() and kill duplicated code
Simplify intel_unmap_sg() by calling intel_unmap_page() and kill duplicated code, no functionality changes. Signed-off-by: Jiang Liu --- drivers/iommu/intel-iommu.c | 63 +-- 1 file changed, 18 insertions(+), 45 deletions(-) diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index f2143b59ad68..4738e64fe097 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -979,6 +979,8 @@ static void dma_pte_free_pagetable(struct dmar_domain *domain, BUG_ON(addr_width < BITS_PER_LONG && last_pfn >> addr_width); BUG_ON(start_pfn > last_pfn); + dma_pte_clear_range(domain, start_pfn, last_pfn); + /* We don't need lock here; nobody else touches the iova range */ dma_pte_free_level(domain, agaw_to_level(domain->agaw), domain->pgd, 0, start_pfn, last_pfn); @@ -2031,12 +2033,14 @@ static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn, /* It is large page*/ if (largepage_lvl > 1) { pteval |= DMA_PTE_LARGE_PAGE; - /* Ensure that old small page tables are removed to make room - for superpage, if they exist. */ - dma_pte_clear_range(domain, iov_pfn, - iov_pfn + lvl_to_nr_pages(largepage_lvl) - 1); + lvl_pages = lvl_to_nr_pages(largepage_lvl); + /* +* Ensure that old small page tables are +* removed to make room for superpage, +* if they exist. +*/ dma_pte_free_pagetable(domain, iov_pfn, - iov_pfn + lvl_to_nr_pages(largepage_lvl) - 1); + iov_pfn + lvl_pages - 1); } else { pteval &= ~(uint64_t)DMA_PTE_LARGE_PAGE; } @@ -3256,43 +3260,17 @@ static void intel_unmap_sg(struct device *dev, struct scatterlist *sglist, int nelems, enum dma_data_direction dir, struct dma_attrs *attrs) { - struct dmar_domain *domain; - unsigned long start_pfn, last_pfn; - struct iova *iova; - struct intel_iommu *iommu; - struct page *freelist; - - if (iommu_no_mapping(dev)) - return; - - domain = find_domain(dev); - BUG_ON(!domain); - - iommu = domain_get_iommu(domain); - - iova = find_iova(>iovad, IOVA_PFN(sglist[0].dma_address)); - if (WARN_ONCE(!iova, "Driver unmaps unmatched sglist at PFN %llx\n", - (unsigned long long)sglist[0].dma_address)) - return; - - start_pfn = mm_to_dma_pfn(iova->pfn_lo); - last_pfn = mm_to_dma_pfn(iova->pfn_hi + 1) - 1; + size_t size = 0; +#if 0 + /* current the third argument of intel_unmap_page is unsued */ + int i; + struct scatterlist *sg; - freelist = domain_unmap(domain, start_pfn, last_pfn); + for_each_sg(sglist, sg, nelems, i) + size += sg->length; +#endif - if (intel_iommu_strict) { - iommu_flush_iotlb_psi(iommu, domain->id, start_pfn, - last_pfn - start_pfn + 1, !freelist, 0); - /* free iova */ - __free_iova(>iovad, iova); - dma_free_pagelist(freelist); - } else { - add_unmap(domain, iova, freelist); - /* -* queue up the release of the unmap to save the 1/6th of the -* cpu used up by the iotlb flush operation... -*/ - } + intel_unmap_page(dev, sglist[0].dma_address, size, dir, attrs); } static int intel_nontranslate_map_sg(struct device *hddev, @@ -3356,13 +3334,8 @@ static int intel_map_sg(struct device *dev, struct scatterlist *sglist, int nele ret = domain_sg_mapping(domain, start_vpfn, sglist, size, prot); if (unlikely(ret)) { - /* clear the page */ - dma_pte_clear_range(domain, start_vpfn, - start_vpfn + size - 1); - /* free page tables */ dma_pte_free_pagetable(domain, start_vpfn, start_vpfn + size - 1); - /* free iova */ __free_iova(>iovad, iova); return 0; } -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ
[Patch Part3 V1 19/22] iommu/vt-d: simplify intel_unmap_sg() and kill duplicated code
Simplify intel_unmap_sg() by calling intel_unmap_page() and kill duplicated code, no functionality changes. Signed-off-by: Jiang Liu jiang@linux.intel.com --- drivers/iommu/intel-iommu.c | 63 +-- 1 file changed, 18 insertions(+), 45 deletions(-) diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index f2143b59ad68..4738e64fe097 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -979,6 +979,8 @@ static void dma_pte_free_pagetable(struct dmar_domain *domain, BUG_ON(addr_width BITS_PER_LONG last_pfn addr_width); BUG_ON(start_pfn last_pfn); + dma_pte_clear_range(domain, start_pfn, last_pfn); + /* We don't need lock here; nobody else touches the iova range */ dma_pte_free_level(domain, agaw_to_level(domain-agaw), domain-pgd, 0, start_pfn, last_pfn); @@ -2031,12 +2033,14 @@ static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn, /* It is large page*/ if (largepage_lvl 1) { pteval |= DMA_PTE_LARGE_PAGE; - /* Ensure that old small page tables are removed to make room - for superpage, if they exist. */ - dma_pte_clear_range(domain, iov_pfn, - iov_pfn + lvl_to_nr_pages(largepage_lvl) - 1); + lvl_pages = lvl_to_nr_pages(largepage_lvl); + /* +* Ensure that old small page tables are +* removed to make room for superpage, +* if they exist. +*/ dma_pte_free_pagetable(domain, iov_pfn, - iov_pfn + lvl_to_nr_pages(largepage_lvl) - 1); + iov_pfn + lvl_pages - 1); } else { pteval = ~(uint64_t)DMA_PTE_LARGE_PAGE; } @@ -3256,43 +3260,17 @@ static void intel_unmap_sg(struct device *dev, struct scatterlist *sglist, int nelems, enum dma_data_direction dir, struct dma_attrs *attrs) { - struct dmar_domain *domain; - unsigned long start_pfn, last_pfn; - struct iova *iova; - struct intel_iommu *iommu; - struct page *freelist; - - if (iommu_no_mapping(dev)) - return; - - domain = find_domain(dev); - BUG_ON(!domain); - - iommu = domain_get_iommu(domain); - - iova = find_iova(domain-iovad, IOVA_PFN(sglist[0].dma_address)); - if (WARN_ONCE(!iova, Driver unmaps unmatched sglist at PFN %llx\n, - (unsigned long long)sglist[0].dma_address)) - return; - - start_pfn = mm_to_dma_pfn(iova-pfn_lo); - last_pfn = mm_to_dma_pfn(iova-pfn_hi + 1) - 1; + size_t size = 0; +#if 0 + /* current the third argument of intel_unmap_page is unsued */ + int i; + struct scatterlist *sg; - freelist = domain_unmap(domain, start_pfn, last_pfn); + for_each_sg(sglist, sg, nelems, i) + size += sg-length; +#endif - if (intel_iommu_strict) { - iommu_flush_iotlb_psi(iommu, domain-id, start_pfn, - last_pfn - start_pfn + 1, !freelist, 0); - /* free iova */ - __free_iova(domain-iovad, iova); - dma_free_pagelist(freelist); - } else { - add_unmap(domain, iova, freelist); - /* -* queue up the release of the unmap to save the 1/6th of the -* cpu used up by the iotlb flush operation... -*/ - } + intel_unmap_page(dev, sglist[0].dma_address, size, dir, attrs); } static int intel_nontranslate_map_sg(struct device *hddev, @@ -3356,13 +3334,8 @@ static int intel_map_sg(struct device *dev, struct scatterlist *sglist, int nele ret = domain_sg_mapping(domain, start_vpfn, sglist, size, prot); if (unlikely(ret)) { - /* clear the page */ - dma_pte_clear_range(domain, start_vpfn, - start_vpfn + size - 1); - /* free page tables */ dma_pte_free_pagetable(domain, start_vpfn, start_vpfn + size - 1); - /* free iova */ __free_iova(domain-iovad, iova); return 0; } -- 1.7.10.4 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at
Re: [Patch Part3 V1 19/22] iommu/vt-d: simplify intel_unmap_sg() and kill duplicated code
On Tue, 2014-04-22 at 15:07 +0800, Jiang Liu wrote: + size_t size = 0; +#if 0 + /* current the third argument of intel_unmap_page is unsued */ + int i; + struct scatterlist *sg; - freelist = domain_unmap(domain, start_pfn, last_pfn); + for_each_sg(sglist, sg, nelems, i) + size += sg-length; +#endif Please don't do that. If you want to rely on the fact that intel_unmap_page() currently just uses the size from the IOVA it finds, then split it out into a separate function which explicitly does precisely that. And call that new function from both intel_unmap_sg() and intel_unmap_page(). -- David WoodhouseOpen Source Technology Centre david.woodho...@intel.com Intel Corporation smime.p7s Description: S/MIME cryptographic signature
Re: [Patch Part3 V1 19/22] iommu/vt-d: simplify intel_unmap_sg() and kill duplicated code
On 2014/4/22 15:38, David Woodhouse wrote: On Tue, 2014-04-22 at 15:07 +0800, Jiang Liu wrote: + size_t size = 0; +#if 0 + /* current the third argument of intel_unmap_page is unsued */ + int i; + struct scatterlist *sg; - freelist = domain_unmap(domain, start_pfn, last_pfn); + for_each_sg(sglist, sg, nelems, i) + size += sg-length; +#endif Please don't do that. If you want to rely on the fact that intel_unmap_page() currently just uses the size from the IOVA it finds, then split it out into a separate function which explicitly does precisely that. And call that new function from both intel_unmap_sg() and intel_unmap_page(). Good suggestion, will change to follow that way in next version. -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/