@@ -171,6 +171,26 @@ void dxgadapter_remove_shared_resource(struct dxgadapter *adapter,
171171 up_write (& adapter -> shared_resource_list_lock );
172172}
173173
174+ void dxgadapter_add_shared_syncobj (struct dxgadapter * adapter ,
175+ struct dxgsharedsyncobject * object )
176+ {
177+ down_write (& adapter -> shared_resource_list_lock );
178+ list_add_tail (& object -> adapter_shared_syncobj_list_entry ,
179+ & adapter -> adapter_shared_syncobj_list_head );
180+ up_write (& adapter -> shared_resource_list_lock );
181+ }
182+
183+ void dxgadapter_remove_shared_syncobj (struct dxgadapter * adapter ,
184+ struct dxgsharedsyncobject * object )
185+ {
186+ down_write (& adapter -> shared_resource_list_lock );
187+ if (object -> adapter_shared_syncobj_list_entry .next ) {
188+ list_del (& object -> adapter_shared_syncobj_list_entry );
189+ object -> adapter_shared_syncobj_list_entry .next = NULL ;
190+ }
191+ up_write (& adapter -> shared_resource_list_lock );
192+ }
193+
174194void dxgadapter_add_syncobj (struct dxgadapter * adapter ,
175195 struct dxgsyncobject * object )
176196{
@@ -622,7 +642,7 @@ void dxgresource_destroy(struct dxgresource *resource)
622642 dxgallocation_destroy (alloc );
623643 }
624644 dxgdevice_remove_resource (device , resource );
625- shared_resource = resource -> shared_owner ;
645+ shared_resource = resource -> shared_owner ;
626646 if (shared_resource ) {
627647 dxgsharedresource_remove_resource (shared_resource ,
628648 resource );
@@ -736,6 +756,9 @@ struct dxgcontext *dxgcontext_create(struct dxgdevice *device)
736756 */
737757void dxgcontext_destroy (struct dxgprocess * process , struct dxgcontext * context )
738758{
759+ struct dxghwqueue * hwqueue ;
760+ struct dxghwqueue * tmp ;
761+
739762 DXG_TRACE ("Destroying context %p" , context );
740763 context -> object_state = DXGOBJECTSTATE_DESTROYED ;
741764 if (context -> device ) {
@@ -747,6 +770,10 @@ void dxgcontext_destroy(struct dxgprocess *process, struct dxgcontext *context)
747770 dxgdevice_remove_context (context -> device , context );
748771 kref_put (& context -> device -> device_kref , dxgdevice_release );
749772 }
773+ list_for_each_entry_safe (hwqueue , tmp , & context -> hwqueue_list_head ,
774+ hwqueue_list_entry ) {
775+ dxghwqueue_destroy (process , hwqueue );
776+ }
750777 kref_put (& context -> context_kref , dxgcontext_release );
751778}
752779
@@ -773,6 +800,38 @@ void dxgcontext_release(struct kref *refcount)
773800 kfree (context );
774801}
775802
803+ int dxgcontext_add_hwqueue (struct dxgcontext * context ,
804+ struct dxghwqueue * hwqueue )
805+ {
806+ int ret = 0 ;
807+
808+ down_write (& context -> hwqueue_list_lock );
809+ if (dxgcontext_is_active (context ))
810+ list_add_tail (& hwqueue -> hwqueue_list_entry ,
811+ & context -> hwqueue_list_head );
812+ else
813+ ret = - ENODEV ;
814+ up_write (& context -> hwqueue_list_lock );
815+ return ret ;
816+ }
817+
818+ void dxgcontext_remove_hwqueue (struct dxgcontext * context ,
819+ struct dxghwqueue * hwqueue )
820+ {
821+ if (hwqueue -> hwqueue_list_entry .next ) {
822+ list_del (& hwqueue -> hwqueue_list_entry );
823+ hwqueue -> hwqueue_list_entry .next = NULL ;
824+ }
825+ }
826+
827+ void dxgcontext_remove_hwqueue_safe (struct dxgcontext * context ,
828+ struct dxghwqueue * hwqueue )
829+ {
830+ down_write (& context -> hwqueue_list_lock );
831+ dxgcontext_remove_hwqueue (context , hwqueue );
832+ up_write (& context -> hwqueue_list_lock );
833+ }
834+
776835struct dxgallocation * dxgallocation_create (struct dxgprocess * process )
777836{
778837 struct dxgallocation * alloc ;
@@ -958,6 +1017,63 @@ void dxgprocess_adapter_remove_device(struct dxgdevice *device)
9581017 mutex_unlock (& device -> adapter_info -> device_list_mutex );
9591018}
9601019
1020+ struct dxgsharedsyncobject * dxgsharedsyncobj_create (struct dxgadapter * adapter ,
1021+ struct dxgsyncobject * so )
1022+ {
1023+ struct dxgsharedsyncobject * syncobj ;
1024+
1025+ syncobj = kzalloc (sizeof (* syncobj ), GFP_KERNEL );
1026+ if (syncobj ) {
1027+ kref_init (& syncobj -> ssyncobj_kref );
1028+ INIT_LIST_HEAD (& syncobj -> shared_syncobj_list_head );
1029+ syncobj -> adapter = adapter ;
1030+ syncobj -> type = so -> type ;
1031+ syncobj -> monitored_fence = so -> monitored_fence ;
1032+ dxgadapter_add_shared_syncobj (adapter , syncobj );
1033+ kref_get (& adapter -> adapter_kref );
1034+ init_rwsem (& syncobj -> syncobj_list_lock );
1035+ mutex_init (& syncobj -> fd_mutex );
1036+ }
1037+ return syncobj ;
1038+ }
1039+
1040+ void dxgsharedsyncobj_release (struct kref * refcount )
1041+ {
1042+ struct dxgsharedsyncobject * syncobj ;
1043+
1044+ syncobj = container_of (refcount , struct dxgsharedsyncobject ,
1045+ ssyncobj_kref );
1046+ DXG_TRACE ("Destroying shared sync object %p" , syncobj );
1047+ if (syncobj -> adapter ) {
1048+ dxgadapter_remove_shared_syncobj (syncobj -> adapter ,
1049+ syncobj );
1050+ kref_put (& syncobj -> adapter -> adapter_kref ,
1051+ dxgadapter_release );
1052+ }
1053+ kfree (syncobj );
1054+ }
1055+
1056+ void dxgsharedsyncobj_add_syncobj (struct dxgsharedsyncobject * shared ,
1057+ struct dxgsyncobject * syncobj )
1058+ {
1059+ DXG_TRACE ("Add syncobj 0x%p 0x%p" , shared , syncobj );
1060+ kref_get (& shared -> ssyncobj_kref );
1061+ down_write (& shared -> syncobj_list_lock );
1062+ list_add (& syncobj -> shared_syncobj_list_entry ,
1063+ & shared -> shared_syncobj_list_head );
1064+ syncobj -> shared_owner = shared ;
1065+ up_write (& shared -> syncobj_list_lock );
1066+ }
1067+
1068+ void dxgsharedsyncobj_remove_syncobj (struct dxgsharedsyncobject * shared ,
1069+ struct dxgsyncobject * syncobj )
1070+ {
1071+ DXG_TRACE ("Remove syncobj 0x%p" , shared );
1072+ down_write (& shared -> syncobj_list_lock );
1073+ list_del (& syncobj -> shared_syncobj_list_entry );
1074+ up_write (& shared -> syncobj_list_lock );
1075+ }
1076+
9611077struct dxgsyncobject * dxgsyncobject_create (struct dxgprocess * process ,
9621078 struct dxgdevice * device ,
9631079 struct dxgadapter * adapter ,
@@ -1091,7 +1207,70 @@ void dxgsyncobject_release(struct kref *refcount)
10911207 struct dxgsyncobject * syncobj ;
10921208
10931209 syncobj = container_of (refcount , struct dxgsyncobject , syncobj_kref );
1210+ if (syncobj -> shared_owner ) {
1211+ dxgsharedsyncobj_remove_syncobj (syncobj -> shared_owner ,
1212+ syncobj );
1213+ kref_put (& syncobj -> shared_owner -> ssyncobj_kref ,
1214+ dxgsharedsyncobj_release );
1215+ }
10941216 if (syncobj -> host_event )
10951217 kfree (syncobj -> host_event );
10961218 kfree (syncobj );
10971219}
1220+
1221+ struct dxghwqueue * dxghwqueue_create (struct dxgcontext * context )
1222+ {
1223+ struct dxgprocess * process = context -> device -> process ;
1224+ struct dxghwqueue * hwqueue = kzalloc (sizeof (* hwqueue ), GFP_KERNEL );
1225+
1226+ if (hwqueue ) {
1227+ kref_init (& hwqueue -> hwqueue_kref );
1228+ hwqueue -> context = context ;
1229+ hwqueue -> process = process ;
1230+ hwqueue -> device_handle = context -> device -> handle ;
1231+ if (dxgcontext_add_hwqueue (context , hwqueue ) < 0 ) {
1232+ kref_put (& hwqueue -> hwqueue_kref , dxghwqueue_release );
1233+ hwqueue = NULL ;
1234+ } else {
1235+ kref_get (& context -> context_kref );
1236+ }
1237+ }
1238+ return hwqueue ;
1239+ }
1240+
1241+ void dxghwqueue_destroy (struct dxgprocess * process , struct dxghwqueue * hwqueue )
1242+ {
1243+ DXG_TRACE ("Destroyng hwqueue %p" , hwqueue );
1244+ hmgrtable_lock (& process -> handle_table , DXGLOCK_EXCL );
1245+ if (hwqueue -> handle .v ) {
1246+ hmgrtable_free_handle (& process -> handle_table ,
1247+ HMGRENTRY_TYPE_DXGHWQUEUE ,
1248+ hwqueue -> handle );
1249+ hwqueue -> handle .v = 0 ;
1250+ }
1251+ if (hwqueue -> progress_fence_sync_object .v ) {
1252+ hmgrtable_free_handle (& process -> handle_table ,
1253+ HMGRENTRY_TYPE_MONITOREDFENCE ,
1254+ hwqueue -> progress_fence_sync_object );
1255+ hwqueue -> progress_fence_sync_object .v = 0 ;
1256+ }
1257+ hmgrtable_unlock (& process -> handle_table , DXGLOCK_EXCL );
1258+
1259+ if (hwqueue -> progress_fence_mapped_address ) {
1260+ dxg_unmap_iospace (hwqueue -> progress_fence_mapped_address ,
1261+ PAGE_SIZE );
1262+ hwqueue -> progress_fence_mapped_address = NULL ;
1263+ }
1264+ dxgcontext_remove_hwqueue_safe (hwqueue -> context , hwqueue );
1265+
1266+ kref_put (& hwqueue -> context -> context_kref , dxgcontext_release );
1267+ kref_put (& hwqueue -> hwqueue_kref , dxghwqueue_release );
1268+ }
1269+
1270+ void dxghwqueue_release (struct kref * refcount )
1271+ {
1272+ struct dxghwqueue * hwqueue ;
1273+
1274+ hwqueue = container_of (refcount , struct dxghwqueue , hwqueue_kref );
1275+ kfree (hwqueue );
1276+ }
0 commit comments