Skip to content

Commit

Permalink
Merge tag 'drm-amdkfd-next-2017-11-02' of git://people.freedesktop.or…
Browse files Browse the repository at this point in the history
…g/~gabbayo/linux into drm-next

- Usermode Events
The current events code implemented some data structures (waitqueue, fifo)
that were already implemented in the kernel. The patches below addresses
this issue by replacing them with the standard kernel implementation.
In addition, they simplify allocation of events IDs and memory for the events.

The patches also increase the maximum number of events while maintaining
compatibility with the older userspace library.

- Remove radeon support
Because Kaveri is fully supported in amdgpu and because current and future
versions of userspace libraries will only support amdgpu, we removed radeon
support from kfd. Current users can move to amdgpu while using the same
userspace libraries.

- Various bug fixes and cleanups

* tag 'drm-amdkfd-next-2017-11-02' of git://people.freedesktop.org/~gabbayo/linux: (26 commits)
  drm/amdkfd: Minor cleanups
  drm/amdkfd: Update queue_count before mapping queues
  drm/amdkfd: Cleanup DQM ASIC-specific ops
  drm/amdkfd: Register/Deregister process on qpd resolution
  drm/amdkfd: Fix debug unregister procedure on process termination
  drm/amdkfd: Avoid calling amd_iommu_unbind_pasid() when suspending
  drm/amdkfd: Disable CP/SDMA ring/doorbell in MQD
  drm/amdkfd: Clean up the data structure in kfd_process
  drm/radeon: deprecate and remove KFD interface
  drm/amdkfd: use a high priority workqueue for IH work
  drm/amdkfd: wait only for IH work on IH exit
  drm/amdkfd: increase IH num entries to 8192
  drm/amdkfd: use standard kernel kfifo for IH
  drm/amdkfd: increase limit of signal events to 4096 per process
  drm/amdkfd: Make event limit dependent on user mode mapping size
  drm/amdkfd: Use IH context ID for signal lookup
  drm/amdkfd: Simplify event ID and signal slot management
  drm/amdkfd: Simplify events page allocator
  drm/amdkfd: Use wait_queue_t to implement event waiting
  drm/amdkfd: remove redundant kfd_event_waiter.input_index
  ...
  • Loading branch information
Dave Airlie committed Nov 2, 2017
2 parents 85f6e0f + 894a829 commit 9ad472e
Show file tree
Hide file tree
Showing 27 changed files with 450 additions and 1,544 deletions.
2 changes: 0 additions & 2 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -759,8 +759,6 @@ F: drivers/gpu/drm/amd/amdkfd/
F: drivers/gpu/drm/amd/include/cik_structs.h
F: drivers/gpu/drm/amd/include/kgd_kfd_interface.h
F: drivers/gpu/drm/amd/include/vi_structs.h
F: drivers/gpu/drm/radeon/radeon_kfd.c
F: drivers/gpu/drm/radeon/radeon_kfd.h
F: include/uapi/linux/kfd_ioctl.h

AMD SEATTLE DEVICE TREE SUPPORT
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/amd/amdkfd/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@

config HSA_AMD
tristate "HSA kernel driver for AMD GPU devices"
depends on (DRM_RADEON || DRM_AMDGPU) && AMD_IOMMU_V2 && X86_64
depends on DRM_AMDGPU && AMD_IOMMU_V2 && X86_64
help
Enable this if you want to use HSA features on AMD GPU devices.
8 changes: 6 additions & 2 deletions drivers/gpu/drm/amd/amdkfd/cik_event_interrupt.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ static bool cik_event_interrupt_isr(struct kfd_dev *dev,
/* Do not process in ISR, just request it to be forwarded to WQ. */
return (pasid != 0) &&
(ihre->source_id == CIK_INTSRC_CP_END_OF_PIPE ||
ihre->source_id == CIK_INTSRC_SDMA_TRAP ||
ihre->source_id == CIK_INTSRC_SQ_INTERRUPT_MSG ||
ihre->source_id == CIK_INTSRC_CP_BAD_OPCODE);
}
Expand All @@ -46,16 +47,19 @@ static void cik_event_interrupt_wq(struct kfd_dev *dev,
unsigned int pasid;
const struct cik_ih_ring_entry *ihre =
(const struct cik_ih_ring_entry *)ih_ring_entry;
uint32_t context_id = ihre->data & 0xfffffff;

pasid = (ihre->ring_id & 0xffff0000) >> 16;

if (pasid == 0)
return;

if (ihre->source_id == CIK_INTSRC_CP_END_OF_PIPE)
kfd_signal_event_interrupt(pasid, 0, 0);
kfd_signal_event_interrupt(pasid, context_id, 28);
else if (ihre->source_id == CIK_INTSRC_SDMA_TRAP)
kfd_signal_event_interrupt(pasid, context_id, 28);
else if (ihre->source_id == CIK_INTSRC_SQ_INTERRUPT_MSG)
kfd_signal_event_interrupt(pasid, ihre->data & 0xFF, 8);
kfd_signal_event_interrupt(pasid, context_id & 0xff, 8);
else if (ihre->source_id == CIK_INTSRC_CP_BAD_OPCODE)
kfd_signal_hw_exception_event(pasid);
}
Expand Down
3 changes: 2 additions & 1 deletion drivers/gpu/drm/amd/amdkfd/cik_int.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,10 @@ struct cik_ih_ring_entry {
uint32_t reserved;
};

#define CIK_INTSRC_DEQUEUE_COMPLETE 0xC6
#define CIK_INTSRC_CP_END_OF_PIPE 0xB5
#define CIK_INTSRC_CP_BAD_OPCODE 0xB7
#define CIK_INTSRC_DEQUEUE_COMPLETE 0xC6
#define CIK_INTSRC_SDMA_TRAP 0xE0
#define CIK_INTSRC_SQ_INTERRUPT_MSG 0xEF

#endif
Expand Down
9 changes: 3 additions & 6 deletions drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
Original file line number Diff line number Diff line change
Expand Up @@ -450,8 +450,8 @@ static int kfd_ioctl_dbg_register(struct file *filep,
return -EINVAL;
}

mutex_lock(kfd_get_dbgmgr_mutex());
mutex_lock(&p->mutex);
mutex_lock(kfd_get_dbgmgr_mutex());

/*
* make sure that we have pdd, if this the first queue created for
Expand Down Expand Up @@ -479,8 +479,8 @@ static int kfd_ioctl_dbg_register(struct file *filep,
}

out:
mutex_unlock(&p->mutex);
mutex_unlock(kfd_get_dbgmgr_mutex());
mutex_unlock(&p->mutex);

return status;
}
Expand Down Expand Up @@ -835,15 +835,12 @@ static int kfd_ioctl_wait_events(struct file *filp, struct kfd_process *p,
void *data)
{
struct kfd_ioctl_wait_events_args *args = data;
enum kfd_event_wait_result wait_result;
int err;

err = kfd_wait_on_events(p, args->num_events,
(void __user *)args->events_ptr,
(args->wait_for_all != 0),
args->timeout, &wait_result);

args->wait_result = wait_result;
args->timeout, &args->wait_result);

return err;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/gpu/drm/amd/amdkfd/kfd_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,7 @@ void kgd2kfd_interrupt(struct kfd_dev *kfd, const void *ih_ring_entry)
if (kfd->interrupts_active
&& interrupt_is_wanted(kfd, ih_ring_entry)
&& enqueue_ih_ring_entry(kfd, ih_ring_entry))
schedule_work(&kfd->interrupt_work);
queue_work(kfd->ih_wq, &kfd->interrupt_work);

spin_unlock(&kfd->interrupt_lock);
}
Expand Down
49 changes: 22 additions & 27 deletions drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -389,12 +389,11 @@ static int update_queue(struct device_queue_manager *dqm, struct queue *q)
if (sched_policy != KFD_SCHED_POLICY_NO_HWS) {
retval = unmap_queues_cpsch(dqm,
KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0);
if (retval != 0) {
if (retval) {
pr_err("unmap queue failed\n");
goto out_unlock;
}
} else if (sched_policy == KFD_SCHED_POLICY_NO_HWS &&
prev_active &&
} else if (prev_active &&
(q->properties.type == KFD_QUEUE_TYPE_COMPUTE ||
q->properties.type == KFD_QUEUE_TYPE_SDMA)) {
retval = mqd->destroy_mqd(mqd, q->mqd,
Expand All @@ -408,24 +407,25 @@ static int update_queue(struct device_queue_manager *dqm, struct queue *q)

retval = mqd->update_mqd(mqd, q->mqd, &q->properties);

if (sched_policy != KFD_SCHED_POLICY_NO_HWS)
retval = map_queues_cpsch(dqm);
else if (sched_policy == KFD_SCHED_POLICY_NO_HWS &&
q->properties.is_active &&
(q->properties.type == KFD_QUEUE_TYPE_COMPUTE ||
q->properties.type == KFD_QUEUE_TYPE_SDMA))
retval = mqd->load_mqd(mqd, q->mqd, q->pipe, q->queue,
&q->properties, q->process->mm);

/*
* check active state vs. the previous state
* and modify counter accordingly
* check active state vs. the previous state and modify
* counter accordingly. map_queues_cpsch uses the
* dqm->queue_count to determine whether a new runlist must be
* uploaded.
*/
if (q->properties.is_active && !prev_active)
dqm->queue_count++;
else if (!q->properties.is_active && prev_active)
dqm->queue_count--;

