Merge tag 'drm-amdkfd-fixes-2017-11-26' of git://people.freedesktop.org/~gabbayo/linux into drm-fixes
This is amdkfd pull request for -rc2. It contains three small fixes to the CIK SDMA code, compilation error fix in kfd_ioctl.h and fix to accessing a pointer after it was released. * tag 'drm-amdkfd-fixes-2017-11-26' of git://people.freedesktop.org/~gabbayo/linux: uapi: fix linux/kfd_ioctl.h userspace compilation errors drm/amdkfd: fix amdkfd use-after-free GP fault drm/amdkfd: Fix SDMA oversubsription handling drm/amdkfd: Fix SDMA ring buffer size calculation drm/amdgpu: Fix SDMA load/unload sequence on HWS disabled mode
This commit is contained in:
commit
662e704007
drivers/gpu/drm/amd
include/uapi/linux
@ -379,29 +379,50 @@ static int kgd_hqd_sdma_load(struct kgd_dev *kgd, void *mqd)
|
||||
{
|
||||
struct amdgpu_device *adev = get_amdgpu_device(kgd);
|
||||
struct cik_sdma_rlc_registers *m;
|
||||
unsigned long end_jiffies;
|
||||
uint32_t sdma_base_addr;
|
||||
uint32_t data;
|
||||
|
||||
m = get_sdma_mqd(mqd);
|
||||
sdma_base_addr = get_sdma_base_addr(m);
|
||||
|
||||
WREG32(sdma_base_addr + mmSDMA0_RLC0_VIRTUAL_ADDR,
|
||||
m->sdma_rlc_virtual_addr);
|
||||
WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_CNTL,
|
||||
m->sdma_rlc_rb_cntl & (~SDMA0_RLC0_RB_CNTL__RB_ENABLE_MASK));
|
||||
|
||||
WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_BASE,
|
||||
m->sdma_rlc_rb_base);
|
||||
|
||||
WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_BASE_HI,
|
||||
m->sdma_rlc_rb_base_hi);
|
||||
|
||||
WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR_ADDR_LO,
|
||||
m->sdma_rlc_rb_rptr_addr_lo);
|
||||
|
||||
WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR_ADDR_HI,
|
||||
m->sdma_rlc_rb_rptr_addr_hi);
|
||||
end_jiffies = msecs_to_jiffies(2000) + jiffies;
|
||||
while (true) {
|
||||
data = RREG32(sdma_base_addr + mmSDMA0_RLC0_CONTEXT_STATUS);
|
||||
if (data & SDMA0_RLC0_CONTEXT_STATUS__IDLE_MASK)
|
||||
break;
|
||||
if (time_after(jiffies, end_jiffies))
|
||||
return -ETIME;
|
||||
usleep_range(500, 1000);
|
||||
}
|
||||
if (m->sdma_engine_id) {
|
||||
data = RREG32(mmSDMA1_GFX_CONTEXT_CNTL);
|
||||
data = REG_SET_FIELD(data, SDMA1_GFX_CONTEXT_CNTL,
|
||||
RESUME_CTX, 0);
|
||||
WREG32(mmSDMA1_GFX_CONTEXT_CNTL, data);
|
||||
} else {
|
||||
data = RREG32(mmSDMA0_GFX_CONTEXT_CNTL);
|
||||
data = REG_SET_FIELD(data, SDMA0_GFX_CONTEXT_CNTL,
|
||||
RESUME_CTX, 0);
|
||||
WREG32(mmSDMA0_GFX_CONTEXT_CNTL, data);
|
||||
}
|
||||
|
||||
WREG32(sdma_base_addr + mmSDMA0_RLC0_DOORBELL,
|
||||
m->sdma_rlc_doorbell);
|
||||
|
||||
m->sdma_rlc_doorbell);
|
||||
WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR, 0);
|
||||
WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_WPTR, 0);
|
||||
WREG32(sdma_base_addr + mmSDMA0_RLC0_VIRTUAL_ADDR,
|
||||
m->sdma_rlc_virtual_addr);
|
||||
WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_BASE, m->sdma_rlc_rb_base);
|
||||
WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_BASE_HI,
|
||||
m->sdma_rlc_rb_base_hi);
|
||||
WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR_ADDR_LO,
|
||||
m->sdma_rlc_rb_rptr_addr_lo);
|
||||
WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR_ADDR_HI,
|
||||
m->sdma_rlc_rb_rptr_addr_hi);
|
||||
WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_CNTL,
|
||||
m->sdma_rlc_rb_cntl);
|
||||
|
||||
@ -574,9 +595,9 @@ static int kgd_hqd_sdma_destroy(struct kgd_dev *kgd, void *mqd,
|
||||
}
|
||||
|
||||
WREG32(sdma_base_addr + mmSDMA0_RLC0_DOORBELL, 0);
|
||||
WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_RPTR, 0);
|
||||
WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_WPTR, 0);
|
||||
WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_BASE, 0);
|
||||
WREG32(sdma_base_addr + mmSDMA0_RLC0_RB_CNTL,
|
||||
RREG32(sdma_base_addr + mmSDMA0_RLC0_RB_CNTL) |
|
||||
SDMA0_RLC0_RB_CNTL__RB_ENABLE_MASK);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <linux/sched.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/printk.h>
|
||||
#include "kfd_priv.h"
|
||||
|
||||
#define KFD_DRIVER_AUTHOR "AMD Inc. and others"
|
||||
@ -132,7 +133,7 @@ static void __exit kfd_module_exit(void)
|
||||
kfd_process_destroy_wq();
|
||||
kfd_topology_shutdown();
|
||||
kfd_chardev_exit();
|
||||
dev_info(kfd_device, "Removed module\n");
|
||||
pr_info("amdkfd: Removed module\n");
|
||||
}
|
||||
|
||||
module_init(kfd_module_init);
|
||||
|
@ -202,8 +202,8 @@ static int update_mqd_sdma(struct mqd_manager *mm, void *mqd,
|
||||
struct cik_sdma_rlc_registers *m;
|
||||
|
||||
m = get_sdma_mqd(mqd);
|
||||
m->sdma_rlc_rb_cntl = ffs(q->queue_size / sizeof(unsigned int)) <<
|
||||
SDMA0_RLC0_RB_CNTL__RB_SIZE__SHIFT |
|
||||
m->sdma_rlc_rb_cntl = (ffs(q->queue_size / sizeof(unsigned int)) - 1)
|
||||
<< SDMA0_RLC0_RB_CNTL__RB_SIZE__SHIFT |
|
||||
q->vmid << SDMA0_RLC0_RB_CNTL__RB_VMID__SHIFT |
|
||||
1 << SDMA0_RLC0_RB_CNTL__RPTR_WRITEBACK_ENABLE__SHIFT |
|
||||
6 << SDMA0_RLC0_RB_CNTL__RPTR_WRITEBACK_TIMER__SHIFT;
|
||||
|
@ -191,6 +191,24 @@ int pqm_create_queue(struct process_queue_manager *pqm,
|
||||
|
||||
switch (type) {
|
||||
case KFD_QUEUE_TYPE_SDMA:
|
||||
if (dev->dqm->queue_count >=
|
||||
CIK_SDMA_QUEUES_PER_ENGINE * CIK_SDMA_ENGINE_NUM) {
|
||||
pr_err("Over-subscription is not allowed for SDMA.\n");
|
||||
retval = -EPERM;
|
||||
goto err_create_queue;
|
||||
}
|
||||
|
||||
retval = create_cp_queue(pqm, dev, &q, properties, f, *qid);
|
||||
if (retval != 0)
|
||||
goto err_create_queue;
|
||||
pqn->q = q;
|
||||
pqn->kq = NULL;
|
||||
retval = dev->dqm->ops.create_queue(dev->dqm, q, &pdd->qpd,
|
||||
&q->properties.vmid);
|
||||
pr_debug("DQM returned %d for create_queue\n", retval);
|
||||
print_queue(q);
|
||||
break;
|
||||
|
||||
case KFD_QUEUE_TYPE_COMPUTE:
|
||||
/* check if there is over subscription */
|
||||
if ((sched_policy == KFD_SCHED_POLICY_HWS_NO_OVERSUBSCRIPTION) &&
|
||||
|
@ -233,29 +233,29 @@ struct kfd_ioctl_wait_events_args {
|
||||
};
|
||||
|
||||
struct kfd_ioctl_set_scratch_backing_va_args {
|
||||
uint64_t va_addr; /* to KFD */
|
||||
uint32_t gpu_id; /* to KFD */
|
||||
uint32_t pad;
|
||||
__u64 va_addr; /* to KFD */
|
||||
__u32 gpu_id; /* to KFD */
|
||||
__u32 pad;
|
||||
};
|
||||
|
||||
struct kfd_ioctl_get_tile_config_args {
|
||||
/* to KFD: pointer to tile array */
|
||||
uint64_t tile_config_ptr;
|
||||
__u64 tile_config_ptr;
|
||||
/* to KFD: pointer to macro tile array */
|
||||
uint64_t macro_tile_config_ptr;
|
||||
__u64 macro_tile_config_ptr;
|
||||
/* to KFD: array size allocated by user mode
|
||||
* from KFD: array size filled by kernel
|
||||
*/
|
||||
uint32_t num_tile_configs;
|
||||
__u32 num_tile_configs;
|
||||
/* to KFD: array size allocated by user mode
|
||||
* from KFD: array size filled by kernel
|
||||
*/
|
||||
uint32_t num_macro_tile_configs;
|
||||
__u32 num_macro_tile_configs;
|
||||
|
||||
uint32_t gpu_id; /* to KFD */
|
||||
uint32_t gb_addr_config; /* from KFD */
|
||||
uint32_t num_banks; /* from KFD */
|
||||
uint32_t num_ranks; /* from KFD */
|
||||
__u32 gpu_id; /* to KFD */
|
||||
__u32 gb_addr_config; /* from KFD */
|
||||
__u32 num_banks; /* from KFD */
|
||||
__u32 num_ranks; /* from KFD */
|
||||
/* struct size can be extended later if needed
|
||||
* without breaking ABI compatibility
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user