Skip to content

Commit

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

- Allow amdkfd to work with multiple kgd instances. This is in preparation for
  AMD's new open source kernel graphic driver (amdgpu), and for the new
  AMD APU, Carrizo.

- Convert timestamping to use 64bit time accessors

- Three other minor changes.

* tag 'drm-amdkfd-next-2015-03-25' of git://people.freedesktop.org/~gabbayo/linux:
  drm/amdkfd: Add multiple kgd support
  drm/amdkfd: Convert timestamping to use 64bit time accessors
  drm/amdkfd: add debug prints for process teardown
  drm/amdkfd: Remove unused field from struct qcm_process_device
  drm/amdkfd: rename fence_wait_timeout
  • Loading branch information
Dave Airlie committed Mar 31, 2015
2 parents 517bc04 + cea405b commit b1f389e
Show file tree
Hide file tree
Showing 11 changed files with 103 additions and 93 deletions.
13 changes: 7 additions & 6 deletions drivers/gpu/drm/amd/amdkfd/kfd_chardev.c
Original file line number Diff line number Diff line change
Expand Up @@ -435,21 +435,22 @@ static int kfd_ioctl_get_clock_counters(struct file *filep,
{
struct kfd_ioctl_get_clock_counters_args *args = data;
struct kfd_dev *dev;
struct timespec time;
struct timespec64 time;

dev = kfd_device_by_id(args->gpu_id);
if (dev == NULL)
return -EINVAL;

/* Reading GPU clock counter from KGD */
args->gpu_clock_counter = kfd2kgd->get_gpu_clock_counter(dev->kgd);
args->gpu_clock_counter =
dev->kfd2kgd->get_gpu_clock_counter(dev->kgd);

/* No access to rdtsc. Using raw monotonic time */
getrawmonotonic(&time);
args->cpu_clock_counter = (uint64_t)timespec_to_ns(&time);
getrawmonotonic64(&time);
args->cpu_clock_counter = (uint64_t)timespec64_to_ns(&time);

get_monotonic_boottime(&time);
args->system_clock_counter = (uint64_t)timespec_to_ns(&time);
get_monotonic_boottime64(&time);
args->system_clock_counter = (uint64_t)timespec64_to_ns(&time);

/* Since the counter is in nano-seconds we use 1GHz frequency */
args->system_clock_freq = 1000000000;
Expand Down
17 changes: 12 additions & 5 deletions drivers/gpu/drm/amd/amdkfd/kfd_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@ static const struct kfd_device_info *lookup_device_info(unsigned short did)
return NULL;
}

struct kfd_dev *kgd2kfd_probe(struct kgd_dev *kgd, struct pci_dev *pdev)
struct kfd_dev *kgd2kfd_probe(struct kgd_dev *kgd,
struct pci_dev *pdev, const struct kfd2kgd_calls *f2g)
{
struct kfd_dev *kfd;

Expand All @@ -112,6 +113,11 @@ struct kfd_dev *kgd2kfd_probe(struct kgd_dev *kgd, struct pci_dev *pdev)
kfd->device_info = device_info;
kfd->pdev = pdev;
kfd->init_complete = false;
kfd->kfd2kgd = f2g;

mutex_init(&kfd->doorbell_mutex);
memset(&kfd->doorbell_available_index, 0,
sizeof(kfd->doorbell_available_index));

return kfd;
}
Expand Down Expand Up @@ -200,8 +206,9 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
/* add another 512KB for all other allocations on gart (HPD, fences) */
size += 512 * 1024;

if (kfd2kgd->init_gtt_mem_allocation(kfd->kgd, size, &kfd->gtt_mem,
&kfd->gtt_start_gpu_addr, &kfd->gtt_start_cpu_ptr)) {
if (kfd->kfd2kgd->init_gtt_mem_allocation(
kfd->kgd, size, &kfd->gtt_mem,
&kfd->gtt_start_gpu_addr, &kfd->gtt_start_cpu_ptr)){
dev_err(kfd_device,
"Could not allocate %d bytes for device (%x:%x)\n",
size, kfd->pdev->vendor, kfd->pdev->device);
Expand Down Expand Up @@ -270,7 +277,7 @@ bool kgd2kfd_device_init(struct kfd_dev *kfd,
kfd_topology_add_device_error:
kfd_gtt_sa_fini(kfd);
kfd_gtt_sa_init_error:
kfd2kgd->free_gtt_mem(kfd->kgd, kfd->gtt_mem);
kfd->kfd2kgd->free_gtt_mem(kfd->kgd, kfd->gtt_mem);
dev_err(kfd_device,
"device (%x:%x) NOT added due to errors\n",
kfd->pdev->vendor, kfd->pdev->device);
Expand All @@ -285,7 +292,7 @@ void kgd2kfd_device_exit(struct kfd_dev *kfd)
amd_iommu_free_device(kfd->pdev);
kfd_topology_remove_device(kfd);
kfd_gtt_sa_fini(kfd);
kfd2kgd->free_gtt_mem(kfd->kgd, kfd->gtt_mem);
kfd->kfd2kgd->free_gtt_mem(kfd->kgd, kfd->gtt_mem);
}

kfree(kfd);
Expand Down
18 changes: 11 additions & 7 deletions drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,8 @@ static inline unsigned int get_pipes_num_cpsch(void)
void program_sh_mem_settings(struct device_queue_manager *dqm,
struct qcm_process_device *qpd)
{
return kfd2kgd->program_sh_mem_settings(dqm->dev->kgd, qpd->vmid,
return dqm->dev->kfd2kgd->program_sh_mem_settings(
dqm->dev->kgd, qpd->vmid,
qpd->sh_mem_config,
qpd->sh_mem_ape1_base,
qpd->sh_mem_ape1_limit,
Expand Down Expand Up @@ -457,9 +458,12 @@ set_pasid_vmid_mapping(struct device_queue_manager *dqm, unsigned int pasid,
{
uint32_t pasid_mapping;

pasid_mapping = (pasid == 0) ? 0 : (uint32_t)pasid |
ATC_VMID_PASID_MAPPING_VALID;
return kfd2kgd->set_pasid_vmid_mapping(dqm->dev->kgd, pasid_mapping,
pasid_mapping = (pasid == 0) ? 0 :
(uint32_t)pasid |
ATC_VMID_PASID_MAPPING_VALID;

return dqm->dev->kfd2kgd->set_pasid_vmid_mapping(
dqm->dev->kgd, pasid_mapping,
vmid);
}

Expand Down Expand Up @@ -511,7 +515,7 @@ int init_pipelines(struct device_queue_manager *dqm,
pipe_hpd_addr = dqm->pipelines_addr + i * CIK_HPD_EOP_BYTES;
pr_debug("kfd: pipeline address %llX\n", pipe_hpd_addr);
/* = log2(bytes/4)-1 */
kfd2kgd->init_pipeline(dqm->dev->kgd, inx,
dqm->dev->kfd2kgd->init_pipeline(dqm->dev->kgd, inx,
CIK_HPD_EOP_BYTES_LOG2 - 3, pipe_hpd_addr);
}

Expand Down Expand Up @@ -897,7 +901,7 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q,
return retval;
}

static int fence_wait_timeout(unsigned int *fence_addr,
static int amdkfd_fence_wait_timeout(unsigned int *fence_addr,
unsigned int fence_value,
unsigned long timeout)
{
Expand Down Expand Up @@ -953,7 +957,7 @@ static int destroy_queues_cpsch(struct device_queue_manager *dqm, bool lock)
pm_send_query_status(&dqm->packets, dqm->fence_gpu_addr,
KFD_FENCE_COMPLETED);
/* should be timed out */
fence_wait_timeout(dqm->fence_addr, KFD_FENCE_COMPLETED,
amdkfd_fence_wait_timeout(dqm->fence_addr, KFD_FENCE_COMPLETED,
QUEUE_PREEMPT_DEFAULT_TIMEOUT_MS);
pm_release_ib(&dqm->packets);
dqm->active_runlist = false;
Expand Down
17 changes: 7 additions & 10 deletions drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,6 @@
* and that's assures that any user process won't get access to the
* kernel doorbells page
*/
static DEFINE_MUTEX(doorbell_mutex);
static unsigned long doorbell_available_index[
DIV_ROUND_UP(KFD_MAX_NUM_OF_QUEUES_PER_PROCESS, BITS_PER_LONG)] = { 0 };

#define KERNEL_DOORBELL_PASID 1
#define KFD_SIZE_OF_DOORBELL_IN_BYTES 4
Expand Down Expand Up @@ -170,12 +167,12 @@ u32 __iomem *kfd_get_kernel_doorbell(struct kfd_dev *kfd,

BUG_ON(!kfd || !doorbell_off);

mutex_lock(&doorbell_mutex);
inx = find_first_zero_bit(doorbell_available_index,
mutex_lock(&kfd->doorbell_mutex);
inx = find_first_zero_bit(kfd->doorbell_available_index,
KFD_MAX_NUM_OF_QUEUES_PER_PROCESS);

__set_bit(inx, doorbell_available_index);
mutex_unlock(&doorbell_mutex);
__set_bit(inx, kfd->doorbell_available_index);
mutex_unlock(&kfd->doorbell_mutex);

if (inx >= KFD_MAX_NUM_OF_QUEUES_PER_PROCESS)
return NULL;
Expand Down Expand Up @@ -203,9 +200,9 @@ void kfd_release_kernel_doorbell(struct kfd_dev *kfd, u32 __iomem *db_addr)

inx = (unsigned int)(db_addr - kfd->doorbell_kernel_ptr);

mutex_lock(&doorbell_mutex);
__clear_bit(inx, doorbell_available_index);
mutex_unlock(&doorbell_mutex);
mutex_lock(&kfd->doorbell_mutex);
__clear_bit(inx, kfd->doorbell_available_index);
mutex_unlock(&kfd->doorbell_mutex);
}

inline void write_kernel_doorbell(u32 __iomem *db, u32 value)
Expand Down
12 changes: 1 addition & 11 deletions drivers/gpu/drm/amd/amdkfd/kfd_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
#define KFD_DRIVER_MINOR 7
#define KFD_DRIVER_PATCHLEVEL 1

const struct kfd2kgd_calls *kfd2kgd;
static const struct kgd2kfd_calls kgd2kfd = {
.exit = kgd2kfd_exit,
.probe = kgd2kfd_probe,
Expand All @@ -55,9 +54,7 @@ module_param(max_num_of_queues_per_device, int, 0444);
MODULE_PARM_DESC(max_num_of_queues_per_device,
"Maximum number of supported queues per device (1 = Minimum, 4096 = default)");

bool kgd2kfd_init(unsigned interface_version,
const struct kfd2kgd_calls *f2g,
const struct kgd2kfd_calls **g2f)
bool kgd2kfd_init(unsigned interface_version, const struct kgd2kfd_calls **g2f)
{
/*
* Only one interface version is supported,
Expand All @@ -66,11 +63,6 @@ bool kgd2kfd_init(unsigned interface_version,
if (interface_version != KFD_INTERFACE_VERSION)
return false;

/* Protection against multiple amd kgd loads */
if (kfd2kgd)
return true;

kfd2kgd = f2g;
*g2f = &kgd2kfd;

return true;
Expand All @@ -85,8 +77,6 @@ static int __init kfd_module_init(void)
{
int err;

kfd2kgd = NULL;

/* Verify module parameters */
if ((sched_policy < KFD_SCHED_POLICY_HWS) ||
(sched_policy > KFD_SCHED_POLICY_NO_HWS)) {
Expand Down
13 changes: 7 additions & 6 deletions drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_cik.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,14 +151,15 @@ static void uninit_mqd_sdma(struct mqd_manager *mm, void *mqd,
static int load_mqd(struct mqd_manager *mm, void *mqd, uint32_t pipe_id,
uint32_t queue_id, uint32_t __user *wptr)
{
return kfd2kgd->hqd_load(mm->dev->kgd, mqd, pipe_id, queue_id, wptr);
return mm->dev->kfd2kgd->hqd_load
(mm->dev->kgd, mqd, pipe_id, queue_id, wptr);
}

static int load_mqd_sdma(struct mqd_manager *mm, void *mqd,
uint32_t pipe_id, uint32_t queue_id,
uint32_t __user *wptr)
{
return kfd2kgd->hqd_sdma_load(mm->dev->kgd, mqd);
return mm->dev->kfd2kgd->hqd_sdma_load(mm->dev->kgd, mqd);
}

static int update_mqd(struct mqd_manager *mm, void *mqd,
Expand Down Expand Up @@ -245,7 +246,7 @@ static int destroy_mqd(struct mqd_manager *mm, void *mqd,
unsigned int timeout, uint32_t pipe_id,
uint32_t queue_id)
{
return kfd2kgd->hqd_destroy(mm->dev->kgd, type, timeout,
return mm->dev->kfd2kgd->hqd_destroy(mm->dev->kgd, type, timeout,
pipe_id, queue_id);
}

Expand All @@ -258,15 +259,15 @@ static int destroy_mqd_sdma(struct mqd_manager *mm, void *mqd,
unsigned int timeout, uint32_t pipe_id,
uint32_t queue_id)
{
return kfd2kgd->hqd_sdma_destroy(mm->dev->kgd, mqd, timeout);
return mm->dev->kfd2kgd->hqd_sdma_destroy(mm->dev->kgd, mqd, timeout);
}

static bool is_occupied(struct mqd_manager *mm, void *mqd,
uint64_t queue_address, uint32_t pipe_id,
uint32_t queue_id)
{

return kfd2kgd->hqd_is_occupied(mm->dev->kgd, queue_address,
return mm->dev->kfd2kgd->hqd_is_occupied(mm->dev->kgd, queue_address,
pipe_id, queue_id);

}
Expand All @@ -275,7 +276,7 @@ static bool is_occupied_sdma(struct mqd_manager *mm, void *mqd,
uint64_t queue_address, uint32_t pipe_id,
uint32_t queue_id)
{
return kfd2kgd->hqd_sdma_is_occupied(mm->dev->kgd, mqd);
return mm->dev->kfd2kgd->hqd_sdma_is_occupied(mm->dev->kgd, mqd);
}

/*
Expand Down
14 changes: 8 additions & 6 deletions drivers/gpu/drm/amd/amdkfd/kfd_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,11 @@ struct kfd_dev {

struct kgd2kfd_shared_resources shared_resources;

const struct kfd2kgd_calls *kfd2kgd;
struct mutex doorbell_mutex;
unsigned long doorbell_available_index[DIV_ROUND_UP(
KFD_MAX_NUM_OF_QUEUES_PER_PROCESS, BITS_PER_LONG)];

void *gtt_mem;
uint64_t gtt_start_gpu_addr;
void *gtt_start_cpu_ptr;
Expand All @@ -164,13 +169,12 @@ struct kfd_dev {

/* KGD2KFD callbacks */
void kgd2kfd_exit(void);
struct kfd_dev *kgd2kfd_probe(struct kgd_dev *kgd, struct pci_dev *pdev);
struct kfd_dev *kgd2kfd_probe(struct kgd_dev *kgd,
struct pci_dev *pdev, const struct kfd2kgd_calls *f2g);
bool kgd2kfd_device_init(struct kfd_dev *kfd,
const struct kgd2kfd_shared_resources *gpu_resources);
const struct kgd2kfd_shared_resources *gpu_resources);
void kgd2kfd_device_exit(struct kfd_dev *kfd);

extern const struct kfd2kgd_calls *kfd2kgd;

enum kfd_mempool {
KFD_MEMPOOL_SYSTEM_CACHEABLE = 1,
KFD_MEMPOOL_SYSTEM_WRITECOMBINE = 2,
Expand Down Expand Up @@ -378,8 +382,6 @@ struct qcm_process_device {
/* The Device Queue Manager that owns this data */
struct device_queue_manager *dqm;
struct process_queue_manager *pqm;
/* Device Queue Manager lock */
struct mutex *lock;
/* Queues list */
struct list_head queues_list;
struct list_head priv_queue_list;
Expand Down
6 changes: 6 additions & 0 deletions drivers/gpu/drm/amd/amdkfd/kfd_process.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,10 +162,16 @@ static void kfd_process_wq_release(struct work_struct *work)

p = my_work->p;

pr_debug("Releasing process (pasid %d) in workqueue\n",
p->pasid);

mutex_lock(&p->mutex);

list_for_each_entry_safe(pdd, temp, &p->per_device_data,
per_device_list) {
pr_debug("Releasing pdd (topology id %d) for process (pasid %d) in workqueue\n",
pdd->dev->id, p->pasid);

amd_iommu_unbind_pasid(pdd->dev->pdev, p->pasid);
list_del(&pdd->per_device_list);

Expand Down
12 changes: 7 additions & 5 deletions drivers/gpu/drm/amd/amdkfd/kfd_topology.c
Original file line number Diff line number Diff line change
Expand Up @@ -726,13 +726,14 @@ static ssize_t node_show(struct kobject *kobj, struct attribute *attr,
}

sysfs_show_32bit_prop(buffer, "max_engine_clk_fcompute",
kfd2kgd->get_max_engine_clock_in_mhz(
dev->gpu->kfd2kgd->get_max_engine_clock_in_mhz(
dev->gpu->kgd));
sysfs_show_64bit_prop(buffer, "local_mem_size",
kfd2kgd->get_vmem_size(dev->gpu->kgd));
dev->gpu->kfd2kgd->get_vmem_size(
dev->gpu->kgd));

sysfs_show_32bit_prop(buffer, "fw_version",
kfd2kgd->get_fw_version(
dev->gpu->kfd2kgd->get_fw_version(
dev->gpu->kgd,
KGD_ENGINE_MEC1));
}
Expand Down Expand Up @@ -1099,8 +1100,9 @@ static uint32_t kfd_generate_gpu_id(struct kfd_dev *gpu)
buf[2] = gpu->pdev->subsystem_device;
buf[3] = gpu->pdev->device;
buf[4] = gpu->pdev->bus->number;
buf[5] = (uint32_t)(kfd2kgd->get_vmem_size(gpu->kgd) & 0xffffffff);
buf[6] = (uint32_t)(kfd2kgd->get_vmem_size(gpu->kgd) >> 32);
buf[5] = (uint32_t)(gpu->kfd2kgd->get_vmem_size(gpu->kgd)
& 0xffffffff);
buf[6] = (uint32_t)(gpu->kfd2kgd->get_vmem_size(gpu->kgd) >> 32);

for (i = 0, hashout = 0; i < 7; i++)
hashout ^= hash_32(buf[i], KFD_GPU_ID_HASH_WIDTH);
Expand Down
Loading

0 comments on commit b1f389e

Please sign in to comment.