@@ -167,6 +167,55 @@ void dxgadapter_remove_process(struct dxgprocess_adapter *process_info)
167167 process_info -> adapter_process_list_entry .prev = NULL ;
168168}
169169
170+ void dxgadapter_remove_shared_resource (struct dxgadapter * adapter ,
171+ struct dxgsharedresource * object )
172+ {
173+ down_write (& adapter -> shared_resource_list_lock );
174+ if (object -> shared_resource_list_entry .next ) {
175+ list_del (& object -> shared_resource_list_entry );
176+ object -> shared_resource_list_entry .next = NULL ;
177+ }
178+ up_write (& adapter -> shared_resource_list_lock );
179+ }
180+
181+ void dxgadapter_add_shared_syncobj (struct dxgadapter * adapter ,
182+ struct dxgsharedsyncobject * object )
183+ {
184+ down_write (& adapter -> shared_resource_list_lock );
185+ list_add_tail (& object -> adapter_shared_syncobj_list_entry ,
186+ & adapter -> adapter_shared_syncobj_list_head );
187+ up_write (& adapter -> shared_resource_list_lock );
188+ }
189+
190+ void dxgadapter_remove_shared_syncobj (struct dxgadapter * adapter ,
191+ struct dxgsharedsyncobject * object )
192+ {
193+ down_write (& adapter -> shared_resource_list_lock );
194+ if (object -> adapter_shared_syncobj_list_entry .next ) {
195+ list_del (& object -> adapter_shared_syncobj_list_entry );
196+ object -> adapter_shared_syncobj_list_entry .next = NULL ;
197+ }
198+ up_write (& adapter -> shared_resource_list_lock );
199+ }
200+
201+ void dxgadapter_add_syncobj (struct dxgadapter * adapter ,
202+ struct dxgsyncobject * object )
203+ {
204+ down_write (& adapter -> shared_resource_list_lock );
205+ list_add_tail (& object -> syncobj_list_entry , & adapter -> syncobj_list_head );
206+ up_write (& adapter -> shared_resource_list_lock );
207+ }
208+
209+ void dxgadapter_remove_syncobj (struct dxgsyncobject * object )
210+ {
211+ down_write (& object -> adapter -> shared_resource_list_lock );
212+ if (object -> syncobj_list_entry .next ) {
213+ list_del (& object -> syncobj_list_entry );
214+ object -> syncobj_list_entry .next = NULL ;
215+ }
216+ up_write (& object -> adapter -> shared_resource_list_lock );
217+ }
218+
170219int dxgadapter_acquire_lock_exclusive (struct dxgadapter * adapter )
171220{
172221 down_write (& adapter -> core_lock );
@@ -680,6 +729,30 @@ void dxgdevice_release(struct kref *refcount)
680729 vfree (device );
681730}
682731
732+ void dxgdevice_add_syncobj (struct dxgdevice * device ,
733+ struct dxgsyncobject * syncobj )
734+ {
735+ dxgdevice_acquire_alloc_list_lock (device );
736+ list_add_tail (& syncobj -> syncobj_list_entry , & device -> syncobj_list_head );
737+ kref_get (& syncobj -> syncobj_kref );
738+ dxgdevice_release_alloc_list_lock (device );
739+ }
740+
741+ void dxgdevice_remove_syncobj (struct dxgsyncobject * entry )
742+ {
743+ struct dxgdevice * device = entry -> device ;
744+
745+ dxgdevice_acquire_alloc_list_lock (device );
746+ if (entry -> syncobj_list_entry .next ) {
747+ list_del (& entry -> syncobj_list_entry );
748+ entry -> syncobj_list_entry .next = NULL ;
749+ kref_put (& entry -> syncobj_kref , dxgsyncobject_release );
750+ }
751+ dxgdevice_release_alloc_list_lock (device );
752+ kref_put (& device -> device_kref , dxgdevice_release );
753+ entry -> device = NULL ;
754+ }
755+
683756struct dxgcontext * dxgcontext_create (struct dxgdevice * device )
684757{
685758 struct dxgcontext * context = vzalloc (sizeof (struct dxgcontext ));
@@ -935,28 +1008,221 @@ void dxgprocess_adapter_remove_device(struct dxgdevice *device)
9351008 mutex_unlock (& device -> adapter_info -> device_list_mutex );
9361009}
9371010
938- void dxghwqueue_destroy (struct dxgprocess * process , struct dxghwqueue * hwqueue )
1011+ struct dxgsharedsyncobject * dxgsharedsyncobj_create (struct dxgadapter * adapter ,
1012+ struct dxgsyncobject * so )
9391013{
940- /* Placeholder */
1014+ struct dxgsharedsyncobject * syncobj ;
1015+
1016+ syncobj = vzalloc (sizeof (* syncobj ));
1017+ if (syncobj ) {
1018+ kref_init (& syncobj -> ssyncobj_kref );
1019+ INIT_LIST_HEAD (& syncobj -> shared_syncobj_list_head );
1020+ syncobj -> adapter = adapter ;
1021+ syncobj -> type = so -> type ;
1022+ syncobj -> monitored_fence = so -> monitored_fence ;
1023+ dxgadapter_add_shared_syncobj (adapter , syncobj );
1024+ kref_get (& adapter -> adapter_kref );
1025+ init_rwsem (& syncobj -> syncobj_list_lock );
1026+ mutex_init (& syncobj -> fd_mutex );
1027+ }
1028+ return syncobj ;
9411029}
9421030
943- void dxgpagingqueue_destroy (struct dxgpagingqueue * pqueue )
1031+ void dxgsharedsyncobj_release (struct kref * refcount )
9441032{
945- /* Placeholder */
1033+ struct dxgsharedsyncobject * syncobj ;
1034+
1035+ syncobj = container_of (refcount , struct dxgsharedsyncobject ,
1036+ ssyncobj_kref );
1037+ dev_dbg (dxgglobaldev , "Destroying shared sync object %p" , syncobj );
1038+ if (syncobj -> adapter ) {
1039+ dxgadapter_remove_shared_syncobj (syncobj -> adapter ,
1040+ syncobj );
1041+ kref_put (& syncobj -> adapter -> adapter_kref ,
1042+ dxgadapter_release );
1043+ }
1044+ vfree (syncobj );
9461045}
9471046
948- void dxgpagingqueue_stop (struct dxgpagingqueue * pqueue )
1047+ void dxgsharedsyncobj_add_syncobj (struct dxgsharedsyncobject * shared ,
1048+ struct dxgsyncobject * syncobj )
9491049{
950- /* Placeholder */
1050+ dev_dbg (dxgglobaldev , "%s 0x%p 0x%p" , __func__ , shared , syncobj );
1051+ kref_get (& shared -> ssyncobj_kref );
1052+ down_write (& shared -> syncobj_list_lock );
1053+ list_add (& syncobj -> shared_syncobj_list_entry ,
1054+ & shared -> shared_syncobj_list_head );
1055+ syncobj -> shared_owner = shared ;
1056+ up_write (& shared -> syncobj_list_lock );
1057+ }
1058+
1059+ void dxgsharedsyncobj_remove_syncobj (struct dxgsharedsyncobject * shared ,
1060+ struct dxgsyncobject * syncobj )
1061+ {
1062+ dev_dbg (dxgglobaldev , "%s 0x%p" , __func__ , shared );
1063+ down_write (& shared -> syncobj_list_lock );
1064+ list_del (& syncobj -> shared_syncobj_list_entry );
1065+ up_write (& shared -> syncobj_list_lock );
1066+ }
1067+
1068+ struct dxgsyncobject * dxgsyncobject_create (struct dxgprocess * process ,
1069+ struct dxgdevice * device ,
1070+ struct dxgadapter * adapter ,
1071+ enum
1072+ d3dddi_synchronizationobject_type
1073+ type ,
1074+ struct
1075+ d3dddi_synchronizationobject_flags
1076+ flags )
1077+ {
1078+ struct dxgsyncobject * syncobj ;
1079+
1080+ syncobj = vzalloc (sizeof (* syncobj ));
1081+ if (syncobj == NULL )
1082+ goto cleanup ;
1083+ syncobj -> type = type ;
1084+ syncobj -> process = process ;
1085+ switch (type ) {
1086+ case _D3DDDI_MONITORED_FENCE :
1087+ case _D3DDDI_PERIODIC_MONITORED_FENCE :
1088+ syncobj -> monitored_fence = 1 ;
1089+ break ;
1090+ case _D3DDDI_CPU_NOTIFICATION :
1091+ syncobj -> cpu_event = 1 ;
1092+ syncobj -> host_event = vzalloc (sizeof (struct dxghostevent ));
1093+ if (syncobj -> host_event == NULL )
1094+ goto cleanup ;
1095+ break ;
1096+ default :
1097+ break ;
1098+ }
1099+ if (flags .shared ) {
1100+ syncobj -> shared = 1 ;
1101+ if (!flags .nt_security_sharing ) {
1102+ dev_err (dxgglobaldev ,
1103+ "%s: nt_security_sharing must be set" ,
1104+ __func__ );
1105+ goto cleanup ;
1106+ }
1107+ }
1108+
1109+ kref_init (& syncobj -> syncobj_kref );
1110+
1111+ if (syncobj -> monitored_fence ) {
1112+ syncobj -> device = device ;
1113+ syncobj -> device_handle = device -> handle ;
1114+ kref_get (& device -> device_kref );
1115+ dxgdevice_add_syncobj (device , syncobj );
1116+ } else {
1117+ dxgadapter_add_syncobj (adapter , syncobj );
1118+ }
1119+ syncobj -> adapter = adapter ;
1120+ kref_get (& adapter -> adapter_kref );
1121+
1122+ dev_dbg (dxgglobaldev , "%s 0x%p\n" , __func__ , syncobj );
1123+ return syncobj ;
1124+ cleanup :
1125+ if (syncobj -> host_event )
1126+ vfree (syncobj -> host_event );
1127+ if (syncobj )
1128+ vfree (syncobj );
1129+ return NULL ;
9511130}
9521131
9531132void dxgsyncobject_destroy (struct dxgprocess * process ,
9541133 struct dxgsyncobject * syncobj )
9551134{
956- /* Placeholder */
1135+ int destroyed ;
1136+ struct dxghosteventcpu * host_event ;
1137+
1138+ dev_dbg (dxgglobaldev , "%s 0x%p" , __func__ , syncobj );
1139+
1140+ dxgsyncobject_stop (syncobj );
1141+
1142+ destroyed = test_and_set_bit (0 , & syncobj -> flags );
1143+ if (!destroyed ) {
1144+ dev_dbg (dxgglobaldev , "Deleting handle: %x" , syncobj -> handle .v );
1145+ hmgrtable_lock (& process -> handle_table , DXGLOCK_EXCL );
1146+ if (syncobj -> handle .v ) {
1147+ hmgrtable_free_handle (& process -> handle_table ,
1148+ HMGRENTRY_TYPE_DXGSYNCOBJECT ,
1149+ syncobj -> handle );
1150+ syncobj -> handle .v = 0 ;
1151+ kref_put (& syncobj -> syncobj_kref , dxgsyncobject_release );
1152+ }
1153+ hmgrtable_unlock (& process -> handle_table , DXGLOCK_EXCL );
1154+
1155+ if (syncobj -> cpu_event ) {
1156+ host_event = syncobj -> host_event ;
1157+ if (host_event -> cpu_event ) {
1158+ eventfd_ctx_put (host_event -> cpu_event );
1159+ if (host_event -> hdr .event_id )
1160+ dxgglobal_remove_host_event (
1161+ & host_event -> hdr );
1162+ host_event -> cpu_event = NULL ;
1163+ }
1164+ }
1165+ if (syncobj -> monitored_fence )
1166+ dxgdevice_remove_syncobj (syncobj );
1167+ else
1168+ dxgadapter_remove_syncobj (syncobj );
1169+ if (syncobj -> adapter ) {
1170+ kref_put (& syncobj -> adapter -> adapter_kref ,
1171+ dxgadapter_release );
1172+ syncobj -> adapter = NULL ;
1173+ }
1174+ }
1175+ kref_put (& syncobj -> syncobj_kref , dxgsyncobject_release );
9571176}
9581177
9591178void dxgsyncobject_stop (struct dxgsyncobject * syncobj )
1179+ {
1180+ int stopped = test_and_set_bit (1 , & syncobj -> flags );
1181+
1182+ if (!stopped ) {
1183+ dev_dbg (dxgglobaldev , "stopping" );
1184+ if (syncobj -> monitored_fence ) {
1185+ if (syncobj -> mapped_address ) {
1186+ int ret =
1187+ dxg_unmap_iospace (syncobj -> mapped_address ,
1188+ PAGE_SIZE );
1189+
1190+ (void )ret ;
1191+ dev_dbg (dxgglobaldev , "fence is unmapped %d %p\n" ,
1192+ ret , syncobj -> mapped_address );
1193+ syncobj -> mapped_address = NULL ;
1194+ }
1195+ }
1196+ }
1197+ }
1198+
1199+ void dxgsyncobject_release (struct kref * refcount )
1200+ {
1201+ struct dxgsyncobject * syncobj ;
1202+
1203+ syncobj = container_of (refcount , struct dxgsyncobject , syncobj_kref );
1204+ if (syncobj -> shared_owner ) {
1205+ dxgsharedsyncobj_remove_syncobj (syncobj -> shared_owner ,
1206+ syncobj );
1207+ kref_put (& syncobj -> shared_owner -> ssyncobj_kref ,
1208+ dxgsharedsyncobj_release );
1209+ }
1210+ if (syncobj -> host_event )
1211+ vfree (syncobj -> host_event );
1212+ vfree (syncobj );
1213+ }
1214+
1215+ void dxghwqueue_destroy (struct dxgprocess * process , struct dxghwqueue * hwqueue )
1216+ {
1217+ /* Placeholder */
1218+ }
1219+
1220+ void dxgpagingqueue_destroy (struct dxgpagingqueue * pqueue )
1221+ {
1222+ /* Placeholder */
1223+ }
1224+
1225+ void dxgpagingqueue_stop (struct dxgpagingqueue * pqueue )
9601226{
9611227 /* Placeholder */
9621228}
0 commit comments