|
@@ -288,20 +288,26 @@ static int eb_create(struct i915_execbuffer *eb)
|
|
|
* direct lookup.
|
|
|
*/
|
|
|
do {
|
|
|
+ unsigned int flags;
|
|
|
+
|
|
|
+ /* While we can still reduce the allocation size, don't
|
|
|
+ * raise a warning and allow the allocation to fail.
|
|
|
+ * On the last pass though, we want to try as hard
|
|
|
+ * as possible to perform the allocation and warn
|
|
|
+ * if it fails.
|
|
|
+ */
|
|
|
+ flags = GFP_TEMPORARY;
|
|
|
+ if (size > 1)
|
|
|
+ flags |= __GFP_NORETRY | __GFP_NOWARN;
|
|
|
+
|
|
|
eb->buckets = kzalloc(sizeof(struct hlist_head) << size,
|
|
|
- GFP_TEMPORARY |
|
|
|
- __GFP_NORETRY |
|
|
|
- __GFP_NOWARN);
|
|
|
+ flags);
|
|
|
if (eb->buckets)
|
|
|
break;
|
|
|
} while (--size);
|
|
|
|
|
|
- if (unlikely(!eb->buckets)) {
|
|
|
- eb->buckets = kzalloc(sizeof(struct hlist_head),
|
|
|
- GFP_TEMPORARY);
|
|
|
- if (unlikely(!eb->buckets))
|
|
|
- return -ENOMEM;
|
|
|
- }
|
|
|
+ if (unlikely(!size))
|
|
|
+ return -ENOMEM;
|
|
|
|
|
|
eb->lut_size = size;
|
|
|
} else {
|
|
@@ -452,7 +458,7 @@ eb_add_vma(struct i915_execbuffer *eb,
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
- if (eb->lut_size >= 0) {
|
|
|
+ if (eb->lut_size > 0) {
|
|
|
vma->exec_handle = entry->handle;
|
|
|
hlist_add_head(&vma->exec_node,
|
|
|
&eb->buckets[hash_32(entry->handle,
|
|
@@ -894,7 +900,7 @@ static void eb_release_vmas(const struct i915_execbuffer *eb)
|
|
|
static void eb_reset_vmas(const struct i915_execbuffer *eb)
|
|
|
{
|
|
|
eb_release_vmas(eb);
|
|
|
- if (eb->lut_size >= 0)
|
|
|
+ if (eb->lut_size > 0)
|
|
|
memset(eb->buckets, 0,
|
|
|
sizeof(struct hlist_head) << eb->lut_size);
|
|
|
}
|
|
@@ -903,7 +909,7 @@ static void eb_destroy(const struct i915_execbuffer *eb)
|
|
|
{
|
|
|
GEM_BUG_ON(eb->reloc_cache.rq);
|
|
|
|
|
|
- if (eb->lut_size >= 0)
|
|
|
+ if (eb->lut_size > 0)
|
|
|
kfree(eb->buckets);
|
|
|
}
|
|
|
|
|
@@ -2180,8 +2186,11 @@ i915_gem_do_execbuffer(struct drm_device *dev,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if (eb_create(&eb))
|
|
|
- return -ENOMEM;
|
|
|
+ err = eb_create(&eb);
|
|
|
+ if (err)
|
|
|
+ goto err_out_fence;
|
|
|
+
|
|
|
+ GEM_BUG_ON(!eb.lut_size);
|
|
|
|
|
|
/*
|
|
|
* Take a local wakeref for preparing to dispatch the execbuf as
|
|
@@ -2340,6 +2349,7 @@ err_unlock:
|
|
|
err_rpm:
|
|
|
intel_runtime_pm_put(eb.i915);
|
|
|
eb_destroy(&eb);
|
|
|
+err_out_fence:
|
|
|
if (out_fence_fd != -1)
|
|
|
put_unused_fd(out_fence_fd);
|
|
|
err_in_fence:
|