Commit 42de677f authored by Philip Yang's avatar Philip Yang Committed by Alex Deucher
Browse files

drm/amdkfd: register svm range



svm range structure stores the range start address, size, attributes,
flags, prefetch location and gpu bitmap which indicates which GPU this
range maps to. Same virtual address is shared by CPU and GPUs.

Process has svm range list which uses both interval tree and list to
store all svm ranges registered by the process. Interval tree is used by
GPU vm fault handler and CPU page fault handler to get svm range
structure from the specific address. List is used to scan all ranges in
eviction restore work.

No overlap range interval [start, last] exist in svms object interval
tree. If process registers new range which has overlap with old range,
the old range split into 2 ranges depending on the overlap happens at
head or tail part of old range.

Apply attributes preferred location, prefetch location, mapping flags,
migration granularity to svm range, store mapping gpu index into bitmap.

Signed-off-by: default avatarPhilip Yang <Philip.Yang@amd.com>
Signed-off-by: default avatarAlex Sierra <alex.sierra@amd.com>
Reviewed-by: default avatarFelix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: default avatarFelix Kuehling <Felix.Kuehling@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 40ce74d1
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -54,7 +54,8 @@ AMDKFD_FILES := $(AMDKFD_PATH)/kfd_module.o \
		$(AMDKFD_PATH)/kfd_dbgdev.o \
		$(AMDKFD_PATH)/kfd_dbgmgr.o \
		$(AMDKFD_PATH)/kfd_smi_events.o \
		$(AMDKFD_PATH)/kfd_crat.o
		$(AMDKFD_PATH)/kfd_crat.o \
		$(AMDKFD_PATH)/kfd_svm.o

ifneq ($(CONFIG_AMD_IOMMU_V2),)
AMDKFD_FILES += $(AMDKFD_PATH)/kfd_iommu.o
+17 −0
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@
#include "kfd_priv.h"
#include "kfd_device_queue_manager.h"
#include "kfd_dbgmgr.h"
#include "kfd_svm.h"
#include "amdgpu_amdkfd.h"
#include "kfd_smi_events.h"

@@ -1746,11 +1747,27 @@ static int kfd_ioctl_smi_events(struct file *filep,

static int kfd_ioctl_svm(struct file *filep, struct kfd_process *p, void *data)
{
	struct kfd_ioctl_svm_args *args = data;
	int r = 0;

	if (p->svm_disabled)
		return -EPERM;

	pr_debug("start 0x%llx size 0x%llx op 0x%x nattr 0x%x\n",
		 args->start_addr, args->size, args->op, args->nattr);

	if ((args->start_addr & ~PAGE_MASK) || (args->size & ~PAGE_MASK))
		return -EINVAL;
	if (!args->start_addr || !args->size)
		return -EINVAL;

	mutex_lock(&p->mutex);

	r = svm_ioctl(p, args->op, args->start_addr, args->size, args->nattr,
		      args->attrs);

	mutex_unlock(&p->mutex);

	return r;
}

+8 −0
Original line number Diff line number Diff line
@@ -731,6 +731,12 @@ struct kfd_process_device {

#define qpd_to_pdd(x) container_of(x, struct kfd_process_device, qpd)

struct svm_range_list {
	struct mutex			lock;
	struct rb_root_cached		objects;
	struct list_head		list;
};

/* Process data */
struct kfd_process {
	/*
@@ -810,6 +816,8 @@ struct kfd_process {
	struct kobject *kobj_queues;
	struct attribute attr_pasid;

	/* shared virtual memory registered by this process */
	struct svm_range_list svms;
	bool svm_disabled;
};

+9 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@
#include <linux/pm_runtime.h>
#include "amdgpu_amdkfd.h"
#include "amdgpu.h"
#include "kfd_svm.h"

struct mm_struct;

@@ -42,6 +43,7 @@ struct mm_struct;
#include "kfd_device_queue_manager.h"
#include "kfd_dbgmgr.h"
#include "kfd_iommu.h"
#include "kfd_svm.h"

/*
 * List of struct kfd_process (field kfd_process).
@@ -1003,6 +1005,7 @@ static void kfd_process_wq_release(struct work_struct *work)
	kfd_iommu_unbind_process(p);

	kfd_process_free_outstanding_kfd_bos(p);
	svm_range_list_fini(p);

	kfd_process_destroy_pdds(p);
	dma_fence_put(p->ef);
@@ -1228,6 +1231,10 @@ static struct kfd_process *create_process(const struct task_struct *thread)
	if (err != 0)
		goto err_init_apertures;

	err = svm_range_list_init(process);
	if (err)
		goto err_init_svm_range_list;

	/* alloc_notifier needs to find the process in the hash table */
	hash_add_rcu(kfd_processes_table, &process->kfd_processes,
			(uintptr_t)process->mm);
@@ -1250,6 +1257,8 @@ static struct kfd_process *create_process(const struct task_struct *thread)

err_register_notifier:
	hash_del_rcu(&process->kfd_processes);
	svm_range_list_fini(process);
err_init_svm_range_list:
	kfd_process_free_outstanding_kfd_bos(process);
	kfd_process_destroy_pdds(process);
err_init_apertures:
+728 −0

File added.

Preview size limit exceeded, changes collapsed.

Loading