From: Iouri Tarassov <[email protected]>

Implement iocts to manage compute device scheduling priority:
  - LX_DXGETCONTEXTINPROCESSSCHEDULINGPRIORITY
  - LX_DXGETCONTEXTSCHEDULINGPRIORITY
  - LX_DXSETCONTEXTINPROCESSSCHEDULINGPRIORITY
  - LX_DXSETCONTEXTSCHEDULINGPRIORITY

Each compute device execution context has an assigned scheduling
priority. It is used by the compute device scheduler on the host to
pick contexts for execution. There is a global priority and a
priority within a process.

Signed-off-by: Iouri Tarassov <[email protected]>
[kms: forward port to 6.6 from 6.1. No code changes made.]
Signed-off-by: Kelsey Steele <[email protected]>
---
 drivers/hv/dxgkrnl/dxgkrnl.h  |   9 ++
 drivers/hv/dxgkrnl/dxgvmbus.c |  67 ++++++++++++-
 drivers/hv/dxgkrnl/dxgvmbus.h |  19 ++++
 drivers/hv/dxgkrnl/ioctl.c    | 177 +++++++++++++++++++++++++++++++++-
 include/uapi/misc/d3dkmthk.h  |  28 ++++++
 5 files changed, 294 insertions(+), 6 deletions(-)

