Skip to content

Commit 8f81198

Browse files
Iouri Tarassovchessturo
authored andcommitted
drivers: hv: dxgkrnl: Manage device allocation properties
Implement ioctls to manage properties of a compute device allocation: - LX_DXUPDATEALLOCPROPERTY, - LX_DXSETALLOCATIONPRIORITY, - LX_DXGETALLOCATIONPRIORITY, - LX_DXQUERYALLOCATIONRESIDENCY. - LX_DXCHANGEVIDEOMEMORYRESERVATION, The LX_DXUPDATEALLOCPROPERTY ioctl requests the host to update various properties of a compute devoce allocation. The LX_DXSETALLOCATIONPRIORITY and LX_DXGETALLOCATIONPRIORITY ioctls are used to set/get allocation priority, which defines the importance of the allocation to be in the local device memory. The LX_DXQUERYALLOCATIONRESIDENCY ioctl queries if the allocation is located in the compute device accessible memory. The LX_DXCHANGEVIDEOMEMORYRESERVATION ioctl changes compute device memory reservation of an allocation. Signed-off-by: Iouri Tarassov <iourit@linux.microsoft.com> [kms: forward port to 6.6 from 6.1. No code changes made.] Signed-off-by: Kelsey Steele <kelseysteele@microsoft.com>
1 parent 5dbd071 commit 8f81198

5 files changed

Lines changed: 708 additions & 7 deletions

File tree

