diff options
author | David Herrmann <dh.herrmann@gmail.com> | 2013-07-27 10:21:27 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2013-08-06 20:16:26 -0400 |
commit | 06e78edff18195f8e416e6961fea7d88118a5c63 (patch) | |
tree | 4caa1d1f5463b5d760c0cc94fb54c1ae13ef68d9 /drivers/gpu/drm/i915/i915_gem_stolen.c | |
parent | 78af329a85bee7dd4671c67abfecde37b0057b10 (diff) |
drm/i915: pre-alloc instead of drm_mm search/get_block
i915 is the last user of the weird search+get_block drm_mm API. Convert it
to an explicit kmalloc()+insert_node(). This drops the last user of the
node-cache in drm_mm. We can remove it now in a follow-up patch.
v2:
- simplify error path in i915_setup_compression()
v3:
- simplify error path even more
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem_stolen.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_stolen.c | 78 |
1 files changed, 47 insertions, 31 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_stolen.c b/drivers/gpu/drm/i915/i915_gem_stolen.c index e3551706f4ff..a3d1a125b5e0 100644 --- a/drivers/gpu/drm/i915/i915_gem_stolen.c +++ b/drivers/gpu/drm/i915/i915_gem_stolen.c | |||
@@ -112,34 +112,36 @@ static int i915_setup_compression(struct drm_device *dev, int size) | |||
112 | { | 112 | { |
113 | struct drm_i915_private *dev_priv = dev->dev_private; | 113 | struct drm_i915_private *dev_priv = dev->dev_private; |
114 | struct drm_mm_node *compressed_fb, *uninitialized_var(compressed_llb); | 114 | struct drm_mm_node *compressed_fb, *uninitialized_var(compressed_llb); |
115 | int ret; | ||
115 | 116 | ||
116 | /* Try to over-allocate to reduce reallocations and fragmentation */ | 117 | compressed_fb = kzalloc(sizeof(*compressed_fb), GFP_KERNEL); |
117 | compressed_fb = drm_mm_search_free(&dev_priv->mm.stolen, | ||
118 | size <<= 1, 4096, | ||
119 | DRM_MM_SEARCH_DEFAULT); | ||
120 | if (!compressed_fb) | ||
121 | compressed_fb = drm_mm_search_free(&dev_priv->mm.stolen, | ||
122 | size >>= 1, 4096, | ||
123 | DRM_MM_SEARCH_DEFAULT); | ||
124 | if (compressed_fb) | ||
125 | compressed_fb = drm_mm_get_block(compressed_fb, size, 4096); | ||
126 | if (!compressed_fb) | 118 | if (!compressed_fb) |
127 | goto err; | 119 | goto err_llb; |
120 | |||
121 | /* Try to over-allocate to reduce reallocations and fragmentation */ | ||
122 | ret = drm_mm_insert_node(&dev_priv->mm.stolen, compressed_fb, | ||
123 | size <<= 1, 4096, DRM_MM_SEARCH_DEFAULT); | ||
124 | if (ret) | ||
125 | ret = drm_mm_insert_node(&dev_priv->mm.stolen, compressed_fb, | ||
126 | size >>= 1, 4096, | ||
127 | DRM_MM_SEARCH_DEFAULT); | ||
128 | if (ret) | ||
129 | goto err_llb; | ||
128 | 130 | ||
129 | if (HAS_PCH_SPLIT(dev)) | 131 | if (HAS_PCH_SPLIT(dev)) |
130 | I915_WRITE(ILK_DPFC_CB_BASE, compressed_fb->start); | 132 | I915_WRITE(ILK_DPFC_CB_BASE, compressed_fb->start); |
131 | else if (IS_GM45(dev)) { | 133 | else if (IS_GM45(dev)) { |
132 | I915_WRITE(DPFC_CB_BASE, compressed_fb->start); | 134 | I915_WRITE(DPFC_CB_BASE, compressed_fb->start); |
133 | } else { | 135 | } else { |
134 | compressed_llb = drm_mm_search_free(&dev_priv->mm.stolen, | 136 | compressed_llb = kzalloc(sizeof(*compressed_llb), GFP_KERNEL); |
135 | 4096, 4096, | ||
136 | DRM_MM_SEARCH_DEFAULT); | ||
137 | if (compressed_llb) | ||
138 | compressed_llb = drm_mm_get_block(compressed_llb, | ||
139 | 4096, 4096); | ||
140 | if (!compressed_llb) | 137 | if (!compressed_llb) |
141 | goto err_fb; | 138 | goto err_fb; |
142 | 139 | ||
140 | ret = drm_mm_insert_node(&dev_priv->mm.stolen, compressed_llb, | ||
141 | 4096, 4096, DRM_MM_SEARCH_DEFAULT); | ||
142 | if (ret) | ||
143 | goto err_fb; | ||
144 | |||
143 | dev_priv->fbc.compressed_llb = compressed_llb; | 145 | dev_priv->fbc.compressed_llb = compressed_llb; |
144 | 146 | ||
145 | I915_WRITE(FBC_CFB_BASE, | 147 | I915_WRITE(FBC_CFB_BASE, |
@@ -157,8 +159,10 @@ static int i915_setup_compression(struct drm_device *dev, int size) | |||
157 | return 0; | 159 | return 0; |
158 | 160 | ||
159 | err_fb: | 161 | err_fb: |
160 | drm_mm_put_block(compressed_fb); | 162 | kfree(compressed_llb); |
161 | err: | 163 | drm_mm_remove_node(compressed_fb); |
164 | err_llb: | ||
165 | kfree(compressed_fb); | ||
162 | 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); | 166 | 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); |
163 | return -ENOSPC; | 167 | return -ENOSPC; |
164 | } | 168 | } |
@@ -186,11 +190,15 @@ void i915_gem_stolen_cleanup_compression(struct drm_device *dev) | |||
186 | if (dev_priv->fbc.size == 0) | 190 | if (dev_priv->fbc.size == 0) |
187 | return; | 191 | return; |
188 | 192 | ||
189 | if (dev_priv->fbc.compressed_fb) | 193 | if (dev_priv->fbc.compressed_fb) { |
190 | drm_mm_put_block(dev_priv->fbc.compressed_fb); | 194 | drm_mm_remove_node(dev_priv->fbc.compressed_fb); |
195 | kfree(dev_priv->fbc.compressed_fb); | ||
196 | } | ||
191 | 197 | ||
192 | if (dev_priv->fbc.compressed_llb) | 198 | if (dev_priv->fbc.compressed_llb) { |
193 | drm_mm_put_block(dev_priv->fbc.compressed_llb); | 199 | drm_mm_remove_node(dev_priv->fbc.compressed_llb); |
200 | kfree(dev_priv->fbc.compressed_llb); | ||
201 | } | ||
194 | 202 | ||
195 | dev_priv->fbc.size = 0; | 203 | dev_priv->fbc.size = 0; |
196 | } | 204 | } |
@@ -323,6 +331,7 @@ i915_gem_object_create_stolen(struct drm_device *dev, u32 size) | |||
323 | struct drm_i915_private *dev_priv = dev->dev_private; | 331 | struct drm_i915_private *dev_priv = dev->dev_private; |
324 | struct drm_i915_gem_object *obj; | 332 | struct drm_i915_gem_object *obj; |
325 | struct drm_mm_node *stolen; | 333 | struct drm_mm_node *stolen; |
334 | int ret; | ||
326 | 335 | ||
327 | if (!drm_mm_initialized(&dev_priv->mm.stolen)) | 336 | if (!drm_mm_initialized(&dev_priv->mm.stolen)) |
328 | return NULL; | 337 | return NULL; |
@@ -331,18 +340,23 @@ i915_gem_object_create_stolen(struct drm_device *dev, u32 size) | |||
331 | if (size == 0) | 340 | if (size == 0) |
332 | return NULL; | 341 | return NULL; |
333 | 342 | ||
334 | stolen = drm_mm_search_free(&dev_priv->mm.stolen, size, 4096, | 343 | stolen = kzalloc(sizeof(*stolen), GFP_KERNEL); |
335 | DRM_MM_SEARCH_DEFAULT); | 344 | if (!stolen) |
336 | if (stolen) | ||
337 | stolen = drm_mm_get_block(stolen, size, 4096); | ||
338 | if (stolen == NULL) | ||
339 | return NULL; | 345 | return NULL; |
340 | 346 | ||
347 | ret = drm_mm_insert_node(&dev_priv->mm.stolen, stolen, size, | ||
348 | 4096, DRM_MM_SEARCH_DEFAULT); | ||
349 | if (ret) { | ||
350 | kfree(stolen); | ||
351 | return NULL; | ||
352 | } | ||
353 | |||
341 | obj = _i915_gem_object_create_stolen(dev, stolen); | 354 | obj = _i915_gem_object_create_stolen(dev, stolen); |
342 | if (obj) | 355 | if (obj) |
343 | return obj; | 356 | return obj; |
344 | 357 | ||
345 | drm_mm_put_block(stolen); | 358 | drm_mm_remove_node(stolen); |
359 | kfree(stolen); | ||
346 | return NULL; | 360 | return NULL; |
347 | } | 361 | } |
348 | 362 | ||
@@ -386,7 +400,8 @@ i915_gem_object_create_stolen_for_preallocated(struct drm_device *dev, | |||
386 | obj = _i915_gem_object_create_stolen(dev, stolen); | 400 | obj = _i915_gem_object_create_stolen(dev, stolen); |
387 | if (obj == NULL) { | 401 | if (obj == NULL) { |
388 | DRM_DEBUG_KMS("failed to allocate stolen object\n"); | 402 | DRM_DEBUG_KMS("failed to allocate stolen object\n"); |
389 | drm_mm_put_block(stolen); | 403 | drm_mm_remove_node(stolen); |
404 | kfree(stolen); | ||
390 | return NULL; | 405 | return NULL; |
391 | } | 406 | } |
392 | 407 | ||
@@ -426,7 +441,8 @@ void | |||
426 | i915_gem_object_release_stolen(struct drm_i915_gem_object *obj) | 441 | i915_gem_object_release_stolen(struct drm_i915_gem_object *obj) |
427 | { | 442 | { |
428 | if (obj->stolen) { | 443 | if (obj->stolen) { |
429 | drm_mm_put_block(obj->stolen); | 444 | drm_mm_remove_node(obj->stolen); |
445 | kfree(obj->stolen); | ||
430 | obj->stolen = NULL; | 446 | obj->stolen = NULL; |
431 | } | 447 | } |
432 | } | 448 | } |