aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/via
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2011-10-25 11:55:31 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2011-12-21 18:33:20 -0500
commit77ee8f3825054f23b17e9c8f728f061defd86cdc (patch)
treeb4e9e7a68d77ae400adc06a3bf935b23666e9046 /drivers/gpu/drm/via
parent763240deb423c477b4d46c23e0b582099d4b8753 (diff)
drm/via: track user->memblock mapping with idr
Massive indirection through a hashtable for a simple key->pointer look-up actually just adds bloat. v2: Drop the misleading comment noted by Chris Wilson. Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/via')
-rw-r--r--drivers/gpu/drm/via/via_drv.h2
-rw-r--r--drivers/gpu/drm/via/via_map.c1
-rw-r--r--drivers/gpu/drm/via/via_mm.c58
3 files changed, 47 insertions, 14 deletions
diff --git a/drivers/gpu/drm/via/via_drv.h b/drivers/gpu/drm/via/via_drv.h
index 9cf87d912325..108ea71f399d 100644
--- a/drivers/gpu/drm/via/via_drv.h
+++ b/drivers/gpu/drm/via/via_drv.h
@@ -91,6 +91,8 @@ typedef struct drm_via_private {
91 struct drm_sman sman; 91 struct drm_sman sman;
92 int vram_initialized; 92 int vram_initialized;
93 int agp_initialized; 93 int agp_initialized;
94 /** Mapping of userspace keys to mm objects */
95 struct idr object_idr;
94 unsigned long vram_offset; 96 unsigned long vram_offset;
95 unsigned long agp_offset; 97 unsigned long agp_offset;
96 drm_via_blitq_t blit_queues[VIA_NUM_BLIT_ENGINES]; 98 drm_via_blitq_t blit_queues[VIA_NUM_BLIT_ENGINES];
diff --git a/drivers/gpu/drm/via/via_map.c b/drivers/gpu/drm/via/via_map.c
index 6cca9a709f7a..b09f6596f15f 100644
--- a/drivers/gpu/drm/via/via_map.c
+++ b/drivers/gpu/drm/via/via_map.c
@@ -104,6 +104,7 @@ int via_driver_load(struct drm_device *dev, unsigned long chipset)
104 104
105 dev_priv->chipset = chipset; 105 dev_priv->chipset = chipset;
106 106
107 idr_init(&dev->object_name_idr);
107 ret = drm_sman_init(&dev_priv->sman, 2, 12, 8); 108 ret = drm_sman_init(&dev_priv->sman, 2, 12, 8);
108 if (ret) { 109 if (ret) {
109 kfree(dev_priv); 110 kfree(dev_priv);
diff --git a/drivers/gpu/drm/via/via_mm.c b/drivers/gpu/drm/via/via_mm.c
index e0110bc27606..e6f2b6371b4e 100644
--- a/drivers/gpu/drm/via/via_mm.c
+++ b/drivers/gpu/drm/via/via_mm.c
@@ -118,7 +118,7 @@ int via_mem_alloc(struct drm_device *dev, void *data,
118 struct drm_file *file) 118 struct drm_file *file)
119{ 119{
120 drm_via_mem_t *mem = data; 120 drm_via_mem_t *mem = data;
121 int retval = 0; 121 int retval = 0, user_key;
122 struct drm_memblock_item *item; 122 struct drm_memblock_item *item;
123 drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; 123 drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
124 struct via_file_private *file_priv = file->driver_priv; 124 struct via_file_private *file_priv = file->driver_priv;
@@ -139,23 +139,44 @@ int via_mem_alloc(struct drm_device *dev, void *data,
139 139
140 tmpSize = (mem->size + VIA_MM_ALIGN_MASK) >> VIA_MM_ALIGN_SHIFT; 140 tmpSize = (mem->size + VIA_MM_ALIGN_MASK) >> VIA_MM_ALIGN_SHIFT;
141 item = drm_sman_alloc(&dev_priv->sman, mem->type, tmpSize, 0, 0); 141 item = drm_sman_alloc(&dev_priv->sman, mem->type, tmpSize, 0, 0);
142 if (!item) {
143 retval = -ENOMEM;
144 goto fail_alloc;
145 }
142 146
143 if (item) { 147again:
144 list_add(&item->owner_list, &file_priv->obj_list); 148 if (idr_pre_get(&dev_priv->object_idr, GFP_KERNEL) == 0) {
145 mem->offset = ((mem->type == VIA_MEM_VIDEO) ?
146 dev_priv->vram_offset : dev_priv->agp_offset) +
147 (item->mm->
148 offset(item->mm, item->mm_info) << VIA_MM_ALIGN_SHIFT);
149 mem->index = item->user_hash.key;
150 } else {
151 mem->offset = 0;
152 mem->size = 0;
153 mem->index = 0;
154 DRM_DEBUG("Video memory allocation failed\n");
155 retval = -ENOMEM; 149 retval = -ENOMEM;
150 goto fail_idr;
156 } 151 }
152
153 retval = idr_get_new_above(&dev_priv->object_idr, item, 1, &user_key);
154 if (retval == -EAGAIN)
155 goto again;
156 if (retval)
157 goto fail_idr;
158
159 list_add(&item->owner_list, &file_priv->obj_list);
157 mutex_unlock(&dev->struct_mutex); 160 mutex_unlock(&dev->struct_mutex);
158 161
162 mem->offset = ((mem->type == VIA_MEM_VIDEO) ?
163 dev_priv->vram_offset : dev_priv->agp_offset) +
164 (item->mm->
165 offset(item->mm, item->mm_info) << VIA_MM_ALIGN_SHIFT);
166 mem->index = user_key;
167
168 return 0;
169
170fail_idr:
171 drm_sman_free(item);
172fail_alloc:
173 mutex_unlock(&dev->struct_mutex);
174
175 mem->offset = 0;
176 mem->size = 0;
177 mem->index = 0;
178 DRM_DEBUG("Video memory allocation failed\n");
179
159 return retval; 180 return retval;
160} 181}
161 182
@@ -163,11 +184,20 @@ int via_mem_free(struct drm_device *dev, void *data, struct drm_file *file_priv)
163{ 184{
164 drm_via_private_t *dev_priv = dev->dev_private; 185 drm_via_private_t *dev_priv = dev->dev_private;
165 drm_via_mem_t *mem = data; 186 drm_via_mem_t *mem = data;
187 struct drm_memblock_item *obj;
166 int ret; 188 int ret;
167 189
168 mutex_lock(&dev->struct_mutex); 190 mutex_lock(&dev->struct_mutex);
169 ret = drm_sman_free_key(&dev_priv->sman, mem->index); 191 obj = idr_find(&dev_priv->object_idr, mem->index);
192 if (obj == NULL) {
193 mutex_unlock(&dev->struct_mutex);
194 return -EINVAL;
195 }
196
197 idr_remove(&dev_priv->object_idr, mem->index);
198 drm_sman_free(obj);
170 mutex_unlock(&dev->struct_mutex); 199 mutex_unlock(&dev->struct_mutex);
200
171 DRM_DEBUG("free = 0x%lx\n", mem->index); 201 DRM_DEBUG("free = 0x%lx\n", mem->index);
172 202
173 return ret; 203 return ret;