History

drm/i915/gem: Defer obj->base.resv fini until RCU callback

Since reservation_object_fini() does an immediate free, rather than kfree_rcu as normal, we have to delay the release until after the RCU grace period has elapsed (i.e. from the rcu cleanup callback) so that we can rely on the RCU protected access to the fences while the object is a zombie. i915_gem_busy_ioctl relies on having an RCU barrier to protect the reservation in order to avoid having to take a reference and strong memory barriers. v2: Order is important; only release after putting the pages!

Chris Wilson committed 7 years ago

Commit 0c159ff1 parent 21de5a94 files · +12 −13Browse files

Unified · Split

4 files
  1. drivers/gpu/drm/i915/gem/i915_gem_object.c +5 −4
  2. drivers/gpu/drm/i915/gem/i915_gem_phys.c +0 −7
  3. drivers/gpu/drm/i915/gem/i915_gem_shmem.c +7 −0
  4. drivers/gpu/drm/i915/gem/i915_gem_stolen.c +0 −2
drivers/gpu/drm/i915/gem/i915_gem_object.c+5−4
@@ -152,6 +152,7 @@ static void __i915_gem_free_object_rcu(struct rcu_head *head) · 151 unmodified lines
152152 container_of(head, typeof(*obj), rcu);
153153 struct drm_i915_private *i915 = to_i915(obj->base.dev);
154154
155+ reservation_object_fini(&obj->base._resv);
155156 i915_gem_object_free(obj);
156157
157158 GEM_BUG_ON(!atomic_read(&i915->mm.free_count));
@@ -187,9 +188,6 @@ static void __i915_gem_free_objects(struct drm_i915_private *i915, · 29 unmodified lines
187188 GEM_BUG_ON(atomic_read(&obj->frontbuffer_bits));
188189 GEM_BUG_ON(!list_empty(&obj->lut_list));
189190
190− if (obj->ops->release)
191− obj->ops->release(obj);
192−
193191 atomic_set(&obj->mm.pages_pin_count, 0);
194192 __i915_gem_object_put_pages(obj, I915_MM_NORMAL);
195193 GEM_BUG_ON(i915_gem_object_has_pages(obj));
@@ -198,7 +196,10 @@ static void __i915_gem_free_objects(struct drm_i915_private *i915, · 2 unmodified lines
198196 if (obj->base.import_attach)
199197 drm_prime_gem_destroy(&obj->base, NULL);
200198
201− drm_gem_object_release(&obj->base);
199+ drm_gem_free_mmap_offset(&obj->base);
200+
201+ if (obj->ops->release)
202+ obj->ops->release(obj);
202203
203204 /* But keep the pointer alive for RCU-protected lookups */
204205 call_rcu(&obj->rcu, __i915_gem_free_object_rcu);
drivers/gpu/drm/i915/gem/i915_gem_phys.c+0−7
@@ -133,16 +133,9 @@ i915_gem_object_put_pages_phys(struct drm_i915_gem_object *obj, · 132 unmodified lines
133133 drm_pci_free(obj->base.dev, obj->phys_handle);
134134 }
135135
136−static void
137−i915_gem_object_release_phys(struct drm_i915_gem_object *obj)
138−{
139− i915_gem_object_unpin_pages(obj);
140−}
141−
142136 static const struct drm_i915_gem_object_ops i915_gem_phys_ops = {
143137 .get_pages = i915_gem_object_get_pages_phys,
144138 .put_pages = i915_gem_object_put_pages_phys,
145− .release = i915_gem_object_release_phys,
146139 };
147140
148141 int i915_gem_object_attach_phys(struct drm_i915_gem_object *obj, int align)
drivers/gpu/drm/i915/gem/i915_gem_shmem.c+7−0
@@ -414,6 +414,11 @@ shmem_pwrite(struct drm_i915_gem_object *obj, · 413 unmodified lines
414414 return 0;
415415 }
416416
417+static void shmem_release(struct drm_i915_gem_object *obj)
418+{
419+ fput(obj->base.filp);
420+}
421+
417422 const struct drm_i915_gem_object_ops i915_gem_shmem_ops = {
418423 .flags = I915_GEM_OBJECT_HAS_STRUCT_PAGE |
419424 I915_GEM_OBJECT_IS_SHRINKABLE,
@@ -424,6 +429,8 @@ const struct drm_i915_gem_object_ops i915_gem_shmem_ops = { · 4 unmodified lines
424429 .writeback = shmem_writeback,
425430
426431 .pwrite = shmem_pwrite,
432+
433+ .release = shmem_release,
427434 };
428435
429436 static int create_shmem(struct drm_i915_private *i915,
drivers/gpu/drm/i915/gem/i915_gem_stolen.c+0−2
@@ -529,8 +529,6 @@ i915_gem_object_release_stolen(struct drm_i915_gem_object *obj) · 528 unmodified lines
529529
530530 GEM_BUG_ON(!stolen);
531531
532− __i915_gem_object_unpin_pages(obj);
533−
534532 i915_gem_stolen_remove_node(dev_priv, stolen);
535533 kfree(stolen);
536534 }