diff --git a/drivers/hv/dxgkrnl/dxgkrnl.h b/drivers/hv/dxgkrnl/dxgkrnl.h
index 494ea8fb0bb3..02d10bdcc820 100644
--- a/drivers/hv/dxgkrnl/dxgkrnl.h
+++ b/drivers/hv/dxgkrnl/dxgkrnl.h
@@ -865,6 +865,15 @@ int dxgvmb_send_set_allocation_priority(struct dxgprocess 
*process,
 int dxgvmb_send_get_allocation_priority(struct dxgprocess *process,
                                        struct dxgadapter *adapter,
                                        struct d3dkmt_getallocationpriority *a);
+int dxgvmb_send_set_context_sch_priority(struct dxgprocess *process,
+                                        struct dxgadapter *adapter,
+                                        struct d3dkmthandle context,
+                                        int priority, bool in_process);
+int dxgvmb_send_get_context_sch_priority(struct dxgprocess *process,
+                                        struct dxgadapter *adapter,
+                                        struct d3dkmthandle context,
+                                        int *priority,
+                                        bool in_process);
 int dxgvmb_send_offer_allocations(struct dxgprocess *process,
                                  struct dxgadapter *adapter,
                                  struct d3dkmt_offerallocations *args);
diff --git a/drivers/hv/dxgkrnl/dxgvmbus.c b/drivers/hv/dxgkrnl/dxgvmbus.c
index 8448fd78975b..9a610d48bed7 100644
--- a/drivers/hv/dxgkrnl/dxgvmbus.c
+++ b/drivers/hv/dxgkrnl/dxgvmbus.c
@@ -2949,6 +2949,69 @@ int dxgvmb_send_get_allocation_priority(struct 
dxgprocess *process,
        return ret;
 }
 
+int dxgvmb_send_set_context_sch_priority(struct dxgprocess *process,
+                                        struct dxgadapter *adapter,
+                                        struct d3dkmthandle context,
+                                        int priority,
+                                        bool in_process)
+{
+       struct dxgkvmb_command_setcontextschedulingpriority2 *command;
+       int ret;
+       struct dxgvmbusmsg msg = {.hdr = NULL};
+
+       ret = init_message(&msg, adapter, process, sizeof(*command));
+       if (ret)
+               goto cleanup;
+       command = (void *)msg.msg;
+
+       command_vgpu_to_host_init2(&command->hdr,
+                                  DXGK_VMBCOMMAND_SETCONTEXTSCHEDULINGPRIORITY,
+                                  process->host_handle);
+       command->context = context;
+       command->priority = priority;
+       command->in_process = in_process;
+       ret = dxgvmb_send_sync_msg_ntstatus(msg.channel, msg.hdr, msg.size);
+cleanup:
+       free_message(&msg, process);
+       if (ret)
+               DXG_TRACE("err: %d", ret);
+       return ret;
+}
+
+int dxgvmb_send_get_context_sch_priority(struct dxgprocess *process,
+                                        struct dxgadapter *adapter,
+                                        struct d3dkmthandle context,
+                                        int *priority,
+                                        bool in_process)
+{
+       struct dxgkvmb_command_getcontextschedulingpriority *command;
+       struct dxgkvmb_command_getcontextschedulingpriority_return result = { };
+       int ret;
+       struct dxgvmbusmsg msg = {.hdr = NULL};
+
+       ret = init_message(&msg, adapter, process, sizeof(*command));
+       if (ret)
+               goto cleanup;
+       command = (void *)msg.msg;
+
+       command_vgpu_to_host_init2(&command->hdr,
+                                  DXGK_VMBCOMMAND_GETCONTEXTSCHEDULINGPRIORITY,
+                                  process->host_handle);
+       command->context = context;
+       command->in_process = in_process;
+       ret = dxgvmb_send_sync_msg(msg.channel, msg.hdr, msg.size,
+                                  &result, sizeof(result));
+       if (ret >= 0) {
+               ret = ntstatus2int(result.status);
+               *priority = result.priority;
+       }
+cleanup:
+       free_message(&msg, process);
+       if (ret)
+               DXG_TRACE("err: %d", ret);
+       return ret;
+}
+
 int dxgvmb_send_offer_allocations(struct dxgprocess *process,
                                  struct dxgadapter *adapter,
                                  struct d3dkmt_offerallocations *args)
@@ -2991,7 +3054,7 @@ int dxgvmb_send_offer_allocations(struct dxgprocess 
*process,
 cleanup:
        free_message(&msg, process);
        if (ret)
-               pr_debug("err: %s %d", __func__, ret);
+               DXG_TRACE("err: %d", ret);
        return ret;
 }
 
@@ -3067,7 +3130,7 @@ int dxgvmb_send_reclaim_allocations(struct dxgprocess 
*process,
 cleanup:
        free_message((struct dxgvmbusmsg *)&msg, process);
        if (ret)
-               pr_debug("err: %s %d", __func__, ret);
+               DXG_TRACE("err: %d", ret);
        return ret;
 }
 
diff --git a/drivers/hv/dxgkrnl/dxgvmbus.h b/drivers/hv/dxgkrnl/dxgvmbus.h
index 558c6576a262..509482e1f870 100644
--- a/drivers/hv/dxgkrnl/dxgvmbus.h
+++ b/drivers/hv/dxgkrnl/dxgvmbus.h
@@ -331,6 +331,25 @@ struct dxgkvmb_command_getallocationpriority_return {
        /* u32 priorities[allocation_count or 1]; */
 };
 
+/* Returns ntstatus */
+struct dxgkvmb_command_setcontextschedulingpriority2 {
+       struct dxgkvmb_command_vgpu_to_host hdr;
+       struct d3dkmthandle             context;
+       int                             priority;
+       bool                            in_process;
+};
+
+struct dxgkvmb_command_getcontextschedulingpriority {
+       struct dxgkvmb_command_vgpu_to_host hdr;
+       struct d3dkmthandle             context;
+       bool                            in_process;
+};
+
+struct dxgkvmb_command_getcontextschedulingpriority_return {
+       struct ntstatus                 status;
+       int                             priority;
+};
+
 struct dxgkvmb_command_createdevice {
        struct dxgkvmb_command_vgpu_to_host hdr;
        struct d3dkmt_createdeviceflags flags;
diff --git a/drivers/hv/dxgkrnl/ioctl.c b/drivers/hv/dxgkrnl/ioctl.c
index fa880aa0196a..bc0adebe52ae 100644
--- a/drivers/hv/dxgkrnl/ioctl.c
+++ b/drivers/hv/dxgkrnl/ioctl.c
@@ -3660,6 +3660,171 @@ dxgkio_get_allocation_priority(struct dxgprocess 
*process, void *__user inargs)
        return ret;
 }
 
+static int
+set_context_scheduling_priority(struct dxgprocess *process,
+                               struct d3dkmthandle hcontext,
+                               int priority, bool in_process)
+{
+       int ret = 0;
+       struct dxgdevice *device = NULL;
+       struct dxgadapter *adapter = NULL;
+
+       device = dxgprocess_device_by_object_handle(process,
+                                                   HMGRENTRY_TYPE_DXGCONTEXT,
+                                                   hcontext);
+       if (device == NULL) {
+               ret = -EINVAL;
+               goto cleanup;
+       }
+       adapter = device->adapter;
+       ret = dxgadapter_acquire_lock_shared(adapter);
+       if (ret < 0) {
+               adapter = NULL;
+               goto cleanup;
+       }
+       ret = dxgvmb_send_set_context_sch_priority(process, adapter,
+                                                  hcontext, priority,
+                                                  in_process);
+       if (ret < 0)
+               DXG_ERR("send_set_context_scheduling_priority failed");
+cleanup:
+       if (adapter)
+               dxgadapter_release_lock_shared(adapter);
+       if (device)
+               kref_put(&device->device_kref, dxgdevice_release);
+
+       return ret;
+}
+
+static int
+dxgkio_set_context_scheduling_priority(struct dxgprocess *process,
+                                       void *__user inargs)
+{
+       struct d3dkmt_setcontextschedulingpriority args;
+       int ret;
+
+       ret = copy_from_user(&args, inargs, sizeof(args));
+       if (ret) {
+               DXG_ERR("failed to copy input args");
+               ret = -EINVAL;
+               goto cleanup;
+       }
+
+       ret = set_context_scheduling_priority(process, args.context,
+                                             args.priority, false);
+cleanup:
+       DXG_TRACE("ioctl:%s %d", errorstr(ret), ret);
+       return ret;
+}
+
+static int
+get_context_scheduling_priority(struct dxgprocess *process,
+                               struct d3dkmthandle hcontext,
+                               int __user *priority,
+                               bool in_process)
+{
+       int ret;
+       struct dxgdevice *device = NULL;
+       struct dxgadapter *adapter = NULL;
+       int pri = 0;
+
+       device = dxgprocess_device_by_object_handle(process,
+                                                   HMGRENTRY_TYPE_DXGCONTEXT,
+                                                   hcontext);
+       if (device == NULL) {
+               ret = -EINVAL;
+               goto cleanup;
+       }
+       adapter = device->adapter;
+       ret = dxgadapter_acquire_lock_shared(adapter);
+       if (ret < 0) {
+               adapter = NULL;
+               goto cleanup;
+       }
+       ret = dxgvmb_send_get_context_sch_priority(process, adapter,
+                                                  hcontext, &pri, in_process);
+       if (ret < 0)
+               goto cleanup;
+       ret = copy_to_user(priority, &pri, sizeof(pri));
+       if (ret) {
+               DXG_ERR("failed to copy priority to user");
+               ret = -EINVAL;
+       }
+
+cleanup:
+       if (adapter)
+               dxgadapter_release_lock_shared(adapter);
+       if (device)
+               kref_put(&device->device_kref, dxgdevice_release);
+
+       return ret;
+}
+
+static int
+dxgkio_get_context_scheduling_priority(struct dxgprocess *process,
+                                       void *__user inargs)
+{
+       struct d3dkmt_getcontextschedulingpriority args;
+       struct d3dkmt_getcontextschedulingpriority __user *input = inargs;
+       int ret;
+
+       ret = copy_from_user(&args, inargs, sizeof(args));
+       if (ret) {
+               DXG_ERR("failed to copy input args");
+               ret = -EINVAL;
+               goto cleanup;
+       }
+
+       ret = get_context_scheduling_priority(process, args.context,
+                                             &input->priority, false);
+cleanup:
+       DXG_TRACE("ioctl:%s %d", errorstr(ret), ret);
+       return ret;
+}
+
+static int
+dxgkio_set_context_process_scheduling_priority(struct dxgprocess *process,
+                                              void *__user inargs)
+{
+       struct d3dkmt_setcontextinprocessschedulingpriority args;
+       int ret;
+
+       ret = copy_from_user(&args, inargs, sizeof(args));
+       if (ret) {
+               DXG_ERR("failed to copy input args");
+               ret = -EINVAL;
+               goto cleanup;
+       }
+
+       ret = set_context_scheduling_priority(process, args.context,
+                                             args.priority, true);
+cleanup:
+       DXG_TRACE("ioctl:%s %d", errorstr(ret), ret);
+       return ret;
+}
+
+static int
+dxgkio_get_context_process_scheduling_priority(struct dxgprocess *process,
+                                              void __user *inargs)
+{
+       struct d3dkmt_getcontextinprocessschedulingpriority args;
+       int ret;
+
+       ret = copy_from_user(&args, inargs, sizeof(args));
+       if (ret) {
+               DXG_ERR("failed to copy input args");
+               ret = -EINVAL;
+               goto cleanup;
+       }
+
+       ret = get_context_scheduling_priority(process, args.context,
+               &((struct d3dkmt_getcontextinprocessschedulingpriority *)
+               inargs)->priority, true);
+cleanup:
+       DXG_TRACE("ioctl:%s %d", errorstr(ret), ret);
+       return ret;
+}
+
 static int
 dxgkio_change_vidmem_reservation(struct dxgprocess *process, void *__user 
inargs)
 {
@@ -4655,8 +4820,10 @@ static struct ioctl_desc ioctls[] = {
 /* 0x1e */     {},
 /* 0x1f */     {dxgkio_flush_heap_transitions, LX_DXFLUSHHEAPTRANSITIONS},
 /* 0x20 */     {},
-/* 0x21 */     {},
-/* 0x22 */     {},
+/* 0x21 */     {dxgkio_get_context_process_scheduling_priority,
+                LX_DXGETCONTEXTINPROCESSSCHEDULINGPRIORITY},
+/* 0x22 */     {dxgkio_get_context_scheduling_priority,
+                LX_DXGETCONTEXTSCHEDULINGPRIORITY},
 /* 0x23 */     {},
 /* 0x24 */     {},
 /* 0x25 */     {dxgkio_lock2, LX_DXLOCK2},
@@ -4669,8 +4836,10 @@ static struct ioctl_desc ioctls[] = {
 /* 0x2c */     {dxgkio_reclaim_allocations, LX_DXRECLAIMALLOCATIONS2},
 /* 0x2d */     {},
 /* 0x2e */     {dxgkio_set_allocation_priority, LX_DXSETALLOCATIONPRIORITY},
-/* 0x2f */     {},
-/* 0x30 */     {},
+/* 0x2f */     {dxgkio_set_context_process_scheduling_priority,
+                LX_DXSETCONTEXTINPROCESSSCHEDULINGPRIORITY},
+/* 0x30 */     {dxgkio_set_context_scheduling_priority,
+                LX_DXSETCONTEXTSCHEDULINGPRIORITY},
 /* 0x31 */     {dxgkio_signal_sync_object_cpu,
                 LX_DXSIGNALSYNCHRONIZATIONOBJECTFROMCPU},
 /* 0x32 */     {dxgkio_signal_sync_object_gpu,
diff --git a/include/uapi/misc/d3dkmthk.h b/include/uapi/misc/d3dkmthk.h
index 46b9f6d303bf..a9bafab97c18 100644
--- a/include/uapi/misc/d3dkmthk.h
+++ b/include/uapi/misc/d3dkmthk.h
@@ -708,6 +708,26 @@ struct d3dkmt_submitcommandtohwqueue {
 #endif
 };
 
+struct d3dkmt_setcontextschedulingpriority {
+       struct d3dkmthandle                     context;
+       int                                     priority;
+};
+
+struct d3dkmt_setcontextinprocessschedulingpriority {
+       struct d3dkmthandle                     context;
+       int                                     priority;
+};
+
+struct d3dkmt_getcontextschedulingpriority {
+       struct d3dkmthandle                     context;
+       int                                     priority;
+};
+
+struct d3dkmt_getcontextinprocessschedulingpriority {
+       struct d3dkmthandle                     context;
+       int                                     priority;
+};
+
 struct d3dkmt_setallocationpriority {
        struct d3dkmthandle             device;
        struct d3dkmthandle             resource;
@@ -1419,6 +1439,10 @@ struct d3dkmt_shareobjectwithhost {
        _IOWR(0x47, 0x1d, struct d3dkmt_destroysynchronizationobject)
 #define LX_DXFLUSHHEAPTRANSITIONS      \
        _IOWR(0x47, 0x1f, struct d3dkmt_flushheaptransitions)
+#define LX_DXGETCONTEXTINPROCESSSCHEDULINGPRIORITY \
+       _IOWR(0x47, 0x21, struct d3dkmt_getcontextinprocessschedulingpriority)
+#define LX_DXGETCONTEXTSCHEDULINGPRIORITY \
+       _IOWR(0x47, 0x22, struct d3dkmt_getcontextschedulingpriority)
 #define LX_DXLOCK2                     \
        _IOWR(0x47, 0x25, struct d3dkmt_lock2)
 #define LX_DXMARKDEVICEASERROR         \
@@ -1431,6 +1455,10 @@ struct d3dkmt_shareobjectwithhost {
        _IOWR(0x47, 0x2c, struct d3dkmt_reclaimallocations2)
 #define LX_DXSETALLOCATIONPRIORITY     \
        _IOWR(0x47, 0x2e, struct d3dkmt_setallocationpriority)
+#define LX_DXSETCONTEXTINPROCESSSCHEDULINGPRIORITY \
+       _IOWR(0x47, 0x2f, struct d3dkmt_setcontextinprocessschedulingpriority)
+#define LX_DXSETCONTEXTSCHEDULINGPRIORITY \
+       _IOWR(0x47, 0x30, struct d3dkmt_setcontextschedulingpriority)
 #define LX_DXSIGNALSYNCHRONIZATIONOBJECTFROMCPU \
        _IOWR(0x47, 0x31, struct d3dkmt_signalsynchronizationobjectfromcpu)
 #define LX_DXSIGNALSYNCHRONIZATIONOBJECTFROMGPU \

Reply via email to