dri-devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: "Christian König" <ckoenig.leichtzumerken-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
To: Andrey Grodzovsky
	<andrey.grodzovsky-5C7GfCeVMHo@public.gmane.org>,
	dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org,
	amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org,
	eric-WhKQ6XTQaPysTnJN9+BGXg@public.gmane.org,
	etnaviv-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org
Cc: david1.zhou-5C7GfCeVMHo@public.gmane.org,
	Monk.Liu-5C7GfCeVMHo@public.gmane.org
Subject: Re: [PATCH v5 1/2] drm/sched: Refactor ring mirror list handling.
Date: Fri, 21 Dec 2018 19:37:01 +0100	[thread overview]
Message-ID: <c62cf367-1485-b1f4-04c2-a11dd8f35416@gmail.com> (raw)
In-Reply-To: <1545333815-29870-1-git-send-email-andrey.grodzovsky-5C7GfCeVMHo@public.gmane.org>

Am 20.12.18 um 20:23 schrieb Andrey Grodzovsky:
> Decauple sched threads stop and start and ring mirror
> list handling from the policy of what to do about the
> guilty jobs.
> When stoppping the sched thread and detaching sched fences
> from non signaled HW fenes wait for all signaled HW fences
> to complete before rerunning the jobs.
>
> v2: Fix resubmission of guilty job into HW after refactoring.
>
> v4:
> Full restart for all the jobs, not only from guilty ring.
> Extract karma increase into standalone function.
>
> v5:
> Rework waiting for signaled jobs without relying on the job
> struct itself as those might already be freed for non 'guilty'
> job's schedulers.
> Expose karma increase to drivers.
>
> Suggested-by: Christian Koenig <Christian.Koenig@amd.com>
> Signed-off-by: Andrey Grodzovsky <andrey.grodzovsky@amd.com>
> ---
>   drivers/gpu/drm/amd/amdgpu/amdgpu_device.c |  18 +--
>   drivers/gpu/drm/etnaviv/etnaviv_sched.c    |  11 +-
>   drivers/gpu/drm/scheduler/sched_main.c     | 188 +++++++++++++++++++----------
>   drivers/gpu/drm/v3d/v3d_sched.c            |  12 +-
>   include/drm/gpu_scheduler.h                |  10 +-
>   5 files changed, 151 insertions(+), 88 deletions(-)
>
> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> index 8a078f4..a4bd2d3 100644
> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
> @@ -3298,12 +3298,10 @@ static int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev,
>   		if (!ring || !ring->sched.thread)
>   			continue;
>   
> -		kthread_park(ring->sched.thread);
> +		drm_sched_stop(&ring->sched, job ? &job->base : NULL);
>   
> -		if (job && job->base.sched != &ring->sched)
> -			continue;
> -
> -		drm_sched_hw_job_reset(&ring->sched, job ? &job->base : NULL);
> +		if(job)
> +			drm_sched_increase_karma(&job->base);

Since we dropped the "job && job->base.sched != &ring->sched" check 
above this will now increase the jobs karma multiple times.

Maybe just move that outside of the loop.