drivers/hv/dxgkrnl/dxgkrnl.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -851,6 +851,23 @@ int dxgvmb_send_lock2(struct dxgprocess *process,
851851
int dxgvmb_send_unlock2(struct dxgprocess *process,
852852
struct dxgadapter *adapter,
853853
struct d3dkmt_unlock2 *args);
854+
int dxgvmb_send_update_alloc_property(struct dxgprocess *process,
855+
struct dxgadapter *adapter,
856+
struct d3dddi_updateallocproperty *args,
857+
struct d3dddi_updateallocproperty *__user
858+
inargs);
859+
int dxgvmb_send_set_allocation_priority(struct dxgprocess *process,
860+
struct dxgadapter *adapter,
861+
struct d3dkmt_setallocationpriority *a);
862+
int dxgvmb_send_get_allocation_priority(struct dxgprocess *process,
863+
struct dxgadapter *adapter,
864+
struct d3dkmt_getallocationpriority *a);
865+
int dxgvmb_send_change_vidmem_reservation(struct dxgprocess *process,
866+
struct dxgadapter *adapter,
867+
struct d3dkmthandle other_process,
868+
struct
869+
d3dkmt_changevideomemoryreservation
870+
*args);
854871
int dxgvmb_send_create_hwqueue(struct dxgprocess *process,
855872
struct dxgadapter *adapter,
856873
struct d3dkmt_createhwqueue *args,
@@ -870,6 +887,10 @@ int dxgvmb_send_open_sync_object_nt(struct dxgprocess *process,
870887
struct d3dkmt_opensyncobjectfromnthandle2
871888
*args,
872889
struct dxgsyncobject *syncobj);
890+
int dxgvmb_send_query_alloc_residency(struct dxgprocess *process,
891+
struct dxgadapter *adapter,
892+
struct d3dkmt_queryallocationresidency
893+
*args);
873894
int dxgvmb_send_get_device_state(struct dxgprocess *process,
874895
struct dxgadapter *adapter,
875896
struct d3dkmt_getdevicestate *args,

drivers/hv/dxgkrnl/dxgvmbus.c

Lines changed: 300 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1829,6 +1829,79 @@ int dxgvmb_send_destroy_allocation(struct dxgprocess *process,
18291829
return ret;
18301830
}
18311831

1832+
int dxgvmb_send_query_alloc_residency(struct dxgprocess *process,
1833+
struct dxgadapter *adapter,
1834+
struct d3dkmt_queryallocationresidency
1835+
*args)
1836+
{
1837+
int ret = -EINVAL;
1838+
struct dxgkvmb_command_queryallocationresidency *command = NULL;
1839+
u32 cmd_size = sizeof(*command);
1840+
u32 alloc_size = 0;
1841+
u32 result_allocation_size = 0;
1842+
struct dxgkvmb_command_queryallocationresidency_return *result = NULL;
1843+
u32 result_size = sizeof(*result);
1844+
struct dxgvmbusmsgres msg = {.hdr = NULL};
1845+
1846+
if (args->allocation_count > DXG_MAX_VM_BUS_PACKET_SIZE) {
1847+
ret = -EINVAL;
1848+
goto cleanup;
1849+
}
1850+
1851+
if (args->allocation_count) {
1852+
alloc_size = args->allocation_count *
1853+
sizeof(struct d3dkmthandle);
1854+
cmd_size += alloc_size;
1855+
result_allocation_size = args->allocation_count *
1856+
sizeof(args->residency_status[0]);
1857+
} else {
1858+
result_allocation_size = sizeof(args->residency_status[0]);
1859+
}
1860+
result_size += result_allocation_size;
1861+
1862+
ret = init_message_res(&msg, adapter, process, cmd_size, result_size);
1863+
if (ret)
1864+
goto cleanup;
1865+
command = (void *)msg.msg;
1866+
result = msg.res;
1867+
1868+
command_vgpu_to_host_init2(&command->hdr,
1869+
DXGK_VMBCOMMAND_QUERYALLOCATIONRESIDENCY,
1870+
process->host_handle);
1871+
command->args = *args;
1872+
if (alloc_size) {
1873+
ret = copy_from_user(&command[1], args->allocations,
1874+
alloc_size);
1875+
if (ret) {
1876+
DXG_ERR("failed to copy alloc handles");
1877+
ret = -EINVAL;
1878+
goto cleanup;
1879+
}
1880+
}
1881+
1882+
ret = dxgvmb_send_sync_msg(msg.channel, msg.hdr, msg.size,
1883+
result, msg.res_size);
1884+
if (ret < 0)
1885+
goto cleanup;
1886+
1887+
ret = ntstatus2int(result->status);
1888+
if (ret < 0)
1889+
goto cleanup;
1890+
1891+
ret = copy_to_user(args->residency_status, &result[1],
1892+
result_allocation_size);
1893+
if (ret) {
1894+
DXG_ERR("failed to copy residency status");
1895+
ret = -EINVAL;
1896+
}
1897+
1898+
cleanup:
1899+
free_message((struct dxgvmbusmsg *)&msg, process);
1900+
if (ret)
1901+
DXG_TRACE("err: %d", ret);
1902+
return ret;
1903+
}
1904+
18321905
int dxgvmb_send_get_device_state(struct dxgprocess *process,
18331906
struct dxgadapter *adapter,
18341907
struct d3dkmt_getdevicestate *args,
@@ -2461,6 +2534,233 @@ int dxgvmb_send_unlock2(struct dxgprocess *process,
24612534
return ret;
24622535
}
24632536

2537+
int dxgvmb_send_update_alloc_property(struct dxgprocess *process,
2538+
struct dxgadapter *adapter,
2539+
struct d3dddi_updateallocproperty *args,
2540+
struct d3dddi_updateallocproperty *__user
2541+
inargs)
2542+
{
2543+
int ret;
2544+
int ret1;
2545+
struct dxgkvmb_command_updateallocationproperty *command;
2546+
struct dxgkvmb_command_updateallocationproperty_return result = { };
2547+
struct dxgvmbusmsg msg = {.hdr = NULL};
2548+
2549+
ret = init_message(&msg, adapter, process, sizeof(*command));
2550+
if (ret)
2551+
goto cleanup;
2552+
command = (void *)msg.msg;
2553+
2554+
command_vgpu_to_host_init2(&command->hdr,
2555+
DXGK_VMBCOMMAND_UPDATEALLOCATIONPROPERTY,
2556+
process->host_handle);
2557+
command->args = *args;
2558+
2559+
ret = dxgvmb_send_sync_msg(msg.channel, msg.hdr, msg.size,
2560+
&result, sizeof(result));
2561+
2562+
if (ret < 0)
2563+
goto cleanup;
2564+
ret = ntstatus2int(result.status);
2565+
/* STATUS_PENING is a success code > 0 */
2566+
if (ret == STATUS_PENDING) {
2567+
ret1 = copy_to_user(&inargs->paging_fence_value,
2568+
&result.paging_fence_value,
2569+
sizeof(u64));
2570+
if (ret1) {
2571+
DXG_ERR("failed to copy paging fence");
2572+
ret = -EINVAL;
2573+
}
2574+
}
2575+
cleanup:
2576+
free_message(&msg, process);
2577+
if (ret)
2578+
DXG_TRACE("err: %d", ret);
2579+
return ret;
2580+
}
2581+
2582+
int dxgvmb_send_set_allocation_priority(struct dxgprocess *process,
2583+
struct dxgadapter *adapter,
2584+
struct d3dkmt_setallocationpriority *args)
2585+
{
2586+
u32 cmd_size = sizeof(struct dxgkvmb_command_setallocationpriority);
2587+
u32 alloc_size = 0;
2588+
u32 priority_size = 0;
2589+
struct dxgkvmb_command_setallocationpriority *command;
2590+
int ret;
2591+
struct d3dkmthandle *allocations;
2592+
struct dxgvmbusmsg msg = {.hdr = NULL};
2593+
2594+
if (args->allocation_count > DXG_MAX_VM_BUS_PACKET_SIZE) {
2595+
ret = -EINVAL;
2596+
goto cleanup;
2597+
}
2598+
if (args->resource.v) {
2599+
priority_size = sizeof(u32);
2600+
if (args->allocation_count != 0) {
2601+
ret = -EINVAL;
2602+
goto cleanup;
2603+
}
2604+
} else {
2605+
if (args->allocation_count == 0) {
2606+
ret = -EINVAL;
2607+
goto cleanup;
2608+
}
2609+
alloc_size = args->allocation_count *
2610+
sizeof(struct d3dkmthandle);
2611+
cmd_size += alloc_size;
2612+
priority_size = sizeof(u32) * args->allocation_count;
2613+
}
2614+
cmd_size += priority_size;
2615+
2616+
ret = init_message(&msg, adapter, process, cmd_size);
2617+
if (ret)
2618+
goto cleanup;
2619+
command = (void *)msg.msg;
2620+
2621+
command_vgpu_to_host_init2(&command->hdr,
2622+
DXGK_VMBCOMMAND_SETALLOCATIONPRIORITY,
2623+
process->host_handle);
2624+
command->device = args->device;
2625+
command->allocation_count = args->allocation_count;
2626+
command->resource = args->resource;
2627+
allocations = (struct d3dkmthandle *) &command[1];
2628+
ret = copy_from_user(allocations, args->allocation_list,
2629+
alloc_size);
2630+
if (ret) {
2631+
DXG_ERR("failed to copy alloc handle");
2632+
ret = -EINVAL;
2633+
goto cleanup;
2634+
}
2635+
ret = copy_from_user((u8 *) allocations + alloc_size,
2636+
args->priorities, priority_size);
2637+
if (ret) {
2638+
DXG_ERR("failed to copy alloc priority");
2639+
ret = -EINVAL;
2640+
goto cleanup;
2641+
}
2642+
2643+
ret = dxgvmb_send_sync_msg_ntstatus(msg.channel, msg.hdr, msg.size);
2644+
2645+
cleanup:
2646+
free_message(&msg, process);
2647+
if (ret)
2648+
DXG_TRACE("err: %d", ret);
2649+
return ret;
2650+
}
2651+
2652+
int dxgvmb_send_get_allocation_priority(struct dxgprocess *process,
2653+
struct dxgadapter *adapter,
2654+
struct d3dkmt_getallocationpriority *args)
2655+
{
2656+
u32 cmd_size = sizeof(struct dxgkvmb_command_getallocationpriority);
2657+
u32 result_size;
2658+
u32 alloc_size = 0;
2659+
u32 priority_size = 0;
2660+
struct dxgkvmb_command_getallocationpriority *command;
2661+
struct dxgkvmb_command_getallocationpriority_return *result;
2662+
int ret;
2663+
struct d3dkmthandle *allocations;
2664+
struct dxgvmbusmsgres msg = {.hdr = NULL};
2665+
2666+
if (args->allocation_count > DXG_MAX_VM_BUS_PACKET_SIZE) {
2667+
ret = -EINVAL;
2668+
goto cleanup;
2669+
}
2670+
if (args->resource.v) {
2671+
priority_size = sizeof(u32);
2672+
if (args->allocation_count != 0) {
2673+
ret = -EINVAL;
2674+
goto cleanup;
2675+
}
2676+
} else {
2677+
if (args->allocation_count == 0) {
2678+
ret = -EINVAL;
2679+
goto cleanup;
2680+
}
2681+
alloc_size = args->allocation_count *
2682+
sizeof(struct d3dkmthandle);
2683+
cmd_size += alloc_size;
2684+
priority_size = sizeof(u32) * args->allocation_count;
2685+
}
2686+
result_size = sizeof(*result) + priority_size;
2687+
2688+
ret = init_message_res(&msg, adapter, process, cmd_size, result_size);
2689+
if (ret)
2690+
goto cleanup;
2691+
command = (void *)msg.msg;
2692+
result = msg.res;
2693+
2694+
command_vgpu_to_host_init2(&command->hdr,
2695+
DXGK_VMBCOMMAND_GETALLOCATIONPRIORITY,
2696+
process->host_handle);
2697+
command->device = args->device;
2698+
command->allocation_count = args->allocation_count;
2699+
command->resource = args->resource;
2700+
allocations = (struct d3dkmthandle *) &command[1];
2701+
ret = copy_from_user(allocations, args->allocation_list,
2702+
alloc_size);
2703+
if (ret) {
2704+
DXG_ERR("failed to copy alloc handles");
2705+
ret = -EINVAL;
2706+
goto cleanup;
2707+
}
2708+
2709+
ret = dxgvmb_send_sync_msg(msg.channel, msg.hdr,
2710+
msg.size + msg.res_size,
2711+
result, msg.res_size);
2712+
if (ret < 0)
2713+
goto cleanup;
2714+
2715+
ret = ntstatus2int(result->status);
2716+
if (ret < 0)
2717+
goto cleanup;
2718+
2719+
ret = copy_to_user(args->priorities,
2720+
(u8 *) result + sizeof(*result),
2721+
priority_size);
2722+
if (ret) {
2723+
DXG_ERR("failed to copy priorities");
2724+
ret = -EINVAL;
2725+
}
2726+
2727+
cleanup:
2728+
free_message((struct dxgvmbusmsg *)&msg, process);
2729+
if (ret)
2730+
DXG_TRACE("err: %d", ret);
2731+
return ret;
2732+
}
2733+
2734+
int dxgvmb_send_change_vidmem_reservation(struct dxgprocess *process,
2735+
struct dxgadapter *adapter,
2736+
struct d3dkmthandle other_process,
2737+
struct
2738+
d3dkmt_changevideomemoryreservation
2739+
*args)
2740+
{
2741+
struct dxgkvmb_command_changevideomemoryreservation *command;
2742+
int ret;
2743+
struct dxgvmbusmsg msg = {.hdr = NULL};
2744+
2745+
ret = init_message(&msg, adapter, process, sizeof(*command));
2746+
if (ret)
2747+
goto cleanup;
2748+
command = (void *)msg.msg;
2749+
2750+
command_vgpu_to_host_init2(&command->hdr,
2751+
DXGK_VMBCOMMAND_CHANGEVIDEOMEMORYRESERVATION,
2752+
process->host_handle);
2753+
command->args = *args;
2754+
command->args.process = other_process.v;
2755+
2756+
ret = dxgvmb_send_sync_msg_ntstatus(msg.channel, msg.hdr, msg.size);
2757+
cleanup:
2758+
free_message(&msg, process);
2759+
if (ret)
2760+
DXG_TRACE("err: %d", ret);
2761+
return ret;
2762+
}
2763+
24642764
int dxgvmb_send_create_hwqueue(struct dxgprocess *process,
24652765
struct dxgadapter *adapter,
24662766
struct d3dkmt_createhwqueue *args,

0 commit comments

Comments
 (0)