[Intel-gfx] [PATCH 1/7] drm/i915: Lift runtime-pm acquire callbacks out of intel_wakeref.mutex
Nirmoy Das
nirmoy.das at intel.com
Wed Sep 20 15:41:46 UTC 2023
Hi Jani,
On 9/20/2023 11:03 AM, Jani Nikula wrote:
> On Mon, 18 Sep 2023, Nirmoy Das <nirmoy.das at intel.com> wrote:
>> From: Chris Wilson <chris.p.wilson at intel.com>
>>
>> When runtime pm is first woken, it will synchronously call the
>> registered callbacks for the device. These callbacks
>> may pull in their own forest of locks, which we do not want to
>> conflate with the intel_wakeref.mutex. A second minor benefit to
>> reducing the coverage of the mutex, is that it will reduce
>> contention for frequent sleeps and wakes (such as when being used
>> for soft-rc6).
>>
>> Signed-off-by: Chris Wilson <chris.p.wilson at intel.com>
>> Signed-off-by: Nirmoy Das <nirmoy.das at intel.com>
>> Reviewed-by: Andi Shyti <andi.shyti at linux.intel.com>
> Is this patch a dependency on the subsequent patches in the series? If
> yes, what's the rationale?
When we do GGTT update with gpu request, we need to take pm wakeref for
GT as well as for the engine and
without this patch/improvement there will be lockdep warning as we are
not allowed to alloc memory with
vm->mutex held which can happen when the runtime pm woken up 1st.
> If not, please submit separately. None of
> this is is obvious in the commit messages.
So I would like to keep this patch in the series. I will add rationale
in the cover letter and
resend with your below suggestions.
Thanks,
Nirmoy
>
>> ---
>> drivers/gpu/drm/i915/intel_wakeref.c | 43 ++++++++++++++--------------
>> 1 file changed, 21 insertions(+), 22 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/i915/intel_wakeref.c b/drivers/gpu/drm/i915/intel_wakeref.c
>> index 718f2f1b6174..af7b4cb5b4d7 100644
>> --- a/drivers/gpu/drm/i915/intel_wakeref.c
>> +++ b/drivers/gpu/drm/i915/intel_wakeref.c
>> @@ -10,21 +10,11 @@
>> #include "intel_wakeref.h"
>> #include "i915_drv.h"
>>
>> -static void rpm_get(struct intel_wakeref *wf)
>> -{
>> - wf->wakeref = intel_runtime_pm_get(&wf->i915->runtime_pm);
>> -}
>> -
>> -static void rpm_put(struct intel_wakeref *wf)
>> -{
>> - intel_wakeref_t wakeref = fetch_and_zero(&wf->wakeref);
>> -
>> - intel_runtime_pm_put(&wf->i915->runtime_pm, wakeref);
>> - INTEL_WAKEREF_BUG_ON(!wakeref);
>> -}
>> -
>> int __intel_wakeref_get_first(struct intel_wakeref *wf)
>> {
>> + intel_wakeref_t wakeref = intel_runtime_pm_get(&wf->i915->runtime_pm);
> No non-trivial function calls in the initializer please.
>
>> + int err = 0;
> Until now err was only for handling error returns. If it's also for
> returning success, it should probably be named ret.
>
>> +
>> /*
>> * Treat get/put as different subclasses, as we may need to run
>> * the put callback from under the shrinker and do not want to
>> @@ -32,41 +22,50 @@ int __intel_wakeref_get_first(struct intel_wakeref *wf)
>> * upon acquiring the wakeref.
>> */
>> mutex_lock_nested(&wf->mutex, SINGLE_DEPTH_NESTING);
>> - if (!atomic_read(&wf->count)) {
>> - int err;
>>
>> - rpm_get(wf);
>> + if (likely(!atomic_read(&wf->count))) {
> Adding the likely should be a separate patch with rationale, not a
> random drive-by change. (And maybe it just should not be added at all.)
>
>> + INTEL_WAKEREF_BUG_ON(wf->wakeref);
>> + wf->wakeref = fetch_and_zero(&wakeref);
> fetch_and_zero() should just die. All it does here is make things more
> confusing, not less. Please don't add new users.
>
> The get and put helpers could probably stay, modified, to make this more
> readable.
>
>>
>> err = wf->ops->get(wf);
>> if (unlikely(err)) {
>> - rpm_put(wf);
>> - mutex_unlock(&wf->mutex);
>> - return err;
>> + wakeref = xchg(&wf->wakeref, 0);
>> + wake_up_var(&wf->wakeref);
> e.g. here this bit is duplicated in ____intel_wakeref_put_last().
>
>> + goto unlock;
>> }
>>
>> smp_mb__before_atomic(); /* release wf->count */
>> }
>> atomic_inc(&wf->count);
>> + INTEL_WAKEREF_BUG_ON(atomic_read(&wf->count) <= 0);
>> +
>> +unlock:
>> mutex_unlock(&wf->mutex);
>> + if (unlikely(wakeref))
>> + intel_runtime_pm_put(&wf->i915->runtime_pm, wakeref);
>>
>> - INTEL_WAKEREF_BUG_ON(atomic_read(&wf->count) <= 0);
>> - return 0;
>> + return err;
>> }
>>
>> static void ____intel_wakeref_put_last(struct intel_wakeref *wf)
>> {
>> + intel_wakeref_t wakeref = 0;
>> +
>> INTEL_WAKEREF_BUG_ON(atomic_read(&wf->count) <= 0);
>> if (unlikely(!atomic_dec_and_test(&wf->count)))
>> goto unlock;
>>
>> /* ops->put() must reschedule its own release on error/deferral */
>> if (likely(!wf->ops->put(wf))) {
>> - rpm_put(wf);
>> + INTEL_WAKEREF_BUG_ON(!wf->wakeref);
>> + wakeref = xchg(&wf->wakeref, 0);
>> wake_up_var(&wf->wakeref);
>> }
>>
>> unlock:
>> mutex_unlock(&wf->mutex);
>> + if (wakeref)
>> + intel_runtime_pm_put(&wf->i915->runtime_pm, wakeref);
>> }
>>
>> void __intel_wakeref_put_last(struct intel_wakeref *wf, unsigned long flags)
More information about the Intel-gfx
mailing list