summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/amdkfd
diff options
context:
space:
mode:
authorFelix Kuehling <Felix.Kuehling@amd.com>2017-10-28 02:35:29 +0300
committerOded Gabbay <oded.gabbay@gmail.com>2017-10-28 02:35:29 +0300
commitb9a5d0a5db802277c93667c6af93e699bb8c773e (patch)
tree7c1daf3d5a0c3a0643c3ad109d91cf51198b6cab /drivers/gpu/drm/amd/amdkfd
parent3f04f9614831b4d18dcaf228cff0617a20073f9d (diff)
downloadlinux-b9a5d0a5db802277c93667c6af93e699bb8c773e.tar.xz
drm/amdkfd: Make event limit dependent on user mode mapping size
This allows increasing the KFD_SIGNAL_EVENT_LIMIT in kfd_ioctl.h without breaking processes built with older kfd_ioctl.h versions. Signed-off-by: Felix Kuehling <Felix.Kuehling@amd.com> Signed-off-by: Oded Gabbay <oded.gabbay@gmail.com>
Diffstat (limited to 'drivers/gpu/drm/amd/amdkfd')
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_events.c25
-rw-r--r--drivers/gpu/drm/amd/amdkfd/kfd_priv.h1
2 files changed, 20 insertions, 6 deletions
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_events.c
index 26e8045aa760..cb92d4b72400 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_events.c
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_events.c
@@ -97,9 +97,17 @@ static int allocate_event_notification_slot(struct kfd_process *p,
p->signal_page = allocate_signal_page(p);
if (!p->signal_page)
return -ENOMEM;
+ /* Oldest user mode expects 256 event slots */
+ p->signal_mapped_size = 256*8;
}
- id = idr_alloc(&p->event_idr, ev, 0, KFD_SIGNAL_EVENT_LIMIT,
+ /*
+ * Compatibility with old user mode: Only use signal slots
+ * user mode has mapped, may be less than
+ * KFD_SIGNAL_EVENT_LIMIT. This also allows future increase
+ * of the event limit without breaking user mode.
+ */
+ id = idr_alloc(&p->event_idr, ev, 0, p->signal_mapped_size / 8,
GFP_KERNEL);
if (id < 0)
return id;
@@ -173,7 +181,8 @@ static int create_signal_event(struct file *devkfd,
{
int ret;
- if (p->signal_event_count == KFD_SIGNAL_EVENT_LIMIT) {
+ if (p->signal_mapped_size &&
+ p->signal_event_count == p->signal_mapped_size / 8) {
if (!p->signal_event_limit_reached) {
pr_warn("Signal event wasn't created because limit was reached\n");
p->signal_event_limit_reached = true;
@@ -744,12 +753,12 @@ out:
int kfd_event_mmap(struct kfd_process *p, struct vm_area_struct *vma)
{
-
unsigned long pfn;
struct kfd_signal_page *page;
+ int ret;
- /* check required size is logical */
- if (get_order(KFD_SIGNAL_EVENT_LIMIT * 8) !=
+ /* check required size doesn't exceed the allocated size */
+ if (get_order(KFD_SIGNAL_EVENT_LIMIT * 8) <
get_order(vma->vm_end - vma->vm_start)) {
pr_err("Event page mmap requested illegal size\n");
return -EINVAL;
@@ -779,8 +788,12 @@ int kfd_event_mmap(struct kfd_process *p, struct vm_area_struct *vma)
page->user_address = (uint64_t __user *)vma->vm_start;
/* mapping the page to user process */
- return remap_pfn_range(vma, vma->vm_start, pfn,
+ ret = remap_pfn_range(vma, vma->vm_start, pfn,
vma->vm_end - vma->vm_start, vma->vm_page_prot);
+ if (!ret)
+ p->signal_mapped_size = vma->vm_end - vma->vm_start;
+
+ return ret;
}
/*
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
index ebae8e1891d2..ba26da81d8ec 100644
--- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
+++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h
@@ -543,6 +543,7 @@ struct kfd_process {
struct idr event_idr;
/* Event page */
struct kfd_signal_page *signal_page;
+ size_t signal_mapped_size;
size_t signal_event_count;
bool signal_event_limit_reached;
};