Skip to content

Commit 3ae5fd2

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 22a0f17 commit 3ae5fd2

3 files changed

Lines changed: 1130 additions & 9 deletions

File tree

drivers/hv/dxgkrnl/dxgadapter.c

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

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

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

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

11891294
(void)ret;
1190-
dev_dbg(dxgglobaldev, "fence is unmapped %d %p\n",
1191-
ret, syncobj->mapped_address);
1295+
dev_dbg(dxgglobaldev, "unmap fence %d %p\n",
1296+
ret, syncobj->mapped_address);
11921297
syncobj->mapped_address = NULL;
11931298
}
11941299
}
@@ -1211,18 +1316,59 @@ void dxgsyncobject_release(struct kref *refcount)
12111316
vfree(syncobj);
12121317
}
12131318

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

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

1224-
void dxgpagingqueue_stop(struct dxgpagingqueue *pqueue)
1368+
void dxghwqueue_release(struct kref *refcount)
12251369
{
1226-
/* Placeholder */
1227-
}
1370+
struct dxghwqueue *hwqueue;
12281371

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

0 commit comments

Comments
 (0)