summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/amd/amdkfd/kfd_svm.c')
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_svm.c62
1 files changed, 36 insertions, 26 deletions
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
index da569d417d1d..dff1011dd7ee 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c
@@ -281,7 +281,8 @@ svm_range *svm_range_new(struct svm_range_list *svms, uint64_t start,
p = container_of(svms, struct kfd_process, svms);
if (p->xnack_enabled)
- bitmap_fill(prange->bitmap_access, MAX_GPU_INSTANCE);
+ bitmap_copy(prange->bitmap_access, svms->bitmap_supported,
+ MAX_GPU_INSTANCE);
svm_range_set_default_attributes(&prange->preferred_loc,
&prange->prefetch_loc,
@@ -577,36 +578,25 @@ svm_range_check_attr(struct kfd_process *p,
uint32_t nattr, struct kfd_ioctl_svm_attribute *attrs)
{
uint32_t i;
- int gpuidx;
for (i = 0; i < nattr; i++) {
+ uint32_t val = attrs[i].value;
+ int gpuidx = MAX_GPU_INSTANCE;
+
switch (attrs[i].type) {
case KFD_IOCTL_SVM_ATTR_PREFERRED_LOC:
- if (attrs[i].value != KFD_IOCTL_SVM_LOCATION_SYSMEM &&
- attrs[i].value != KFD_IOCTL_SVM_LOCATION_UNDEFINED &&
- kfd_process_gpuidx_from_gpuid(p,
- attrs[i].value) < 0) {
- pr_debug("no GPU 0x%x found\n", attrs[i].value);
- return -EINVAL;
- }
+ if (val != KFD_IOCTL_SVM_LOCATION_SYSMEM &&
+ val != KFD_IOCTL_SVM_LOCATION_UNDEFINED)
+ gpuidx = kfd_process_gpuidx_from_gpuid(p, val);
break;
case KFD_IOCTL_SVM_ATTR_PREFETCH_LOC:
- if (attrs[i].value != KFD_IOCTL_SVM_LOCATION_SYSMEM &&
- kfd_process_gpuidx_from_gpuid(p,
- attrs[i].value) < 0) {
- pr_debug("no GPU 0x%x found\n", attrs[i].value);
- return -EINVAL;
- }
+ if (val != KFD_IOCTL_SVM_LOCATION_SYSMEM)
+ gpuidx = kfd_process_gpuidx_from_gpuid(p, val);
break;
case KFD_IOCTL_SVM_ATTR_ACCESS:
case KFD_IOCTL_SVM_ATTR_ACCESS_IN_PLACE:
case KFD_IOCTL_SVM_ATTR_NO_ACCESS:
- gpuidx = kfd_process_gpuidx_from_gpuid(p,
- attrs[i].value);
- if (gpuidx < 0) {
- pr_debug("no GPU 0x%x found\n", attrs[i].value);
- return -EINVAL;
- }
+ gpuidx = kfd_process_gpuidx_from_gpuid(p, val);
break;
case KFD_IOCTL_SVM_ATTR_SET_FLAGS:
break;
@@ -618,6 +608,15 @@ svm_range_check_attr(struct kfd_process *p,
pr_debug("unknown attr type 0x%x\n", attrs[i].type);
return -EINVAL;
}
+
+ if (gpuidx < 0) {
+ pr_debug("no GPU 0x%x found\n", val);
+ return -EINVAL;
+ } else if (gpuidx < MAX_GPU_INSTANCE &&
+ !test_bit(gpuidx, p->svms.bitmap_supported)) {
+ pr_debug("GPU 0x%x not supported\n", val);
+ return -EINVAL;
+ }
}
return 0;
@@ -1274,7 +1273,7 @@ static int svm_range_reserve_bos(struct svm_validate_context *ctx)
adev = (struct amdgpu_device *)pdd->dev->kgd;
vm = drm_priv_to_vm(pdd->drm_priv);
- ctx->tv[gpuidx].bo = &vm->root.base.bo->tbo;
+ ctx->tv[gpuidx].bo = &vm->root.bo->tbo;
ctx->tv[gpuidx].num_shared = 4;
list_add(&ctx->tv[gpuidx].head, &ctx->validate_list);
}
@@ -1855,7 +1854,7 @@ static void svm_range_drain_retry_fault(struct svm_range_list *svms)
p = container_of(svms, struct kfd_process, svms);
- for (i = 0; i < p->n_pdds; i++) {
+ for_each_set_bit(i, svms->bitmap_supported, p->n_pdds) {
pdd = p->pdds[i];
if (!pdd)
continue;
@@ -2325,6 +2324,11 @@ svm_range_restore_pages(struct amdgpu_device *adev, unsigned int pasid,
bool write_locked = false;
int r = 0;
+ if (!KFD_IS_SVM_API_SUPPORTED(adev->kfd.dev)) {
+ pr_debug("device does not support SVM\n");
+ return -EFAULT;
+ }
+
p = kfd_lookup_process_by_pasid(pasid);
if (!p) {
pr_debug("kfd process not founded pasid 0x%x\n", pasid);
@@ -2472,6 +2476,7 @@ void svm_range_list_fini(struct kfd_process *p)
int svm_range_list_init(struct kfd_process *p)
{
struct svm_range_list *svms = &p->svms;
+ int i;
svms->objects = RB_ROOT_CACHED;
mutex_init(&svms->lock);
@@ -2482,6 +2487,10 @@ int svm_range_list_init(struct kfd_process *p)
INIT_LIST_HEAD(&svms->deferred_range_list);
spin_lock_init(&svms->deferred_list_lock);
+ for (i = 0; i < p->n_pdds; i++)
+ if (KFD_IS_SVM_API_SUPPORTED(p->pdds[i]->dev))
+ bitmap_set(svms->bitmap_supported, i, 1);
+
return 0;
}
@@ -2978,14 +2987,15 @@ svm_range_get_attr(struct kfd_process *p, uint64_t start, uint64_t size,
svm_range_set_default_attributes(&location, &prefetch_loc,
&granularity, &flags);
if (p->xnack_enabled)
- bitmap_fill(bitmap_access, MAX_GPU_INSTANCE);
+ bitmap_copy(bitmap_access, svms->bitmap_supported,
+ MAX_GPU_INSTANCE);
else
bitmap_zero(bitmap_access, MAX_GPU_INSTANCE);
bitmap_zero(bitmap_aip, MAX_GPU_INSTANCE);
goto fill_values;
}
- bitmap_fill(bitmap_access, MAX_GPU_INSTANCE);
- bitmap_fill(bitmap_aip, MAX_GPU_INSTANCE);
+ bitmap_copy(bitmap_access, svms->bitmap_supported, MAX_GPU_INSTANCE);
+ bitmap_copy(bitmap_aip, svms->bitmap_supported, MAX_GPU_INSTANCE);
while (node) {
struct interval_tree_node *next;