Skip to content

Commit d9726c3

Browse files
author
Iouri Tarassov
committed
drivers: hv: dxgkrnl: Implementation of submit command, paging and hardware queue.
Implement various IOCTLs to deal with hardware queues and paging queues. Hardware queues are used when a compute device supports "hardware scheduling". This means that the compute device itself schedules execution of DMA buffers from hardware queues without CPU intervention. This is as oppose to the "packet scheduling" mode where the software GPU scheduler on the host schedules DMA buffer execution. LX_DXSUBMITCOMMAND This IOCTL is used to submit GPU commands when the device supports the "packet scheduling" mode. LX_DXSUBMITCOMMANDTOHWQUEUE This IOCTL is used to submit GPU commands when the device supports the "hardware scheduling" mode. LX_DXCREATEPAGINGQUEUE, LX_DXDESTROYPAGINGQUEUE These IOCTLs are used to create/destroy a paging queue. Paging queues are used to 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. LX_DXCREATEHWQUEUE, LX_DXDESTROYHWQUEUE These IOCTLs are used to create/destroy hardware queue objects. Hardware queues are used when the compute device supports the "hardware scheduling" mode. Signed-off-by: Iouri Tarassov <iourit@linux.microsoft.com>
1 parent 4f3d0d5 commit d9726c3

4 files changed

Lines changed: 5310 additions & 1450 deletions

File tree

drivers/hv/dxgkrnl/dxgadapter.c

Lines changed: 155 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,26 @@ void dxgdevice_release(struct kref *refcount)
729729
vfree(device);
730730
}
731731

732+
void dxgdevice_add_paging_queue(struct dxgdevice *device,
733+
struct dxgpagingqueue *entry)
734+
{
735+
dxgdevice_acquire_alloc_list_lock(device);
736+
list_add_tail(&entry->pqueue_list_entry, &device->pqueue_list_head);
737+
dxgdevice_release_alloc_list_lock(device);
738+
}
739+
740+
void dxgdevice_remove_paging_queue(struct dxgpagingqueue *pqueue)
741+
{
742+
struct dxgdevice *device = pqueue->device;
743+
744+
dxgdevice_acquire_alloc_list_lock(device);
745+
if (pqueue->pqueue_list_entry.next) {
746+
list_del(&pqueue->pqueue_list_entry);
747+
pqueue->pqueue_list_entry.next = NULL;
748+
}
749+
dxgdevice_release_alloc_list_lock(device);
750+
}
751+
732752
void dxgdevice_add_syncobj(struct dxgdevice *device,
733753
struct dxgsyncobject *syncobj)
734754
{
@@ -820,6 +840,38 @@ void dxgcontext_release(struct kref *refcount)
820840
vfree(context);
821841
}
822842

843+
int dxgcontext_add_hwqueue(struct dxgcontext *context,
844+
struct dxghwqueue *hwqueue)
845+
{
846+
int ret = 0;
847+
848+
down_write(&context->hwqueue_list_lock);
849+
if (dxgcontext_is_active(context))
850+
list_add_tail(&hwqueue->hwqueue_list_entry,
851+
&context->hwqueue_list_head);
852+
else
853+
ret = -ENODEV;
854+
up_write(&context->hwqueue_list_lock);
855+
return ret;
856+
}
857+
858+
void dxgcontext_remove_hwqueue(struct dxgcontext *context,
859+
struct dxghwqueue *hwqueue)
860+
{
861+
if (hwqueue->hwqueue_list_entry.next) {
862+
list_del(&hwqueue->hwqueue_list_entry);
863+
hwqueue->hwqueue_list_entry.next = NULL;
864+
}
865+
}
866+
867+
void dxgcontext_remove_hwqueue_safe(struct dxgcontext *context,
868+
struct dxghwqueue *hwqueue)
869+
{
870+
down_write(&context->hwqueue_list_lock);
871+
dxgcontext_remove_hwqueue(context, hwqueue);
872+
up_write(&context->hwqueue_list_lock);
873+
}
874+
823875
struct dxgallocation *dxgallocation_create(struct dxgprocess *process)
824876
{
825877
struct dxgallocation *alloc = vzalloc(sizeof(struct dxgallocation));
@@ -890,6 +942,59 @@ void dxgallocation_destroy(struct dxgallocation *alloc)
890942
vfree(alloc);
891943
}
892944

945+
struct dxgpagingqueue *dxgpagingqueue_create(struct dxgdevice *device)
946+
{
947+
struct dxgpagingqueue *pqueue;
948+
949+
pqueue = vzalloc(sizeof(*pqueue));
950+
if (pqueue) {
951+
pqueue->device = device;
952+
pqueue->process = device->process;
953+
pqueue->device_handle = device->handle;
954+
dxgdevice_add_paging_queue(device, pqueue);
955+
}
956+
return pqueue;
957+
}
958+
959+
void dxgpagingqueue_stop(struct dxgpagingqueue *pqueue)
960+
{
961+
int ret;
962+
963+
if (pqueue->mapped_address) {
964+
ret = dxg_unmap_iospace(pqueue->mapped_address, PAGE_SIZE);
965+
dev_dbg(dxgglobaldev, "fence is unmapped %d %p",
966+
ret, pqueue->mapped_address);
967+
pqueue->mapped_address = NULL;
968+
}
969+
}
970+
971+
void dxgpagingqueue_destroy(struct dxgpagingqueue *pqueue)
972+
{
973+
struct dxgprocess *process = pqueue->process;
974+
975+
dev_dbg(dxgglobaldev, "%s %p %x\n", __func__, pqueue, pqueue->handle.v);
976+
977+
dxgpagingqueue_stop(pqueue);
978+
979+
hmgrtable_lock(&process->handle_table, DXGLOCK_EXCL);
980+
if (pqueue->handle.v) {
981+
hmgrtable_free_handle(&process->handle_table,
982+
HMGRENTRY_TYPE_DXGPAGINGQUEUE,
983+
pqueue->handle);
984+
pqueue->handle.v = 0;
985+
}
986+
if (pqueue->syncobj_handle.v) {
987+
hmgrtable_free_handle(&process->handle_table,
988+
HMGRENTRY_TYPE_MONITOREDFENCE,
989+
pqueue->syncobj_handle);
990+
pqueue->syncobj_handle.v = 0;
991+
}
992+
hmgrtable_unlock(&process->handle_table, DXGLOCK_EXCL);
993+
if (pqueue->device)
994+
dxgdevice_remove_paging_queue(pqueue);
995+
vfree(pqueue);
996+
}
997+
893998
struct dxgprocess_adapter *dxgprocess_adapter_create(struct dxgprocess *process,
894999
struct dxgadapter *adapter)
8951000
{
@@ -1188,8 +1293,8 @@ void dxgsyncobject_stop(struct dxgsyncobject *syncobj)
11881293
PAGE_SIZE);
11891294

11901295
(void)ret;
1191-
dev_dbg(dxgglobaldev, "fence is unmapped %d %p\n",
1192-
ret, syncobj->mapped_address);
1296+
dev_dbg(dxgglobaldev, "unmap fence %d %p\n",
1297+
ret, syncobj->mapped_address);
11931298
syncobj->mapped_address = NULL;
11941299
}
11951300
}
@@ -1212,18 +1317,59 @@ void dxgsyncobject_release(struct kref *refcount)
12121317
vfree(syncobj);
12131318
}
12141319

1215-
void dxghwqueue_destroy(struct dxgprocess *process, struct dxghwqueue *hwqueue)
1320+
struct dxghwqueue *dxghwqueue_create(struct dxgcontext *context)
12161321
{
1217-
/* Placeholder */
1322+
struct dxgprocess *process = context->device->process;
1323+
struct dxghwqueue *hwqueue = vzalloc(sizeof(*hwqueue));
1324+
1325+
if (hwqueue) {
1326+
kref_init(&hwqueue->hwqueue_kref);
1327+
hwqueue->context = context;
1328+
hwqueue->process = process;
1329+
hwqueue->device_handle = context->device->handle;
1330+
if (dxgcontext_add_hwqueue(context, hwqueue) < 0) {
1331+
kref_put(&hwqueue->hwqueue_kref, dxghwqueue_release);
1332+
hwqueue = NULL;
1333+
} else {
1334+
kref_get(&context->context_kref);
1335+
}
1336+
}
1337+
return hwqueue;
12181338
}
12191339

1220-
void dxgpagingqueue_destroy(struct dxgpagingqueue *pqueue)
1340+
void dxghwqueue_destroy(struct dxgprocess *process, struct dxghwqueue *hwqueue)
12211341
{
1222-
/* Placeholder */
1342+
dev_dbg(dxgglobaldev, "%s %p\n", __func__, hwqueue);
1343+
hmgrtable_lock(&process->handle_table, DXGLOCK_EXCL);
1344+
if (hwqueue->handle.v) {
1345+
hmgrtable_free_handle(&process->handle_table,
1346+
HMGRENTRY_TYPE_DXGHWQUEUE,
1347+
hwqueue->handle);
1348+
hwqueue->handle.v = 0;
1349+
}
1350+
if (hwqueue->progress_fence_sync_object.v) {
1351+
hmgrtable_free_handle(&process->handle_table,
1352+
HMGRENTRY_TYPE_MONITOREDFENCE,
1353+
hwqueue->progress_fence_sync_object);
1354+
hwqueue->progress_fence_sync_object.v = 0;
1355+
}
1356+
hmgrtable_unlock(&process->handle_table, DXGLOCK_EXCL);
1357+
1358+
if (hwqueue->progress_fence_mapped_address) {
1359+
dxg_unmap_iospace(hwqueue->progress_fence_mapped_address,
1360+
PAGE_SIZE);
1361+
hwqueue->progress_fence_mapped_address = NULL;
1362+
}
1363+
dxgcontext_remove_hwqueue_safe(hwqueue->context, hwqueue);
1364+
1365+
kref_put(&hwqueue->context->context_kref, dxgcontext_release);
1366+
kref_put(&hwqueue->hwqueue_kref, dxghwqueue_release);
12231367
}
12241368

1225-
void dxgpagingqueue_stop(struct dxgpagingqueue *pqueue)
1369+
void dxghwqueue_release(struct kref *refcount)
12261370
{
1227-
/* Placeholder */
1228-
}
1371+
struct dxghwqueue *hwqueue;
12291372

1373+
hwqueue = container_of(refcount, struct dxghwqueue, hwqueue_kref);
1374+
vfree(hwqueue);
1375+
}

drivers/hv/dxgkrnl/dxgkrnl.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -943,5 +943,7 @@ int dxgvmb_send_get_stdalloc_data(struct dxgdevice *device,
943943
int dxgvmb_send_query_statistics(struct dxgprocess *process,
944944
struct dxgadapter *adapter,
945945
struct d3dkmt_querystatistics *args);
946+
int dxgvmb_send_share_object_with_host(struct dxgprocess *process,
947+
struct d3dkmt_shareobjectwithhost *args);
946948

947949
#endif

0 commit comments

Comments
 (0)