Re: [Patch Part3 V1 19/22] iommu/vt-d: simplify intel_unmap_sg() and kill duplicated code

2014-04-22 Thread Jiang Liu
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

2014-04-22 Thread David Woodhouse
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

2014-04-22 Thread Jiang Liu
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

2014-04-22 Thread Jiang Liu
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

2014-04-22 Thread David Woodhouse
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

2014-04-22 Thread Jiang Liu
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/