[RFC v2 07/20] drm/i915: pre-alloc instead of drm_mm search/get_block
David Herrmann
dh.herrmann at gmail.com
Sun Jul 7 10:17:23 PDT 2013
i915 is the last user of the weird search+get_block drm_mm API. Convert it
to an explicit kmalloc()+insert_node().
Signed-off-by: David Herrmann <dh.herrmann at gmail.com>
---
drivers/gpu/drm/i915/i915_gem.c | 9 +++--
drivers/gpu/drm/i915/i915_gem_stolen.c | 72 ++++++++++++++++++++++------------
2 files changed, 53 insertions(+), 28 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 324f3c5..f7c3b09 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2628,7 +2628,8 @@ i915_gem_object_unbind(struct drm_i915_gem_object *obj)
/* Avoid an unnecessary call to unbind on rebind. */
obj->map_and_fenceable = true;
- drm_mm_put_block(obj->gtt_space);
+ drm_mm_remove_node(obj->gtt_space);
+ kfree(obj->gtt_space);
obj->gtt_space = NULL;
obj->gtt_offset = 0;
@@ -3146,14 +3147,16 @@ search_free:
}
if (WARN_ON(!i915_gem_valid_gtt_space(dev, node, obj->cache_level))) {
i915_gem_object_unpin_pages(obj);
- drm_mm_put_block(node);
+ drm_mm_remove_node(node);
+ kfree(node);
return -EINVAL;
}
ret = i915_gem_gtt_prepare_object(obj);
if (ret) {
i915_gem_object_unpin_pages(obj);
- drm_mm_put_block(node);
+ drm_mm_remove_node(node);
+ kfree(node);
return ret;
}
diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c
index 982d473..820e78f 100644
--- a/drivers/gpu/drm/i915/i915_gem_stolen.c
+++ b/drivers/gpu/drm/i915/i915_gem_stolen.c
@@ -95,31 +95,39 @@ static int i915_setup_compression(struct drm_device *dev, int size)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_mm_node *compressed_fb, *uninitialized_var(compressed_llb);
+ int ret;
- /* Try to over-allocate to reduce reallocations and fragmentation */
- compressed_fb = drm_mm_search_free(&dev_priv->mm.stolen,
- size <<= 1, 4096, 0);
- if (!compressed_fb)
- compressed_fb = drm_mm_search_free(&dev_priv->mm.stolen,
- size >>= 1, 4096, 0);
- if (compressed_fb)
- compressed_fb = drm_mm_get_block(compressed_fb, size, 4096);
+ compressed_fb = kzalloc(sizeof(*compressed_fb), GFP_KERNEL);
if (!compressed_fb)
goto err;
+ /* Try to over-allocate to reduce reallocations and fragmentation */
+ ret = drm_mm_insert_node(&dev_priv->mm.stolen, compressed_fb,
+ size <<= 1, 4096, false);
+ if (ret)
+ ret = drm_mm_insert_node(&dev_priv->mm.stolen, compressed_fb,
+ size >>= 1, 4096, false);
+ if (ret) {
+ kfree(compressed_fb);
+ goto err;
+ }
+
if (HAS_PCH_SPLIT(dev))
I915_WRITE(ILK_DPFC_CB_BASE, compressed_fb->start);
else if (IS_GM45(dev)) {
I915_WRITE(DPFC_CB_BASE, compressed_fb->start);
} else {
- compressed_llb = drm_mm_search_free(&dev_priv->mm.stolen,
- 4096, 4096, 0);
- if (compressed_llb)
- compressed_llb = drm_mm_get_block(compressed_llb,
- 4096, 4096);
+ compressed_llb = kzalloc(sizeof(*compressed_llb), GFP_KERNEL);
if (!compressed_llb)
goto err_fb;
+ ret = drm_mm_insert_node(&dev_priv->mm.stolen, compressed_llb,
+ 4096, 4096, false);
+ if (ret) {
+ kfree(compressed_llb);
+ goto err_fb;
+ }
+
dev_priv->compressed_llb = compressed_llb;
I915_WRITE(FBC_CFB_BASE,
@@ -137,7 +145,8 @@ static int i915_setup_compression(struct drm_device *dev, int size)
return 0;
err_fb:
- drm_mm_put_block(compressed_fb);
+ drm_mm_remove_node(compressed_fb);
+ kfree(compressed_fb);
err:
pr_info_once("drm: not enough stolen space for compressed buffer (need %d more bytes), disabling. Hint: you may be able to increase stolen memory size in the BIOS to avoid this.\n", size);
return -ENOSPC;
@@ -166,11 +175,15 @@ void i915_gem_stolen_cleanup_compression(struct drm_device *dev)
if (dev_priv->cfb_size == 0)
return;
- if (dev_priv->compressed_fb)
- drm_mm_put_block(dev_priv->compressed_fb);
+ if (dev_priv->compressed_fb) {
+ drm_mm_remove_node(dev_priv->compressed_fb);
+ kfree(dev_priv->compressed_fb);
+ }
- if (dev_priv->compressed_llb)
- drm_mm_put_block(dev_priv->compressed_llb);
+ if (dev_priv->compressed_llb) {
+ drm_mm_remove_node(dev_priv->compressed_llb);
+ kfree(dev_priv->compressed_llb);
+ }
dev_priv->cfb_size = 0;
}
@@ -302,6 +315,7 @@ i915_gem_object_create_stolen(struct drm_device *dev, u32 size)
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_i915_gem_object *obj;
struct drm_mm_node *stolen;
+ int ret;
if (!drm_mm_initialized(&dev_priv->mm.stolen))
return NULL;
@@ -310,17 +324,23 @@ i915_gem_object_create_stolen(struct drm_device *dev, u32 size)
if (size == 0)
return NULL;
- stolen = drm_mm_search_free(&dev_priv->mm.stolen, size, 4096, 0);
- if (stolen)
- stolen = drm_mm_get_block(stolen, size, 4096);
- if (stolen == NULL)
+ stolen = kzalloc(sizeof(*stolen), GFP_KERNEL);
+ if (!stolen)
return NULL;
+ ret = drm_mm_insert_node(&dev_priv->mm.stolen, stolen, size,
+ 4096, false);
+ if (ret) {
+ kfree(stolen);
+ return NULL;
+ }
+
obj = _i915_gem_object_create_stolen(dev, stolen);
if (obj)
return obj;
- drm_mm_put_block(stolen);
+ drm_mm_remove_node(stolen);
+ kfree(stolen);
return NULL;
}
@@ -358,7 +378,8 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev,
obj = _i915_gem_object_create_stolen(dev, stolen);
if (obj == NULL) {
DRM_DEBUG_KMS("failed to allocate stolen object\n");
- drm_mm_put_block(stolen);
+ drm_mm_remove_node(stolen);
+ kfree(stolen);
return NULL;
}
@@ -396,7 +417,8 @@ void
i915_gem_object_release_stolen(struct drm_i915_gem_object *obj)
{
if (obj->stolen) {
- drm_mm_put_block(obj->stolen);
+ drm_mm_remove_node(obj->stolen);
+ kfree(obj->stolen);
obj->stolen = NULL;
}
}
--
1.8.3.2
More information about the dri-devel
mailing list