Commit 40ce74d1 authored by Philip Yang's avatar Philip Yang Committed by Alex Deucher

drm/amdkfd: add svm ioctl API

Add svm (shared virtual memory) ioctl data structure and API definition.

The svm ioctl API is designed to be extensible in the future. All
operations are provided by a single IOCTL to preserve ioctl number
space. The arguments structure ends with a variable size array of
attributes that can be used to set or get one or multiple attributes.
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 2aeb742b
...@@ -1744,6 +1744,16 @@ static int kfd_ioctl_smi_events(struct file *filep, ...@@ -1744,6 +1744,16 @@ static int kfd_ioctl_smi_events(struct file *filep,
return kfd_smi_event_open(dev, &args->anon_fd); return kfd_smi_event_open(dev, &args->anon_fd);
} }
static int kfd_ioctl_svm(struct file *filep, struct kfd_process *p, void *data)
{
int r = 0;
if (p->svm_disabled)
return -EPERM;
return r;
}
#define AMDKFD_IOCTL_DEF(ioctl, _func, _flags) \ #define AMDKFD_IOCTL_DEF(ioctl, _func, _flags) \
[_IOC_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, \ [_IOC_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, \
.cmd_drv = 0, .name = #ioctl} .cmd_drv = 0, .name = #ioctl}
...@@ -1842,6 +1852,8 @@ static const struct amdkfd_ioctl_desc amdkfd_ioctls[] = { ...@@ -1842,6 +1852,8 @@ static const struct amdkfd_ioctl_desc amdkfd_ioctls[] = {
AMDKFD_IOCTL_DEF(AMDKFD_IOC_SMI_EVENTS, AMDKFD_IOCTL_DEF(AMDKFD_IOC_SMI_EVENTS,
kfd_ioctl_smi_events, 0), kfd_ioctl_smi_events, 0),
AMDKFD_IOCTL_DEF(AMDKFD_IOC_SVM, kfd_ioctl_svm, 0),
}; };
#define AMDKFD_CORE_IOCTL_COUNT ARRAY_SIZE(amdkfd_ioctls) #define AMDKFD_CORE_IOCTL_COUNT ARRAY_SIZE(amdkfd_ioctls)
......
...@@ -405,6 +405,10 @@ int kfd_init_apertures(struct kfd_process *process) ...@@ -405,6 +405,10 @@ int kfd_init_apertures(struct kfd_process *process)
case CHIP_POLARIS12: case CHIP_POLARIS12:
case CHIP_VEGAM: case CHIP_VEGAM:
kfd_init_apertures_vi(pdd, id); kfd_init_apertures_vi(pdd, id);
/* VI GPUs cannot support SVM with only
* 40 bits of virtual address space.
*/
process->svm_disabled = true;
break; break;
case CHIP_VEGA10: case CHIP_VEGA10:
case CHIP_VEGA12: case CHIP_VEGA12:
......
...@@ -809,6 +809,8 @@ struct kfd_process { ...@@ -809,6 +809,8 @@ struct kfd_process {
struct kobject *kobj; struct kobject *kobj;
struct kobject *kobj_queues; struct kobject *kobj_queues;
struct attribute attr_pasid; struct attribute attr_pasid;
bool svm_disabled;
}; };
#define KFD_PROCESS_TABLE_SIZE 5 /* bits: 32 entries */ #define KFD_PROCESS_TABLE_SIZE 5 /* bits: 32 entries */
......
...@@ -1208,6 +1208,7 @@ static struct kfd_process *create_process(const struct task_struct *thread) ...@@ -1208,6 +1208,7 @@ static struct kfd_process *create_process(const struct task_struct *thread)
process->mm = thread->mm; process->mm = thread->mm;
process->lead_thread = thread->group_leader; process->lead_thread = thread->group_leader;
process->n_pdds = 0; process->n_pdds = 0;
process->svm_disabled = false;
INIT_DELAYED_WORK(&process->eviction_work, evict_process_worker); INIT_DELAYED_WORK(&process->eviction_work, evict_process_worker);
INIT_DELAYED_WORK(&process->restore_work, restore_process_worker); INIT_DELAYED_WORK(&process->restore_work, restore_process_worker);
process->last_restore_timestamp = get_jiffies_64(); process->last_restore_timestamp = get_jiffies_64();
......
...@@ -30,9 +30,10 @@ ...@@ -30,9 +30,10 @@
* - 1.1 - initial version * - 1.1 - initial version
* - 1.3 - Add SMI events support * - 1.3 - Add SMI events support
* - 1.4 - Indicate new SRAM EDC bit in device properties * - 1.4 - Indicate new SRAM EDC bit in device properties
* - 1.5 - Add SVM API
*/ */
#define KFD_IOCTL_MAJOR_VERSION 1 #define KFD_IOCTL_MAJOR_VERSION 1
#define KFD_IOCTL_MINOR_VERSION 4 #define KFD_IOCTL_MINOR_VERSION 5
struct kfd_ioctl_get_version_args { struct kfd_ioctl_get_version_args {
__u32 major_version; /* from KFD */ __u32 major_version; /* from KFD */
...@@ -473,6 +474,129 @@ enum kfd_mmio_remap { ...@@ -473,6 +474,129 @@ enum kfd_mmio_remap {
KFD_MMIO_REMAP_HDP_REG_FLUSH_CNTL = 4, KFD_MMIO_REMAP_HDP_REG_FLUSH_CNTL = 4,
}; };
/* Guarantee host access to memory */
#define KFD_IOCTL_SVM_FLAG_HOST_ACCESS 0x00000001
/* Fine grained coherency between all devices with access */
#define KFD_IOCTL_SVM_FLAG_COHERENT 0x00000002
/* Use any GPU in same hive as preferred device */
#define KFD_IOCTL_SVM_FLAG_HIVE_LOCAL 0x00000004
/* GPUs only read, allows replication */
#define KFD_IOCTL_SVM_FLAG_GPU_RO 0x00000008
/* Allow execution on GPU */
#define KFD_IOCTL_SVM_FLAG_GPU_EXEC 0x00000010
/* GPUs mostly read, may allow similar optimizations as RO, but writes fault */
#define KFD_IOCTL_SVM_FLAG_GPU_READ_MOSTLY 0x00000020
/**
* kfd_ioctl_svm_op - SVM ioctl operations
*
* @KFD_IOCTL_SVM_OP_SET_ATTR: Modify one or more attributes
* @KFD_IOCTL_SVM_OP_GET_ATTR: Query one or more attributes
*/
enum kfd_ioctl_svm_op {
KFD_IOCTL_SVM_OP_SET_ATTR,
KFD_IOCTL_SVM_OP_GET_ATTR
};
/** kfd_ioctl_svm_location - Enum for preferred and prefetch locations
*
* GPU IDs are used to specify GPUs as preferred and prefetch locations.
* Below definitions are used for system memory or for leaving the preferred
* location unspecified.
*/
enum kfd_ioctl_svm_location {
KFD_IOCTL_SVM_LOCATION_SYSMEM = 0,
KFD_IOCTL_SVM_LOCATION_UNDEFINED = 0xffffffff
};
/**
* kfd_ioctl_svm_attr_type - SVM attribute types
*
* @KFD_IOCTL_SVM_ATTR_PREFERRED_LOC: gpuid of the preferred location, 0 for
* system memory
* @KFD_IOCTL_SVM_ATTR_PREFETCH_LOC: gpuid of the prefetch location, 0 for
* system memory. Setting this triggers an
* immediate prefetch (migration).
* @KFD_IOCTL_SVM_ATTR_ACCESS:
* @KFD_IOCTL_SVM_ATTR_ACCESS_IN_PLACE:
* @KFD_IOCTL_SVM_ATTR_NO_ACCESS: specify memory access for the gpuid given
* by the attribute value
* @KFD_IOCTL_SVM_ATTR_SET_FLAGS: bitmask of flags to set (see
* KFD_IOCTL_SVM_FLAG_...)
* @KFD_IOCTL_SVM_ATTR_CLR_FLAGS: bitmask of flags to clear
* @KFD_IOCTL_SVM_ATTR_GRANULARITY: migration granularity
* (log2 num pages)
*/
enum kfd_ioctl_svm_attr_type {
KFD_IOCTL_SVM_ATTR_PREFERRED_LOC,
KFD_IOCTL_SVM_ATTR_PREFETCH_LOC,
KFD_IOCTL_SVM_ATTR_ACCESS,
KFD_IOCTL_SVM_ATTR_ACCESS_IN_PLACE,
KFD_IOCTL_SVM_ATTR_NO_ACCESS,
KFD_IOCTL_SVM_ATTR_SET_FLAGS,
KFD_IOCTL_SVM_ATTR_CLR_FLAGS,
KFD_IOCTL_SVM_ATTR_GRANULARITY
};
/**
* kfd_ioctl_svm_attribute - Attributes as pairs of type and value
*
* The meaning of the @value depends on the attribute type.
*
* @type: attribute type (see enum @kfd_ioctl_svm_attr_type)
* @value: attribute value
*/
struct kfd_ioctl_svm_attribute {
__u32 type;
__u32 value;
};
/**
* kfd_ioctl_svm_args - Arguments for SVM ioctl
*
* @op specifies the operation to perform (see enum
* @kfd_ioctl_svm_op). @start_addr and @size are common for all
* operations.
*
* A variable number of attributes can be given in @attrs.
* @nattr specifies the number of attributes. New attributes can be
* added in the future without breaking the ABI. If unknown attributes
* are given, the function returns -EINVAL.
*
* @KFD_IOCTL_SVM_OP_SET_ATTR sets attributes for a virtual address
* range. It may overlap existing virtual address ranges. If it does,
* the existing ranges will be split such that the attribute changes
* only apply to the specified address range.
*
* @KFD_IOCTL_SVM_OP_GET_ATTR returns the intersection of attributes
* over all memory in the given range and returns the result as the
* attribute value. If different pages have different preferred or
* prefetch locations, 0xffffffff will be returned for
* @KFD_IOCTL_SVM_ATTR_PREFERRED_LOC or
* @KFD_IOCTL_SVM_ATTR_PREFETCH_LOC resepctively. For
* @KFD_IOCTL_SVM_ATTR_SET_FLAGS, flags of all pages will be
* aggregated by bitwise AND. The minimum migration granularity
* throughout the range will be returned for
* @KFD_IOCTL_SVM_ATTR_GRANULARITY.
*
* Querying of accessibility attributes works by initializing the
* attribute type to @KFD_IOCTL_SVM_ATTR_ACCESS and the value to the
* GPUID being queried. Multiple attributes can be given to allow
* querying multiple GPUIDs. The ioctl function overwrites the
* attribute type to indicate the access for the specified GPU.
*
* @KFD_IOCTL_SVM_ATTR_CLR_FLAGS is invalid for
* @KFD_IOCTL_SVM_OP_GET_ATTR.
*/
struct kfd_ioctl_svm_args {
__u64 start_addr;
__u64 size;
__u32 op;
__u32 nattr;
/* Variable length array of attributes */
struct kfd_ioctl_svm_attribute attrs[0];
};
#define AMDKFD_IOCTL_BASE 'K' #define AMDKFD_IOCTL_BASE 'K'
#define AMDKFD_IO(nr) _IO(AMDKFD_IOCTL_BASE, nr) #define AMDKFD_IO(nr) _IO(AMDKFD_IOCTL_BASE, nr)
#define AMDKFD_IOR(nr, type) _IOR(AMDKFD_IOCTL_BASE, nr, type) #define AMDKFD_IOR(nr, type) _IOR(AMDKFD_IOCTL_BASE, nr, type)
...@@ -573,7 +697,9 @@ enum kfd_mmio_remap { ...@@ -573,7 +697,9 @@ enum kfd_mmio_remap {
#define AMDKFD_IOC_SMI_EVENTS \ #define AMDKFD_IOC_SMI_EVENTS \
AMDKFD_IOWR(0x1F, struct kfd_ioctl_smi_events_args) AMDKFD_IOWR(0x1F, struct kfd_ioctl_smi_events_args)
#define AMDKFD_IOC_SVM AMDKFD_IOWR(0x20, struct kfd_ioctl_svm_args)
#define AMDKFD_COMMAND_START 0x01 #define AMDKFD_COMMAND_START 0x01
#define AMDKFD_COMMAND_END 0x20 #define AMDKFD_COMMAND_END 0x21
#endif #endif
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