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