From b3a070cccb9135f8bec63d9f194ddaa422136fb0 Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Fri, 5 Jul 2013 14:41:02 -0700 Subject: drm: pre allocate node for create_block For an upcoming patch where we introduce the i915 VMA, it's ideal to have the drm_mm_node as part of the VMA struct (ie. it's pre-allocated). Part of the conversion to VMAs is to kill off obj->gtt_space. Doing this will break a bunch of code, but amongst them are 2 callers of drm_mm_create_block(), both related to stolen memory. It also allows us to embed the drm_mm_node into the object currently which provides a nice transition over to the new code. v2: Reordered to do before ripping out obj->gtt_offset. Some minor cleanups made available because of reordering. v3: s/continue/break on failed stolen node allocation (David) Set obj->gtt_space on failed node allocation (David) Only unref stolen (fix double free) on failed create_stolen (David) Free node, and NULL it in failed create_stolen (David) Add back accidentally removed newline (David) CC: Reviewed-by: David Herrmann Signed-off-by: Ben Widawsky Acked-by: David Airlie Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_mm.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) (limited to 'drivers/gpu/drm/drm_mm.c') diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index 07cf99cc8862..9e8dfbc1955e 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c @@ -147,12 +147,10 @@ static void drm_mm_insert_helper(struct drm_mm_node *hole_node, } } -struct drm_mm_node *drm_mm_create_block(struct drm_mm *mm, - unsigned long start, - unsigned long size, - bool atomic) +int drm_mm_create_block(struct drm_mm *mm, struct drm_mm_node *node, + unsigned long start, unsigned long size) { - struct drm_mm_node *hole, *node; + struct drm_mm_node *hole; unsigned long end = start + size; unsigned long hole_start; unsigned long hole_end; @@ -161,10 +159,6 @@ struct drm_mm_node *drm_mm_create_block(struct drm_mm *mm, if (hole_start > start || hole_end < end) continue; - node = drm_mm_kmalloc(mm, atomic); - if (unlikely(node == NULL)) - return NULL; - node->start = start; node->size = size; node->mm = mm; @@ -184,11 +178,11 @@ struct drm_mm_node *drm_mm_create_block(struct drm_mm *mm, node->hole_follows = 1; } - return node; + return 0; } WARN(1, "no hole found for block 0x%lx + 0x%lx\n", start, size); - return NULL; + return -ENOSPC; } EXPORT_SYMBOL(drm_mm_create_block); -- cgit v1.2.3 From 338710e7aff3428dc8170a03704a8ae981b58dcd Mon Sep 17 00:00:00 2001 From: Ben Widawsky Date: Fri, 5 Jul 2013 14:41:03 -0700 Subject: drm: Change create block to reserve node With the previous patch we no longer actually create a node, we simply find the correct hole and occupy it. This very well could have been squashed with the last patch, but since I already had David's review, I figured it's easiest to keep it distinct. Also update the users in i915. Conveniently this is the only user of the interface. CC: David Airlie CC: Signed-off-by: Ben Widawsky Acked-by: David Airlie Signed-off-by: Daniel Vetter --- drivers/gpu/drm/drm_mm.c | 19 ++++++++++--------- drivers/gpu/drm/i915/i915_gem_gtt.c | 8 ++++---- drivers/gpu/drm/i915/i915_gem_stolen.c | 12 +++++++----- include/drm/drm_mm.h | 5 +---- 4 files changed, 22 insertions(+), 22 deletions(-) (limited to 'drivers/gpu/drm/drm_mm.c') diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index 9e8dfbc1955e..52e0ee7f4a6f 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c @@ -147,27 +147,27 @@ static void drm_mm_insert_helper(struct drm_mm_node *hole_node, } } -int drm_mm_create_block(struct drm_mm *mm, struct drm_mm_node *node, - unsigned long start, unsigned long size) +int drm_mm_reserve_node(struct drm_mm *mm, struct drm_mm_node *node) { struct drm_mm_node *hole; - unsigned long end = start + size; + unsigned long end = node->start + node->size; unsigned long hole_start; unsigned long hole_end; + BUG_ON(node == NULL); + + /* Find the relevant hole to add our node to */ drm_mm_for_each_hole(hole, mm, hole_start, hole_end) { - if (hole_start > start || hole_end < end) + if (hole_start > node->start || hole_end < end) continue; - node->start = start; - node->size = size; node->mm = mm; node->allocated = 1; INIT_LIST_HEAD(&node->hole_stack); list_add(&node->node_list, &hole->node_list); - if (start == hole_start) { + if (node->start == hole_start) { hole->hole_follows = 0; list_del_init(&hole->hole_stack); } @@ -181,10 +181,11 @@ int drm_mm_create_block(struct drm_mm *mm, struct drm_mm_node *node, return 0; } - WARN(1, "no hole found for block 0x%lx + 0x%lx\n", start, size); + WARN(1, "no hole found for node 0x%lx + 0x%lx\n", + node->start, node->size); return -ENOSPC; } -EXPORT_SYMBOL(drm_mm_create_block); +EXPORT_SYMBOL(drm_mm_reserve_node); struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *hole_node, unsigned long size, diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 88180a597c0a..afba7e5e7739 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -640,10 +640,10 @@ void i915_gem_setup_global_gtt(struct drm_device *dev, obj->gtt_offset); continue; } - ret = drm_mm_create_block(&dev_priv->mm.gtt_space, - obj->gtt_space, - obj->gtt_offset, - obj->base.size); + obj->gtt_space->start = obj->gtt_offset; + obj->gtt_space->size = obj->base.size; + ret = drm_mm_reserve_node(&dev_priv->mm.gtt_space, + obj->gtt_space); if (ret) { DRM_DEBUG_KMS("Reservation failed\n"); kfree(obj->gtt_space); diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c index 2746ff2d846a..4e6dbbb47dfe 100644 --- a/drivers/gpu/drm/i915/i915_gem_stolen.c +++ b/drivers/gpu/drm/i915/i915_gem_stolen.c @@ -349,8 +349,9 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, if (!stolen) return NULL; - ret = drm_mm_create_block(&dev_priv->mm.stolen, stolen, stolen_offset, - size); + stolen->start = stolen_offset; + stolen->size = size; + ret = drm_mm_reserve_node(&dev_priv->mm.stolen, stolen); if (ret) { DRM_DEBUG_KMS("failed to allocate stolen space\n"); kfree(stolen); @@ -380,9 +381,10 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, goto unref_out; } - ret = drm_mm_create_block(&dev_priv->mm.gtt_space, - obj->gtt_space, - gtt_offset, size); + obj->gtt_space->start = gtt_offset; + obj->gtt_space->size = size; + ret = drm_mm_reserve_node(&dev_priv->mm.gtt_space, + obj->gtt_space); if (ret) { DRM_DEBUG_KMS("failed to allocate stolen GTT space\n"); goto free_out; diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h index d8b56b7d1839..2de91e3da5cc 100644 --- a/include/drm/drm_mm.h +++ b/include/drm/drm_mm.h @@ -138,10 +138,7 @@ static inline unsigned long drm_mm_hole_node_end(struct drm_mm_node *hole_node) /* * Basic range manager support (drm_mm.c) */ -extern int drm_mm_create_block(struct drm_mm *mm, - struct drm_mm_node *node, - unsigned long start, - unsigned long size); +extern int drm_mm_reserve_node(struct drm_mm *mm, struct drm_mm_node *node); extern struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *node, unsigned long size, unsigned alignment, -- cgit v1.2.3