Re: [PATCH 2/2] drm/vmwgfx: Use the linux DMA api to get valid device addresses of pages

2013-11-05 Thread Konrad Rzeszutek Wilk
On Mon, Nov 04, 2013 at 05:57:39AM -0800, Thomas Hellstrom wrote:
 The code handles three different cases:
 1) physical page addresses. The ttm page array is used.
 2) DMA subsystem addresses. A scatter-gather list is used.
 3) Coherent pages. The ttm dma pool is used, together with the dma_ttm
 array os dma_addr_t
 
 Signed-off-by: Thomas Hellstrom thellst...@vmware.com
 Reviewed-by: Jakob Bornecrantz ja...@vmware.com

I looked at it from the TTM DMA perspective and it looks OK for me.

 ---
  drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c |  379 
 ++--
  drivers/gpu/drm/vmwgfx/vmwgfx_drv.c|   87 +++-
  drivers/gpu/drm/vmwgfx/vmwgfx_drv.h|   98 -
  drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c|  150 ++---
  4 files changed, 620 insertions(+), 94 deletions(-)
 
 diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c 
 b/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c
 index 96dc84d..7776e6f 100644
 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c
 +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c
 @@ -141,37 +141,374 @@ struct ttm_placement vmw_srf_placement = {
  };
  
  struct vmw_ttm_tt {
 - struct ttm_tt ttm;
 + struct ttm_dma_tt dma_ttm;
   struct vmw_private *dev_priv;
   int gmr_id;
 + struct sg_table sgt;
 + struct vmw_sg_table vsgt;
 + uint64_t sg_alloc_size;
 + bool mapped;
  };
  
 +/**
 + * Helper functions to advance a struct vmw_piter iterator.
 + *
 + * @viter: Pointer to the iterator.
 + *
 + * These functions return false if past the end of the list,
 + * true otherwise. Functions are selected depending on the current
 + * DMA mapping mode.
 + */
 +static bool __vmw_piter_non_sg_next(struct vmw_piter *viter)
 +{
 + return ++(viter-i)  viter-num_pages;
 +}
 +
 +static bool __vmw_piter_sg_next(struct vmw_piter *viter)
 +{
 + return __sg_page_iter_next(viter-iter);
 +}
 +
 +
 +/**
 + * Helper functions to return a pointer to the current page.
 + *
 + * @viter: Pointer to the iterator
 + *
 + * These functions return a pointer to the page currently
 + * pointed to by @viter. Functions are selected depending on the
 + * current mapping mode.
 + */
 +static struct page *__vmw_piter_non_sg_page(struct vmw_piter *viter)
 +{
 + return viter-pages[viter-i];
 +}
 +
 +static struct page *__vmw_piter_sg_page(struct vmw_piter *viter)
 +{
 + return sg_page_iter_page(viter-iter);
 +}
 +
 +
 +/**
 + * Helper functions to return the DMA address of the current page.
 + *
 + * @viter: Pointer to the iterator
 + *
 + * These functions return the DMA address of the page currently
 + * pointed to by @viter. Functions are selected depending on the
 + * current mapping mode.
 + */
 +static dma_addr_t __vmw_piter_phys_addr(struct vmw_piter *viter)
 +{
 + return page_to_phys(viter-pages[viter-i]);
 +}
 +
 +static dma_addr_t __vmw_piter_dma_addr(struct vmw_piter *viter)
 +{
 + return viter-addrs[viter-i];
 +}
 +
 +static dma_addr_t __vmw_piter_sg_addr(struct vmw_piter *viter)
 +{
 + return sg_page_iter_dma_address(viter-iter);
 +}
 +
 +
 +/**
 + * vmw_piter_start - Initialize a struct vmw_piter.
 + *
 + * @viter: Pointer to the iterator to initialize
 + * @vsgt: Pointer to a struct vmw_sg_table to initialize from
 + *
 + * Note that we're following the convention of __sg_page_iter_start, so that
 + * the iterator doesn't point to a valid page after initialization; it has
 + * to be advanced one step first.
 + */
 +void vmw_piter_start(struct vmw_piter *viter, const struct vmw_sg_table 
 *vsgt,
 +  unsigned long p_offset)
 +{
 + viter-i = p_offset - 1;
 + viter-num_pages = vsgt-num_pages;
 + switch (vsgt-mode) {
 + case vmw_dma_phys:
 + viter-next = __vmw_piter_non_sg_next;
 + viter-dma_address = __vmw_piter_phys_addr;
 + viter-page = __vmw_piter_non_sg_page;
 + viter-pages = vsgt-pages;
 + break;
 + case vmw_dma_alloc_coherent:
 + viter-next = __vmw_piter_non_sg_next;
 + viter-dma_address = __vmw_piter_dma_addr;
 + viter-page = __vmw_piter_non_sg_page;
 + viter-addrs = vsgt-addrs;
 + break;
 + case vmw_dma_map_populate:
 + case vmw_dma_map_bind:
 + viter-next = __vmw_piter_sg_next;
 + viter-dma_address = __vmw_piter_sg_addr;
 + viter-page = __vmw_piter_sg_page;
 + __sg_page_iter_start(viter-iter, vsgt-sgt-sgl,
 +  vsgt-sgt-orig_nents, p_offset);
 + break;
 + default:
 + BUG();
 + }
 +}
 +
 +/**
 + * vmw_ttm_unmap_from_dma - unmap  device addresses previsouly mapped for
 + * TTM pages
 + *
 + * @vmw_tt: Pointer to a struct vmw_ttm_backend
 + *
 + * Used to free dma mappings previously mapped by vmw_ttm_map_for_dma.
 + */
 +static void vmw_ttm_unmap_from_dma(struct vmw_ttm_tt *vmw_tt)
 +{
 + struct device *dev = vmw_tt-dev_priv-dev-dev;
 +
 + dma_unmap_sg(dev, 

Re: [PATCH 2/2] drm/vmwgfx: Use the linux DMA api to get valid device addresses of pages

2013-11-04 Thread Daniel Vetter
On Mon, Nov 04, 2013 at 05:57:39AM -0800, Thomas Hellstrom wrote:
 The code handles three different cases:
 1) physical page addresses. The ttm page array is used.
 2) DMA subsystem addresses. A scatter-gather list is used.
 3) Coherent pages. The ttm dma pool is used, together with the dma_ttm
 array os dma_addr_t
 
 Signed-off-by: Thomas Hellstrom thellst...@vmware.com
 Reviewed-by: Jakob Bornecrantz ja...@vmware.com

For i915.ko use we've added page iterators which should walk the physical
backing storage.

commit a321e91b6d73ed011ffceed384c40d2785cf723b
Author: Imre Deak imre.d...@intel.com
Date:   Wed Feb 27 17:02:56 2013 -0800

lib/scatterlist: add simple page iterator

Now we've unified all our backing storage handling around sg tables (even
for stolen memory), so maybe that's not useful for you guys. Just figured
I'll drop this here, it imo made our code look fairly tidy.

Cheers, Daniel

 ---
  drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c |  379 
 ++--
  drivers/gpu/drm/vmwgfx/vmwgfx_drv.c|   87 +++-
  drivers/gpu/drm/vmwgfx/vmwgfx_drv.h|   98 -
  drivers/gpu/drm/vmwgfx/vmwgfx_gmr.c|  150 ++---
  4 files changed, 620 insertions(+), 94 deletions(-)
 
 diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c 
 b/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c
 index 96dc84d..7776e6f 100644
 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c
 +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_buffer.c
 @@ -141,37 +141,374 @@ struct ttm_placement vmw_srf_placement = {
  };
  
  struct vmw_ttm_tt {
 - struct ttm_tt ttm;
 + struct ttm_dma_tt dma_ttm;
   struct vmw_private *dev_priv;
   int gmr_id;
 + struct sg_table sgt;
 + struct vmw_sg_table vsgt;
 + uint64_t sg_alloc_size;
 + bool mapped;
  };
  
 +/**
 + * Helper functions to advance a struct vmw_piter iterator.
 + *
 + * @viter: Pointer to the iterator.
 + *
 + * These functions return false if past the end of the list,
 + * true otherwise. Functions are selected depending on the current
 + * DMA mapping mode.
 + */
 +static bool __vmw_piter_non_sg_next(struct vmw_piter *viter)
 +{
 + return ++(viter-i)  viter-num_pages;
 +}
 +
 +static bool __vmw_piter_sg_next(struct vmw_piter *viter)
 +{
 + return __sg_page_iter_next(viter-iter);
 +}
 +
 +
 +/**
 + * Helper functions to return a pointer to the current page.
 + *
 + * @viter: Pointer to the iterator
 + *
 + * These functions return a pointer to the page currently
 + * pointed to by @viter. Functions are selected depending on the
 + * current mapping mode.
 + */
 +static struct page *__vmw_piter_non_sg_page(struct vmw_piter *viter)
 +{
 + return viter-pages[viter-i];
 +}
 +
 +static struct page *__vmw_piter_sg_page(struct vmw_piter *viter)
 +{
 + return sg_page_iter_page(viter-iter);
 +}
 +
 +
 +/**
 + * Helper functions to return the DMA address of the current page.
 + *
 + * @viter: Pointer to the iterator
 + *
 + * These functions return the DMA address of the page currently
 + * pointed to by @viter. Functions are selected depending on the
 + * current mapping mode.
 + */
 +static dma_addr_t __vmw_piter_phys_addr(struct vmw_piter *viter)
 +{
 + return page_to_phys(viter-pages[viter-i]);
 +}
 +
 +static dma_addr_t __vmw_piter_dma_addr(struct vmw_piter *viter)
 +{
 + return viter-addrs[viter-i];
 +}
 +
 +static dma_addr_t __vmw_piter_sg_addr(struct vmw_piter *viter)
 +{
 + return sg_page_iter_dma_address(viter-iter);
 +}
 +
 +
 +/**
 + * vmw_piter_start - Initialize a struct vmw_piter.
 + *
 + * @viter: Pointer to the iterator to initialize
 + * @vsgt: Pointer to a struct vmw_sg_table to initialize from
 + *
 + * Note that we're following the convention of __sg_page_iter_start, so that
 + * the iterator doesn't point to a valid page after initialization; it has
 + * to be advanced one step first.
 + */
 +void vmw_piter_start(struct vmw_piter *viter, const struct vmw_sg_table 
 *vsgt,
 +  unsigned long p_offset)
 +{
 + viter-i = p_offset - 1;
 + viter-num_pages = vsgt-num_pages;
 + switch (vsgt-mode) {
 + case vmw_dma_phys:
 + viter-next = __vmw_piter_non_sg_next;
 + viter-dma_address = __vmw_piter_phys_addr;
 + viter-page = __vmw_piter_non_sg_page;
 + viter-pages = vsgt-pages;
 + break;
 + case vmw_dma_alloc_coherent:
 + viter-next = __vmw_piter_non_sg_next;
 + viter-dma_address = __vmw_piter_dma_addr;
 + viter-page = __vmw_piter_non_sg_page;
 + viter-addrs = vsgt-addrs;
 + break;
 + case vmw_dma_map_populate:
 + case vmw_dma_map_bind:
 + viter-next = __vmw_piter_sg_next;
 + viter-dma_address = __vmw_piter_sg_addr;
 + viter-page = __vmw_piter_sg_page;
 + __sg_page_iter_start(viter-iter, vsgt-sgt-sgl,
 +  vsgt-sgt-orig_nents, p_offset);
 + break;
 + default:
 

Re: [PATCH 2/2] drm/vmwgfx: Use the linux DMA api to get valid device addresses of pages

2013-11-04 Thread Thomas Hellstrom
On 11/04/2013 05:27 PM, Daniel Vetter wrote:
 On Mon, Nov 04, 2013 at 05:57:39AM -0800, Thomas Hellstrom wrote:
 The code handles three different cases:
 1) physical page addresses. The ttm page array is used.
 2) DMA subsystem addresses. A scatter-gather list is used.
 3) Coherent pages. The ttm dma pool is used, together with the dma_ttm
 array os dma_addr_t

 Signed-off-by: Thomas Hellstrom thellst...@vmware.com
 Reviewed-by: Jakob Bornecrantz ja...@vmware.com
 For i915.ko use we've added page iterators which should walk the physical
 backing storage.

 commit a321e91b6d73ed011ffceed384c40d2785cf723b
 Author: Imre Deak imre.d...@intel.com
 Date:   Wed Feb 27 17:02:56 2013 -0800

  lib/scatterlist: add simple page iterator



