diff options
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem_execbuffer.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_execbuffer.c | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index b7e787fb4649..a3ba9a8cd687 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c | |||
@@ -93,7 +93,7 @@ eb_lookup_vmas(struct eb_vmas *eb, | |||
93 | { | 93 | { |
94 | struct drm_i915_gem_object *obj; | 94 | struct drm_i915_gem_object *obj; |
95 | struct list_head objects; | 95 | struct list_head objects; |
96 | int i, ret = 0; | 96 | int i, ret; |
97 | 97 | ||
98 | INIT_LIST_HEAD(&objects); | 98 | INIT_LIST_HEAD(&objects); |
99 | spin_lock(&file->table_lock); | 99 | spin_lock(&file->table_lock); |
@@ -106,7 +106,7 @@ eb_lookup_vmas(struct eb_vmas *eb, | |||
106 | DRM_DEBUG("Invalid object handle %d at index %d\n", | 106 | DRM_DEBUG("Invalid object handle %d at index %d\n", |
107 | exec[i].handle, i); | 107 | exec[i].handle, i); |
108 | ret = -ENOENT; | 108 | ret = -ENOENT; |
109 | goto out; | 109 | goto err; |
110 | } | 110 | } |
111 | 111 | ||
112 | if (!list_empty(&obj->obj_exec_link)) { | 112 | if (!list_empty(&obj->obj_exec_link)) { |
@@ -114,7 +114,7 @@ eb_lookup_vmas(struct eb_vmas *eb, | |||
114 | DRM_DEBUG("Object %p [handle %d, index %d] appears more than once in object list\n", | 114 | DRM_DEBUG("Object %p [handle %d, index %d] appears more than once in object list\n", |
115 | obj, exec[i].handle, i); | 115 | obj, exec[i].handle, i); |
116 | ret = -EINVAL; | 116 | ret = -EINVAL; |
117 | goto out; | 117 | goto err; |
118 | } | 118 | } |
119 | 119 | ||
120 | drm_gem_object_reference(&obj->base); | 120 | drm_gem_object_reference(&obj->base); |
@@ -123,9 +123,13 @@ eb_lookup_vmas(struct eb_vmas *eb, | |||
123 | spin_unlock(&file->table_lock); | 123 | spin_unlock(&file->table_lock); |
124 | 124 | ||
125 | i = 0; | 125 | i = 0; |
126 | list_for_each_entry(obj, &objects, obj_exec_link) { | 126 | while (!list_empty(&objects)) { |
127 | struct i915_vma *vma; | 127 | struct i915_vma *vma; |
128 | 128 | ||
129 | obj = list_first_entry(&objects, | ||
130 | struct drm_i915_gem_object, | ||
131 | obj_exec_link); | ||
132 | |||
129 | /* | 133 | /* |
130 | * NOTE: We can leak any vmas created here when something fails | 134 | * NOTE: We can leak any vmas created here when something fails |
131 | * later on. But that's no issue since vma_unbind can deal with | 135 | * later on. But that's no issue since vma_unbind can deal with |
@@ -138,10 +142,12 @@ eb_lookup_vmas(struct eb_vmas *eb, | |||
138 | if (IS_ERR(vma)) { | 142 | if (IS_ERR(vma)) { |
139 | DRM_DEBUG("Failed to lookup VMA\n"); | 143 | DRM_DEBUG("Failed to lookup VMA\n"); |
140 | ret = PTR_ERR(vma); | 144 | ret = PTR_ERR(vma); |
141 | goto out; | 145 | goto err; |
142 | } | 146 | } |
143 | 147 | ||
148 | /* Transfer ownership from the objects list to the vmas list. */ | ||
144 | list_add_tail(&vma->exec_list, &eb->vmas); | 149 | list_add_tail(&vma->exec_list, &eb->vmas); |
150 | list_del_init(&obj->obj_exec_link); | ||
145 | 151 | ||
146 | vma->exec_entry = &exec[i]; | 152 | vma->exec_entry = &exec[i]; |
147 | if (eb->and < 0) { | 153 | if (eb->and < 0) { |
@@ -155,16 +161,22 @@ eb_lookup_vmas(struct eb_vmas *eb, | |||
155 | ++i; | 161 | ++i; |
156 | } | 162 | } |
157 | 163 | ||
164 | return 0; | ||
165 | |||
158 | 166 | ||
159 | out: | 167 | err: |
160 | while (!list_empty(&objects)) { | 168 | while (!list_empty(&objects)) { |
161 | obj = list_first_entry(&objects, | 169 | obj = list_first_entry(&objects, |
162 | struct drm_i915_gem_object, | 170 | struct drm_i915_gem_object, |
163 | obj_exec_link); | 171 | obj_exec_link); |
164 | list_del_init(&obj->obj_exec_link); | 172 | list_del_init(&obj->obj_exec_link); |
165 | if (ret) | 173 | drm_gem_object_unreference(&obj->base); |
166 | drm_gem_object_unreference(&obj->base); | ||
167 | } | 174 | } |
175 | /* | ||
176 | * Objects already transfered to the vmas list will be unreferenced by | ||
177 | * eb_destroy. | ||
178 | */ | ||
179 | |||
168 | return ret; | 180 | return ret; |
169 | } | 181 | } |
170 | 182 | ||