From 1365aa6266fad0669487240af3f098593796172c Mon Sep 17 00:00:00 2001 From: Oded Gabbay Date: Tue, 17 Feb 2015 11:58:27 +0200 Subject: [PATCH 1/2] drm/amdkfd: Initialize only amdkfd's assigned pipelines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch fixes a bug in the initialization of the pipelines. The init_pipelines() function was called with a constant value of 0 in the first_pipe argument. This is an error because amdkfd doesn't handle pipe 0. The correct way is to pass the value that get_first_pipe() returns as the argument for first_pipe. This bug appeared in 3.19 (first version with amdkfd) and it causes around 15% drop in CPU performance of Kaveri (A10-7850). v2: Don't set get_first_pipe() as inline because it calls BUG_ON() Signed-off-by: Oded Gabbay Cc: stable@vger.kernel.org Tested-by: Michel Dänzer --- drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 4 ++-- drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h | 1 + drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_cik.c | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index b3589d0e39b9..1b58f331afee 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -62,9 +62,9 @@ enum KFD_MQD_TYPE get_mqd_type_from_queue_type(enum kfd_queue_type type) return KFD_MQD_TYPE_CP; } -static inline unsigned int get_first_pipe(struct device_queue_manager *dqm) +unsigned int get_first_pipe(struct device_queue_manager *dqm) { - BUG_ON(!dqm); + BUG_ON(!dqm || !dqm->dev); return dqm->dev->shared_resources.first_compute_pipe; } diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h index d64f86cda34f..386bd7df7c30 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h @@ -163,6 +163,7 @@ void program_sh_mem_settings(struct device_queue_manager *dqm, struct qcm_process_device *qpd); int init_pipelines(struct device_queue_manager *dqm, unsigned int pipes_num, unsigned int first_pipe); +unsigned int get_first_pipe(struct device_queue_manager *dqm); extern inline unsigned int get_sh_mem_bases_32(struct kfd_process_device *pdd) { diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_cik.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_cik.c index 6b072466e2a6..5469efe0523e 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_cik.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_cik.c @@ -131,5 +131,5 @@ static int register_process_cik(struct device_queue_manager *dqm, static int initialize_cpsch_cik(struct device_queue_manager *dqm) { - return init_pipelines(dqm, get_pipes_num(dqm), 0); + return init_pipelines(dqm, get_pipes_num(dqm), get_first_pipe(dqm)); } From 64ea8f4af57cee9f8b0bf542819b41ee82acfcb9 Mon Sep 17 00:00:00 2001 From: Oded Gabbay Date: Tue, 17 Feb 2015 11:30:31 +0200 Subject: [PATCH 2/2] drm/amdkfd: don't set get_pipes_num() as inline get_pipes_num() calls BUG_ON so we can't set it as inline because it produces a warning as BUG_ON() uses static variables when it is expanded. Signed-off-by: Oded Gabbay --- drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | 6 ++++++ drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h | 7 +------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index 1b58f331afee..910ff8ab9c9c 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c @@ -68,6 +68,12 @@ unsigned int get_first_pipe(struct device_queue_manager *dqm) return dqm->dev->shared_resources.first_compute_pipe; } +unsigned int get_pipes_num(struct device_queue_manager *dqm) +{ + BUG_ON(!dqm || !dqm->dev); + return dqm->dev->shared_resources.compute_pipe_count; +} + static inline unsigned int get_pipes_num_cpsch(void) { return PIPE_PER_ME_CP_SCHEDULING; diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h index 386bd7df7c30..488f51d19427 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h @@ -164,6 +164,7 @@ void program_sh_mem_settings(struct device_queue_manager *dqm, int init_pipelines(struct device_queue_manager *dqm, unsigned int pipes_num, unsigned int first_pipe); unsigned int get_first_pipe(struct device_queue_manager *dqm); +unsigned int get_pipes_num(struct device_queue_manager *dqm); extern inline unsigned int get_sh_mem_bases_32(struct kfd_process_device *pdd) { @@ -176,10 +177,4 @@ get_sh_mem_bases_nybble_64(struct kfd_process_device *pdd) return (pdd->lds_base >> 60) & 0x0E; } -extern inline unsigned int get_pipes_num(struct device_queue_manager *dqm) -{ - BUG_ON(!dqm || !dqm->dev); - return dqm->dev->shared_resources.compute_pipe_count; -} - #endif /* KFD_DEVICE_QUEUE_MANAGER_H_ */