diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2011-10-25 10:32:34 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2011-12-21 18:33:15 -0500 |
commit | fdc0b8a63c1124bb025a2846d41531a123845740 (patch) | |
tree | 3913d201022d789970b6d07355864fece7455ff3 | |
parent | 4cf73129cbe001b41be2f8b56f763fbf3acaa4ce (diff) |
drm/sis: track obj->drm_fd relations in the driver
By attach a driver private struct to each open drm fd.
Because we steal the owner_list from drm_sman until things settle,
use list_move instead of list_add.
This requires to export a drm_sman function temporarily before
drm_sman will die for real completely.
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r-- | drivers/gpu/drm/drm_sman.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/sis/sis_drv.c | 25 | ||||
-rw-r--r-- | drivers/gpu/drm/sis/sis_mm.c | 22 | ||||
-rw-r--r-- | include/drm/drm_sman.h | 1 | ||||
-rw-r--r-- | include/drm/sis_drm.h | 4 |
5 files changed, 46 insertions, 9 deletions
diff --git a/drivers/gpu/drm/drm_sman.c b/drivers/gpu/drm/drm_sman.c index cebce45f4429..462cdc87cdb8 100644 --- a/drivers/gpu/drm/drm_sman.c +++ b/drivers/gpu/drm/drm_sman.c | |||
@@ -244,7 +244,7 @@ out: | |||
244 | 244 | ||
245 | EXPORT_SYMBOL(drm_sman_alloc); | 245 | EXPORT_SYMBOL(drm_sman_alloc); |
246 | 246 | ||
247 | static void drm_sman_free(struct drm_memblock_item *item) | 247 | void drm_sman_free(struct drm_memblock_item *item) |
248 | { | 248 | { |
249 | struct drm_sman *sman = item->sman; | 249 | struct drm_sman *sman = item->sman; |
250 | 250 | ||
@@ -253,6 +253,7 @@ static void drm_sman_free(struct drm_memblock_item *item) | |||
253 | item->mm->free(item->mm->private, item->mm_info); | 253 | item->mm->free(item->mm->private, item->mm_info); |
254 | kfree(item); | 254 | kfree(item); |
255 | } | 255 | } |
256 | EXPORT_SYMBOL(drm_sman_free); | ||
256 | 257 | ||
257 | int drm_sman_free_key(struct drm_sman *sman, unsigned int key) | 258 | int drm_sman_free_key(struct drm_sman *sman, unsigned int key) |
258 | { | 259 | { |
diff --git a/drivers/gpu/drm/sis/sis_drv.c b/drivers/gpu/drm/sis/sis_drv.c index bda96a8cd939..6ad0b857ba2e 100644 --- a/drivers/gpu/drm/sis/sis_drv.c +++ b/drivers/gpu/drm/sis/sis_drv.c | |||
@@ -76,10 +76,35 @@ static const struct file_operations sis_driver_fops = { | |||
76 | .llseek = noop_llseek, | 76 | .llseek = noop_llseek, |
77 | }; | 77 | }; |
78 | 78 | ||
79 | static int sis_driver_open(struct drm_device *dev, struct drm_file *file) | ||
80 | { | ||
81 | struct sis_file_private *file_priv; | ||
82 | |||
83 | DRM_DEBUG_DRIVER("\n"); | ||
84 | file_priv = kmalloc(sizeof(*file_priv), GFP_KERNEL); | ||
85 | if (!file_priv) | ||
86 | return -ENOMEM; | ||
87 | |||
88 | file->driver_priv = file_priv; | ||
89 | |||
90 | INIT_LIST_HEAD(&file_priv->obj_list); | ||
91 | |||
92 | return 0; | ||
93 | } | ||
94 | |||
95 | void sis_driver_postclose(struct drm_device *dev, struct drm_file *file) | ||
96 | { | ||
97 | struct sis_file_private *file_priv = file->driver_priv; | ||
98 | |||
99 | kfree(file_priv); | ||
100 | } | ||
101 | |||
79 | static struct drm_driver driver = { | 102 | static struct drm_driver driver = { |
80 | .driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR, | 103 | .driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR, |
81 | .load = sis_driver_load, | 104 | .load = sis_driver_load, |
82 | .unload = sis_driver_unload, | 105 | .unload = sis_driver_unload, |
106 | .open = sis_driver_open, | ||
107 | .postclose = sis_driver_postclose, | ||
83 | .dma_quiescent = sis_idle, | 108 | .dma_quiescent = sis_idle, |
84 | .reclaim_buffers = NULL, | 109 | .reclaim_buffers = NULL, |
85 | .reclaim_buffers_idlelocked = sis_reclaim_buffers_locked, | 110 | .reclaim_buffers_idlelocked = sis_reclaim_buffers_locked, |
diff --git a/drivers/gpu/drm/sis/sis_mm.c b/drivers/gpu/drm/sis/sis_mm.c index 7fe2b63412ce..a70b1bbff2e6 100644 --- a/drivers/gpu/drm/sis/sis_mm.c +++ b/drivers/gpu/drm/sis/sis_mm.c | |||
@@ -120,13 +120,14 @@ static int sis_fb_init(struct drm_device *dev, void *data, struct drm_file *file | |||
120 | return 0; | 120 | return 0; |
121 | } | 121 | } |
122 | 122 | ||
123 | static int sis_drm_alloc(struct drm_device *dev, struct drm_file *file_priv, | 123 | static int sis_drm_alloc(struct drm_device *dev, struct drm_file *file, |
124 | void *data, int pool) | 124 | void *data, int pool) |
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; |
129 | struct drm_memblock_item *item; | 129 | struct drm_memblock_item *item; |
130 | struct sis_file_private *file_priv = file->driver_priv; | ||
130 | 131 | ||
131 | mutex_lock(&dev->struct_mutex); | 132 | mutex_lock(&dev->struct_mutex); |
132 | 133 | ||
@@ -139,11 +140,10 @@ static int sis_drm_alloc(struct drm_device *dev, struct drm_file *file_priv, | |||
139 | } | 140 | } |
140 | 141 | ||
141 | 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; |
142 | item = drm_sman_alloc(&dev_priv->sman, pool, mem->size, 0, | 143 | item = drm_sman_alloc(&dev_priv->sman, pool, mem->size, 0, 0); |
143 | (unsigned long)file_priv); | ||
144 | 144 | ||
145 | mutex_unlock(&dev->struct_mutex); | ||
146 | if (item) { | 145 | if (item) { |
146 | list_move(&item->owner_list, &file_priv->obj_list); | ||
147 | mem->offset = ((pool == 0) ? | 147 | mem->offset = ((pool == 0) ? |
148 | dev_priv->vram_offset : dev_priv->agp_offset) + | 148 | dev_priv->vram_offset : dev_priv->agp_offset) + |
149 | (item->mm-> | 149 | (item->mm-> |
@@ -156,6 +156,7 @@ static int sis_drm_alloc(struct drm_device *dev, struct drm_file *file_priv, | |||
156 | mem->free = 0; | 156 | mem->free = 0; |
157 | retval = -ENOMEM; | 157 | retval = -ENOMEM; |
158 | } | 158 | } |
159 | mutex_unlock(&dev->struct_mutex); | ||
159 | 160 | ||
160 | DRM_DEBUG("alloc %d, size = %d, offset = %d\n", pool, mem->size, | 161 | DRM_DEBUG("alloc %d, size = %d, offset = %d\n", pool, mem->size, |
161 | mem->offset); | 162 | mem->offset); |
@@ -301,12 +302,13 @@ void sis_lastclose(struct drm_device *dev) | |||
301 | } | 302 | } |
302 | 303 | ||
303 | void sis_reclaim_buffers_locked(struct drm_device *dev, | 304 | void sis_reclaim_buffers_locked(struct drm_device *dev, |
304 | struct drm_file *file_priv) | 305 | struct drm_file *file) |
305 | { | 306 | { |
306 | drm_sis_private_t *dev_priv = dev->dev_private; | 307 | struct sis_file_private *file_priv = file->driver_priv; |
308 | struct drm_memblock_item *entry, *next; | ||
307 | 309 | ||
308 | mutex_lock(&dev->struct_mutex); | 310 | mutex_lock(&dev->struct_mutex); |
309 | if (drm_sman_owner_clean(&dev_priv->sman, (unsigned long)file_priv)) { | 311 | if (list_empty(&file_priv->obj_list)) { |
310 | mutex_unlock(&dev->struct_mutex); | 312 | mutex_unlock(&dev->struct_mutex); |
311 | return; | 313 | return; |
312 | } | 314 | } |
@@ -314,7 +316,11 @@ void sis_reclaim_buffers_locked(struct drm_device *dev, | |||
314 | if (dev->driver->dma_quiescent) | 316 | if (dev->driver->dma_quiescent) |
315 | dev->driver->dma_quiescent(dev); | 317 | dev->driver->dma_quiescent(dev); |
316 | 318 | ||
317 | drm_sman_owner_cleanup(&dev_priv->sman, (unsigned long)file_priv); | 319 | |
320 | list_for_each_entry_safe(entry, next, &file_priv->obj_list, | ||
321 | owner_list) { | ||
322 | drm_sman_free(entry); | ||
323 | } | ||
318 | mutex_unlock(&dev->struct_mutex); | 324 | mutex_unlock(&dev->struct_mutex); |
319 | return; | 325 | return; |
320 | } | 326 | } |
diff --git a/include/drm/drm_sman.h b/include/drm/drm_sman.h index 08ecf83ad5d4..3b65ccfd1400 100644 --- a/include/drm/drm_sman.h +++ b/include/drm/drm_sman.h | |||
@@ -146,6 +146,7 @@ extern struct drm_memblock_item *drm_sman_alloc(struct drm_sman * sman, | |||
146 | */ | 146 | */ |
147 | 147 | ||
148 | extern int drm_sman_free_key(struct drm_sman * sman, unsigned int key); | 148 | extern int drm_sman_free_key(struct drm_sman * sman, unsigned int key); |
149 | extern void drm_sman_free(struct drm_memblock_item *item); | ||
149 | 150 | ||
150 | /* | 151 | /* |
151 | * returns 1 iff there are no stale memory blocks associated with this owner. | 152 | * returns 1 iff there are no stale memory blocks associated with this owner. |
diff --git a/include/drm/sis_drm.h b/include/drm/sis_drm.h index 30f7b3827466..035b804dda6d 100644 --- a/include/drm/sis_drm.h +++ b/include/drm/sis_drm.h | |||
@@ -64,4 +64,8 @@ typedef struct { | |||
64 | unsigned int offset, size; | 64 | unsigned int offset, size; |
65 | } drm_sis_fb_t; | 65 | } drm_sis_fb_t; |
66 | 66 | ||
67 | struct sis_file_private { | ||
68 | struct list_head obj_list; | ||
69 | }; | ||
70 | |||
67 | #endif /* __SIS_DRM_H__ */ | 71 | #endif /* __SIS_DRM_H__ */ |