aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@gmail.com>2013-07-24 15:07:52 -0400
committerDave Airlie <airlied@gmail.com>2013-07-25 06:47:06 -0400
commit0de23977cfeb5b357ec884ba15417ae118ff9e9b (patch)
treebad8f04fc993b778020f6a2f7e9e7d2be8deb293
parentfe3078fa5c367186c94a6652581ffbe9ccea4640 (diff)
drm/gem: convert to new unified vma manager
Use the new vma manager instead of the old hashtable. Also convert all drivers to use the new convenience helpers. This drops all the (map_list.hash.key << PAGE_SHIFT) non-sense. Locking and access-management is exactly the same as before with an additional lock inside of the vma-manager, which strictly wouldn't be needed for gem. v2: - rebase on drm-next - init nodes via drm_vma_node_reset() in drm_gem.c v3: - fix tegra v4: - remove duplicate if (drm_vma_node_has_offset()) checks - inline now trivial drm_vma_node_offset_addr() calls v5: - skip node-reset on gem-init due to kzalloc() - do not allow mapping gem-objects with offsets (backwards compat) - remove unneccessary casts Cc: Inki Dae <inki.dae@samsung.com> Cc: Rob Clark <robdclark@gmail.com> Cc: Dave Airlie <airlied@redhat.com> Cc: Thierry Reding <thierry.reding@gmail.com> Signed-off-by: David Herrmann <dh.herrmann@gmail.com> Acked-by: Patrik Jakobsson <patrik.r.jakobsson@gmail.com> Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Dave Airlie <airlied@gmail.com>
-rw-r--r--drivers/gpu/drm/drm_gem.c89
-rw-r--r--drivers/gpu/drm/drm_gem_cma_helper.c16
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_gem.c14
-rw-r--r--drivers/gpu/drm/gma500/gem.c15
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c10
-rw-r--r--drivers/gpu/drm/omapdrm/omap_gem.c28
-rw-r--r--drivers/gpu/drm/omapdrm/omap_gem_helpers.c49
-rw-r--r--drivers/gpu/drm/udl/udl_gem.c13
-rw-r--r--drivers/gpu/host1x/drm/gem.c5
-rw-r--r--include/drm/drmP.h7
-rw-r--r--include/uapi/drm/drm.h2
11 files changed, 62 insertions, 186 deletions
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 1ad9e7ec0119..3613b50b5c26 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -37,6 +37,7 @@
37#include <linux/shmem_fs.h> 37#include <linux/shmem_fs.h>
38#include <linux/dma-buf.h> 38#include <linux/dma-buf.h>
39#include <drm/drmP.h> 39#include <drm/drmP.h>
40#include <drm/drm_vma_manager.h>
40 41
41/** @file drm_gem.c 42/** @file drm_gem.c
42 * 43 *
@@ -102,14 +103,9 @@ drm_gem_init(struct drm_device *dev)
102 } 103 }
103 104
104 dev->mm_private = mm; 105 dev->mm_private = mm;
105 106 drm_vma_offset_manager_init(&mm->vma_manager,
106 if (drm_ht_create(&mm->offset_hash, 12)) { 107 DRM_FILE_PAGE_OFFSET_START,
107 kfree(mm); 108 DRM_FILE_PAGE_OFFSET_SIZE);
108 return -ENOMEM;
109 }
110
111 drm_mm_init(&mm->offset_manager, DRM_FILE_PAGE_OFFSET_START,
112 DRM_FILE_PAGE_OFFSET_SIZE);
113 109
114 return 0; 110 return 0;
115} 111}
@@ -119,8 +115,7 @@ drm_gem_destroy(struct drm_device *dev)
119{ 115{
120 struct drm_gem_mm *mm = dev->mm_private; 116 struct drm_gem_mm *mm = dev->mm_private;
121 117
122 drm_mm_takedown(&mm->offset_manager); 118 drm_vma_offset_manager_destroy(&mm->vma_manager);
123 drm_ht_remove(&mm->offset_hash);
124 kfree(mm); 119 kfree(mm);
125 dev->mm_private = NULL; 120 dev->mm_private = NULL;
126} 121}
@@ -302,12 +297,8 @@ drm_gem_free_mmap_offset(struct drm_gem_object *obj)
302{ 297{
303 struct drm_device *dev = obj->dev; 298 struct drm_device *dev = obj->dev;
304 struct drm_gem_mm *mm = dev->mm_private; 299 struct drm_gem_mm *mm = dev->mm_private;
305 struct drm_map_list *list = &obj->map_list;
306 300
307 drm_ht_remove_item(&mm->offset_hash, &list->hash); 301 drm_vma_offset_remove(&mm->vma_manager, &obj->vma_node);
308 drm_mm_put_block(list->file_offset_node);
309 kfree(list->map);
310 list->map = NULL;
311} 302}
312EXPORT_SYMBOL(drm_gem_free_mmap_offset); 303EXPORT_SYMBOL(drm_gem_free_mmap_offset);
313 304
@@ -327,54 +318,9 @@ drm_gem_create_mmap_offset(struct drm_gem_object *obj)
327{ 318{
328 struct drm_device *dev = obj->dev; 319 struct drm_device *dev = obj->dev;
329 struct drm_gem_mm *mm = dev->mm_private; 320 struct drm_gem_mm *mm = dev->mm_private;
330 struct drm_map_list *list;
331 struct drm_local_map *map;
332 int ret;
333
334 /* Set the object up for mmap'ing */
335 list = &obj->map_list;
336 list->map = kzalloc(sizeof(struct drm_map_list), GFP_KERNEL);
337 if (!list->map)
338 return -ENOMEM;
339
340 map = list->map;
341 map->type = _DRM_GEM;
342 map->size = obj->size;
343 map->handle = obj;
344
345 /* Get a DRM GEM mmap offset allocated... */
346 list->file_offset_node = drm_mm_search_free(&mm->offset_manager,
347 obj->size / PAGE_SIZE, 0, false);
348
349 if (!list->file_offset_node) {
350 DRM_ERROR("failed to allocate offset for bo %d\n", obj->name);
351 ret = -ENOSPC;
352 goto out_free_list;
353 }
354 321
355 list->file_offset_node = drm_mm_get_block(list->file_offset_node, 322 return drm_vma_offset_add(&mm->vma_manager, &obj->vma_node,
356 obj->size / PAGE_SIZE, 0); 323 obj->size / PAGE_SIZE);
357 if (!list->file_offset_node) {
358 ret = -ENOMEM;
359 goto out_free_list;
360 }
361
362 list->hash.key = list->file_offset_node->start;
363 ret = drm_ht_insert_item(&mm->offset_hash, &list->hash);
364 if (ret) {
365 DRM_ERROR("failed to add to map hash\n");
366 goto out_free_mm;
367 }
368
369 return 0;
370
371out_free_mm:
372 drm_mm_put_block(list->file_offset_node);
373out_free_list:
374 kfree(list->map);
375 list->map = NULL;
376
377 return ret;
378} 324}
379EXPORT_SYMBOL(drm_gem_create_mmap_offset); 325EXPORT_SYMBOL(drm_gem_create_mmap_offset);
380 326
@@ -703,8 +649,8 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
703 struct drm_file *priv = filp->private_data; 649 struct drm_file *priv = filp->private_data;
704 struct drm_device *dev = priv->minor->dev; 650 struct drm_device *dev = priv->minor->dev;
705 struct drm_gem_mm *mm = dev->mm_private; 651 struct drm_gem_mm *mm = dev->mm_private;
706 struct drm_local_map *map = NULL; 652 struct drm_gem_object *obj;
707 struct drm_hash_item *hash; 653 struct drm_vma_offset_node *node;
708 int ret = 0; 654 int ret = 0;
709 655
710 if (drm_device_is_unplugged(dev)) 656 if (drm_device_is_unplugged(dev))
@@ -712,21 +658,16 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
712 658
713 mutex_lock(&dev->struct_mutex); 659 mutex_lock(&dev->struct_mutex);
714 660
715 if (drm_ht_find_item(&mm->offset_hash, vma->vm_pgoff, &hash)) { 661 node = drm_vma_offset_exact_lookup(&mm->vma_manager, vma->vm_pgoff,
662 vma_pages(vma));
663 if (!node) {
716 mutex_unlock(&dev->struct_mutex); 664 mutex_unlock(&dev->struct_mutex);
717 return drm_mmap(filp, vma); 665 return drm_mmap(filp, vma);
718 } 666 }
719 667
720 map = drm_hash_entry(hash, struct drm_map_list, hash)->map; 668 obj = container_of(node, struct drm_gem_object, vma_node);
721 if (!map || 669 ret = drm_gem_mmap_obj(obj, drm_vma_node_size(node), vma);
722 ((map->flags & _DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN))) {
723 ret = -EPERM;
724 goto out_unlock;
725 }
726
727 ret = drm_gem_mmap_obj(map->handle, map->size, vma);
728 670
729out_unlock:
730 mutex_unlock(&dev->struct_mutex); 671 mutex_unlock(&dev->struct_mutex);
731 672
732 return ret; 673 return ret;
diff --git a/drivers/gpu/drm/drm_gem_cma_helper.c b/drivers/gpu/drm/drm_gem_cma_helper.c
index ece72a8ac245..847f09117666 100644
--- a/drivers/gpu/drm/drm_gem_cma_helper.c
+++ b/drivers/gpu/drm/drm_gem_cma_helper.c
@@ -27,11 +27,7 @@
27#include <drm/drmP.h> 27#include <drm/drmP.h>
28#include <drm/drm.h> 28#include <drm/drm.h>
29#include <drm/drm_gem_cma_helper.h> 29#include <drm/drm_gem_cma_helper.h>
30 30#include <drm/drm_vma_manager.h>
31static unsigned int get_gem_mmap_offset(struct drm_gem_object *obj)
32{
33 return (unsigned int)obj->map_list.hash.key << PAGE_SHIFT;
34}
35 31
36/* 32/*
37 * __drm_gem_cma_create - Create a GEM CMA object without allocating memory 33 * __drm_gem_cma_create - Create a GEM CMA object without allocating memory
@@ -172,8 +168,7 @@ void drm_gem_cma_free_object(struct drm_gem_object *gem_obj)
172{ 168{
173 struct drm_gem_cma_object *cma_obj; 169 struct drm_gem_cma_object *cma_obj;
174 170
175 if (gem_obj->map_list.map) 171 drm_gem_free_mmap_offset(gem_obj);
176 drm_gem_free_mmap_offset(gem_obj);
177 172
178 cma_obj = to_drm_gem_cma_obj(gem_obj); 173 cma_obj = to_drm_gem_cma_obj(gem_obj);
179 174
@@ -237,7 +232,7 @@ int drm_gem_cma_dumb_map_offset(struct drm_file *file_priv,
237 return -EINVAL; 232 return -EINVAL;
238 } 233 }
239 234
240 *offset = get_gem_mmap_offset(gem_obj); 235 *offset = drm_vma_node_offset_addr(&gem_obj->vma_node);
241 236
242 drm_gem_object_unreference(gem_obj); 237 drm_gem_object_unreference(gem_obj);
243 238
@@ -301,12 +296,11 @@ void drm_gem_cma_describe(struct drm_gem_cma_object *cma_obj, struct seq_file *m
301{ 296{
302 struct drm_gem_object *obj = &cma_obj->base; 297 struct drm_gem_object *obj = &cma_obj->base;
303 struct drm_device *dev = obj->dev; 298 struct drm_device *dev = obj->dev;
304 uint64_t off = 0; 299 uint64_t off;
305 300
306 WARN_ON(!mutex_is_locked(&dev->struct_mutex)); 301 WARN_ON(!mutex_is_locked(&dev->struct_mutex));
307 302
308 if (obj->map_list.map) 303 off = drm_vma_node_start(&obj->vma_node);
309 off = (uint64_t)obj->map_list.hash.key;
310 304
311 seq_printf(m, "%2d (%2d) %08llx %08Zx %p %d", 305 seq_printf(m, "%2d (%2d) %08llx %08Zx %p %d",
312 obj->name, obj->refcount.refcount.counter, 306 obj->name, obj->refcount.refcount.counter,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_gem.c b/drivers/gpu/drm/exynos/exynos_drm_gem.c
index 24c22a8c3364..be32db1ab290 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_gem.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_gem.c
@@ -10,6 +10,7 @@
10 */ 10 */
11 11
12#include <drm/drmP.h> 12#include <drm/drmP.h>
13#include <drm/drm_vma_manager.h>
13 14
14#include <linux/shmem_fs.h> 15#include <linux/shmem_fs.h>
15#include <drm/exynos_drm.h> 16#include <drm/exynos_drm.h>
@@ -152,8 +153,7 @@ out:
152 exynos_drm_fini_buf(obj->dev, buf); 153 exynos_drm_fini_buf(obj->dev, buf);
153 exynos_gem_obj->buffer = NULL; 154 exynos_gem_obj->buffer = NULL;
154 155
155 if (obj->map_list.map) 156 drm_gem_free_mmap_offset(obj);
156 drm_gem_free_mmap_offset(obj);
157 157
158 /* release file pointer to gem object. */ 158 /* release file pointer to gem object. */
159 drm_gem_object_release(obj); 159 drm_gem_object_release(obj);
@@ -703,13 +703,11 @@ int exynos_drm_gem_dumb_map_offset(struct drm_file *file_priv,
703 goto unlock; 703 goto unlock;
704 } 704 }
705 705
706 if (!obj->map_list.map) { 706 ret = drm_gem_create_mmap_offset(obj);
707 ret = drm_gem_create_mmap_offset(obj); 707 if (ret)
708 if (ret) 708 goto out;
709 goto out;
710 }
711 709
712 *offset = (u64)obj->map_list.hash.key << PAGE_SHIFT; 710 *offset = drm_vma_node_offset_addr(&obj->vma_node);
713 DRM_DEBUG_KMS("offset = 0x%lx\n", (unsigned long)*offset); 711 DRM_DEBUG_KMS("offset = 0x%lx\n", (unsigned long)*offset);
714 712
715out: 713out:
diff --git a/drivers/gpu/drm/gma500/gem.c b/drivers/gpu/drm/gma500/gem.c
index fe1d3320ce6a..2f77bea30b11 100644
--- a/drivers/gpu/drm/gma500/gem.c
+++ b/drivers/gpu/drm/gma500/gem.c
@@ -26,6 +26,7 @@
26#include <drm/drmP.h> 26#include <drm/drmP.h>
27#include <drm/drm.h> 27#include <drm/drm.h>
28#include <drm/gma_drm.h> 28#include <drm/gma_drm.h>
29#include <drm/drm_vma_manager.h>
29#include "psb_drv.h" 30#include "psb_drv.h"
30 31
31int psb_gem_init_object(struct drm_gem_object *obj) 32int psb_gem_init_object(struct drm_gem_object *obj)
@@ -38,8 +39,7 @@ void psb_gem_free_object(struct drm_gem_object *obj)
38 struct gtt_range *gtt = container_of(obj, struct gtt_range, gem); 39 struct gtt_range *gtt = container_of(obj, struct gtt_range, gem);
39 40
40 /* Remove the list map if one is present */ 41 /* Remove the list map if one is present */
41 if (obj->map_list.map) 42 drm_gem_free_mmap_offset(obj);
42 drm_gem_free_mmap_offset(obj);
43 drm_gem_object_release(obj); 43 drm_gem_object_release(obj);
44 44
45 /* This must occur last as it frees up the memory of the GEM object */ 45 /* This must occur last as it frees up the memory of the GEM object */
@@ -81,13 +81,10 @@ int psb_gem_dumb_map_gtt(struct drm_file *file, struct drm_device *dev,
81 /* What validation is needed here ? */ 81 /* What validation is needed here ? */
82 82
83 /* Make it mmapable */ 83 /* Make it mmapable */
84 if (!obj->map_list.map) { 84 ret = drm_gem_create_mmap_offset(obj);
85 ret = drm_gem_create_mmap_offset(obj); 85 if (ret)
86 if (ret) 86 goto out;
87 goto out; 87 *offset = drm_vma_node_offset_addr(&obj->vma_node);
88 }
89 /* GEM should really work out the hash offsets for us */
90 *offset = (u64)obj->map_list.hash.key << PAGE_SHIFT;
91out: 88out:
92 drm_gem_object_unreference(obj); 89 drm_gem_object_unreference(obj);
93unlock: 90unlock:
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 46bf7e3887d4..53f81b3b3424 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28#include <drm/drmP.h> 28#include <drm/drmP.h>
29#include <drm/drm_vma_manager.h>
29#include <drm/i915_drm.h> 30#include <drm/i915_drm.h>
30#include "i915_drv.h" 31#include "i915_drv.h"
31#include "i915_trace.h" 32#include "i915_trace.h"
@@ -1428,7 +1429,7 @@ i915_gem_release_mmap(struct drm_i915_gem_object *obj)
1428 1429
1429 if (obj->base.dev->dev_mapping) 1430 if (obj->base.dev->dev_mapping)
1430 unmap_mapping_range(obj->base.dev->dev_mapping, 1431 unmap_mapping_range(obj->base.dev->dev_mapping,
1431 (loff_t)obj->base.map_list.hash.key<<PAGE_SHIFT, 1432 (loff_t)drm_vma_node_offset_addr(&obj->base.vma_node),
1432 obj->base.size, 1); 1433 obj->base.size, 1);
1433 1434
1434 obj->fault_mappable = false; 1435 obj->fault_mappable = false;
@@ -1486,7 +1487,7 @@ static int i915_gem_object_create_mmap_offset(struct drm_i915_gem_object *obj)
1486 struct drm_i915_private *dev_priv = obj->base.dev->dev_private; 1487 struct drm_i915_private *dev_priv = obj->base.dev->dev_private;
1487 int ret; 1488 int ret;
1488 1489
1489 if (obj->base.map_list.map) 1490 if (drm_vma_node_has_offset(&obj->base.vma_node))
1490 return 0; 1491 return 0;
1491 1492
1492 dev_priv->mm.shrinker_no_lock_stealing = true; 1493 dev_priv->mm.shrinker_no_lock_stealing = true;
@@ -1517,9 +1518,6 @@ out:
1517 1518
1518static void i915_gem_object_free_mmap_offset(struct drm_i915_gem_object *obj) 1519static void i915_gem_object_free_mmap_offset(struct drm_i915_gem_object *obj)
1519{ 1520{
1520 if (!obj->base.map_list.map)
1521 return;
1522
1523 drm_gem_free_mmap_offset(&obj->base); 1521 drm_gem_free_mmap_offset(&obj->base);
1524} 1522}
1525 1523
@@ -1558,7 +1556,7 @@ i915_gem_mmap_gtt(struct drm_file *file,
1558 if (ret) 1556 if (ret)
1559 goto out; 1557 goto out;
1560 1558
1561 *offset = (u64)obj->base.map_list.hash.key << PAGE_SHIFT; 1559 *offset = drm_vma_node_offset_addr(&obj->base.vma_node);
1562 1560
1563out: 1561out:
1564 drm_gem_object_unreference(&obj->base); 1562 drm_gem_object_unreference(&obj->base);
diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c
index cbcd71e6ed83..f90531fc00c9 100644
--- a/drivers/gpu/drm/omapdrm/omap_gem.c
+++ b/drivers/gpu/drm/omapdrm/omap_gem.c
@@ -20,6 +20,7 @@
20 20
21#include <linux/spinlock.h> 21#include <linux/spinlock.h>
22#include <linux/shmem_fs.h> 22#include <linux/shmem_fs.h>
23#include <drm/drm_vma_manager.h>
23 24
24#include "omap_drv.h" 25#include "omap_drv.h"
25#include "omap_dmm_tiler.h" 26#include "omap_dmm_tiler.h"
@@ -308,21 +309,20 @@ uint32_t omap_gem_flags(struct drm_gem_object *obj)
308static uint64_t mmap_offset(struct drm_gem_object *obj) 309static uint64_t mmap_offset(struct drm_gem_object *obj)
309{ 310{
310 struct drm_device *dev = obj->dev; 311 struct drm_device *dev = obj->dev;
312 int ret;
313 size_t size;
311 314
312 WARN_ON(!mutex_is_locked(&dev->struct_mutex)); 315 WARN_ON(!mutex_is_locked(&dev->struct_mutex));
313 316
314 if (!obj->map_list.map) { 317 /* Make it mmapable */
315 /* Make it mmapable */ 318 size = omap_gem_mmap_size(obj);
316 size_t size = omap_gem_mmap_size(obj); 319 ret = _drm_gem_create_mmap_offset_size(obj, size);
317 int ret = _drm_gem_create_mmap_offset_size(obj, size); 320 if (ret) {
318 321 dev_err(dev->dev, "could not allocate mmap offset\n");
319 if (ret) { 322 return 0;
320 dev_err(dev->dev, "could not allocate mmap offset\n");
321 return 0;
322 }
323 } 323 }
324 324
325 return (uint64_t)obj->map_list.hash.key << PAGE_SHIFT; 325 return drm_vma_node_offset_addr(&obj->vma_node);
326} 326}
327 327
328uint64_t omap_gem_mmap_offset(struct drm_gem_object *obj) 328uint64_t omap_gem_mmap_offset(struct drm_gem_object *obj)
@@ -997,12 +997,11 @@ void omap_gem_describe(struct drm_gem_object *obj, struct seq_file *m)
997{ 997{
998 struct drm_device *dev = obj->dev; 998 struct drm_device *dev = obj->dev;
999 struct omap_gem_object *omap_obj = to_omap_bo(obj); 999 struct omap_gem_object *omap_obj = to_omap_bo(obj);
1000 uint64_t off = 0; 1000 uint64_t off;
1001 1001
1002 WARN_ON(!mutex_is_locked(&dev->struct_mutex)); 1002 WARN_ON(!mutex_is_locked(&dev->struct_mutex));
1003 1003
1004 if (obj->map_list.map) 1004 off = drm_vma_node_start(&obj->vma_node);
1005 off = (uint64_t)obj->map_list.hash.key;
1006 1005
1007 seq_printf(m, "%08x: %2d (%2d) %08llx %08Zx (%2d) %p %4d", 1006 seq_printf(m, "%08x: %2d (%2d) %08llx %08Zx (%2d) %p %4d",
1008 omap_obj->flags, obj->name, obj->refcount.refcount.counter, 1007 omap_obj->flags, obj->name, obj->refcount.refcount.counter,
@@ -1309,8 +1308,7 @@ void omap_gem_free_object(struct drm_gem_object *obj)
1309 1308
1310 list_del(&omap_obj->mm_list); 1309 list_del(&omap_obj->mm_list);
1311 1310
1312 if (obj->map_list.map) 1311 drm_gem_free_mmap_offset(obj);
1313 drm_gem_free_mmap_offset(obj);
1314 1312
1315 /* this means the object is still pinned.. which really should 1313 /* this means the object is still pinned.. which really should
1316 * not happen. I think.. 1314 * not happen. I think..
diff --git a/drivers/gpu/drm/omapdrm/omap_gem_helpers.c b/drivers/gpu/drm/omapdrm/omap_gem_helpers.c
index f9eb679eb79b..dbb157542f8f 100644
--- a/drivers/gpu/drm/omapdrm/omap_gem_helpers.c
+++ b/drivers/gpu/drm/omapdrm/omap_gem_helpers.c
@@ -118,52 +118,7 @@ _drm_gem_create_mmap_offset_size(struct drm_gem_object *obj, size_t size)
118{ 118{
119 struct drm_device *dev = obj->dev; 119 struct drm_device *dev = obj->dev;
120 struct drm_gem_mm *mm = dev->mm_private; 120 struct drm_gem_mm *mm = dev->mm_private;
121 struct drm_map_list *list;
122 struct drm_local_map *map;
123 int ret = 0;
124
125 /* Set the object up for mmap'ing */
126 list = &obj->map_list;
127 list->map = kzalloc(sizeof(struct drm_map_list), GFP_KERNEL);
128 if (!list->map)
129 return -ENOMEM;
130
131 map = list->map;
132 map->type = _DRM_GEM;
133 map->size = size;
134 map->handle = obj;
135
136 /* Get a DRM GEM mmap offset allocated... */
137 list->file_offset_node = drm_mm_search_free(&mm->offset_manager,
138 size / PAGE_SIZE, 0, 0);
139
140 if (!list->file_offset_node) {
141 DRM_ERROR("failed to allocate offset for bo %d\n", obj->name);
142 ret = -ENOSPC;
143 goto out_free_list;
144 }
145
146 list->file_offset_node = drm_mm_get_block(list->file_offset_node,
147 size / PAGE_SIZE, 0);
148 if (!list->file_offset_node) {
149 ret = -ENOMEM;
150 goto out_free_list;
151 }
152
153 list->hash.key = list->file_offset_node->start;
154 ret = drm_ht_insert_item(&mm->offset_hash, &list->hash);
155 if (ret) {
156 DRM_ERROR("failed to add to map hash\n");
157 goto out_free_mm;
158 }
159
160 return 0;
161
162out_free_mm:
163 drm_mm_put_block(list->file_offset_node);
164out_free_list:
165 kfree(list->map);
166 list->map = NULL;
167 121
168 return ret; 122 return drm_vma_offset_add(&mm->vma_manager, &obj->vma_node,
123 size / PAGE_SIZE);
169} 124}
diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c
index ef034fa3e6f5..2a4cb2f83b36 100644
--- a/drivers/gpu/drm/udl/udl_gem.c
+++ b/drivers/gpu/drm/udl/udl_gem.c
@@ -223,8 +223,7 @@ void udl_gem_free_object(struct drm_gem_object *gem_obj)
223 if (obj->pages) 223 if (obj->pages)
224 udl_gem_put_pages(obj); 224 udl_gem_put_pages(obj);
225 225
226 if (gem_obj->map_list.map) 226 drm_gem_free_mmap_offset(gem_obj);
227 drm_gem_free_mmap_offset(gem_obj);
228} 227}
229 228
230/* the dumb interface doesn't work with the GEM straight MMAP 229/* the dumb interface doesn't work with the GEM straight MMAP
@@ -247,13 +246,11 @@ int udl_gem_mmap(struct drm_file *file, struct drm_device *dev,
247 ret = udl_gem_get_pages(gobj, GFP_KERNEL); 246 ret = udl_gem_get_pages(gobj, GFP_KERNEL);
248 if (ret) 247 if (ret)
249 goto out; 248 goto out;
250 if (!gobj->base.map_list.map) { 249 ret = drm_gem_create_mmap_offset(obj);
251 ret = drm_gem_create_mmap_offset(obj); 250 if (ret)
252 if (ret) 251 goto out;
253 goto out;
254 }
255 252
256 *offset = (u64)gobj->base.map_list.hash.key << PAGE_SHIFT; 253 *offset = drm_vma_node_offset_addr(&gobj->base.vma_node);
257 254
258out: 255out:
259 drm_gem_object_unreference(&gobj->base); 256 drm_gem_object_unreference(&gobj->base);
diff --git a/drivers/gpu/host1x/drm/gem.c b/drivers/gpu/host1x/drm/gem.c
index c5e9a9b494c2..bc323b3dbe4d 100644
--- a/drivers/gpu/host1x/drm/gem.c
+++ b/drivers/gpu/host1x/drm/gem.c
@@ -108,7 +108,7 @@ static void tegra_bo_destroy(struct drm_device *drm, struct tegra_bo *bo)
108 108
109unsigned int tegra_bo_get_mmap_offset(struct tegra_bo *bo) 109unsigned int tegra_bo_get_mmap_offset(struct tegra_bo *bo)
110{ 110{
111 return (unsigned int)bo->gem.map_list.hash.key << PAGE_SHIFT; 111 return (unsigned int)drm_vma_node_offset_addr(&bo->gem.vma_node);
112} 112}
113 113
114struct tegra_bo *tegra_bo_create(struct drm_device *drm, unsigned int size) 114struct tegra_bo *tegra_bo_create(struct drm_device *drm, unsigned int size)
@@ -182,8 +182,7 @@ void tegra_bo_free_object(struct drm_gem_object *gem)
182{ 182{
183 struct tegra_bo *bo = to_tegra_bo(gem); 183 struct tegra_bo *bo = to_tegra_bo(gem);
184 184
185 if (gem->map_list.map) 185 drm_gem_free_mmap_offset(gem);
186 drm_gem_free_mmap_offset(gem);
187 186
188 drm_gem_object_release(gem); 187 drm_gem_object_release(gem);
189 tegra_bo_destroy(gem->dev, bo); 188 tegra_bo_destroy(gem->dev, bo);
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index 0ab6a090a15c..4b518e05d293 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -71,6 +71,7 @@
71#include <asm/pgalloc.h> 71#include <asm/pgalloc.h>
72#include <drm/drm.h> 72#include <drm/drm.h>
73#include <drm/drm_sarea.h> 73#include <drm/drm_sarea.h>
74#include <drm/drm_vma_manager.h>
74 75
75#include <linux/idr.h> 76#include <linux/idr.h>
76 77
@@ -587,7 +588,6 @@ struct drm_map_list {
587 struct drm_local_map *map; /**< mapping */ 588 struct drm_local_map *map; /**< mapping */
588 uint64_t user_token; 589 uint64_t user_token;
589 struct drm_master *master; 590 struct drm_master *master;
590 struct drm_mm_node *file_offset_node; /**< fake offset */
591}; 591};
592 592
593/** 593/**
@@ -622,8 +622,7 @@ struct drm_ati_pcigart_info {
622 * GEM specific mm private for tracking GEM objects 622 * GEM specific mm private for tracking GEM objects
623 */ 623 */
624struct drm_gem_mm { 624struct drm_gem_mm {
625 struct drm_mm offset_manager; /**< Offset mgmt for buffer objects */ 625 struct drm_vma_offset_manager vma_manager;
626 struct drm_open_hash offset_hash; /**< User token hash table for maps */
627}; 626};
628 627
629/** 628/**
@@ -644,7 +643,7 @@ struct drm_gem_object {
644 struct file *filp; 643 struct file *filp;
645 644
646 /* Mapping info for this object */ 645 /* Mapping info for this object */
647 struct drm_map_list map_list; 646 struct drm_vma_offset_node vma_node;
648 647
649 /** 648 /**
650 * Size of the object, in bytes. Immutable over the object's 649 * Size of the object, in bytes. Immutable over the object's
diff --git a/include/uapi/drm/drm.h b/include/uapi/drm/drm.h
index 238a166b9fe6..272580ca320f 100644
--- a/include/uapi/drm/drm.h
+++ b/include/uapi/drm/drm.h
@@ -181,7 +181,7 @@ enum drm_map_type {
181 _DRM_AGP = 3, /**< AGP/GART */ 181 _DRM_AGP = 3, /**< AGP/GART */
182 _DRM_SCATTER_GATHER = 4, /**< Scatter/gather memory for PCI DMA */ 182 _DRM_SCATTER_GATHER = 4, /**< Scatter/gather memory for PCI DMA */
183 _DRM_CONSISTENT = 5, /**< Consistent memory for PCI DMA */ 183 _DRM_CONSISTENT = 5, /**< Consistent memory for PCI DMA */
184 _DRM_GEM = 6, /**< GEM object */ 184 _DRM_GEM = 6, /**< GEM object (obsolete) */
185}; 185};
186 186
187/** 187/**