>   
>   		/* after all hw jobs are reset, hw fence is meaningless, so force_completion */
>   		amdgpu_fence_driver_force_completion(ring);
> @@ -3454,14 +3452,10 @@ static void amdgpu_device_post_asic_reset(struct amdgpu_device *adev,
>   		if (!ring || !ring->sched.thread)
>   			continue;
>   
> -		/* only need recovery sched of the given job's ring
> -		 * or all rings (in the case @job is NULL)
> -		 * after above amdgpu_reset accomplished
> -		 */
> -		if ((!job || job->base.sched == &ring->sched) && !adev->asic_reset_res)
> -			drm_sched_job_recovery(&ring->sched);
> +		if (!adev->asic_reset_res)
> +			drm_sched_resubmit_jobs(&ring->sched);
>   
> -		kthread_unpark(ring->sched.thread);
> +		drm_sched_start(&ring->sched, !adev->asic_reset_res);
>   	}
>   
>   	if (!amdgpu_device_has_dc_support(adev)) {
> diff --git a/drivers/gpu/drm/etnaviv/etnaviv_sched.c b/drivers/gpu/drm/etnaviv/etnaviv_sched.c
> index 49a6763..6f1268f 100644
> --- a/drivers/gpu/drm/etnaviv/etnaviv_sched.c
> +++ b/drivers/gpu/drm/etnaviv/etnaviv_sched.c
> @@ -109,16 +109,19 @@ static void etnaviv_sched_timedout_job(struct drm_sched_job *sched_job)
>   	}
>   
>   	/* block scheduler */
> -	kthread_park(gpu->sched.thread);
> -	drm_sched_hw_job_reset(&gpu->sched, sched_job);
> +	drm_sched_stop(&gpu->sched, sched_job);
> +
> +	if(sched_job)
> +		drm_sched_increase_karma(sched_job);
>   
>   	/* get the GPU back into the init state */
>   	etnaviv_core_dump(gpu);
>   	etnaviv_gpu_recover_hang(gpu);
>   
> +	drm_sched_resubmit_jobs(&gpu->sched);
> +
>   	/* restart scheduler after GPU is usable again */
> -	drm_sched_job_recovery(&gpu->sched);
> -	kthread_unpark(gpu->sched.thread);
> +	drm_sched_start(&gpu->sched, true);
>   }
>   
>   static void etnaviv_sched_free_job(struct drm_sched_job *sched_job)
> diff --git a/drivers/gpu/drm/scheduler/sched_main.c b/drivers/gpu/drm/scheduler/sched_main.c
> index dbb6906..b5c5bee 100644
> --- a/drivers/gpu/drm/scheduler/sched_main.c
> +++ b/drivers/gpu/drm/scheduler/sched_main.c
> @@ -60,8 +60,6 @@
>   
>   static void drm_sched_process_job(struct dma_fence *f, struct dma_fence_cb *cb);
>   
> -static void drm_sched_expel_job_unlocked(struct drm_sched_job *s_job);
> -
>   /**
>    * drm_sched_rq_init - initialize a given run queue struct
>    *
> @@ -335,6 +333,42 @@ static void drm_sched_job_timedout(struct work_struct *work)
>   	spin_unlock_irqrestore(&sched->job_list_lock, flags);
>   }
>   

Kernel doc here would be nice to have.

> +void drm_sched_increase_karma(struct drm_sched_job *bad)
> +{
> +	int i;
> +	struct drm_sched_entity *tmp;
> +	struct drm_sched_entity *entity;
> +	struct drm_gpu_scheduler *sched = bad->sched;
> +
> +	/* don't increase @bad's karma if it's from KERNEL RQ,
> +	 * because sometimes GPU hang would cause kernel jobs (like VM updating jobs)
> +	 * corrupt but keep in mind that kernel jobs always considered good.
> +	 */
> +	if (bad->s_priority != DRM_SCHED_PRIORITY_KERNEL) {
> +		atomic_inc(&bad->karma);
> +		for (i = DRM_SCHED_PRIORITY_MIN; i < DRM_SCHED_PRIORITY_KERNEL;
> +		     i++) {
> +			struct drm_sched_rq *rq = &sched->sched_rq[i];
> +
> +			spin_lock(&rq->lock);
> +			list_for_each_entry_safe(entity, tmp, &rq->entities, list) {
> +				if (bad->s_fence->scheduled.context ==
> +				    entity->fence_context) {
> +					if (atomic_read(&bad->karma) >
> +					    bad->sched->hang_limit)
> +						if (entity->guilty)
> +							atomic_set(entity->guilty, 1);
> +					break;
> +				}
> +			}
> +			spin_unlock(&rq->lock);
> +			if (&entity->list != &rq->entities)
> +				break;
> +		}
> +	}
> +}
> +EXPORT_SYMBOL(drm_sched_increase_karma);
> +
>   /**
>    * drm_sched_hw_job_reset - stop the scheduler if it contains the bad job
>    *
> @@ -342,13 +376,22 @@ static void drm_sched_job_timedout(struct work_struct *work)
>    * @bad: bad scheduler job
>    *
>    */
> -void drm_sched_hw_job_reset(struct drm_gpu_scheduler *sched, struct drm_sched_job *bad)
> +void drm_sched_stop(struct drm_gpu_scheduler *sched, struct drm_sched_job *bad)
>   {
> -	struct drm_sched_job *s_job;
> -	struct drm_sched_entity *entity, *tmp;
> +	struct drm_sched_job *s_job, *last_job;
>   	unsigned long flags;
> -	int i;
> +	struct dma_fence *wait_fence =  NULL;
> +	int r;
> +
> +	kthread_park(sched->thread);
>   
> +	/*
> +	 * Verify all the signaled jobs in mirror list are removed from the ring
> +	 * by waiting for their respective scheduler fences to signal.
> +	 * Continually  repeat traversing the ring mirror list until no more signaled
> +	 * fences are found
> +	 */
> +retry_wait:
>   	spin_lock_irqsave(&sched->job_list_lock, flags);
>   	list_for_each_entry_reverse(s_job, &sched->ring_mirror_list, node) {
>   		if (s_job->s_fence->parent &&
> @@ -357,35 +400,45 @@ void drm_sched_hw_job_reset(struct drm_gpu_scheduler *sched, struct drm_sched_jo
>   			dma_fence_put(s_job->s_fence->parent);
>   			s_job->s_fence->parent = NULL;
>   			atomic_dec(&sched->hw_rq_count);
> +		} else {
> +			 wait_fence = dma_fence_get(&s_job->s_fence->finished);
> +			 last_job = s_job;
> +			 break;
>   		}
>   	}
> -	spin_unlock_irqrestore(&sched->job_list_lock, flags);
>   
> -	if (bad && bad->s_priority != DRM_SCHED_PRIORITY_KERNEL) {
> -		atomic_inc(&bad->karma);
> -		/* don't increase @bad's karma if it's from KERNEL RQ,
> -		 * becuase sometimes GPU hang would cause kernel jobs (like VM updating jobs)
> -		 * corrupt but keep in mind that kernel jobs always considered good.
> -		 */
> -		for (i = DRM_SCHED_PRIORITY_MIN; i < DRM_SCHED_PRIORITY_KERNEL; i++ ) {
> -			struct drm_sched_rq *rq = &sched->sched_rq[i];
> +	/* No signaled jobs in the ring, its safe to proceed to ASIC reset */
> +	if (!wait_fence) {
> +		spin_unlock_irqrestore(&sched->job_list_lock, flags);
> +		goto done;
> +	}
>   
> -			spin_lock(&rq->lock);
> -			list_for_each_entry_safe(entity, tmp, &rq->entities, list) {
> -				if (bad->s_fence->scheduled.context == entity->fence_context) {
> -				    if (atomic_read(&bad->karma) > bad->sched->hang_limit)
> -						if (entity->guilty)
> -							atomic_set(entity->guilty, 1);
> -					break;
> -				}
> -			}
> -			spin_unlock(&rq->lock);
> -			if (&entity->list != &rq->entities)
> -				break;
> +	/* Restore removed cb since removing again already removed cb is undefined */
> +	list_for_each_entry_reverse(s_job, &sched->ring_mirror_list, node) {
> +		if(s_job == last_job)
> +			break;

Need to double check after the holidays, but you should be able to use 
list_for_each_entry_continue here.

> +
> +		if (s_job->s_fence->parent) {
> +			r = dma_fence_add_callback(s_job->s_fence->parent,
> +						   &s_job->s_fence->cb,
> +						   drm_sched_process_job);
> +			if (r)
> +				DRM_ERROR("fence restore callback failed (%d)\n",
> +									  r);

When you fail to add the callback this means that you need to call call 
drm_sched_process_job manually here.

>   		}
>   	}
> +	spin_unlock_irqrestore(&sched->job_list_lock, flags);
> +
> +	dma_fence_wait(wait_fence, false);
> +	dma_fence_put(wait_fence);
> +	wait_fence = NULL;
> +
> +	goto retry_wait;
> +
> +done:
> +	return;

Drop the done: label and return directly above.

Apart from all those nit picks that starts to look like it should work,
Christian.

>   }
> -EXPORT_SYMBOL(drm_sched_hw_job_reset);
> +EXPORT_SYMBOL(drm_sched_stop);
>   
>   /**
>    * drm_sched_job_recovery - recover jobs after a reset
> @@ -393,33 +446,21 @@ EXPORT_SYMBOL(drm_sched_hw_job_reset);
>    * @sched: scheduler instance
>    *
>    */
> -void drm_sched_job_recovery(struct drm_gpu_scheduler *sched)
> +void drm_sched_start(struct drm_gpu_scheduler *sched, bool full_recovery)
>   {
>   	struct drm_sched_job *s_job, *tmp;
> -	bool found_guilty = false;
>   	unsigned long flags;
>   	int r;
>   
> +	if (!full_recovery)
> +		goto unpark;
> +
>   	spin_lock_irqsave(&sched->job_list_lock, flags);
>   	list_for_each_entry_safe(s_job, tmp, &sched->ring_mirror_list, node) {
>   		struct drm_sched_fence *s_fence = s_job->s_fence;
> -		struct dma_fence *fence;
> -		uint64_t guilty_context;
> -
> -		if (!found_guilty && atomic_read(&s_job->karma) > sched->hang_limit) {
> -			found_guilty = true;
> -			guilty_context = s_job->s_fence->scheduled.context;
> -		}
> -
> -		if (found_guilty && s_job->s_fence->scheduled.context == guilty_context)
> -			dma_fence_set_error(&s_fence->finished, -ECANCELED);
> -
> -		spin_unlock_irqrestore(&sched->job_list_lock, flags);
> -		fence = sched->ops->run_job(s_job);
> -		atomic_inc(&sched->hw_rq_count);
> +		struct dma_fence *fence = s_job->s_fence->parent;
>   
>   		if (fence) {
> -			s_fence->parent = dma_fence_get(fence);
>   			r = dma_fence_add_callback(fence, &s_fence->cb,
>   						   drm_sched_process_job);
>   			if (r == -ENOENT)
> @@ -427,18 +468,47 @@ void drm_sched_job_recovery(struct drm_gpu_scheduler *sched)
>   			else if (r)
>   				DRM_ERROR("fence add callback failed (%d)\n",
>   					  r);
> -			dma_fence_put(fence);
> -		} else {
> -			if (s_fence->finished.error < 0)
> -				drm_sched_expel_job_unlocked(s_job);
> +		} else
>   			drm_sched_process_job(NULL, &s_fence->cb);
> -		}
> -		spin_lock_irqsave(&sched->job_list_lock, flags);
>   	}
> +
>   	drm_sched_start_timeout(sched);
>   	spin_unlock_irqrestore(&sched->job_list_lock, flags);
> +
> +unpark:
> +	kthread_unpark(sched->thread);
> +}
> +EXPORT_SYMBOL(drm_sched_start);
> +
> +/**
> + * drm_sched_resubmit_jobs - helper to relunch job from mirror ring list
> + *
> + * @sched: scheduler instance
> + *
> + */
> +void drm_sched_resubmit_jobs(struct drm_gpu_scheduler *sched)
> +{
> +	struct drm_sched_job *s_job, *tmp;
> +	uint64_t guilty_context;
> +	bool found_guilty = false;
> +
> +	/*TODO DO we need spinlock here ? */
> +	list_for_each_entry_safe(s_job, tmp, &sched->ring_mirror_list, node) {
> +		struct drm_sched_fence *s_fence = s_job->s_fence;
> +
> +		if (!found_guilty && atomic_read(&s_job->karma) > sched->hang_limit) {
> +			found_guilty = true;
> +			guilty_context = s_job->s_fence->scheduled.context;
> +		}
> +
> +		if (found_guilty && s_job->s_fence->scheduled.context == guilty_context)
> +			dma_fence_set_error(&s_fence->finished, -ECANCELED);
> +
> +		s_job->s_fence->parent = sched->ops->run_job(s_job);
> +		atomic_inc(&sched->hw_rq_count);
> +	}
>   }
> -EXPORT_SYMBOL(drm_sched_job_recovery);
> +EXPORT_SYMBOL(drm_sched_resubmit_jobs);
>   
>   /**
>    * drm_sched_job_init - init a scheduler job
> @@ -634,26 +704,14 @@ static int drm_sched_main(void *param)
>   				DRM_ERROR("fence add callback failed (%d)\n",
>   					  r);
>   			dma_fence_put(fence);
> -		} else {
> -			if (s_fence->finished.error < 0)
> -				drm_sched_expel_job_unlocked(sched_job);
> +		} else
>   			drm_sched_process_job(NULL, &s_fence->cb);
> -		}
>   
>   		wake_up(&sched->job_scheduled);
>   	}
>   	return 0;
>   }
>   
> -static void drm_sched_expel_job_unlocked(struct drm_sched_job *s_job)
> -{
> -	struct drm_gpu_scheduler *sched = s_job->sched;
> -
> -	spin_lock(&sched->job_list_lock);
> -	list_del_init(&s_job->node);
> -	spin_unlock(&sched->job_list_lock);
> -}
> -
>   /**
>    * drm_sched_init - Init a gpu scheduler instance
>    *
> diff --git a/drivers/gpu/drm/v3d/v3d_sched.c b/drivers/gpu/drm/v3d/v3d_sched.c
> index 445b2ef..f76d9ed 100644
> --- a/drivers/gpu/drm/v3d/v3d_sched.c
> +++ b/drivers/gpu/drm/v3d/v3d_sched.c
> @@ -178,18 +178,22 @@ v3d_job_timedout(struct drm_sched_job *sched_job)
>   	for (q = 0; q < V3D_MAX_QUEUES; q++) {
>   		struct drm_gpu_scheduler *sched = &v3d->queue[q].sched;
>   
> -		kthread_park(sched->thread);
> -		drm_sched_hw_job_reset(sched, (sched_job->sched == sched ?
> +		drm_sched_stop(sched, (sched_job->sched == sched ?
>   					       sched_job : NULL));
> +
> +		if(sched_job)
> +			drm_sched_increase_karma(sched_job);
>   	}
>   
>   	/* get the GPU back into the init state */
>   	v3d_reset(v3d);
>   
> +	for (q = 0; q < V3D_MAX_QUEUES; q++)
> +		drm_sched_resubmit_jobs(sched_job->sched);
> +
>   	/* Unblock schedulers and restart their jobs. */
>   	for (q = 0; q < V3D_MAX_QUEUES; q++) {
> -		drm_sched_job_recovery(&v3d->queue[q].sched);
> -		kthread_unpark(v3d->queue[q].sched.thread);
> +		drm_sched_start(&v3d->queue[q].sched, true);
>   	}
>   
>   	mutex_unlock(&v3d->reset_lock);
> diff --git a/include/drm/gpu_scheduler.h b/include/drm/gpu_scheduler.h
> index 47e1979..5ab2d97 100644
> --- a/include/drm/gpu_scheduler.h
> +++ b/include/drm/gpu_scheduler.h
> @@ -175,6 +175,7 @@ struct drm_sched_fence *to_drm_sched_fence(struct dma_fence *f);
>    *               finished to remove the job from the
>    *               @drm_gpu_scheduler.ring_mirror_list.
>    * @node: used to append this struct to the @drm_gpu_scheduler.ring_mirror_list.
> + * @finish_node: used in a list to wait on before resetting the scheduler
>    * @id: a unique id assigned to each job scheduled on the scheduler.
>    * @karma: increment on every hang caused by this job. If this exceeds the hang
>    *         limit of the scheduler then the job is marked guilty and will not
> @@ -193,6 +194,7 @@ struct drm_sched_job {
>   	struct dma_fence_cb		finish_cb;
>   	struct work_struct		finish_work;
>   	struct list_head		node;
> +	struct list_head		finish_node;
>   	uint64_t			id;
>   	atomic_t			karma;
>   	enum drm_sched_priority		s_priority;
> @@ -298,9 +300,11 @@ int drm_sched_job_init(struct drm_sched_job *job,
>   		       void *owner);
>   void drm_sched_job_cleanup(struct drm_sched_job *job);
>   void drm_sched_wakeup(struct drm_gpu_scheduler *sched);
> -void drm_sched_hw_job_reset(struct drm_gpu_scheduler *sched,
> -			    struct drm_sched_job *job);
> -void drm_sched_job_recovery(struct drm_gpu_scheduler *sched);
> +void drm_sched_stop(struct drm_gpu_scheduler *sched,
> +		    struct drm_sched_job *job);
> +void drm_sched_start(struct drm_gpu_scheduler *sched, bool full_recovery);
> +void drm_sched_resubmit_jobs(struct drm_gpu_scheduler *sched);
> +void drm_sched_increase_karma(struct drm_sched_job *bad);
>   bool drm_sched_dependency_optimized(struct dma_fence* fence,
>   				    struct drm_sched_entity *entity);
>   void drm_sched_fault(struct drm_gpu_scheduler *sched);

_______________________________________________
amd-gfx mailing list
amd-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/amd-gfx

  parent reply	other threads:[~2018-12-21 18:37 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-12-20 19:23 [PATCH v5 1/2] drm/sched: Refactor ring mirror list handling Andrey Grodzovsky
     [not found] ` <1545333815-29870-1-git-send-email-andrey.grodzovsky-5C7GfCeVMHo@public.gmane.org>
2018-12-20 19:23   ` [PATCH v5 2/2] drm/sched: Rework HW fence processing Andrey Grodzovsky
2018-12-21 18:37   ` Christian König [this message]
2018-12-21 20:36     ` [PATCH v5 1/2] drm/sched: Refactor ring mirror list handling Grodzovsky, Andrey
     [not found]       ` <fc3e12f7-55e1-bf04-b190-7393e84d22a8-5C7GfCeVMHo@public.gmane.org>
2019-01-03  8:54         ` Koenig, Christian
2019-01-03 16:20           ` Grodzovsky, Andrey
2019-01-03 17:42             ` Grodzovsky, Andrey
2019-01-07 14:13               ` Christian König
2019-01-07 19:47                 ` Grodzovsky, Andrey
     [not found]                   ` <d5a3470a-21a1-adf7-6f85-4d22fae7bb81-5C7GfCeVMHo@public.gmane.org>
2019-01-09 10:22                     ` Christian König
2019-01-09 15:18                       ` Grodzovsky, Andrey
     [not found]                         ` <ea37c55f-ee56-cce7-a4e1-1a599642c54c-5C7GfCeVMHo@public.gmane.org>
2019-01-10 15:56                           ` Grodzovsky, Andrey
     [not found]                             ` <cbd07551-4f5e-fb80-a4ef-376b19bb3655-5C7GfCeVMHo@public.gmane.org>
2019-01-11  9:42                               ` Koenig, Christian
     [not found]                                 ` <37ad8228-355e-1d53-593f-b0cb736eadff-5C7GfCeVMHo@public.gmane.org>
2019-01-11 15:37                                   ` Grodzovsky, Andrey
     [not found]                                     ` <5434e38b-c5c6-26e8-d632-bd1b1b52a44a-5C7GfCeVMHo@public.gmane.org>
2019-01-11 19:11                                       ` Koenig, Christian
     [not found]                                         ` <8a615696-a9ff-7670-5d25-6120282e818b-5C7GfCeVMHo@public.gmane.org>
2019-01-11 22:03                                           ` Grodzovsky, Andrey
     [not found]                                             ` <468f5a41-aa07-2cc2-d7dc-2f6e1d9af7e9-5C7GfCeVMHo@public.gmane.org>
2019-01-15 22:01                                               ` Grodzovsky, Andrey
     [not found]                                                 ` <de7d180d-f959-d8a6-0f99-99906f07e76c-5C7GfCeVMHo@public.gmane.org>
2019-01-16  7:46                                                   ` Christian König
     [not found]                                                     ` <cbacbef0-d82b-1f44-2fd4-87d81d7ce00b-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2019-01-16 15:45                                                       ` Grodzovsky, Andrey
2019-01-16 16:02                                                         ` Koenig, Christian
2019-01-16 17:17                                                           ` Grodzovsky, Andrey
2019-01-17  7:45                                                             ` Christian König
2019-01-17 15:22                                                               ` Grodzovsky, Andrey
     [not found]                                                                 ` <87ecd86c-4bd2-4cb7-0203-7e088e9e150b-5C7GfCeVMHo@public.gmane.org>
2019-01-17 15:29                                                                   ` Koenig, Christian
     [not found]                                                                     ` <3de2a2bd-83cf-590b-e278-590c4907b78b-5C7GfCeVMHo@public.gmane.org>
2019-01-17 16:24                                                                       ` Grodzovsky, Andrey
2019-01-17 22:50                                                                       ` Grodzovsky, Andrey
     [not found]                                                                         ` <13082b0c-d5dc-82c5-56ba-03eb3d301695-5C7GfCeVMHo@public.gmane.org>
2019-01-18  9:25                                                                           ` Koenig, Christian
2019-01-18 15:21                                                                             ` Grodzovsky, Andrey
     [not found]                                                                               ` <99c5c0c7-43c0-152b-0a1a-fba846f8e46f-5C7GfCeVMHo@public.gmane.org>
2019-01-18 17:10                                                                                 ` Koenig, Christian
     [not found]                                                                                   ` <a85762db-c4a0-69c2-1757-b5eca3e87e8f-5C7GfCeVMHo@public.gmane.org>
2019-01-18 17:34                                                                                     ` Grodzovsky, Andrey
2019-01-18 18:32                                                                                       ` Koenig, Christian
     [not found]                                                                                         ` <2c383b45-069e-1498-1b97-d14ac6373c7b-5C7GfCeVMHo@public.gmane.org>
2019-01-18 19:15                                                                                           ` Grodzovsky, Andrey
     [not found]                                                                                             ` <abdcbb70-6080-7669-7939-21cbd0031cbd-5C7GfCeVMHo@public.gmane.org>
2019-01-24 11:34                                                                                               ` Koenig, Christian
2019-01-24 15:29                                                                                                 ` Grodzovsky, Andrey

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=c62cf367-1485-b1f4-04c2-a11dd8f35416@gmail.com \
    --to=ckoenig.leichtzumerken-re5jqeeqqe8avxtiumwx3w@public.gmane.org \
    --cc=Monk.Liu-5C7GfCeVMHo@public.gmane.org \
    --cc=amd-gfx-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org \
    --cc=andrey.grodzovsky-5C7GfCeVMHo@public.gmane.org \
    --cc=christian.koenig-5C7GfCeVMHo@public.gmane.org \
    --cc=david1.zhou-5C7GfCeVMHo@public.gmane.org \
    --cc=dri-devel-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org \
    --cc=eric-WhKQ6XTQaPysTnJN9+BGXg@public.gmane.org \
    --cc=etnaviv-PD4FTy7X32lNgt0PjOBp9y5qC8QIuHrW@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox