aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/sis/sis_mm.c
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2011-10-25 12:00:41 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2011-12-21 18:33:21 -0500
commit6de8a748881f1cd9d795454da2b6db616d5ca3d7 (patch)
tree55bedac6fab93c90461167039024eafdab72395f /drivers/gpu/drm/sis/sis_mm.c
parent77ee8f3825054f23b17e9c8f728f061defd86cdc (diff)
drm/sis: track user->memblock mapping with idr
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/sis/sis_mm.c')
-rw-r--r--drivers/gpu/drm/sis/sis_mm.c57
1 files changed, 43 insertions, 14 deletions
diff --git a/drivers/gpu/drm/sis/sis_mm.c b/drivers/gpu/drm/sis/sis_mm.c
index c76a118812a9..21d36df02a88 100644
--- a/drivers/gpu/drm/sis/sis_mm.c
+++ b/drivers/gpu/drm/sis/sis_mm.c
@@ -125,7 +125,7 @@ static int sis_drm_alloc(struct drm_device *dev, struct drm_file *file,
125{ 125{
126 drm_sis_private_t *dev_priv = dev->dev_private; 126 drm_sis_private_t *dev_priv = dev->dev_private;
127 drm_sis_mem_t *mem = data; 127 drm_sis_mem_t *mem = data;
128 int retval = 0; 128 int retval = 0, user_key;
129 struct drm_memblock_item *item; 129 struct drm_memblock_item *item;
130 struct sis_file_private *file_priv = file->driver_priv; 130 struct sis_file_private *file_priv = file->driver_priv;
131 131
@@ -141,23 +141,44 @@ static int sis_drm_alloc(struct drm_device *dev, struct drm_file *file,
141 141
142 mem->size = (mem->size + SIS_MM_ALIGN_MASK) >> SIS_MM_ALIGN_SHIFT; 142 mem->size = (mem->size + SIS_MM_ALIGN_MASK) >> SIS_MM_ALIGN_SHIFT;
143 item = drm_sman_alloc(&dev_priv->sman, pool, mem->size, 0, 0); 143 item = drm_sman_alloc(&dev_priv->sman, pool, mem->size, 0, 0);
144 if (!item) {
145 retval = -ENOMEM;
146 goto fail_alloc;
147 }
144 148
145 if (item) { 149again:
146 list_add(&item->owner_list, &file_priv->obj_list); 150 if (idr_pre_get(&dev_priv->object_idr, GFP_KERNEL) == 0) {
147 mem->offset = ((pool == 0) ?
148 dev_priv->vram_offset : dev_priv->agp_offset) +
149 (item->mm->
150 offset(item->mm, item->mm_info) << SIS_MM_ALIGN_SHIFT);
151 mem->free = item->user_hash.key;
152 mem->size = mem->size << SIS_MM_ALIGN_SHIFT;
153 } else {
154 mem->offset = 0;
155 mem->size = 0;
156 mem->free = 0;
157 retval = -ENOMEM; 151 retval = -ENOMEM;
152 goto fail_idr;
158 } 153 }
154
155 retval = idr_get_new_above(&dev_priv->object_idr, item, 1, &user_key);
156 if (retval == -EAGAIN)
157 goto again;
158 if (retval)
159 goto fail_idr;
160
161 list_add(&item->owner_list, &file_priv->obj_list);
162 mutex_unlock(&dev->struct_mutex);
163
164 mem->offset = ((pool == 0) ?
165 dev_priv->vram_offset : dev_priv->agp_offset) +
166 (item->mm->
167 offset(item->mm, item->mm_info) << SIS_MM_ALIGN_SHIFT);
168 mem->free = user_key;
169 mem->size = mem->size << SIS_MM_ALIGN_SHIFT;
170
171 return 0;
172
173fail_idr:
174 drm_sman_free(item);
175fail_alloc:
159 mutex_unlock(&dev->struct_mutex); 176 mutex_unlock(&dev->struct_mutex);
160 177
178 mem->offset = 0;
179 mem->size = 0;
180 mem->free = 0;
181
161 DRM_DEBUG("alloc %d, size = %d, offset = %d\n", pool, mem->size, 182 DRM_DEBUG("alloc %d, size = %d, offset = %d\n", pool, mem->size,
162 mem->offset); 183 mem->offset);
163 184
@@ -168,10 +189,18 @@ static int sis_drm_free(struct drm_device *dev, void *data, struct drm_file *fil
168{ 189{
169 drm_sis_private_t *dev_priv = dev->dev_private; 190 drm_sis_private_t *dev_priv = dev->dev_private;
170 drm_sis_mem_t *mem = data; 191 drm_sis_mem_t *mem = data;
192 struct drm_memblock_item *obj;
171 int ret; 193 int ret;
172 194
173 mutex_lock(&dev->struct_mutex); 195 mutex_lock(&dev->struct_mutex);
174 ret = drm_sman_free_key(&dev_priv->sman, mem->free); 196 obj = idr_find(&dev_priv->object_idr, mem->free);
197 if (obj == NULL) {
198 mutex_unlock(&dev->struct_mutex);
199 return -EINVAL;
200 }
201
202 idr_remove(&dev_priv->object_idr, mem->free);
203 drm_sman_free(obj);
175 mutex_unlock(&dev->struct_mutex); 204 mutex_unlock(&dev->struct_mutex);
176 DRM_DEBUG("free = 0x%lx\n", mem->free); 205 DRM_DEBUG("free = 0x%lx\n", mem->free);
177 206