mirror of https://gitee.com/openkylin/linux.git
drm/i915: Fix unsafe loop iteration over vma whilst unbinding them
On non-LLC platforms, when changing the cache level of an object, we may
need to unbind it so that prefetching across page boundaries does not
cross into a different memory domain. This requires us to unbind
conflicting vma, but we did so iterating over the objects vma in an
unsafe manner (as the list was being modified as we iterated).
The regression was introduced in
commit 3089c6f239
Author: Ben Widawsky <ben@bwidawsk.net>
Date: Wed Jul 31 17:00:03 2013 -0700
drm/i915: make caching operate on all address spaces
apparently as far back as v3.12-rc1, but it has only just begun to
trigger real world bug reports.
Reported-and-tested-by: Nikolay Martynov <mar.kolya@gmail.com>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=76384
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Ben Widawsky <ben@bwidawsk.net>
Cc: stable@vger.kernel.org
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This commit is contained in:
parent
4726e0b045
commit
df6f783a4e
|
@ -3467,7 +3467,7 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj,
|
||||||
enum i915_cache_level cache_level)
|
enum i915_cache_level cache_level)
|
||||||
{
|
{
|
||||||
struct drm_device *dev = obj->base.dev;
|
struct drm_device *dev = obj->base.dev;
|
||||||
struct i915_vma *vma;
|
struct i915_vma *vma, *next;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (obj->cache_level == cache_level)
|
if (obj->cache_level == cache_level)
|
||||||
|
@ -3478,7 +3478,7 @@ int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj,
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
list_for_each_entry(vma, &obj->vma_list, vma_link) {
|
list_for_each_entry_safe(vma, next, &obj->vma_list, vma_link) {
|
||||||
if (!i915_gem_valid_gtt_space(dev, &vma->node, cache_level)) {
|
if (!i915_gem_valid_gtt_space(dev, &vma->node, cache_level)) {
|
||||||
ret = i915_vma_unbind(vma);
|
ret = i915_vma_unbind(vma);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
Loading…
Reference in New Issue