Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c35936b3 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: kgsl: Add array of page pointers to memdesc"

parents 091b6e5d fa5e623a
Loading
Loading
Loading
Loading
+3 −8
Original line number Diff line number Diff line
@@ -3663,21 +3663,16 @@ static int kgsl_mmap(struct file *file, struct vm_area_struct *vma)

	if (cache == KGSL_CACHEMODE_WRITEBACK
		|| cache == KGSL_CACHEMODE_WRITETHROUGH) {
		struct scatterlist *s;
		int i;
		unsigned long addr = vma->vm_start;
		struct kgsl_memdesc *m = &entry->memdesc;

		for_each_sg(entry->memdesc.sgt->sgl, s,
				entry->memdesc.sgt->nents, i) {
			int j;
			for (j = 0; j < (s->length >> PAGE_SHIFT); j++) {
				struct page *page = sg_page(s);
				page = nth_page(page, j);
		for (i = 0; i < m->page_count; i++) {
				struct page *page = m->pages[i];
				vm_insert_page(vma, addr, page);
				addr += PAGE_SIZE;
		}
	}
	}

	vma->vm_file = file;

+5 −2
Original line number Diff line number Diff line
@@ -179,8 +179,9 @@ struct kgsl_memdesc_ops {
 * @ops: Function hooks for the memdesc memory type
 * @flags: Flags set from userspace
 * @dev: Pointer to the struct device that owns this memory
 * @memmap: bitmap of pages for mmapsize
 * @memmap_len: Number of bits for memmap
 * @attrs: dma attributes for this memory
 * @pages: An array of pointers to allocated pages
 * @page_count: Total number of pages allocated
 */
struct kgsl_memdesc {
	struct kgsl_pagetable *pagetable;
@@ -197,6 +198,8 @@ struct kgsl_memdesc {
	uint64_t flags;
	struct device *dev;
	struct dma_attrs attrs;
	struct page **pages;
	unsigned int page_count;
};

/*
+1 −1
Original line number Diff line number Diff line
@@ -150,7 +150,7 @@ static int print_mem_entry(int id, void *ptr, void *data)
			(unsigned long *) m->useraddr,
			m->size, entry->id, flags,
			memtype_str(kgsl_memdesc_usermem_type(m)),
			usage, m->sgt->nents, m->mapsize);
			usage, (m->sgt ? m->sgt->nents : 0), m->mapsize);

	if (entry->metadata[0] != 0)
		seq_printf(s, " %s", entry->metadata);
+44 −6
Original line number Diff line number Diff line
@@ -1579,16 +1579,34 @@ kgsl_iommu_map(struct kgsl_pagetable *pt,
	uint64_t addr = memdesc->gpuaddr;
	uint64_t size = memdesc->size;
	unsigned int flags = _get_protection_flags(memdesc);
	struct sg_table *sgt = NULL;

	ret = _iommu_map_sg_sync_pc(pt, addr, memdesc, memdesc->sgt->sgl,
			memdesc->sgt->nents, flags);
	/*
	 * For paged memory allocated through kgsl, memdesc->pages is not NULL.
	 * Allocate sgt here just for its map operation. Contiguous memory
	 * already has its sgt, so no need to allocate it here.
	 */
	if (memdesc->pages != NULL)
		sgt = kgsl_alloc_sgt_from_pages(memdesc);
	else
		sgt = memdesc->sgt;

	if (IS_ERR(sgt))
		return PTR_ERR(sgt);

	ret = _iommu_map_sg_sync_pc(pt, addr, memdesc, sgt->sgl,
				sgt->nents, flags);
	if (ret)
		return ret;
		goto done;

	ret = _iommu_map_guard_page(pt, memdesc, addr + size, flags);
	if (ret)
		_iommu_unmap_sync_pc(pt, memdesc, addr, size);

done:
	if (memdesc->pages != NULL)
		kgsl_free_sgt(sgt);

	return ret;
}

@@ -1599,6 +1617,8 @@ static int kgsl_iommu_map_offset(struct kgsl_pagetable *pt,
{
	int pg_sz;
	unsigned int protflags = _get_protection_flags(memdesc);
	int ret;
	struct sg_table *sgt = NULL;

	pg_sz = (1 << kgsl_memdesc_get_align(memdesc));
	if (!IS_ALIGNED(virtaddr | virtoffset | physoffset | size, pg_sz))
@@ -1607,9 +1627,27 @@ static int kgsl_iommu_map_offset(struct kgsl_pagetable *pt,
	if (size == 0)
		return -EINVAL;

	return _iommu_map_sg_offset_sync_pc(pt, virtaddr + virtoffset,
			memdesc, memdesc->sgt->sgl, memdesc->sgt->nents,
	/*
	 * For paged memory allocated through kgsl, memdesc->pages is not NULL.
	 * Allocate sgt here just for its map operation. Contiguous memory
	 * already has its sgt, so no need to allocate it here.
	 */
	if (memdesc->pages != NULL)
		sgt = kgsl_alloc_sgt_from_pages(memdesc);
	else
		sgt = memdesc->sgt;

	if (IS_ERR(sgt))
		return PTR_ERR(sgt);

	ret = _iommu_map_sg_offset_sync_pc(pt, virtaddr + virtoffset,
		memdesc, sgt->sgl, sgt->nents,
		physoffset, size, protflags);

	if (memdesc->pages != NULL)
		kgsl_free_sgt(sgt);

	return ret;
}

/* This function must be called with context bank attached */
+25 −0
Original line number Diff line number Diff line
@@ -263,6 +263,31 @@ void kgsl_pool_free_sgt(struct sg_table *sgt)
	}
}

/**
 * kgsl_pool_free_pages() - Free pages in the pages array
 * @pages: pointer of the pages array
 *
 * Free the pages by collapsing any physical adjacent pages.
 * Pages are added back to the pool, if pool has sufficient space
 * otherwise they are given back to system.
 */
void kgsl_pool_free_pages(struct page **pages, unsigned int pcount)
{
	int i;

	if (pages == NULL || pcount == 0)
		return;

	for (i = 0; i < pcount;) {
		/*
		 * Free each page or compound page group individually.
		 */
		struct page *p = pages[i];

		i += 1 << compound_order(p);
		kgsl_pool_free_page(p);
	}
}
static int kgsl_pool_idx_lookup(unsigned int order)
{
	int i;
Loading