Skip to content

Commit 853697a

Browse files
author
Iouri Tarassov
committed
drivers: hv: dxgkrnl: Implementation of submit command, paging queue and hardware queue implementation.
The following ioctls are implemented: LX_DXSUBMITCOMMAND, LX_DXSUBMITCOMMANDTOHWQUEUE - to submit GPU commands, which are built by the user mode driver. LX_DXCREATEPAGINGQUEUE, LX_DXDESTROYPAGINGQUEUE, LX_DXCREATEHWQUEUE, LX_DXDESTROYHWQUEUE. Signed-off-by: Iouri Tarassov <iourit@linux.microsoft.com>
1 parent 80ff56c commit 853697a

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)