<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  </head>
  <body>
    On 8/11/2023 11:20, Zhanjun Dong wrote:<br>
    <blockquote type="cite" cite="mid:20230811182011.546026-1-zhanjun.dong@intel.com">
      <pre class="moz-quote-pre" wrap="">This attempts to avoid circular locking dependency between flush delayed
work and intel_gt_reset.
When intel_gt_reset was called, task will hold a lock.
To cacel delayed work here, the _sync version will also acquire a lock,
which might trigger the possible cirular locking dependency warning.
When intel_gt_reset called, reset_in_progress flag will be set, add code
to check the flag, call async verion if reset is in progress.

Signed-off-by: Zhanjun Dong <a class="moz-txt-link-rfc2396E" href="mailto:zhanjun.dong@intel.com"><zhanjun.dong@intel.com></a>
Cc: John Harrison <a class="moz-txt-link-rfc2396E" href="mailto:John.C.Harrison@Intel.com"><John.C.Harrison@Intel.com></a>
Cc: Andi Shyti <a class="moz-txt-link-rfc2396E" href="mailto:andi.shyti@linux.intel.com"><andi.shyti@linux.intel.com></a>
Cc: Daniel Vetter <a class="moz-txt-link-rfc2396E" href="mailto:daniel@ffwll.ch"><daniel@ffwll.ch></a>
---
 drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
index a0e3ef1c65d2..600388c849f7 100644
--- a/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
+++ b/drivers/gpu/drm/i915/gt/uc/intel_guc_submission.c
@@ -1359,7 +1359,16 @@ static void guc_enable_busyness_worker(struct intel_guc *guc)
 
 static void guc_cancel_busyness_worker(struct intel_guc *guc)
 {
-       cancel_delayed_work_sync(&guc->timestamp.work);
+       /*
+        * When intel_gt_reset was called, task will hold a lock.
+        * To cacel delayed work here, the _sync version will also acquire a lock, which might
+        * trigger the possible cirular locking dependency warning.
+        * Check the reset_in_progress flag, call async verion if reset is in progress.
+        */</pre>
    </blockquote>
    This needs to explain in much more detail what is going on and why
    it is not a problem. E.g.:<br>
    <blockquote>The busyness worker needs to be cancelled. In general
      that means using the synchronous cancel version to ensure that an
      in-progress worker will not keep executing beyond whatever is
      happening that needs the cancel. E.g. suspend, driver unload, etc.
      However, in the case of a reset, the synchronous version is not
      required and can trigger a false deadlock detection warning.<br>
      <br>
      The business worker takes the reset mutex to protect against
      resets interfering with it. However, it does a trylock and bails
      out if the reset lock is already acquired. Thus there is no actual
      deadlock or other concern with the worker running concurrently
      with a reset. So an asynchronous cancel is safe in the case of a
      reset rather than a driver unload or suspend type operation. On
      the other hand, if the cancel_sync version is used when a reset is
      in progress then the mutex deadlock detection sees the mutex being
      acquired through multiple paths and complains.<br>
      <br>
      So just don't bother. That keeps the detection code happy and is
      safe because of the trylock code described above.<br>
    </blockquote>
    <br>
    John.<br>
    <br>
    <br>
    <blockquote type="cite" cite="mid:20230811182011.546026-1-zhanjun.dong@intel.com">
      <pre class="moz-quote-pre" wrap="">
+       if (guc_to_gt(guc)->uc.reset_in_progress)
+               cancel_delayed_work(&guc->timestamp.work);
+       else
+               cancel_delayed_work_sync(&guc->timestamp.work);
 }
 
 static void __reset_guc_busyness_stats(struct intel_guc *guc)
</pre>
    </blockquote>
    <br>
  </body>
</html>