Yes, I saw those iterators, (nice stuff!) and my patch are using them as 
a base class, handling also
TTM page - and dma address arrays basically with the same interface. In 
the long run we might
want to move ttm over to sg_tables as well.

One problem, though, the page iterators break in the mapped case where
sg_dma_len(sg) != sg_len(sg).
An iommu implementation is allowed to reduce the sg list to a single 
segment, in which case those page
iterators will fall apart. I was planning to see if I could fix that up, 
but unfortunately there is no generic
dma_to_phys.
It all works now because intel_iommu, amd_iommu and swiotlb all keep the 
number of entries in an
sg list across mapping

/Thomas

--
Android is increasing in popularity, but the open development platform that
developers love is also attractive to malware creators. Download this white
paper to learn more about secure code signing practices that can help keep
Android apps secure.
http://pubads.g.doubleclick.net/gampad/clk?id=65839951iu=/4140/ostg.clktrk
--
___
Dri-devel mailing list
Dri-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel


Re: [PATCH 2/2] drm/vmwgfx: Use the linux DMA api to get valid device addresses of pages

2013-11-04 Thread Thomas Hellstrom
On 11/04/2013 05:40 PM, Konrad Rzeszutek Wilk wrote:
 On Mon, Nov 04, 2013 at 05:57:39AM -0800, Thomas Hellstrom wrote:
 The code handles three different cases:
 1) physical page addresses. The ttm page array is used.
 2) DMA subsystem addresses. A scatter-gather list is used.
 3) Coherent pages. The ttm dma pool is used, together with the dma_ttm
 array os dma_addr_t

 Signed-off-by: Thomas Hellstrom thellst...@vmware.com
 Reviewed-by: Jakob Bornecrantz ja...@vmware.com
 I looked at it from the TTM DMA perspective and it looks OK for me.

Great. Thanks,

Thomas

--
Android is increasing in popularity, but the open development platform that
developers love is also attractive to malware creators. Download this white
paper to learn more about secure code signing practices that can help keep
Android apps secure.
http://pubads.g.doubleclick.net/gampad/clk?id=65839951iu=/4140/ostg.clktrk
--
___
Dri-devel mailing list
Dri-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel