diff options
author | Prathyush K <prathyush.k@samsung.com> | 2012-11-20 05:32:56 -0500 |
---|---|---|
committer | Inki Dae <inki.dae@samsung.com> | 2012-12-05 00:39:20 -0500 |
commit | 465ed6606018b56d55219b6c58a7b98793d8cbcc (patch) | |
tree | 974610e76ec23feef25f873cbe4441b319154214 | |
parent | dd265850f10a16e4525ed002f0173a1acd8c8876 (diff) |
drm/exynos: remove 'pages' and 'page_size' elements in exynos gem buffer
Changelog v2:
Removed redundant check for invalid sgl.
Added check for valid page_offset in the beginning of exynos_drm_gem_map_buf.
Changelog v1:
The 'pages' structure is not required since we can use the 'sgt'. Even for
CONTIG buffers, a SGT is created (which will have just one sgl). This SGT
can be used during mmap instead of 'pages'. The 'page_size' element of the
structure is also not used anywhere and is removed.
This patch also fixes a memory leak where the 'pages' structure was being
allocated during gem buffer allocation but not being freed during deallocate.
Signed-off-by: Prathyush K <prathyush.k@samsung.com>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_buf.c | 20 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_buf.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_dmabuf.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_gem.c | 37 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_gem.h | 4 |
5 files changed, 16 insertions, 52 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_buf.c b/drivers/gpu/drm/exynos/exynos_drm_buf.c index 48c589661cbe..72bf97b96ba0 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_buf.c +++ b/drivers/gpu/drm/exynos/exynos_drm_buf.c | |||
@@ -34,8 +34,6 @@ static int lowlevel_buffer_allocate(struct drm_device *dev, | |||
34 | unsigned int flags, struct exynos_drm_gem_buf *buf) | 34 | unsigned int flags, struct exynos_drm_gem_buf *buf) |
35 | { | 35 | { |
36 | int ret = 0; | 36 | int ret = 0; |
37 | unsigned int npages, i = 0; | ||
38 | struct scatterlist *sgl; | ||
39 | enum dma_attr attr = DMA_ATTR_FORCE_CONTIGUOUS; | 37 | enum dma_attr attr = DMA_ATTR_FORCE_CONTIGUOUS; |
40 | 38 | ||
41 | DRM_DEBUG_KMS("%s\n", __FILE__); | 39 | DRM_DEBUG_KMS("%s\n", __FILE__); |
@@ -73,22 +71,6 @@ static int lowlevel_buffer_allocate(struct drm_device *dev, | |||
73 | goto err_free_sgt; | 71 | goto err_free_sgt; |
74 | } | 72 | } |
75 | 73 | ||
76 | npages = buf->sgt->nents; | ||
77 | |||
78 | buf->pages = kzalloc(sizeof(struct page) * npages, GFP_KERNEL); | ||
79 | if (!buf->pages) { | ||
80 | DRM_ERROR("failed to allocate pages.\n"); | ||
81 | ret = -ENOMEM; | ||
82 | goto err_free_table; | ||
83 | } | ||
84 | |||
85 | sgl = buf->sgt->sgl; | ||
86 | while (i < npages) { | ||
87 | buf->pages[i] = sg_page(sgl); | ||
88 | sgl = sg_next(sgl); | ||
89 | i++; | ||
90 | } | ||
91 | |||
92 | DRM_DEBUG_KMS("vaddr(0x%lx), dma_addr(0x%lx), size(0x%lx)\n", | 74 | DRM_DEBUG_KMS("vaddr(0x%lx), dma_addr(0x%lx), size(0x%lx)\n", |
93 | (unsigned long)buf->kvaddr, | 75 | (unsigned long)buf->kvaddr, |
94 | (unsigned long)buf->dma_addr, | 76 | (unsigned long)buf->dma_addr, |
@@ -96,8 +78,6 @@ static int lowlevel_buffer_allocate(struct drm_device *dev, | |||
96 | 78 | ||
97 | return ret; | 79 | return ret; |
98 | 80 | ||
99 | err_free_table: | ||
100 | sg_free_table(buf->sgt); | ||
101 | err_free_sgt: | 81 | err_free_sgt: |
102 | kfree(buf->sgt); | 82 | kfree(buf->sgt); |
103 | buf->sgt = NULL; | 83 | buf->sgt = NULL; |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_buf.h b/drivers/gpu/drm/exynos/exynos_drm_buf.h index 3388e4eb4ba2..25cf16285033 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_buf.h +++ b/drivers/gpu/drm/exynos/exynos_drm_buf.h | |||
@@ -34,12 +34,12 @@ struct exynos_drm_gem_buf *exynos_drm_init_buf(struct drm_device *dev, | |||
34 | void exynos_drm_fini_buf(struct drm_device *dev, | 34 | void exynos_drm_fini_buf(struct drm_device *dev, |
35 | struct exynos_drm_gem_buf *buffer); | 35 | struct exynos_drm_gem_buf *buffer); |
36 | 36 | ||
37 | /* allocate physical memory region and setup sgt and pages. */ | 37 | /* allocate physical memory region and setup sgt. */ |
38 | int exynos_drm_alloc_buf(struct drm_device *dev, | 38 | int exynos_drm_alloc_buf(struct drm_device *dev, |
39 | struct exynos_drm_gem_buf *buf, | 39 | struct exynos_drm_gem_buf *buf, |
40 | unsigned int flags); | 40 | unsigned int flags); |
41 | 41 | ||
42 | /* release physical memory region, sgt and pages. */ | 42 | /* release physical memory region, and sgt. */ |
43 | void exynos_drm_free_buf(struct drm_device *dev, | 43 | void exynos_drm_free_buf(struct drm_device *dev, |
44 | unsigned int flags, | 44 | unsigned int flags, |
45 | struct exynos_drm_gem_buf *buffer); | 45 | struct exynos_drm_gem_buf *buffer); |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c index d9307bd29738..539da9f4eb97 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c +++ b/drivers/gpu/drm/exynos/exynos_drm_dmabuf.c | |||
@@ -87,8 +87,7 @@ static struct sg_table * | |||
87 | goto err_unlock; | 87 | goto err_unlock; |
88 | } | 88 | } |
89 | 89 | ||
90 | DRM_DEBUG_PRIME("buffer size = 0x%lx page_size = 0x%lx\n", | 90 | DRM_DEBUG_PRIME("buffer size = 0x%lx\n", buf->size); |
91 | buf->size, buf->page_size); | ||
92 | 91 | ||
93 | err_unlock: | 92 | err_unlock: |
94 | mutex_unlock(&dev->struct_mutex); | 93 | mutex_unlock(&dev->struct_mutex); |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c index 52187aec8692..99227246ce82 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.c +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c | |||
@@ -99,34 +99,23 @@ static int exynos_drm_gem_map_buf(struct drm_gem_object *obj, | |||
99 | unsigned long pfn; | 99 | unsigned long pfn; |
100 | int i; | 100 | int i; |
101 | 101 | ||
102 | if (exynos_gem_obj->flags & EXYNOS_BO_NONCONTIG) { | 102 | if (!buf->sgt) |
103 | if (!buf->sgt) | 103 | return -EINTR; |
104 | return -EINTR; | ||
105 | |||
106 | sgl = buf->sgt->sgl; | ||
107 | for_each_sg(buf->sgt->sgl, sgl, buf->sgt->nents, i) { | ||
108 | if (!sgl) { | ||
109 | DRM_ERROR("invalid SG table\n"); | ||
110 | return -EINTR; | ||
111 | } | ||
112 | if (page_offset < (sgl->length >> PAGE_SHIFT)) | ||
113 | break; | ||
114 | page_offset -= (sgl->length >> PAGE_SHIFT); | ||
115 | } | ||
116 | |||
117 | if (i >= buf->sgt->nents) { | ||
118 | DRM_ERROR("invalid page offset\n"); | ||
119 | return -EINVAL; | ||
120 | } | ||
121 | 104 | ||
122 | pfn = __phys_to_pfn(sg_phys(sgl)) + page_offset; | 105 | if (page_offset >= (buf->size >> PAGE_SHIFT)) { |
123 | } else { | 106 | DRM_ERROR("invalid page offset\n"); |
124 | if (!buf->pages) | 107 | return -EINVAL; |
125 | return -EINTR; | 108 | } |
126 | 109 | ||
127 | pfn = page_to_pfn(buf->pages[0]) + page_offset; | 110 | sgl = buf->sgt->sgl; |
111 | for_each_sg(buf->sgt->sgl, sgl, buf->sgt->nents, i) { | ||
112 | if (page_offset < (sgl->length >> PAGE_SHIFT)) | ||
113 | break; | ||
114 | page_offset -= (sgl->length >> PAGE_SHIFT); | ||
128 | } | 115 | } |
129 | 116 | ||
117 | pfn = __phys_to_pfn(sg_phys(sgl)) + page_offset; | ||
118 | |||
130 | return vm_insert_mixed(vma, f_vaddr, pfn); | 119 | return vm_insert_mixed(vma, f_vaddr, pfn); |
131 | } | 120 | } |
132 | 121 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.h b/drivers/gpu/drm/exynos/exynos_drm_gem.h index 4248d7fb698f..d3ea106a9a77 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_gem.h +++ b/drivers/gpu/drm/exynos/exynos_drm_gem.h | |||
@@ -41,8 +41,6 @@ | |||
41 | * device address with IOMMU. | 41 | * device address with IOMMU. |
42 | * @write: whether pages will be written to by the caller. | 42 | * @write: whether pages will be written to by the caller. |
43 | * @sgt: sg table to transfer page data. | 43 | * @sgt: sg table to transfer page data. |
44 | * @pages: contain all pages to allocated memory region. | ||
45 | * @page_size: could be 4K, 64K or 1MB. | ||
46 | * @size: size of allocated memory region. | 44 | * @size: size of allocated memory region. |
47 | * @pfnmap: indicate whether memory region from userptr is mmaped with | 45 | * @pfnmap: indicate whether memory region from userptr is mmaped with |
48 | * VM_PFNMAP or not. | 46 | * VM_PFNMAP or not. |
@@ -54,8 +52,6 @@ struct exynos_drm_gem_buf { | |||
54 | struct dma_attrs dma_attrs; | 52 | struct dma_attrs dma_attrs; |
55 | unsigned int write; | 53 | unsigned int write; |
56 | struct sg_table *sgt; | 54 | struct sg_table *sgt; |
57 | struct page **pages; | ||
58 | unsigned long page_size; | ||
59 | unsigned long size; | 55 | unsigned long size; |
60 | bool pfnmap; | 56 | bool pfnmap; |
61 | }; | 57 | }; |