@@ -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 );
@@ -679,6 +728,30 @@ void dxgdevice_release(struct kref *refcount)
679728 vfree (device );
680729}
681730
731+ void dxgdevice_add_syncobj (struct dxgdevice * device ,
732+ struct dxgsyncobject * syncobj )
733+ {
734+ dxgdevice_acquire_alloc_list_lock (device );
735+ list_add_tail (& syncobj -> syncobj_list_entry , & device -> syncobj_list_head );
736+ kref_get (& syncobj -> syncobj_kref );
737+ dxgdevice_release_alloc_list_lock (device );
738+ }
739+
740+ void dxgdevice_remove_syncobj (struct dxgsyncobject * entry )
741+ {
742+ struct dxgdevice * device = entry -> device ;
743+
744+ dxgdevice_acquire_alloc_list_lock (device );
745+ if (entry -> syncobj_list_entry .next ) {
746+ list_del (& entry -> syncobj_list_entry );
747+ entry -> syncobj_list_entry .next = NULL ;
748+ kref_put (& entry -> syncobj_kref , dxgsyncobject_release );
749+ }
750+ dxgdevice_release_alloc_list_lock (device );
751+ kref_put (& device -> device_kref , dxgdevice_release );
752+ entry -> device = NULL ;
753+ }
754+
682755struct dxgcontext * dxgcontext_create (struct dxgdevice * device )
683756{
684757 struct dxgcontext * context = vzalloc (sizeof (struct dxgcontext ));
@@ -934,28 +1007,221 @@ void dxgprocess_adapter_remove_device(struct dxgdevice *device)
9341007 mutex_unlock (& device -> adapter_info -> device_list_mutex );
9351008}
9361009
937- void dxghwqueue_destroy (struct dxgprocess * process , struct dxghwqueue * hwqueue )
1010+ struct dxgsharedsyncobject * dxgsharedsyncobj_create (struct dxgadapter * adapter ,
1011+ struct dxgsyncobject * so )
9381012{
939- /* Placeholder */
1013+ struct dxgsharedsyncobject * syncobj ;
1014+
1015+ syncobj = vzalloc (sizeof (* syncobj ));
1016+ if (syncobj ) {
1017+ kref_init (& syncobj -> ssyncobj_kref );
1018+ INIT_LIST_HEAD (& syncobj -> shared_syncobj_list_head );
1019+ syncobj -> adapter = adapter ;
1020+ syncobj -> type = so -> type ;
1021+ syncobj -> monitored_fence = so -> monitored_fence ;
1022+ dxgadapter_add_shared_syncobj (adapter , syncobj );
1023+ kref_get (& adapter -> adapter_kref );
1024+ init_rwsem (& syncobj -> syncobj_list_lock );
1025+ mutex_init (& syncobj -> fd_mutex );
1026+ }
1027+ return syncobj ;
9401028}
9411029
942- void dxgpagingqueue_destroy (struct dxgpagingqueue * pqueue )
1030+ void dxgsharedsyncobj_release (struct kref * refcount )
9431031{
944- /* Placeholder */
1032+ struct dxgsharedsyncobject * syncobj ;
1033+
1034+ syncobj = container_of (refcount , struct dxgsharedsyncobject ,
1035+ ssyncobj_kref );
1036+ dev_dbg (dxgglobaldev , "Destroying shared sync object %p" , syncobj );
1037+ if (syncobj -> adapter ) {
1038+ dxgadapter_remove_shared_syncobj (syncobj -> adapter ,
1039+ syncobj );
1040+ kref_put (& syncobj -> adapter -> adapter_kref ,
1041+ dxgadapter_release );
1042+ }
1043+ vfree (syncobj );
9451044}
9461045
947- void dxgpagingqueue_stop (struct dxgpagingqueue * pqueue )
1046+ void dxgsharedsyncobj_add_syncobj (struct dxgsharedsyncobject * shared ,
1047+ struct dxgsyncobject * syncobj )
9481048{
949- /* Placeholder */
1049+ dev_dbg (dxgglobaldev , "%s 0x%p 0x%p" , __func__ , shared , syncobj );
1050+ kref_get (& shared -> ssyncobj_kref );
1051+ down_write (& shared -> syncobj_list_lock );
1052+ list_add (& syncobj -> shared_syncobj_list_entry ,
1053+ & shared -> shared_syncobj_list_head );
1054+ syncobj -> shared_owner = shared ;
1055+ up_write (& shared -> syncobj_list_lock );
1056+ }
1057+
1058+ void dxgsharedsyncobj_remove_syncobj (struct dxgsharedsyncobject * shared ,
1059+ struct dxgsyncobject * syncobj )
1060+ {
1061+ dev_dbg (dxgglobaldev , "%s 0x%p" , __func__ , shared );
1062+ down_write (& shared -> syncobj_list_lock );
1063+ list_del (& syncobj -> shared_syncobj_list_entry );
1064+ up_write (& shared -> syncobj_list_lock );
1065+ }
1066+
1067+ struct dxgsyncobject * dxgsyncobject_create (struct dxgprocess * process ,
1068+ struct dxgdevice * device ,
1069+ struct dxgadapter * adapter ,
1070+ enum
1071+ d3dddi_synchronizationobject_type
1072+ type ,
1073+ struct
1074+ d3dddi_synchronizationobject_flags
1075+ flags )
1076+ {
1077+ struct dxgsyncobject * syncobj ;
1078+
1079+ syncobj = vzalloc (sizeof (* syncobj ));
1080+ if (syncobj == NULL )
1081+ goto cleanup ;
1082+ syncobj -> type = type ;
1083+ syncobj -> process = process ;
1084+ switch (type ) {
1085+ case _D3DDDI_MONITORED_FENCE :
1086+ case _D3DDDI_PERIODIC_MONITORED_FENCE :
1087+ syncobj -> monitored_fence = 1 ;
1088+ break ;
1089+ case _D3DDDI_CPU_NOTIFICATION :
1090+ syncobj -> cpu_event = 1 ;
1091+ syncobj -> host_event = vzalloc (sizeof (struct dxghostevent ));
1092+ if (syncobj -> host_event == NULL )
1093+ goto cleanup ;
1094+ break ;
1095+ default :
1096+ break ;
1097+ }
1098+ if (flags .shared ) {
1099+ syncobj -> shared = 1 ;
1100+ if (!flags .nt_security_sharing ) {
1101+ dev_err (dxgglobaldev ,
1102+ "%s: nt_security_sharing must be set" ,
1103+ __func__ );
1104+ goto cleanup ;
1105+ }
1106+ }
1107+
1108+ kref_init (& syncobj -> syncobj_kref );
1109+
1110+ if (syncobj -> monitored_fence ) {
1111+ syncobj -> device = device ;
1112+ syncobj -> device_handle = device -> handle ;
1113+ kref_get (& device -> device_kref );
1114+ dxgdevice_add_syncobj (device , syncobj );
1115+ } else {
1116+ dxgadapter_add_syncobj (adapter , syncobj );
1117+ }
1118+ syncobj -> adapter = adapter ;
1119+ kref_get (& adapter -> adapter_kref );
1120+
1121+ dev_dbg (dxgglobaldev , "%s 0x%p\n" , __func__ , syncobj );
1122+ return syncobj ;
1123+ cleanup :
1124+ if (syncobj -> host_event )
1125+ vfree (syncobj -> host_event );
1126+ if (syncobj )
1127+ vfree (syncobj );
1128+ return NULL ;
9501129}
9511130
9521131void dxgsyncobject_destroy (struct dxgprocess * process ,
9531132 struct dxgsyncobject * syncobj )
9541133{
955- /* Placeholder */
1134+ int destroyed ;
1135+ struct dxghosteventcpu * host_event ;
1136+
1137+ dev_dbg (dxgglobaldev , "%s 0x%p" , __func__ , syncobj );
1138+
1139+ dxgsyncobject_stop (syncobj );
1140+
1141+ destroyed = test_and_set_bit (0 , & syncobj -> flags );
1142+ if (!destroyed ) {
1143+ dev_dbg (dxgglobaldev , "Deleting handle: %x" , syncobj -> handle .v );
1144+ hmgrtable_lock (& process -> handle_table , DXGLOCK_EXCL );
1145+ if (syncobj -> handle .v ) {
1146+ hmgrtable_free_handle (& process -> handle_table ,
1147+ HMGRENTRY_TYPE_DXGSYNCOBJECT ,
1148+ syncobj -> handle );
1149+ syncobj -> handle .v = 0 ;
1150+ kref_put (& syncobj -> syncobj_kref , dxgsyncobject_release );
1151+ }
1152+ hmgrtable_unlock (& process -> handle_table , DXGLOCK_EXCL );
1153+
1154+ if (syncobj -> cpu_event ) {
1155+ host_event = syncobj -> host_event ;
1156+ if (host_event -> cpu_event ) {
1157+ eventfd_ctx_put (host_event -> cpu_event );
1158+ if (host_event -> hdr .event_id )
1159+ dxgglobal_remove_host_event (
1160+ & host_event -> hdr );
1161+ host_event -> cpu_event = NULL ;
1162+ }
1163+ }
1164+ if (syncobj -> monitored_fence )
1165+ dxgdevice_remove_syncobj (syncobj );
1166+ else
1167+ dxgadapter_remove_syncobj (syncobj );
1168+ if (syncobj -> adapter ) {
1169+ kref_put (& syncobj -> adapter -> adapter_kref ,
1170+ dxgadapter_release );
1171+ syncobj -> adapter = NULL ;
1172+ }
1173+ }
1174+ kref_put (& syncobj -> syncobj_kref , dxgsyncobject_release );
9561175}
9571176
9581177void dxgsyncobject_stop (struct dxgsyncobject * syncobj )
1178+ {
1179+ int stopped = test_and_set_bit (1 , & syncobj -> flags );
1180+
1181+ if (!stopped ) {
1182+ dev_dbg (dxgglobaldev , "stopping" );
1183+ if (syncobj -> monitored_fence ) {
1184+ if (syncobj -> mapped_address ) {
1185+ int ret =
1186+ dxg_unmap_iospace (syncobj -> mapped_address ,
1187+ PAGE_SIZE );
1188+
1189+ (void )ret ;
1190+ dev_dbg (dxgglobaldev , "fence is unmapped %d %p\n" ,
1191+ ret , syncobj -> mapped_address );
1192+ syncobj -> mapped_address = NULL ;
1193+ }
1194+ }
1195+ }
1196+ }
1197+
1198+ void dxgsyncobject_release (struct kref * refcount )
1199+ {
1200+ struct dxgsyncobject * syncobj ;
1201+
1202+ syncobj = container_of (refcount , struct dxgsyncobject , syncobj_kref );
1203+ if (syncobj -> shared_owner ) {
1204+ dxgsharedsyncobj_remove_syncobj (syncobj -> shared_owner ,
1205+ syncobj );
1206+ kref_put (& syncobj -> shared_owner -> ssyncobj_kref ,
1207+ dxgsharedsyncobj_release );
1208+ }
1209+ if (syncobj -> host_event )
1210+ vfree (syncobj -> host_event );
1211+ vfree (syncobj );
1212+ }
1213+
1214+ void dxghwqueue_destroy (struct dxgprocess * process , struct dxghwqueue * hwqueue )
1215+ {
1216+ /* Placeholder */
1217+ }
1218+
1219+ void dxgpagingqueue_destroy (struct dxgpagingqueue * pqueue )
1220+ {
1221+ /* Placeholder */
1222+ }
1223+
1224+ void dxgpagingqueue_stop (struct dxgpagingqueue * pqueue )
9591225{
9601226 /* Placeholder */
9611227}
0 commit comments