if (sched_policy != KFD_SCHED_POLICY_NO_HWS)
retval = map_queues_cpsch(dqm);
else if (q->properties.is_active &&
(q->properties.type == KFD_QUEUE_TYPE_COMPUTE ||
q->properties.type == KFD_QUEUE_TYPE_SDMA))
retval = mqd->load_mqd(mqd, q->mqd, q->pipe, q->queue,
&q->properties, q->process->mm);

out_unlock:
mutex_unlock(&dqm->lock);
return retval;
Expand Down Expand Up @@ -467,7 +467,7 @@ static int register_process(struct device_queue_manager *dqm,
mutex_lock(&dqm->lock);
list_add(&n->list, &dqm->queues);

retval = dqm->ops_asic_specific.register_process(dqm, qpd);
retval = dqm->asic_ops.update_qpd(dqm, qpd);

dqm->processes_count++;

Expand Down Expand Up @@ -629,7 +629,7 @@ static int create_sdma_queue_nocpsch(struct device_queue_manager *dqm,
pr_debug("SDMA queue id: %d\n", q->properties.sdma_queue_id);
pr_debug("SDMA engine id: %d\n", q->properties.sdma_engine_id);

dqm->ops_asic_specific.init_sdma_vm(dqm, q, qpd);
dqm->asic_ops.init_sdma_vm(dqm, q, qpd);
retval = mqd->init_mqd(mqd, &q->mqd, &q->mqd_mem_obj,
&q->gart_mqd_addr, &q->properties);
if (retval)
Expand Down Expand Up @@ -696,8 +696,6 @@ static int set_sched_resources(struct device_queue_manager *dqm)

static int initialize_cpsch(struct device_queue_manager *dqm)
{
int retval;

pr_debug("num of pipes: %d\n", get_pipes_per_mec(dqm));

mutex_init(&dqm->lock);
Expand All @@ -706,11 +704,8 @@ static int initialize_cpsch(struct device_queue_manager *dqm)
dqm->sdma_queue_count = 0;
dqm->active_runlist = false;
dqm->sdma_bitmap = (1 << CIK_SDMA_QUEUES) - 1;
retval = dqm->ops_asic_specific.initialize(dqm);
if (retval)
mutex_destroy(&dqm->lock);

return retval;
return 0;
}

static int start_cpsch(struct device_queue_manager *dqm)
Expand Down Expand Up @@ -835,7 +830,7 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q,

if (q->properties.type == KFD_QUEUE_TYPE_SDMA) {
retval = allocate_sdma_queue(dqm, &q->sdma_id);
if (retval != 0)
if (retval)
goto out;
q->properties.sdma_queue_id =
q->sdma_id / CIK_SDMA_QUEUES_PER_ENGINE;
Expand All @@ -850,7 +845,7 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q,
goto out;
}

dqm->ops_asic_specific.init_sdma_vm(dqm, q, qpd);
dqm->asic_ops.init_sdma_vm(dqm, q, qpd);
retval = mqd->init_mqd(mqd, &q->mqd, &q->mqd_mem_obj,
&q->gart_mqd_addr, &q->properties);
if (retval)
Expand Down Expand Up @@ -1095,7 +1090,7 @@ static bool set_cache_memory_policy(struct device_queue_manager *dqm,
qpd->sh_mem_ape1_limit = limit >> 16;
}

retval = dqm->ops_asic_specific.set_cache_memory_policy(
retval = dqm->asic_ops.set_cache_memory_policy(
dqm,
qpd,
default_policy,
Expand Down Expand Up @@ -1270,11 +1265,11 @@ struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev)

switch (dev->device_info->asic_family) {
case CHIP_CARRIZO:
device_queue_manager_init_vi(&dqm->ops_asic_specific);
device_queue_manager_init_vi(&dqm->asic_ops);
break;

case CHIP_KAVERI:
device_queue_manager_init_cik(&dqm->ops_asic_specific);
device_queue_manager_init_cik(&dqm->asic_ops);
break;
default:
WARN(1, "Unexpected ASIC family %u",
Expand Down
11 changes: 6 additions & 5 deletions drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,8 @@ struct device_queue_manager_ops {
};

struct device_queue_manager_asic_ops {
int (*register_process)(struct device_queue_manager *dqm,
int (*update_qpd)(struct device_queue_manager *dqm,
struct qcm_process_device *qpd);
int (*initialize)(struct device_queue_manager *dqm);
bool (*set_cache_memory_policy)(struct device_queue_manager *dqm,
struct qcm_process_device *qpd,
enum cache_policy default_policy,
Expand All @@ -156,7 +155,7 @@ struct device_queue_manager_asic_ops {

struct device_queue_manager {
struct device_queue_manager_ops ops;
struct device_queue_manager_asic_ops ops_asic_specific;
struct device_queue_manager_asic_ops asic_ops;

struct mqd_manager *mqds[KFD_MQD_TYPE_MAX];
struct packet_manager packets;
Expand All @@ -179,8 +178,10 @@ struct device_queue_manager {
bool active_runlist;
};

void device_queue_manager_init_cik(struct device_queue_manager_asic_ops *ops);
void device_queue_manager_init_vi(struct device_queue_manager_asic_ops *ops);
void device_queue_manager_init_cik(
struct device_queue_manager_asic_ops *asic_ops);
void device_queue_manager_init_vi(
struct device_queue_manager_asic_ops *asic_ops);
void program_sh_mem_settings(struct device_queue_manager *dqm,
struct qcm_process_device *qpd);
unsigned int get_queues_num(struct device_queue_manager *dqm);
Expand Down
20 changes: 7 additions & 13 deletions drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_cik.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,18 +32,17 @@ static bool set_cache_memory_policy_cik(struct device_queue_manager *dqm,
enum cache_policy alternate_policy,
void __user *alternate_aperture_base,
uint64_t alternate_aperture_size);
static int register_process_cik(struct device_queue_manager *dqm,
static int update_qpd_cik(struct device_queue_manager *dqm,
struct qcm_process_device *qpd);
static int initialize_cpsch_cik(struct device_queue_manager *dqm);
static void init_sdma_vm(struct device_queue_manager *dqm, struct queue *q,
struct qcm_process_device *qpd);

void device_queue_manager_init_cik(struct device_queue_manager_asic_ops *ops)
void device_queue_manager_init_cik(
struct device_queue_manager_asic_ops *asic_ops)
{
ops->set_cache_memory_policy = set_cache_memory_policy_cik;
ops->register_process = register_process_cik;
ops->initialize = initialize_cpsch_cik;
ops->init_sdma_vm = init_sdma_vm;
asic_ops->set_cache_memory_policy = set_cache_memory_policy_cik;
asic_ops->update_qpd = update_qpd_cik;
asic_ops->init_sdma_vm = init_sdma_vm;
}

static uint32_t compute_sh_mem_bases_64bit(unsigned int top_address_nybble)
Expand Down Expand Up @@ -99,7 +98,7 @@ static bool set_cache_memory_policy_cik(struct device_queue_manager *dqm,
return true;
}

static int register_process_cik(struct device_queue_manager *dqm,
static int update_qpd_cik(struct device_queue_manager *dqm,
struct qcm_process_device *qpd)
{
struct kfd_process_device *pdd;
Expand Down Expand Up @@ -148,8 +147,3 @@ static void init_sdma_vm(struct device_queue_manager *dqm, struct queue *q,

q->properties.sdma_vm_addr = value;
}

static int initialize_cpsch_cik(struct device_queue_manager *dqm)
{
return 0;
}
20 changes: 7 additions & 13 deletions drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager_vi.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,18 +33,17 @@ static bool set_cache_memory_policy_vi(struct device_queue_manager *dqm,
enum cache_policy alternate_policy,
void __user *alternate_aperture_base,
uint64_t alternate_aperture_size);
static int register_process_vi(struct device_queue_manager *dqm,
static int update_qpd_vi(struct device_queue_manager *dqm,
struct qcm_process_device *qpd);
static int initialize_cpsch_vi(struct device_queue_manager *dqm);
static void init_sdma_vm(struct device_queue_manager *dqm, struct queue *q,
struct qcm_process_device *qpd);

void device_queue_manager_init_vi(struct device_queue_manager_asic_ops *ops)
void device_queue_manager_init_vi(
struct device_queue_manager_asic_ops *asic_ops)
{
ops->set_cache_memory_policy = set_cache_memory_policy_vi;
ops->register_process = register_process_vi;
ops->initialize = initialize_cpsch_vi;
ops->init_sdma_vm = init_sdma_vm;
asic_ops->set_cache_memory_policy = set_cache_memory_policy_vi;
asic_ops->update_qpd = update_qpd_vi;
asic_ops->init_sdma_vm = init_sdma_vm;
}

static uint32_t compute_sh_mem_bases_64bit(unsigned int top_address_nybble)
Expand Down Expand Up @@ -104,7 +103,7 @@ static bool set_cache_memory_policy_vi(struct device_queue_manager *dqm,
return true;
}

static int register_process_vi(struct device_queue_manager *dqm,
static int update_qpd_vi(struct device_queue_manager *dqm,
struct qcm_process_device *qpd)
{
struct kfd_process_device *pdd;
Expand Down Expand Up @@ -160,8 +159,3 @@ static void init_sdma_vm(struct device_queue_manager *dqm, struct queue *q,

q->properties.sdma_vm_addr = value;
}

static int initialize_cpsch_vi(struct device_queue_manager *dqm)
{
return 0;
}
Loading

0 comments on commit 9ad472e

Please sign in to comment.