@@ -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+
732752void 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+
823875struct 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+
893998struct 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+ }
0 commit comments