Loading drivers/gpu/msm/kgsl.c +3 −8 Original line number Diff line number Diff line Loading @@ -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; Loading drivers/gpu/msm/kgsl.h +5 −2 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -197,6 +198,8 @@ struct kgsl_memdesc { uint64_t flags; struct device *dev; struct dma_attrs attrs; struct page **pages; unsigned int page_count; }; /* Loading drivers/gpu/msm/kgsl_debugfs.c +1 −1 Original line number Diff line number Diff line Loading @@ -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); Loading drivers/gpu/msm/kgsl_iommu.c +44 −6 Original line number Diff line number Diff line Loading @@ -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; } Loading @@ -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)) Loading @@ -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 */ Loading drivers/gpu/msm/kgsl_pool.c +25 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
drivers/gpu/msm/kgsl.c +3 −8 Original line number Diff line number Diff line Loading @@ -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; Loading
drivers/gpu/msm/kgsl.h +5 −2 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -197,6 +198,8 @@ struct kgsl_memdesc { uint64_t flags; struct device *dev; struct dma_attrs attrs; struct page **pages; unsigned int page_count; }; /* Loading
drivers/gpu/msm/kgsl_debugfs.c +1 −1 Original line number Diff line number Diff line Loading @@ -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); Loading
drivers/gpu/msm/kgsl_iommu.c +44 −6 Original line number Diff line number Diff line Loading @@ -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; } Loading @@ -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)) Loading @@ -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 */ Loading
drivers/gpu/msm/kgsl_pool.c +25 −0 Original line number Diff line number Diff line Loading @@ -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