Skip to content

Commit 26a1249

Browse files
Iouri Tarassovchessturo
authored andcommitted
drivers: hv: dxgkrnl: Creation of paging queue objects.
Implement ioctls for creation/destruction of the paging queue objects: - LX_DXCREATEPAGINGQUEUE, - LX_DXDESTROYPAGINGQUEUE Paging queue objects (dxgpagingqueue) contain operations, which handle residency of device accessible allocations. An allocation is resident, when the device has access to it. For example, the allocation resides in local device memory or device page tables point to system memory which is made non-pageable. Each paging queue has an associated monitored fence sync object, which is used to detect when a paging operation is completed. 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 052799b commit 26a1249

7 files changed

Lines changed: 418 additions & 6 deletions

File tree

drivers/hv/dxgkrnl/dxgadapter.c

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@ struct dxgdevice *dxgdevice_create(struct dxgadapter *adapter,
278278
void dxgdevice_stop(struct dxgdevice *device)
279279
{
280280
struct dxgallocation *alloc;
281+
struct dxgpagingqueue *pqueue;
281282
struct dxgsyncobject *syncobj;
282283

283284
DXG_TRACE("Stopping device: %p", device);
@@ -288,6 +289,10 @@ void dxgdevice_stop(struct dxgdevice *device)
288289
dxgdevice_release_alloc_list_lock(device);
289290

290291
hmgrtable_lock(&device->process->handle_table, DXGLOCK_EXCL);
292+
list_for_each_entry(pqueue, &device->pqueue_list_head,
293+
pqueue_list_entry) {
294+
dxgpagingqueue_stop(pqueue);
295+
}
291296
list_for_each_entry(syncobj, &device->syncobj_list_head,
292297
syncobj_list_entry) {
293298
dxgsyncobject_stop(syncobj);
@@ -375,6 +380,17 @@ void dxgdevice_destroy(struct dxgdevice *device)
375380
dxgdevice_release_context_list_lock(device);
376381
}
377382

383+
{
384+
struct dxgpagingqueue *tmp;
385+
struct dxgpagingqueue *pqueue;
386+
387+
DXG_TRACE("destroying paging queues");
388+
list_for_each_entry_safe(pqueue, tmp, &device->pqueue_list_head,
389+
pqueue_list_entry) {
390+
dxgpagingqueue_destroy(pqueue);
391+
}
392+
}
393+
378394
/* Guest handles need to be released before the host handles */
379395
hmgrtable_lock(&process->handle_table, DXGLOCK_EXCL);
380396
if (device->handle_valid) {
@@ -708,6 +724,26 @@ void dxgdevice_release(struct kref *refcount)
708724
kfree(device);
709725
}
710726

727+
void dxgdevice_add_paging_queue(struct dxgdevice *device,
728+
struct dxgpagingqueue *entry)
729+
{
730+
dxgdevice_acquire_alloc_list_lock(device);
731+
list_add_tail(&entry->pqueue_list_entry, &device->pqueue_list_head);
732+
dxgdevice_release_alloc_list_lock(device);
733+
}
734+
735+
void dxgdevice_remove_paging_queue(struct dxgpagingqueue *pqueue)
736+
{
737+
struct dxgdevice *device = pqueue->device;
738+
739+
dxgdevice_acquire_alloc_list_lock(device);
740+
if (pqueue->pqueue_list_entry.next) {
741+
list_del(&pqueue->pqueue_list_entry);
742+
pqueue->pqueue_list_entry.next = NULL;
743+
}
744+
dxgdevice_release_alloc_list_lock(device);
745+
}
746+
711747
void dxgdevice_add_syncobj(struct dxgdevice *device,
712748
struct dxgsyncobject *syncobj)
713749
{
@@ -899,6 +935,59 @@ else
899935
kfree(alloc);
900936
}
901937

938+
struct dxgpagingqueue *dxgpagingqueue_create(struct dxgdevice *device)
939+
{
940+
struct dxgpagingqueue *pqueue;
941+
942+
pqueue = kzalloc(sizeof(*pqueue), GFP_KERNEL);
943+
if (pqueue) {
944+
pqueue->device = device;
945+
pqueue->process = device->process;
946+
pqueue->device_handle = device->handle;
947+
dxgdevice_add_paging_queue(device, pqueue);
948+
}
949+
return pqueue;
950+
}
951+
952+
void dxgpagingqueue_stop(struct dxgpagingqueue *pqueue)
953+
{
954+
int ret;
955+
956+
if (pqueue->mapped_address) {
957+
ret = dxg_unmap_iospace(pqueue->mapped_address, PAGE_SIZE);
958+
DXG_TRACE("fence is unmapped %d %p",
959+
ret, pqueue->mapped_address);
960+
pqueue->mapped_address = NULL;
961+
}
962+
}
963+
964+
void dxgpagingqueue_destroy(struct dxgpagingqueue *pqueue)
965+
{
966+
struct dxgprocess *process = pqueue->process;
967+
968+
DXG_TRACE("Destroying pqueue %p %x", pqueue, pqueue->handle.v);
969+
970+
dxgpagingqueue_stop(pqueue);
971+
972+
hmgrtable_lock(&process->handle_table, DXGLOCK_EXCL);
973+
if (pqueue->handle.v) {
974+
hmgrtable_free_handle(&process->handle_table,
975+
HMGRENTRY_TYPE_DXGPAGINGQUEUE,
976+
pqueue->handle);
977+
pqueue->handle.v = 0;
978+
}
979+
if (pqueue->syncobj_handle.v) {
980+
hmgrtable_free_handle(&process->handle_table,
981+
HMGRENTRY_TYPE_MONITOREDFENCE,
982+
pqueue->syncobj_handle);
983+
pqueue->syncobj_handle.v = 0;
984+
}
985+
hmgrtable_unlock(&process->handle_table, DXGLOCK_EXCL);
986+
if (pqueue->device)
987+
dxgdevice_remove_paging_queue(pqueue);
988+
kfree(pqueue);
989+
}
990+
902991
struct dxgprocess_adapter *dxgprocess_adapter_create(struct dxgprocess *process,
903992
struct dxgadapter *adapter)
904993
{

drivers/hv/dxgkrnl/dxgkrnl.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,16 @@ int dxgvmbuschannel_init(struct dxgvmbuschannel *ch, struct hv_device *hdev);
104104
void dxgvmbuschannel_destroy(struct dxgvmbuschannel *ch);
105105
void dxgvmbuschannel_receive(void *ctx);
106106

107+
struct dxgpagingqueue {
108+
struct dxgdevice *device;
109+
struct dxgprocess *process;
110+
struct list_head pqueue_list_entry;
111+
struct d3dkmthandle device_handle;
112+
struct d3dkmthandle handle;
113+
struct d3dkmthandle syncobj_handle;
114+
void *mapped_address;
115+
};
116+
107117
/*
108118
* The structure describes an event, which will be signaled by
109119
* a message from host.
@@ -127,6 +137,10 @@ struct dxghosteventcpu {
127137
bool remove_from_list;
128138
};
129139

140+
struct dxgpagingqueue *dxgpagingqueue_create(struct dxgdevice *device);
141+
void dxgpagingqueue_destroy(struct dxgpagingqueue *pqueue);
142+
void dxgpagingqueue_stop(struct dxgpagingqueue *pqueue);
143+
130144
/*
131145
* This is GPU synchronization object, which is used to synchronize execution
132146
* between GPU contextx/hardware queues or for tracking GPU execution progress.
@@ -516,6 +530,9 @@ void dxgdevice_remove_alloc_safe(struct dxgdevice *dev,
516530
struct dxgallocation *a);
517531
void dxgdevice_add_resource(struct dxgdevice *dev, struct dxgresource *res);
518532
void dxgdevice_remove_resource(struct dxgdevice *dev, struct dxgresource *res);
533+
void dxgdevice_add_paging_queue(struct dxgdevice *dev,
534+
struct dxgpagingqueue *pqueue);
535+
void dxgdevice_remove_paging_queue(struct dxgpagingqueue *pqueue);
519536
void dxgdevice_add_syncobj(struct dxgdevice *dev, struct dxgsyncobject *so);
520537
void dxgdevice_remove_syncobj(struct dxgsyncobject *so);
521538
bool dxgdevice_is_active(struct dxgdevice *dev);
@@ -762,6 +779,13 @@ dxgvmb_send_create_context(struct dxgadapter *adapter,
762779
int dxgvmb_send_destroy_context(struct dxgadapter *adapter,
763780
struct dxgprocess *process,
764781
struct d3dkmthandle h);
782+
int dxgvmb_send_create_paging_queue(struct dxgprocess *pr,
783+
struct dxgdevice *dev,
784+
struct d3dkmt_createpagingqueue *args,
785+
struct dxgpagingqueue *pq);
786+
int dxgvmb_send_destroy_paging_queue(struct dxgprocess *process,
787+
struct dxgadapter *adapter,
788+
struct d3dkmthandle h);
765789
int dxgvmb_send_create_allocation(struct dxgprocess *pr, struct dxgdevice *dev,
766790
struct d3dkmt_createallocation *args,
767791
struct d3dkmt_createallocation *__user inargs,

drivers/hv/dxgkrnl/dxgprocess.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,10 @@ struct dxgdevice *dxgprocess_device_by_object_handle(struct dxgprocess *process,
277277
device_handle =
278278
((struct dxgcontext *)obj)->device_handle;
279279
break;
280+
case HMGRENTRY_TYPE_DXGPAGINGQUEUE:
281+
device_handle =
282+
((struct dxgpagingqueue *)obj)->device_handle;
283+
break;
280284
case HMGRENTRY_TYPE_DXGHWQUEUE:
281285
device_handle =
282286
((struct dxghwqueue *)obj)->device_handle;

drivers/hv/dxgkrnl/dxgvmbus.c

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1155,6 +1155,80 @@ int dxgvmb_send_destroy_context(struct dxgadapter *adapter,
11551155
return ret;
11561156
}
11571157

1158+
int dxgvmb_send_create_paging_queue(struct dxgprocess *process,
1159+
struct dxgdevice *device,
1160+
struct d3dkmt_createpagingqueue *args,
1161+
struct dxgpagingqueue *pqueue)
1162+
{
1163+
struct dxgkvmb_command_createpagingqueue_return result;
1164+
struct dxgkvmb_command_createpagingqueue *command;
1165+
int ret;
1166+
struct dxgvmbusmsg msg = {.hdr = NULL};
1167+
1168+
ret = init_message(&msg, device->adapter, process, sizeof(*command));
1169+
if (ret)
1170+
goto cleanup;
1171+
command = (void *)msg.msg;
1172+
1173+
command_vgpu_to_host_init2(&command->hdr,
1174+
DXGK_VMBCOMMAND_CREATEPAGINGQUEUE,
1175+
process->host_handle);
1176+
command->args = *args;
1177+
args->paging_queue.v = 0;
1178+
1179+
ret = dxgvmb_send_sync_msg(msg.channel, msg.hdr, msg.size, &result,
1180+
sizeof(result));
1181+
if (ret < 0) {
1182+
DXG_ERR("send_create_paging_queue failed %x", ret);
1183+
goto cleanup;
1184+
}
1185+
1186+
args->paging_queue = result.paging_queue;
1187+
args->sync_object = result.sync_object;
1188+
args->fence_cpu_virtual_address =
1189+
dxg_map_iospace(result.fence_storage_physical_address, PAGE_SIZE,
1190+
PROT_READ | PROT_WRITE, true);
1191+
if (args->fence_cpu_virtual_address == NULL) {
1192+
ret = -ENOMEM;
1193+
goto cleanup;
1194+
}
1195+
pqueue->mapped_address = args->fence_cpu_virtual_address;
1196+
pqueue->handle = args->paging_queue;
1197+
1198+
cleanup:
1199+
free_message(&msg, process);
1200+
if (ret)
1201+
DXG_TRACE("err: %d", ret);
1202+
return ret;
1203+
}
1204+
1205+
int dxgvmb_send_destroy_paging_queue(struct dxgprocess *process,
1206+
struct dxgadapter *adapter,
1207+
struct d3dkmthandle h)
1208+
{
1209+
int ret;
1210+
struct dxgkvmb_command_destroypagingqueue *command;
1211+
struct dxgvmbusmsg msg = {.hdr = NULL};
1212+
1213+
ret = init_message(&msg, adapter, process, sizeof(*command));
1214+
if (ret)
1215+
goto cleanup;
1216+
command = (void *)msg.msg;
1217+
1218+
command_vgpu_to_host_init2(&command->hdr,
1219+
DXGK_VMBCOMMAND_DESTROYPAGINGQUEUE,
1220+
process->host_handle);
1221+
command->paging_queue = h;
1222+
1223+
ret = dxgvmb_send_sync_msg(msg.channel, msg.hdr, msg.size, NULL, 0);
1224+
1225+
cleanup:
1226+
free_message(&msg, process);
1227+
if (ret)
1228+
DXG_TRACE("err: %d", ret);
1229+
return ret;
1230+
}
1231+
11581232
static int
11591233
copy_private_data(struct d3dkmt_createallocation *args,
11601234
struct dxgkvmb_command_createallocation *command,

drivers/hv/dxgkrnl/dxgvmbus.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,23 @@ struct dxgkvmb_command_destroycontext {
462462
struct d3dkmthandle context;
463463
};
464464

465+
struct dxgkvmb_command_createpagingqueue {
466+
struct dxgkvmb_command_vgpu_to_host hdr;
467+
struct d3dkmt_createpagingqueue args;
468+
};
469+
470+
struct dxgkvmb_command_createpagingqueue_return {
471+
struct d3dkmthandle paging_queue;
472+
struct d3dkmthandle sync_object;
473+
u64 fence_storage_physical_address;
474+
u64 fence_storage_offset;
475+
};
476+
477+
struct dxgkvmb_command_destroypagingqueue {
478+
struct dxgkvmb_command_vgpu_to_host hdr;
479+
struct d3dkmthandle paging_queue;
480+
};
481+
465482
struct dxgkvmb_command_createsyncobject {
466483
struct dxgkvmb_command_vgpu_to_host hdr;
467484
struct d3dkmt_createsynchronizationobject2 args;

0 commit comments

Comments
 (0)