06cba268e17afa84c43afb964f2eee4e2ea97679
[platform/kernel/linux-rpi.git] / drivers / gpu / drm / vc4 / vc4_bo.c
1 /*
2  *  Copyright © 2015 Broadcom
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  */
8
9 /* DOC: VC4 GEM BO management support.
10  *
11  * The VC4 GPU architecture (both scanout and rendering) has direct
12  * access to system memory with no MMU in between.  To support it, we
13  * use the GEM CMA helper functions to allocate contiguous ranges of
14  * physical memory for our BOs.
15  *
16  * Since the CMA allocator is very slow, we keep a cache of recently
17  * freed BOs around so that the kernel's allocation of objects for 3D
18  * rendering can return quickly.
19  */
20
21 #include "vc4_drv.h"
22 #include "uapi/drm/vc4_drm.h"
23
24 static void vc4_bo_stats_dump(struct vc4_dev *vc4)
25 {
26         DRM_INFO("num bos allocated: %d\n",
27                  vc4->bo_stats.num_allocated);
28         DRM_INFO("size bos allocated: %dkb\n",
29                  vc4->bo_stats.size_allocated / 1024);
30         DRM_INFO("num bos used: %d\n",
31                  vc4->bo_stats.num_allocated - vc4->bo_stats.num_cached);
32         DRM_INFO("size bos used: %dkb\n",
33                  (vc4->bo_stats.size_allocated -
34                   vc4->bo_stats.size_cached) / 1024);
35         DRM_INFO("num bos cached: %d\n",
36                  vc4->bo_stats.num_cached);
37         DRM_INFO("size bos cached: %dkb\n",
38                  vc4->bo_stats.size_cached / 1024);
39 }
40
41 #ifdef CONFIG_DEBUG_FS
42 int vc4_bo_stats_debugfs(struct seq_file *m, void *unused)
43 {
44         struct drm_info_node *node = (struct drm_info_node *)m->private;
45         struct drm_device *dev = node->minor->dev;
46         struct vc4_dev *vc4 = to_vc4_dev(dev);
47         struct vc4_bo_stats stats;
48
49         /* Take a snapshot of the current stats with the lock held. */
50         mutex_lock(&vc4->bo_lock);
51         stats = vc4->bo_stats;
52         mutex_unlock(&vc4->bo_lock);
53
54         seq_printf(m, "num bos allocated: %d\n",
55                    stats.num_allocated);
56         seq_printf(m, "size bos allocated: %dkb\n",
57                    stats.size_allocated / 1024);
58         seq_printf(m, "num bos used: %d\n",
59                    stats.num_allocated - stats.num_cached);
60         seq_printf(m, "size bos used: %dkb\n",
61                    (stats.size_allocated - stats.size_cached) / 1024);
62         seq_printf(m, "num bos cached: %d\n",
63                    stats.num_cached);
64         seq_printf(m, "size bos cached: %dkb\n",
65                    stats.size_cached / 1024);
66
67         return 0;
68 }
69 #endif
70
71 static uint32_t bo_page_index(size_t size)
72 {
73         return (size / PAGE_SIZE) - 1;
74 }
75
76 /* Must be called with bo_lock held. */
77 static void vc4_bo_destroy(struct vc4_bo *bo)
78 {
79         struct drm_gem_object *obj = &bo->base.base;
80         struct vc4_dev *vc4 = to_vc4_dev(obj->dev);
81
82         vc4->bo_stats.num_allocated--;
83         vc4->bo_stats.size_allocated -= obj->size;
84         drm_gem_cma_free_object(obj);
85 }
86
87 /* Must be called with bo_lock held. */
88 static void vc4_bo_remove_from_cache(struct vc4_bo *bo)
89 {
90         struct drm_gem_object *obj = &bo->base.base;
91         struct vc4_dev *vc4 = to_vc4_dev(obj->dev);
92
93         vc4->bo_stats.num_cached--;
94         vc4->bo_stats.size_cached -= obj->size;
95
96         list_del(&bo->unref_head);
97         list_del(&bo->size_head);
98 }
99
100 static struct list_head *vc4_get_cache_list_for_size(struct drm_device *dev,
101                                                      size_t size)
102 {
103         struct vc4_dev *vc4 = to_vc4_dev(dev);
104         uint32_t page_index = bo_page_index(size);
105
106         if (vc4->bo_cache.size_list_size <= page_index) {
107                 uint32_t new_size = max(vc4->bo_cache.size_list_size * 2,
108                                         page_index + 1);
109                 struct list_head *new_list;
110                 uint32_t i;
111
112                 new_list = kmalloc_array(new_size, sizeof(struct list_head),
113                                          GFP_KERNEL);
114                 if (!new_list)
115                         return NULL;
116
117                 /* Rebase the old cached BO lists to their new list
118                  * head locations.
119                  */
120                 for (i = 0; i < vc4->bo_cache.size_list_size; i++) {
121                         struct list_head *old_list =
122                                 &vc4->bo_cache.size_list[i];
123
124                         if (list_empty(old_list))
125                                 INIT_LIST_HEAD(&new_list[i]);
126                         else
127                                 list_replace(old_list, &new_list[i]);
128                 }
129                 /* And initialize the brand new BO list heads. */
130                 for (i = vc4->bo_cache.size_list_size; i < new_size; i++)
131                         INIT_LIST_HEAD(&new_list[i]);
132
133                 kfree(vc4->bo_cache.size_list);
134                 vc4->bo_cache.size_list = new_list;
135                 vc4->bo_cache.size_list_size = new_size;
136         }
137
138         return &vc4->bo_cache.size_list[page_index];
139 }
140
141 void vc4_bo_cache_purge(struct drm_device *dev)
142 {
143         struct vc4_dev *vc4 = to_vc4_dev(dev);
144
145         mutex_lock(&vc4->bo_lock);
146         while (!list_empty(&vc4->bo_cache.time_list)) {
147                 struct vc4_bo *bo = list_last_entry(&vc4->bo_cache.time_list,
148                                                     struct vc4_bo, unref_head);
149                 vc4_bo_remove_from_cache(bo);
150                 vc4_bo_destroy(bo);
151         }
152         mutex_unlock(&vc4->bo_lock);
153 }
154
155 static struct vc4_bo *vc4_bo_get_from_cache(struct drm_device *dev,
156                                             uint32_t size)
157 {
158         struct vc4_dev *vc4 = to_vc4_dev(dev);
159         uint32_t page_index = bo_page_index(size);
160         struct vc4_bo *bo = NULL;
161
162         size = roundup(size, PAGE_SIZE);
163
164         mutex_lock(&vc4->bo_lock);
165         if (page_index >= vc4->bo_cache.size_list_size)
166                 goto out;
167
168         if (list_empty(&vc4->bo_cache.size_list[page_index]))
169                 goto out;
170
171         bo = list_first_entry(&vc4->bo_cache.size_list[page_index],
172                               struct vc4_bo, size_head);
173         vc4_bo_remove_from_cache(bo);
174         kref_init(&bo->base.base.refcount);
175
176 out:
177         mutex_unlock(&vc4->bo_lock);
178         return bo;
179 }
180
181 /**
182  * vc4_gem_create_object - Implementation of driver->gem_create_object.
183  *
184  * This lets the CMA helpers allocate object structs for us, and keep
185  * our BO stats correct.
186  */
187 struct drm_gem_object *vc4_create_object(struct drm_device *dev, size_t size)
188 {
189         struct vc4_dev *vc4 = to_vc4_dev(dev);
190         struct vc4_bo *bo;
191
192         bo = kzalloc(sizeof(*bo), GFP_KERNEL);
193         if (!bo)
194                 return ERR_PTR(-ENOMEM);
195
196         mutex_lock(&vc4->bo_lock);
197         vc4->bo_stats.num_allocated++;
198         vc4->bo_stats.size_allocated += size;
199         mutex_unlock(&vc4->bo_lock);
200
201         return &bo->base.base;
202 }
203
204 struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t unaligned_size,
205                              bool from_cache)
206 {
207         size_t size = roundup(unaligned_size, PAGE_SIZE);
208         struct vc4_dev *vc4 = to_vc4_dev(dev);
209         struct drm_gem_cma_object *cma_obj;
210
211         if (size == 0)
212                 return NULL;
213
214         /* First, try to get a vc4_bo from the kernel BO cache. */
215         if (from_cache) {
216                 struct vc4_bo *bo = vc4_bo_get_from_cache(dev, size);
217
218                 if (bo)
219                         return bo;
220         }
221
222         cma_obj = drm_gem_cma_create(dev, size);
223         if (IS_ERR(cma_obj)) {
224                 /*
225                  * If we've run out of CMA memory, kill the cache of
226                  * CMA allocations we've got laying around and try again.
227                  */
228                 vc4_bo_cache_purge(dev);
229
230                 cma_obj = drm_gem_cma_create(dev, size);
231                 if (IS_ERR(cma_obj)) {
232                         DRM_ERROR("Failed to allocate from CMA:\n");
233                         vc4_bo_stats_dump(vc4);
234                         return NULL;
235                 }
236         }
237
238         return to_vc4_bo(&cma_obj->base);
239 }
240
241 int vc4_dumb_create(struct drm_file *file_priv,
242                     struct drm_device *dev,
243                     struct drm_mode_create_dumb *args)
244 {
245         int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
246         struct vc4_bo *bo = NULL;
247         int ret;
248
249         if (args->pitch < min_pitch)
250                 args->pitch = min_pitch;
251
252         if (args->size < args->pitch * args->height)
253                 args->size = args->pitch * args->height;
254
255         bo = vc4_bo_create(dev, args->size, false);
256         if (!bo)
257                 return -ENOMEM;
258
259         ret = drm_gem_handle_create(file_priv, &bo->base.base, &args->handle);
260         drm_gem_object_unreference_unlocked(&bo->base.base);
261
262         return ret;
263 }
264
265 /* Must be called with bo_lock held. */
266 static void vc4_bo_cache_free_old(struct drm_device *dev)
267 {
268         struct vc4_dev *vc4 = to_vc4_dev(dev);
269         unsigned long expire_time = jiffies - msecs_to_jiffies(1000);
270
271         while (!list_empty(&vc4->bo_cache.time_list)) {
272                 struct vc4_bo *bo = list_last_entry(&vc4->bo_cache.time_list,
273                                                     struct vc4_bo, unref_head);
274                 if (time_before(expire_time, bo->free_time)) {
275                         mod_timer(&vc4->bo_cache.time_timer,
276                                   round_jiffies_up(jiffies +
277                                                    msecs_to_jiffies(1000)));
278                         return;
279                 }
280
281                 vc4_bo_remove_from_cache(bo);
282                 vc4_bo_destroy(bo);
283         }
284 }
285
286 /* Called on the last userspace/kernel unreference of the BO.  Returns
287  * it to the BO cache if possible, otherwise frees it.
288  *
289  * Note that this is called with the struct_mutex held.
290  */
291 void vc4_free_object(struct drm_gem_object *gem_bo)
292 {
293         struct drm_device *dev = gem_bo->dev;
294         struct vc4_dev *vc4 = to_vc4_dev(dev);
295         struct vc4_bo *bo = to_vc4_bo(gem_bo);
296         struct list_head *cache_list;
297
298         mutex_lock(&vc4->bo_lock);
299         /* If the object references someone else's memory, we can't cache it.
300          */
301         if (gem_bo->import_attach) {
302                 vc4_bo_destroy(bo);
303                 goto out;
304         }
305
306         /* Don't cache if it was publicly named. */
307         if (gem_bo->name) {
308                 vc4_bo_destroy(bo);
309                 goto out;
310         }
311
312         cache_list = vc4_get_cache_list_for_size(dev, gem_bo->size);
313         if (!cache_list) {
314                 vc4_bo_destroy(bo);
315                 goto out;
316         }
317
318         bo->free_time = jiffies;
319         list_add(&bo->size_head, cache_list);
320         list_add(&bo->unref_head, &vc4->bo_cache.time_list);
321
322         vc4->bo_stats.num_cached++;
323         vc4->bo_stats.size_cached += gem_bo->size;
324
325         vc4_bo_cache_free_old(dev);
326
327 out:
328         mutex_unlock(&vc4->bo_lock);
329 }
330
331 static void vc4_bo_cache_time_work(struct work_struct *work)
332 {
333         struct vc4_dev *vc4 =
334                 container_of(work, struct vc4_dev, bo_cache.time_work);
335         struct drm_device *dev = vc4->dev;
336
337         mutex_lock(&vc4->bo_lock);
338         vc4_bo_cache_free_old(dev);
339         mutex_unlock(&vc4->bo_lock);
340 }
341
342 static void vc4_bo_cache_time_timer(unsigned long data)
343 {
344         struct drm_device *dev = (struct drm_device *)data;
345         struct vc4_dev *vc4 = to_vc4_dev(dev);
346
347         schedule_work(&vc4->bo_cache.time_work);
348 }
349
350 int vc4_create_bo_ioctl(struct drm_device *dev, void *data,
351                         struct drm_file *file_priv)
352 {
353         struct drm_vc4_create_bo *args = data;
354         struct vc4_bo *bo = NULL;
355         int ret;
356
357         /*
358          * We can't allocate from the BO cache, because the BOs don't
359          * get zeroed, and that might leak data between users.
360          */
361         bo = vc4_bo_create(dev, args->size, false);
362         if (!bo)
363                 return -ENOMEM;
364
365         ret = drm_gem_handle_create(file_priv, &bo->base.base, &args->handle);
366         drm_gem_object_unreference_unlocked(&bo->base.base);
367
368         return ret;
369 }
370
371 int vc4_mmap_bo_ioctl(struct drm_device *dev, void *data,
372                       struct drm_file *file_priv)
373 {
374         struct drm_vc4_mmap_bo *args = data;
375         struct drm_gem_object *gem_obj;
376
377         gem_obj = drm_gem_object_lookup(dev, file_priv, args->handle);
378         if (!gem_obj) {
379                 DRM_ERROR("Failed to look up GEM BO %d\n", args->handle);
380                 return -EINVAL;
381         }
382
383         /* The mmap offset was set up at BO allocation time. */
384         args->offset = drm_vma_node_offset_addr(&gem_obj->vma_node);
385
386         drm_gem_object_unreference_unlocked(gem_obj);
387         return 0;
388 }
389
390 void vc4_bo_cache_init(struct drm_device *dev)
391 {
392         struct vc4_dev *vc4 = to_vc4_dev(dev);
393
394         mutex_init(&vc4->bo_lock);
395
396         INIT_LIST_HEAD(&vc4->bo_cache.time_list);
397
398         INIT_WORK(&vc4->bo_cache.time_work, vc4_bo_cache_time_work);
399         setup_timer(&vc4->bo_cache.time_timer,
400                     vc4_bo_cache_time_timer,
401                     (unsigned long)dev);
402 }
403
404 void vc4_bo_cache_destroy(struct drm_device *dev)
405 {
406         struct vc4_dev *vc4 = to_vc4_dev(dev);
407
408         del_timer(&vc4->bo_cache.time_timer);
409         cancel_work_sync(&vc4->bo_cache.time_work);
410
411         vc4_bo_cache_purge(dev);
412
413         if (vc4->bo_stats.num_allocated) {
414                 DRM_ERROR("Destroying BO cache while BOs still allocated:\n");
415                 vc4_bo_stats_dump(vc4);
416         }
417 }