@@ -448,6 +448,230 @@ void dxgdevice_remove_context(struct dxgdevice *device,
448448 }
449449}
450450
451+ void dxgdevice_add_alloc (struct dxgdevice * device , struct dxgallocation * alloc )
452+ {
453+ dxgdevice_acquire_alloc_list_lock (device );
454+ list_add_tail (& alloc -> alloc_list_entry , & device -> alloc_list_head );
455+ kref_get (& device -> device_kref );
456+ alloc -> owner .device = device ;
457+ dxgdevice_release_alloc_list_lock (device );
458+ }
459+
460+ void dxgdevice_remove_alloc (struct dxgdevice * device ,
461+ struct dxgallocation * alloc )
462+ {
463+ if (alloc -> alloc_list_entry .next ) {
464+ list_del (& alloc -> alloc_list_entry );
465+ alloc -> alloc_list_entry .next = NULL ;
466+ kref_put (& device -> device_kref , dxgdevice_release );
467+ }
468+ }
469+
470+ void dxgdevice_remove_alloc_safe (struct dxgdevice * device ,
471+ struct dxgallocation * alloc )
472+ {
473+ dxgdevice_acquire_alloc_list_lock (device );
474+ dxgdevice_remove_alloc (device , alloc );
475+ dxgdevice_release_alloc_list_lock (device );
476+ }
477+
478+ void dxgdevice_add_resource (struct dxgdevice * device , struct dxgresource * res )
479+ {
480+ dxgdevice_acquire_alloc_list_lock (device );
481+ list_add_tail (& res -> resource_list_entry , & device -> resource_list_head );
482+ kref_get (& device -> device_kref );
483+ dxgdevice_release_alloc_list_lock (device );
484+ }
485+
486+ void dxgdevice_remove_resource (struct dxgdevice * device ,
487+ struct dxgresource * res )
488+ {
489+ if (res -> resource_list_entry .next ) {
490+ list_del (& res -> resource_list_entry );
491+ res -> resource_list_entry .next = NULL ;
492+ kref_put (& device -> device_kref , dxgdevice_release );
493+ }
494+ }
495+
496+ struct dxgsharedresource * dxgsharedresource_create (struct dxgadapter * adapter )
497+ {
498+ struct dxgsharedresource * resource ;
499+
500+ resource = vzalloc (sizeof (* resource ));
501+ if (resource ) {
502+ INIT_LIST_HEAD (& resource -> resource_list_head );
503+ kref_init (& resource -> sresource_kref );
504+ mutex_init (& resource -> fd_mutex );
505+ resource -> adapter = adapter ;
506+ }
507+ return resource ;
508+ }
509+
510+ void dxgsharedresource_destroy (struct kref * refcount )
511+ {
512+ struct dxgsharedresource * resource ;
513+
514+ resource = container_of (refcount , struct dxgsharedresource ,
515+ sresource_kref );
516+ if (resource -> runtime_private_data )
517+ vfree (resource -> runtime_private_data );
518+ if (resource -> resource_private_data )
519+ vfree (resource -> resource_private_data );
520+ if (resource -> alloc_private_data_sizes )
521+ vfree (resource -> alloc_private_data_sizes );
522+ if (resource -> alloc_private_data )
523+ vfree (resource -> alloc_private_data );
524+ vfree (resource );
525+ }
526+
527+ void dxgsharedresource_add_resource (struct dxgsharedresource * shared_resource ,
528+ struct dxgresource * resource )
529+ {
530+ down_write (& shared_resource -> adapter -> shared_resource_list_lock );
531+ dev_dbg (dxgglobaldev , "%s: %p %p" , __func__ , shared_resource , resource );
532+ list_add_tail (& resource -> shared_resource_list_entry ,
533+ & shared_resource -> resource_list_head );
534+ kref_get (& shared_resource -> sresource_kref );
535+ kref_get (& resource -> resource_kref );
536+ resource -> shared_owner = shared_resource ;
537+ up_write (& shared_resource -> adapter -> shared_resource_list_lock );
538+ }
539+
540+ void dxgsharedresource_remove_resource (struct dxgsharedresource
541+ * shared_resource ,
542+ struct dxgresource * resource )
543+ {
544+ struct dxgadapter * adapter = shared_resource -> adapter ;
545+
546+ down_write (& adapter -> shared_resource_list_lock );
547+ dev_dbg (dxgglobaldev , "%s: %p %p" , __func__ , shared_resource , resource );
548+ if (resource -> shared_resource_list_entry .next ) {
549+ list_del (& resource -> shared_resource_list_entry );
550+ resource -> shared_resource_list_entry .next = NULL ;
551+ kref_put (& shared_resource -> sresource_kref ,
552+ dxgsharedresource_destroy );
553+ resource -> shared_owner = NULL ;
554+ kref_put (& resource -> resource_kref , dxgresource_release );
555+ }
556+ up_write (& adapter -> shared_resource_list_lock );
557+ }
558+
559+ struct dxgresource * dxgresource_create (struct dxgdevice * device )
560+ {
561+ struct dxgresource * resource = vzalloc (sizeof (struct dxgresource ));
562+
563+ if (resource ) {
564+ kref_init (& resource -> resource_kref );
565+ resource -> device = device ;
566+ resource -> process = device -> process ;
567+ resource -> object_state = DXGOBJECTSTATE_ACTIVE ;
568+ mutex_init (& resource -> resource_mutex );
569+ INIT_LIST_HEAD (& resource -> alloc_list_head );
570+ dxgdevice_add_resource (device , resource );
571+ }
572+ return resource ;
573+ }
574+
575+ void dxgresource_free_handle (struct dxgresource * resource )
576+ {
577+ struct dxgallocation * alloc ;
578+ struct dxgprocess * process ;
579+
580+ if (resource -> handle_valid ) {
581+ process = resource -> device -> process ;
582+ hmgrtable_free_handle_safe (& process -> handle_table ,
583+ HMGRENTRY_TYPE_DXGRESOURCE ,
584+ resource -> handle );
585+ resource -> handle_valid = 0 ;
586+ }
587+ list_for_each_entry (alloc , & resource -> alloc_list_head ,
588+ alloc_list_entry ) {
589+ dxgallocation_free_handle (alloc );
590+ }
591+ }
592+
593+ void dxgresource_destroy (struct dxgresource * resource )
594+ {
595+ /* device->alloc_list_lock is held */
596+ struct dxgallocation * alloc ;
597+ struct dxgallocation * tmp ;
598+ struct d3dkmt_destroyallocation2 args = { };
599+ int destroyed = test_and_set_bit (0 , & resource -> flags );
600+ struct dxgdevice * device = resource -> device ;
601+ struct dxgsharedresource * shared_resource ;
602+
603+ if (!destroyed ) {
604+ dxgresource_free_handle (resource );
605+ if (resource -> handle .v ) {
606+ args .device = device -> handle ;
607+ args .resource = resource -> handle ;
608+ dxgvmb_send_destroy_allocation (device -> process ,
609+ device , & args , NULL );
610+ resource -> handle .v = 0 ;
611+ }
612+ list_for_each_entry_safe (alloc , tmp , & resource -> alloc_list_head ,
613+ alloc_list_entry ) {
614+ dxgallocation_destroy (alloc );
615+ }
616+ dxgdevice_remove_resource (device , resource );
617+ shared_resource = resource -> shared_owner ;
618+ if (shared_resource ) {
619+ dxgsharedresource_remove_resource (shared_resource ,
620+ resource );
621+ resource -> shared_owner = NULL ;
622+ }
623+ }
624+ kref_put (& resource -> resource_kref , dxgresource_release );
625+ }
626+
627+ void dxgresource_release (struct kref * refcount )
628+ {
629+ struct dxgresource * resource ;
630+
631+ resource = container_of (refcount , struct dxgresource , resource_kref );
632+ vfree (resource );
633+ }
634+
635+ bool dxgresource_is_active (struct dxgresource * resource )
636+ {
637+ return resource -> object_state == DXGOBJECTSTATE_ACTIVE ;
638+ }
639+
640+ int dxgresource_add_alloc (struct dxgresource * resource ,
641+ struct dxgallocation * alloc )
642+ {
643+ int ret = - ENODEV ;
644+ struct dxgdevice * device = resource -> device ;
645+
646+ dxgdevice_acquire_alloc_list_lock (device );
647+ if (dxgresource_is_active (resource )) {
648+ list_add_tail (& alloc -> alloc_list_entry ,
649+ & resource -> alloc_list_head );
650+ alloc -> owner .resource = resource ;
651+ ret = 0 ;
652+ }
653+ alloc -> resource_owner = 1 ;
654+ dxgdevice_release_alloc_list_lock (device );
655+ return ret ;
656+ }
657+
658+ void dxgresource_remove_alloc (struct dxgresource * resource ,
659+ struct dxgallocation * alloc )
660+ {
661+ if (alloc -> alloc_list_entry .next ) {
662+ list_del (& alloc -> alloc_list_entry );
663+ alloc -> alloc_list_entry .next = NULL ;
664+ }
665+ }
666+
667+ void dxgresource_remove_alloc_safe (struct dxgresource * resource ,
668+ struct dxgallocation * alloc )
669+ {
670+ dxgdevice_acquire_alloc_list_lock (resource -> device );
671+ dxgresource_remove_alloc (resource , alloc );
672+ dxgdevice_release_alloc_list_lock (resource -> device );
673+ }
674+
451675void dxgdevice_release (struct kref * refcount )
452676{
453677 struct dxgdevice * device ;
@@ -523,6 +747,76 @@ void dxgcontext_release(struct kref *refcount)
523747 vfree (context );
524748}
525749
750+ struct dxgallocation * dxgallocation_create (struct dxgprocess * process )
751+ {
752+ struct dxgallocation * alloc = vzalloc (sizeof (struct dxgallocation ));
753+
754+ if (alloc )
755+ alloc -> process = process ;
756+ return alloc ;
757+ }
758+
759+ void dxgallocation_stop (struct dxgallocation * alloc )
760+ {
761+ if (alloc -> pages ) {
762+ release_pages (alloc -> pages , alloc -> num_pages );
763+ vfree (alloc -> pages );
764+ alloc -> pages = NULL ;
765+ }
766+ dxgprocess_ht_lock_exclusive_down (alloc -> process );
767+ if (alloc -> cpu_address_mapped ) {
768+ dxg_unmap_iospace (alloc -> cpu_address ,
769+ alloc -> num_pages << PAGE_SHIFT );
770+ alloc -> cpu_address_mapped = false;
771+ alloc -> cpu_address = NULL ;
772+ alloc -> cpu_address_refcount = 0 ;
773+ }
774+ dxgprocess_ht_lock_exclusive_up (alloc -> process );
775+ }
776+
777+ void dxgallocation_free_handle (struct dxgallocation * alloc )
778+ {
779+ dxgprocess_ht_lock_exclusive_down (alloc -> process );
780+ if (alloc -> handle_valid ) {
781+ hmgrtable_free_handle (& alloc -> process -> handle_table ,
782+ HMGRENTRY_TYPE_DXGALLOCATION ,
783+ alloc -> alloc_handle );
784+ alloc -> handle_valid = 0 ;
785+ }
786+ dxgprocess_ht_lock_exclusive_up (alloc -> process );
787+ }
788+
789+ void dxgallocation_destroy (struct dxgallocation * alloc )
790+ {
791+ struct dxgprocess * process = alloc -> process ;
792+ struct d3dkmt_destroyallocation2 args = { };
793+
794+ dxgallocation_stop (alloc );
795+ if (alloc -> resource_owner )
796+ dxgresource_remove_alloc (alloc -> owner .resource , alloc );
797+ else if (alloc -> owner .device )
798+ dxgdevice_remove_alloc (alloc -> owner .device , alloc );
799+ dxgallocation_free_handle (alloc );
800+ if (alloc -> alloc_handle .v && !alloc -> resource_owner ) {
801+ args .device = alloc -> owner .device -> handle ;
802+ args .alloc_count = 1 ;
803+ dxgvmb_send_destroy_allocation (process ,
804+ alloc -> owner .device ,
805+ & args , & alloc -> alloc_handle );
806+ }
807+ if (alloc -> gpadl ) {
808+ dev_dbg (dxgglobaldev , "Teardown gpadl %d" , alloc -> gpadl );
809+ vmbus_teardown_gpadl (dxgglobal_get_vmbus (), alloc -> gpadl );
810+ dev_dbg (dxgglobaldev , "Teardown gpadl end" );
811+ alloc -> gpadl = 0 ;
812+ }
813+ if (alloc -> priv_drv_data )
814+ vfree (alloc -> priv_drv_data );
815+ if (alloc -> cpu_address_mapped )
816+ pr_err ("Alloc IO space is mapped: %p" , alloc );
817+ vfree (alloc );
818+ }
819+
526820struct dxgprocess_adapter * dxgprocess_adapter_create (struct dxgprocess * process ,
527821 struct dxgadapter * adapter )
528822{
@@ -656,21 +950,6 @@ void dxgpagingqueue_stop(struct dxgpagingqueue *pqueue)
656950 /* Placeholder */
657951}
658952
659- void dxgallocation_destroy (struct dxgallocation * alloc )
660- {
661- /* Placeholder */
662- }
663-
664- void dxgallocation_stop (struct dxgallocation * alloc )
665- {
666- /* Placeholder */
667- }
668-
669- void dxgresource_destroy (struct dxgresource * resource )
670- {
671- /* Placeholder */
672- }
673-
674953void dxgsyncobject_destroy (struct dxgprocess * process ,
675954 struct dxgsyncobject * syncobj )
676955{
0 commit comments