summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2013-01-08 12:08:13 -0800
committerEric Anholt <eric@anholt.net>2013-01-08 14:51:43 -0800
commitcd6fef6a660c35bc109923ff64d5b393b80c1c6b (patch)
tree1c5cf3fe899a833030b2d02ba8266ff0b18e1377
parent50d0324f3f124b1a0bed2b8d137c6c26287eff00 (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.c41
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,