Commit 30ca6365 authored by Imre Deak's avatar Imre Deak

drm/i915: Fix assert on pending async-put power domain work when it requeues itself

Commit dd839aa8 ("drm/i915: Fix incorrect assert about pending power domain async-put work")

fixed the assert about a pending work dropping a display power reference
asynchronously, leading to the

drm_WARN_ON(!queue_delayed_work(&power_domains->async_put_work));

warn next time around a power reference was put asynchronously, due to a
stale instance of the work still being pending. However the fix didn't
consider the case where multiple power reference was acquired and put,
requiring the work to requeue itself. Extend the fix for this case as
well canceling the pending instance of the work before it requeues
itself.

Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/10915Signed-off-by: default avatarImre Deak <imre.deak@intel.com>
Reviewed-by: default avatarJouni Högander <jouni.hogander@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240530105312.1016485-1-imre.deak@intel.com
parent b330568f
...@@ -675,6 +675,12 @@ intel_display_power_put_async_work(struct work_struct *work) ...@@ -675,6 +675,12 @@ intel_display_power_put_async_work(struct work_struct *work)
release_async_put_domains(power_domains, release_async_put_domains(power_domains,
&power_domains->async_put_domains[0]); &power_domains->async_put_domains[0]);
/*
* Cancel the work that got queued after this one got dequeued,
* since here we released the corresponding async-put reference.
*/
cancel_async_put_work(power_domains, false);
/* Requeue the work if more domains were async put meanwhile. */ /* Requeue the work if more domains were async put meanwhile. */
if (!bitmap_empty(power_domains->async_put_domains[1].bits, POWER_DOMAIN_NUM)) { if (!bitmap_empty(power_domains->async_put_domains[1].bits, POWER_DOMAIN_NUM)) {
bitmap_copy(power_domains->async_put_domains[0].bits, bitmap_copy(power_domains->async_put_domains[0].bits,
...@@ -686,12 +692,6 @@ intel_display_power_put_async_work(struct work_struct *work) ...@@ -686,12 +692,6 @@ intel_display_power_put_async_work(struct work_struct *work)
fetch_and_zero(&new_work_wakeref), fetch_and_zero(&new_work_wakeref),
power_domains->async_put_next_delay); power_domains->async_put_next_delay);
power_domains->async_put_next_delay = 0; power_domains->async_put_next_delay = 0;
} else {
/*
* Cancel the work that got queued after this one got dequeued,
* since here we released the corresponding async-put reference.
*/
cancel_async_put_work(power_domains, false);
} }
out_verify: out_verify:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment