diff options
author | Eric Anholt <eric@anholt.net> | 2013-01-08 12:08:13 -0800 |
---|---|---|
committer | Eric Anholt <eric@anholt.net> | 2013-01-08 14:51:43 -0800 |
commit | cd6fef6a660c35bc109923ff64d5b393b80c1c6b (patch) | |
tree | 1c5cf3fe899a833030b2d02ba8266ff0b18e1377 | |
parent | 50d0324f3f124b1a0bed2b8d137c6c26287eff00 (diff) |
drm/i915: Look up objects for relocations using the idr.
We know those cachelines are hot because we just looked at them when
looking up the whole object list.
Signed-off-by: Eric Anholt <eric@anholt.net>
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_execbuffer.c | 41 |
1 files changed, 13 insertions, 28 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index f7084ec95fd..3855b61970a 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -69,23 +69,6 @@ eb_add_object(struct eb_objects *eb, struct drm_i915_gem_object *obj) &eb->buckets[obj->exec_handle & eb->and]); } -static struct drm_i915_gem_object * -eb_get_object(struct eb_objects *eb, unsigned long handle) -{ - struct hlist_head *head; - struct hlist_node *node; - struct drm_i915_gem_object *obj; - - head = &eb->buckets[handle & eb->and]; - hlist_for_each(node, head) { - obj = hlist_entry(node, struct drm_i915_gem_object, exec_node); - if (obj->exec_handle == handle) - return obj; - } - - return NULL; -} - static void eb_destroy(struct eb_objects *eb) { @@ -101,7 +84,7 @@ static inline int use_cpu_reloc(struct drm_i915_gem_object *obj) static int i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, - struct eb_objects *eb, + struct drm_file *file, struct drm_i915_gem_relocation_entry *reloc) { struct drm_device *dev = obj->base.dev; @@ -110,8 +93,10 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, uint32_t target_offset; int ret = -EINVAL; - /* we've already hold a reference to all valid objects */ - target_obj = &eb_get_object(eb, reloc->target_handle)->base; + /* Note that objects can't disappear from the idr while we + * hold the struct_mutex, and thus can't be unreferenced. + */ + target_obj = idr_find(&file->object_idr, reloc->target_handle); if (unlikely(target_obj == NULL)) return -ENOENT; @@ -225,7 +210,7 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, static int i915_gem_execbuffer_relocate_object(struct drm_i915_gem_object *obj, - struct eb_objects *eb) + struct drm_file *file) { #define N_RELOC(x) ((x) / sizeof(struct drm_i915_gem_relocation_entry)) struct drm_i915_gem_relocation_entry stack_reloc[N_RELOC(512)]; @@ -249,7 +234,7 @@ i915_gem_execbuffer_relocate_object(struct drm_i915_gem_object *obj, do { u64 offset = r->presumed_offset; - ret = i915_gem_execbuffer_relocate_entry(obj, eb, r); + ret = i915_gem_execbuffer_relocate_entry(obj, file, r); if (ret) return ret; @@ -271,14 +256,14 @@ i915_gem_execbuffer_relocate_object(struct drm_i915_gem_object *obj, static int i915_gem_execbuffer_relocate_object_slow(struct drm_i915_gem_object *obj, - struct eb_objects *eb, + struct drm_file *file, struct drm_i915_gem_relocation_entry *relocs) { const struct drm_i915_gem_exec_object2 *entry = obj->exec_entry; int i, ret; for (i = 0; i < entry->relocation_count; i++) { - ret = i915_gem_execbuffer_relocate_entry(obj, eb, &relocs[i]); + ret = i915_gem_execbuffer_relocate_entry(obj, file, &relocs[i]); if (ret) return ret; } @@ -288,7 +273,7 @@ i915_gem_execbuffer_relocate_object_slow(struct drm_i915_gem_object *obj, static int i915_gem_execbuffer_relocate(struct drm_device *dev, - struct eb_objects *eb, + struct drm_file *file, struct list_head *objects) { struct drm_i915_gem_object *obj; @@ -303,7 +288,7 @@ i915_gem_execbuffer_relocate(struct drm_device *dev, */ pagefault_disable(); list_for_each_entry(obj, objects, exec_list) { - ret = i915_gem_execbuffer_relocate_object(obj, eb); + ret = i915_gem_execbuffer_relocate_object(obj, file); if (ret) break; } @@ -572,7 +557,7 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, list_for_each_entry(obj, objects, exec_list) { int offset = obj->exec_entry - exec; - ret = i915_gem_execbuffer_relocate_object_slow(obj, eb, + ret = i915_gem_execbuffer_relocate_object_slow(obj, file, reloc + reloc_offset[offset]); if (ret) goto err; @@ -908,7 +893,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, goto err; /* The objects are in their final locations, apply the relocations. */ - ret = i915_gem_execbuffer_relocate(dev, eb, &objects); + ret = i915_gem_execbuffer_relocate(dev, file, &objects); if (ret) { if (ret == -EFAULT) { ret = i915_gem_execbuffer_relocate_slow(dev, file, ring, |