Commit 8dc39cfc authored by Thomas Hellstrom's avatar Thomas Hellstrom
Browse files

drm/vmwgfx: Use the dma scatter-gather iterator to get dma addresses



Use struct sg_dma_page_iter in favour struct of sg_page_iter, which fairly
recently was declared useless for obtaining dma addresses.

With a struct sg_dma_page_iter we can't call sg_page_iter_page() so
when the page is needed, use the same page lookup mechanism as for the
non-sg dma modes instead of calling sg_dma_page_iter.

Note, the fixes tag doesn't really point to a commit introducing a
failure / regression, but rather to a commit that implemented a simple
workaround for this problem.

Cc: Jason Gunthorpe <jgg@mellanox.com>
Fixes: d901b276 ("lib/scatterlist: Provide a DMA page iterator")
Signed-off-by: default avatarThomas Hellstrom <thellstrom@vmware.com>
Reviewed-by: default avatarJason Gunthorpe <jgg@mellanox.com>
parent e41c20cf
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -296,7 +296,7 @@ struct vmw_sg_table {
struct vmw_piter {
struct vmw_piter {
	struct page **pages;
	struct page **pages;
	const dma_addr_t *addrs;
	const dma_addr_t *addrs;
	struct sg_page_iter iter;
	struct sg_dma_page_iter iter;
	unsigned long i;
	unsigned long i;
	unsigned long num_pages;
	unsigned long num_pages;
	bool (*next)(struct vmw_piter *);
	bool (*next)(struct vmw_piter *);
+7 −20
Original line number Original line Diff line number Diff line
@@ -266,7 +266,9 @@ static bool __vmw_piter_non_sg_next(struct vmw_piter *viter)


static bool __vmw_piter_sg_next(struct vmw_piter *viter)
static bool __vmw_piter_sg_next(struct vmw_piter *viter)
{
{
	return __sg_page_iter_next(&viter->iter);
	bool ret = __vmw_piter_non_sg_next(viter);

	return __sg_page_iter_dma_next(&viter->iter) && ret;
}
}




@@ -284,12 +286,6 @@ static struct page *__vmw_piter_non_sg_page(struct vmw_piter *viter)
	return viter->pages[viter->i];
	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.
 * Helper functions to return the DMA address of the current page.
 *
 *
@@ -311,13 +307,7 @@ static dma_addr_t __vmw_piter_dma_addr(struct vmw_piter *viter)


static dma_addr_t __vmw_piter_sg_addr(struct vmw_piter *viter)
static dma_addr_t __vmw_piter_sg_addr(struct vmw_piter *viter)
{
{
	/*
	return sg_page_iter_dma_address(&viter->iter);
	 * FIXME: This driver wrongly mixes DMA and CPU SG list iteration and
	 * needs revision. See
	 * https://lore.kernel.org/lkml/20190104223531.GA1705@ziepe.ca/
	 */
	return sg_page_iter_dma_address(
		container_of(&viter->iter, struct sg_dma_page_iter, base));
}
}




@@ -336,26 +326,23 @@ void vmw_piter_start(struct vmw_piter *viter, const struct vmw_sg_table *vsgt,
{
{
	viter->i = p_offset - 1;
	viter->i = p_offset - 1;
	viter->num_pages = vsgt->num_pages;
	viter->num_pages = vsgt->num_pages;
	viter->page = &__vmw_piter_non_sg_page;
	viter->pages = vsgt->pages;
	switch (vsgt->mode) {
	switch (vsgt->mode) {
	case vmw_dma_phys:
	case vmw_dma_phys:
		viter->next = &__vmw_piter_non_sg_next;
		viter->next = &__vmw_piter_non_sg_next;
		viter->dma_address = &__vmw_piter_phys_addr;
		viter->dma_address = &__vmw_piter_phys_addr;
		viter->page = &__vmw_piter_non_sg_page;
		viter->pages = vsgt->pages;
		break;
		break;
	case vmw_dma_alloc_coherent:
	case vmw_dma_alloc_coherent:
		viter->next = &__vmw_piter_non_sg_next;
		viter->next = &__vmw_piter_non_sg_next;
		viter->dma_address = &__vmw_piter_dma_addr;
		viter->dma_address = &__vmw_piter_dma_addr;
		viter->page = &__vmw_piter_non_sg_page;
		viter->addrs = vsgt->addrs;
		viter->addrs = vsgt->addrs;
		viter->pages = vsgt->pages;
		break;
		break;
	case vmw_dma_map_populate:
	case vmw_dma_map_populate:
	case vmw_dma_map_bind:
	case vmw_dma_map_bind:
		viter->next = &__vmw_piter_sg_next;
		viter->next = &__vmw_piter_sg_next;
		viter->dma_address = &__vmw_piter_sg_addr;
		viter->dma_address = &__vmw_piter_sg_addr;
		viter->page = &__vmw_piter_sg_page;
		__sg_page_iter_start(&viter->iter.base, vsgt->sgt->sgl,
		__sg_page_iter_start(&viter->iter, vsgt->sgt->sgl,
				     vsgt->sgt->orig_nents, p_offset);
				     vsgt->sgt->orig_nents, p_offset);
		break;
		break;
	default:
	default: