提交 5a8cf90d 编写于 作者: C Chris Wilson 提交者: Jani Nikula

drm/i915: Drain the freed state from the tail of the next commit

If we have any residual freed atomic state from earlier commits, flush
the freed list after performing the current modeset. This prevents the
freed list from ever-growing if userspace manages to starve the kernel
threads (i.e. we are never able to run our free state worker and
eventually the system may even oom).

Fixes: 6f0f02dc ("drm/i915: Move atomic state free from out of fence release")
Testcase: igt/kms_cursor/legacy/all-pipes-single-bo
Reported-by: NMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
Signed-off-by: NChris Wilson <chris@chris-wilson.co.uk>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Daniel Vetter <daniel.vetter@ffwll.ch>
Link: http://patchwork.freedesktop.org/patch/msgid/20170202204741.18231-1-chris@chris-wilson.co.ukReviewed-by: NMaarten Lankhorst <maarten.lankhorst@linux.intel.com>
(cherry picked from commit ba318c61)
Signed-off-by: NJani Nikula <jani.nikula@intel.com>
上级 edd06b83
......@@ -14369,6 +14369,24 @@ static void skl_update_crtcs(struct drm_atomic_state *state,
} while (progress);
}
static void intel_atomic_helper_free_state(struct drm_i915_private *dev_priv)
{
struct intel_atomic_state *state, *next;
struct llist_node *freed;
freed = llist_del_all(&dev_priv->atomic_helper.free_list);
llist_for_each_entry_safe(state, next, freed, freed)
drm_atomic_state_put(&state->base);
}
static void intel_atomic_helper_free_state_worker(struct work_struct *work)
{
struct drm_i915_private *dev_priv =
container_of(work, typeof(*dev_priv), atomic_helper.free_work);
intel_atomic_helper_free_state(dev_priv);
}
static void intel_atomic_commit_tail(struct drm_atomic_state *state)
{
struct drm_device *dev = state->dev;
......@@ -14535,6 +14553,8 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state)
* can happen also when the device is completely off.
*/
intel_uncore_arm_unclaimed_mmio_detection(dev_priv);
intel_atomic_helper_free_state(dev_priv);
}
static void intel_atomic_commit_work(struct work_struct *work)
......@@ -16591,18 +16611,6 @@ static void sanitize_watermarks(struct drm_device *dev)
drm_modeset_acquire_fini(&ctx);
}
static void intel_atomic_helper_free_state(struct work_struct *work)
{
struct drm_i915_private *dev_priv =
container_of(work, typeof(*dev_priv), atomic_helper.free_work);
struct intel_atomic_state *state, *next;
struct llist_node *freed;
freed = llist_del_all(&dev_priv->atomic_helper.free_list);
llist_for_each_entry_safe(state, next, freed, freed)
drm_atomic_state_put(&state->base);
}
int intel_modeset_init(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = to_i915(dev);
......@@ -16623,7 +16631,7 @@ int intel_modeset_init(struct drm_device *dev)
dev->mode_config.funcs = &intel_mode_funcs;
INIT_WORK(&dev_priv->atomic_helper.free_work,
intel_atomic_helper_free_state);
intel_atomic_helper_free_state_worker);
intel_init_quirks(dev);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册