Hi Shaoyun, You'd need to squash these 3 patches into 1 because otherwise you break the build. But I think there should be a way to do this without requiring an interface change. In kgd_hqd_load you could remember the pipe_id and queue_id of the HIQ somewhere in adev. Then you can use that to detect when the HIQ is destroyed later without looking at the MQD. Regards, Felix On 17-07-18 05:42 PM, Shaoyun Liu wrote: > Change-Id: Ibc3ae5ac852405b77908bc26f899fe97bde88d86 > Signed-off-by: Shaoyun Liu <Shaoyun.Liu at amd.com> > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c | 4 ++-- > drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c | 15 +++++++++++++-- > drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c | 16 ++++++++++++++-- > 3 files changed, 29 insertions(+), 6 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c > index fc3cd2b..13a595c 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v7.c > @@ -123,7 +123,7 @@ static int kgd_hqd_sdma_dump(struct kgd_dev *kgd, > static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address, > uint32_t pipe_id, uint32_t queue_id); > static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd); > -static int kgd_hqd_destroy(struct kgd_dev *kgd, > +static int kgd_hqd_destroy(struct kgd_dev *kgd,void *mqd, > enum kfd_preempt_type reset_type, > unsigned int utimeout, uint32_t pipe_id, > uint32_t queue_id); > @@ -586,7 +586,7 @@ static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd) > return false; > } > > -static int kgd_hqd_destroy(struct kgd_dev *kgd, > +static int kgd_hqd_destroy(struct kgd_dev *kgd, void *mqd, > enum kfd_preempt_type reset_type, > unsigned int utimeout, uint32_t pipe_id, > uint32_t queue_id) > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c > index ea08ce7..5fa2f8e 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v8.c > @@ -95,7 +95,7 @@ static int kgd_hqd_sdma_dump(struct kgd_dev *kgd, > static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address, > uint32_t pipe_id, uint32_t queue_id); > static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd); > -static int kgd_hqd_destroy(struct kgd_dev *kgd, > +static int kgd_hqd_destroy(struct kgd_dev *kgd, void *mqd, > enum kfd_preempt_type reset_type, > unsigned int utimeout, uint32_t pipe_id, > uint32_t queue_id); > @@ -609,7 +609,7 @@ static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd) > return false; > } > > -static int kgd_hqd_destroy(struct kgd_dev *kgd, > +static int kgd_hqd_destroy(struct kgd_dev *kgd, void *mqd, > enum kfd_preempt_type reset_type, > unsigned int utimeout, uint32_t pipe_id, > uint32_t queue_id) > @@ -619,9 +619,20 @@ static int kgd_hqd_destroy(struct kgd_dev *kgd, > enum hqd_dequeue_request_type type; > unsigned long flags, end_jiffies; > int retry; > + struct vi_mqd *m; > + > + m = get_mqd(mqd); > > acquire_queue(kgd, pipe_id, queue_id); > > + if (m->cp_hqd_vmid == 0) { > + uint32_t value; > + > + value = RREG32(mmRLC_CP_SCHEDULERS); > + value = REG_SET_FIELD(value, RLC_CP_SCHEDULERS, scheduler1, 0); > + WREG32(mmRLC_CP_SCHEDULERS, value); > + } > + > switch (reset_type) { > case KFD_PREEMPT_TYPE_WAVEFRONT_DRAIN: > type = DRAIN_PIPE; > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c > index 280ccf5..d47cdff 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gfx_v9.c > @@ -132,7 +132,7 @@ static int kgd_hqd_sdma_dump(struct kgd_dev *kgd, > static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address, > uint32_t pipe_id, uint32_t queue_id); > static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd); > -static int kgd_hqd_destroy(struct kgd_dev *kgd, > +static int kgd_hqd_destroy(struct kgd_dev *kgd, void *mqd, > enum kfd_preempt_type reset_type, > unsigned int utimeout, uint32_t pipe_id, > uint32_t queue_id); > @@ -746,7 +746,7 @@ static bool kgd_hqd_sdma_is_occupied(struct kgd_dev *kgd, void *mqd) > return false; > } > > -static int kgd_hqd_destroy(struct kgd_dev *kgd, > +static int kgd_hqd_destroy(struct kgd_dev *kgd, void *mqd, > enum kfd_preempt_type reset_type, > unsigned int utimeout, uint32_t pipe_id, > uint32_t queue_id) > @@ -754,14 +754,26 @@ static int kgd_hqd_destroy(struct kgd_dev *kgd, > struct amdgpu_device *adev = get_amdgpu_device(kgd); > enum hqd_dequeue_request_type type; > unsigned long end_jiffies; > + struct v9_mqd *m; > uint32_t temp; > + > #if 0 > unsigned long flags; > int retry; > #endif > + m = get_mqd(mqd); > > acquire_queue(kgd, pipe_id, queue_id); > > + if (m->cp_hqd_vmid == 0) { > + uint32_t value; > + > + value = RREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_CP_SCHEDULERS)); > + value = REG_SET_FIELD(value, RLC_CP_SCHEDULERS, scheduler1, 0); > + WREG32(SOC15_REG_OFFSET(GC, 0, mmRLC_CP_SCHEDULERS), value); > + } > + > + > switch (reset_type) { > case KFD_PREEMPT_TYPE_WAVEFRONT_DRAIN: > type = DRAIN_PIPE;