@@ -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+
731751void 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+
822874struct 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+
892997struct 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