[Intel-gfx] [PATCH 17/17] drm/i915: Use rt priority kthread to do GuC log buffer sampling

Goel, Akash akash.goel at intel.com
Thu Jul 21 06:18:38 UTC 2016



On 7/21/2016 11:13 AM, Chris Wilson wrote:
> On Thu, Jul 21, 2016 at 09:11:42AM +0530, Goel, Akash wrote:
>>
>>
>> On 7/21/2016 1:04 AM, Chris Wilson wrote:
>>> In the end, just the silly locking and placement of complete_all() is
>>> dangerous. reinit_completion() lacks the barrier to be used like this
>>> really, at any rate, racy with the irq handler, so use sparingly or when
>>> you control the irq handler.
>> Sorry I forgot to add a comment that
>> guc_cancel_log_flush_work_sync() should be invoked only after
>> ensuring that there will be no more flush interrupts, which will
>> happen either by explicitly disabling the interrupt or disabling the
>> logging and that's what is done at the 2 call sites.
>>
>> Since had covered reinit_completion() under the irq_lock, thought an
>> explicit barrier is not needed.
>
> You hadn't controlled everything via the irq_lock, and nor should you.
>
>>
>> 	spin_lock_irq(&dev_priv->irq_lock);
>> 	if (guc->log.flush_signal) {
>> 		guc->log.flush_signal = false;
>> 		reinit_completion(&guc->log.flush_completion);
>> 		spin_unlock_irq(&dev_priv->irq_lock);
>> 		i915_guc_capture_logs(&dev_priv->drm);
>> 	 	complete_all(&guc->log.flush_completion);
>>
>> The placement of complete_all isn't right for the case, where
>> a guc_cancel_log_flush_work_sync() is called but there was no prior
>> flush interrupt received.
>
> Exactly.
>
>>> (Also not sure if log.signal = 0 is sane,
>> Did log.signal = 0 for fast cancellation. Will remove that.
>>
>> A smp_wmb() after reinit_completion(&flush_completion) would be fine ?
>
> Don't worry, the race can only be controlled by controlling the irq.


> In the end, I think something more like
>
> 	while (signal) ...
>
> 	complete_all();
> 	schedule();
> 	reinit_completion();
>
> is the simplest.
Thanks much, so will have the task body like this.
do {
	set_current_state(TASK_INT);
	while (cmpxchg(&log.signal, 1, 0)) {
		i915_guc_capture_logs();
	};
	complete_all(log.complete);
	if (kthread_should_stop())
		break;
	schedule();
	reinit_completion();
} while(1);

>
>>> or the current callsites really require the flush.)
>>
>> Sync against a ongoing/pending flush is being done for the 2
>> forceful flush cases, which will be effective only if the pending
>> flush is completed, so forceful flush should be serialized with a
>> pending flush.
>
> Or you just signal=true, wakeup task, wait_timeout. Otherwise you
> haven't really serialized anything without disabling the interrupt.
Agree without disabling the interrupt, serialization cannot be provided,

For the sync can use,
{
	WARN_ON(guc->interrupts_enabled);
	wait_for_completion_interruptible_timeout(
			guc->log.complete, 5 /* in jiffies*/);
}


Best regards
Akash
> -Chris
>


More information about the Intel-gfx mailing list