Commit 74c5b85d authored by Mukul Joshi's avatar Mukul Joshi Committed by Alex Deucher

drm/amdkfd: Add spatial partitioning support in KFD

This patch introduces multi-partition support in KFD.
This patch includes:
- Support for maximum 8 spatial partitions in KFD.
- Initialize one HIQ per partition.
- Management of VMID range depending on partition mode.
- Management of doorbell aperture space between all
  partitions.
- Each partition does its own queue management, interrupt
  handling, SMI event reporting.
- IOMMU, if enabled with multiple partitions, will only work
  on first partition.
- SPM is only supported on the first partition.
- Currently, there is no support for resetting individual
  partitions. All partitions will reset together.
Signed-off-by: default avatarMukul Joshi <mukul.joshi@amd.com>
Tested-by: default avatarAmber Lin <Amber.Lin@amd.com>
Reviewed-by: default avatarFelix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 8dc1db31
This diff is collapsed.
......@@ -1426,7 +1426,7 @@ static int set_sched_resources(struct device_queue_manager *dqm)
int i, mec;
struct scheduling_resources res;
res.vmid_mask = dqm->dev->kfd->shared_resources.compute_vmid_bitmap;
res.vmid_mask = dqm->dev->compute_vmid_bitmap;
res.queue_mask = 0;
for (i = 0; i < KGD_MAX_QUEUES; ++i) {
......
......@@ -121,6 +121,12 @@ int kfd_iommu_bind_process_to_device(struct kfd_process_device *pdd)
return -EINVAL;
}
if (!kfd_is_first_node(dev)) {
dev_warn_once(kfd_device,
"IOMMU supported only on first node\n");
return 0;
}
err = amd_iommu_bind_pasid(dev->adev->pdev, p->pasid, p->lead_thread);
if (!err)
pdd->bound = PDD_BOUND;
......@@ -138,7 +144,8 @@ void kfd_iommu_unbind_process(struct kfd_process *p)
int i;
for (i = 0; i < p->n_pdds; i++)
if (p->pdds[i]->bound == PDD_BOUND)
if ((p->pdds[i]->bound == PDD_BOUND) &&
(kfd_is_first_node((p->pdds[i]->dev))))
amd_iommu_unbind_pasid(p->pdds[i]->dev->adev->pdev,
p->pasid);
}
......@@ -281,7 +288,7 @@ void kfd_iommu_suspend(struct kfd_dev *kfd)
if (!kfd->use_iommu_v2)
return;
kfd_unbind_processes_from_device(kfd->node);
kfd_unbind_processes_from_device(kfd->nodes[0]);
amd_iommu_set_invalidate_ctx_cb(kfd->adev->pdev, NULL);
amd_iommu_set_invalid_ppr_cb(kfd->adev->pdev, NULL);
......@@ -312,7 +319,7 @@ int kfd_iommu_resume(struct kfd_dev *kfd)
amd_iommu_set_invalid_ppr_cb(kfd->adev->pdev,
iommu_invalid_ppr_cb);
err = kfd_bind_processes_to_device(kfd->node);
err = kfd_bind_processes_to_device(kfd->nodes[0]);
if (err) {
amd_iommu_set_invalidate_ctx_cb(kfd->adev->pdev, NULL);
amd_iommu_set_invalid_ppr_cb(kfd->adev->pdev, NULL);
......
......@@ -423,7 +423,7 @@ svm_migrate_vma_to_vram(struct amdgpu_device *adev, struct svm_range *prange,
kfd_smi_event_migration_start(adev->kfd.dev, p->lead_thread->pid,
start >> PAGE_SHIFT, end >> PAGE_SHIFT,
0, adev->kfd.dev->node->id, prange->prefetch_loc,
0, adev->kfd.dev->nodes[0]->id, prange->prefetch_loc,
prange->preferred_loc, trigger);
r = migrate_vma_setup(&migrate);
......@@ -456,7 +456,7 @@ svm_migrate_vma_to_vram(struct amdgpu_device *adev, struct svm_range *prange,
kfd_smi_event_migration_end(adev->kfd.dev, p->lead_thread->pid,
start >> PAGE_SHIFT, end >> PAGE_SHIFT,
0, adev->kfd.dev->node->id, trigger);
0, adev->kfd.dev->nodes[0]->id, trigger);
svm_range_dma_unmap(adev->dev, scratch, 0, npages);
svm_range_free_dma_mappings(prange);
......@@ -701,7 +701,7 @@ svm_migrate_vma_to_ram(struct amdgpu_device *adev, struct svm_range *prange,
kfd_smi_event_migration_start(adev->kfd.dev, p->lead_thread->pid,
start >> PAGE_SHIFT, end >> PAGE_SHIFT,
adev->kfd.dev->node->id, 0, prange->prefetch_loc,
adev->kfd.dev->nodes[0]->id, 0, prange->prefetch_loc,
prange->preferred_loc, trigger);
r = migrate_vma_setup(&migrate);
......@@ -737,7 +737,7 @@ svm_migrate_vma_to_ram(struct amdgpu_device *adev, struct svm_range *prange,
kfd_smi_event_migration_end(adev->kfd.dev, p->lead_thread->pid,
start >> PAGE_SHIFT, end >> PAGE_SHIFT,
adev->kfd.dev->node->id, 0, trigger);
adev->kfd.dev->nodes[0]->id, 0, trigger);
svm_range_dma_unmap(adev->dev, scratch, 0, npages);
......
......@@ -255,6 +255,8 @@ struct kfd_vmid_info {
uint32_t vmid_num_kfd;
};
#define MAX_KFD_NODES 8
struct kfd_dev;
struct kfd_node {
......@@ -267,6 +269,10 @@ struct kfd_node {
*/
struct kfd_vmid_info vm_info;
unsigned int id; /* topology stub index */
unsigned int num_xcc_per_node;
unsigned int start_xcc_id; /* Starting XCC instance
* number for the node
*/
/* Interrupts */
struct kfifo ih_fifo;
struct workqueue_struct *ih_wq;
......@@ -300,6 +306,8 @@ struct kfd_node {
/* Maximum process number mapped to HW scheduler */
unsigned int max_proc_per_quantum;
unsigned int compute_vmid_bitmap;
struct kfd_dev *kfd;
};
......@@ -368,7 +376,8 @@ struct kfd_dev {
/* HMM page migration MEMORY_DEVICE_PRIVATE mapping */
struct dev_pagemap pgmap;
struct kfd_node *node;
struct kfd_node *nodes[MAX_KFD_NODES];
unsigned int num_nodes;
};
enum kfd_mempool {
......@@ -1397,6 +1406,11 @@ static inline int kfd_devcgroup_check_permission(struct kfd_node *kfd)
#endif
}
static inline bool kfd_is_first_node(struct kfd_node *node)
{
return (node == node->kfd->nodes[0]);
}
/* Debugfs */
#if defined(CONFIG_DEBUG_FS)
......
......@@ -254,17 +254,17 @@ void kfd_smi_event_page_fault_start(struct kfd_dev *dev, pid_t pid,
unsigned long address, bool write_fault,
ktime_t ts)
{
kfd_smi_event_add(pid, dev->node, KFD_SMI_EVENT_PAGE_FAULT_START,
kfd_smi_event_add(pid, dev->nodes[0], KFD_SMI_EVENT_PAGE_FAULT_START,
"%lld -%d @%lx(%x) %c\n", ktime_to_ns(ts), pid,
address, dev->node->id, write_fault ? 'W' : 'R');
address, dev->nodes[0]->id, write_fault ? 'W' : 'R');
}
void kfd_smi_event_page_fault_end(struct kfd_dev *dev, pid_t pid,
unsigned long address, bool migration)
{
kfd_smi_event_add(pid, dev->node, KFD_SMI_EVENT_PAGE_FAULT_END,
kfd_smi_event_add(pid, dev->nodes[0], KFD_SMI_EVENT_PAGE_FAULT_END,
"%lld -%d @%lx(%x) %c\n", ktime_get_boottime_ns(),
pid, address, dev->node->id, migration ? 'M' : 'U');
pid, address, dev->nodes[0]->id, migration ? 'M' : 'U');
}
void kfd_smi_event_migration_start(struct kfd_dev *dev, pid_t pid,
......@@ -273,7 +273,7 @@ void kfd_smi_event_migration_start(struct kfd_dev *dev, pid_t pid,
uint32_t prefetch_loc, uint32_t preferred_loc,
uint32_t trigger)
{
kfd_smi_event_add(pid, dev->node, KFD_SMI_EVENT_MIGRATE_START,
kfd_smi_event_add(pid, dev->nodes[0], KFD_SMI_EVENT_MIGRATE_START,
"%lld -%d @%lx(%lx) %x->%x %x:%x %d\n",
ktime_get_boottime_ns(), pid, start, end - start,
from, to, prefetch_loc, preferred_loc, trigger);
......@@ -283,7 +283,7 @@ void kfd_smi_event_migration_end(struct kfd_dev *dev, pid_t pid,
unsigned long start, unsigned long end,
uint32_t from, uint32_t to, uint32_t trigger)
{
kfd_smi_event_add(pid, dev->node, KFD_SMI_EVENT_MIGRATE_END,
kfd_smi_event_add(pid, dev->nodes[0], KFD_SMI_EVENT_MIGRATE_END,
"%lld -%d @%lx(%lx) %x->%x %d\n",
ktime_get_boottime_ns(), pid, start, end - start,
from, to, trigger);
......@@ -292,16 +292,16 @@ void kfd_smi_event_migration_end(struct kfd_dev *dev, pid_t pid,
void kfd_smi_event_queue_eviction(struct kfd_dev *dev, pid_t pid,
uint32_t trigger)
{
kfd_smi_event_add(pid, dev->node, KFD_SMI_EVENT_QUEUE_EVICTION,
kfd_smi_event_add(pid, dev->nodes[0], KFD_SMI_EVENT_QUEUE_EVICTION,
"%lld -%d %x %d\n", ktime_get_boottime_ns(), pid,
dev->node->id, trigger);
dev->nodes[0]->id, trigger);
}
void kfd_smi_event_queue_restore(struct kfd_dev *dev, pid_t pid)
{
kfd_smi_event_add(pid, dev->node, KFD_SMI_EVENT_QUEUE_RESTORE,
kfd_smi_event_add(pid, dev->nodes[0], KFD_SMI_EVENT_QUEUE_RESTORE,
"%lld -%d %x\n", ktime_get_boottime_ns(), pid,
dev->node->id);
dev->nodes[0]->id);
}
void kfd_smi_event_queue_restore_rescheduled(struct mm_struct *mm)
......@@ -328,9 +328,9 @@ void kfd_smi_event_unmap_from_gpu(struct kfd_dev *dev, pid_t pid,
unsigned long address, unsigned long last,
uint32_t trigger)
{
kfd_smi_event_add(pid, dev->node, KFD_SMI_EVENT_UNMAP_FROM_GPU,
kfd_smi_event_add(pid, dev->nodes[0], KFD_SMI_EVENT_UNMAP_FROM_GPU,
"%lld -%d @%lx(%lx) %x %d\n", ktime_get_boottime_ns(),
pid, address, last - address + 1, dev->node->id, trigger);
pid, address, last - address + 1, dev->nodes[0]->id, trigger);
}
int kfd_smi_event_open(struct kfd_node *dev, uint32_t *fd)
......
......@@ -555,7 +555,8 @@ static ssize_t node_show(struct kobject *kobj, struct attribute *attr,
dev->gpu->kfd->sdma_fw_version);
sysfs_show_64bit_prop(buffer, offs, "unique_id",
dev->gpu->adev->unique_id);
sysfs_show_32bit_prop(buffer, offs, "num_xcc",
dev->gpu->num_xcc_per_node);
}
return sysfs_show_32bit_prop(buffer, offs, "max_engine_clk_ccompute",
......@@ -1160,7 +1161,7 @@ void kfd_topology_shutdown(void)
static uint32_t kfd_generate_gpu_id(struct kfd_node *gpu)
{
uint32_t hashout;
uint32_t buf[7];
uint32_t buf[8];
uint64_t local_mem_size;
int i;
......@@ -1177,8 +1178,9 @@ static uint32_t kfd_generate_gpu_id(struct kfd_node *gpu)
buf[4] = gpu->adev->pdev->bus->number;
buf[5] = lower_32_bits(local_mem_size);
buf[6] = upper_32_bits(local_mem_size);
buf[7] = gpu->start_xcc_id | (gpu->num_xcc_per_node << 16);
for (i = 0, hashout = 0; i < 7; i++)
for (i = 0, hashout = 0; i < 8; i++)
hashout ^= hash_32(buf[i], KFD_GPU_ID_HASH_WIDTH);
return hashout;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment