aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
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
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')
-rw-r--r--drivers/gpu/drm/sis/sis_drv.c4
-rw-r--r--drivers/gpu/drm/sis/sis_drv.h2
-rw-r--r--drivers/gpu/drm/sis/sis_mm.c57
-rw-r--r--drivers/gpu/drm/via/via_map.c2
4 files changed, 51 insertions, 14 deletions
diff --git a/drivers/gpu/drm/sis/sis_drv.c b/drivers/gpu/drm/sis/sis_drv.c
index 6ad0b857ba2e..64d329f7d9b6 100644
--- a/drivers/gpu/drm/sis/sis_drv.c
+++ b/drivers/gpu/drm/sis/sis_drv.c
@@ -48,6 +48,7 @@ static int sis_driver_load(struct drm_device *dev, unsigned long chipset)
48 48
49 dev->dev_private = (void *)dev_priv; 49 dev->dev_private = (void *)dev_priv;
50 dev_priv->chipset = chipset; 50 dev_priv->chipset = chipset;
51 idr_init(&dev->object_name_idr);
51 ret = drm_sman_init(&dev_priv->sman, 2, 12, 8); 52 ret = drm_sman_init(&dev_priv->sman, 2, 12, 8);
52 if (ret) 53 if (ret)
53 kfree(dev_priv); 54 kfree(dev_priv);
@@ -60,6 +61,9 @@ static int sis_driver_unload(struct drm_device *dev)
60 drm_sis_private_t *dev_priv = dev->dev_private; 61 drm_sis_private_t *dev_priv = dev->dev_private;
61 62
62 drm_sman_takedown(&dev_priv->sman); 63 drm_sman_takedown(&dev_priv->sman);
64 idr_remove_all(&dev_priv->object_idr);
65 idr_destroy(&dev_priv->object_idr);
66
63 kfree(dev_priv); 67 kfree(dev_priv);
64 68
65 return 0; 69 return 0;
diff --git a/drivers/gpu/drm/sis/sis_drv.h b/drivers/gpu/drm/sis/sis_drv.h
index 194303c177ad..fcdd06ad5dc3 100644
--- a/drivers/gpu/drm/sis/sis_drv.h
+++ b/drivers/gpu/drm/sis/sis_drv.h
@@ -60,6 +60,8 @@ typedef struct drm_sis_private {
60 int agp_initialized; 60 int agp_initialized;
61 unsigned long vram_offset; 61 unsigned long vram_offset;
62 unsigned long agp_offset; 62 unsigned long agp_offset;
63 /** Mapping of userspace keys to mm objects */
64 struct idr object_idr;
63} drm_sis_private_t; 65} drm_sis_private_t;
64 66
65extern int sis_idle(struct drm_device *dev); 67extern int sis_idle(struct drm_device *dev);
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
diff --git a/drivers/gpu/drm/via/via_map.c b/drivers/gpu/drm/via/via_map.c
index b09f6596f15f..fa5afbcf7e28 100644
--- a/drivers/gpu/drm/via/via_map.c
+++ b/drivers/gpu/drm/via/via_map.c
@@ -126,6 +126,8 @@ int via_driver_unload(struct drm_device *dev)
126 drm_via_private_t *dev_priv = dev->dev_private; 126 drm_via_private_t *dev_priv = dev->dev_private;
127 127
128 drm_sman_takedown(&dev_priv->sman); 128 drm_sman_takedown(&dev_priv->sman);
129 idr_remove_all(&dev_priv->object_idr);
130 idr_destroy(&dev_priv->object_idr);
129 131
130 kfree(dev_priv); 132 kfree(dev_priv);
131 133