@@ -708,14 +708,14 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args)
708708 const struct amdgpu_userq_funcs * uq_funcs ;
709709 struct amdgpu_usermode_queue * queue ;
710710 struct amdgpu_db_info db_info ;
711- bool skip_map_queue ;
712- u32 qid ;
713711 uint64_t index ;
714- int r = 0 ;
715- int priority =
716- (args -> in .flags & AMDGPU_USERQ_CREATE_FLAGS_QUEUE_PRIORITY_MASK ) >>
717- AMDGPU_USERQ_CREATE_FLAGS_QUEUE_PRIORITY_SHIFT ;
712+ int priority ;
713+ u32 qid ;
714+ int r ;
718715
716+ priority =
717+ (args -> in .flags & AMDGPU_USERQ_CREATE_FLAGS_QUEUE_PRIORITY_MASK )
718+ >> AMDGPU_USERQ_CREATE_FLAGS_QUEUE_PRIORITY_SHIFT ;
719719 r = amdgpu_userq_priority_permit (filp , priority );
720720 if (r )
721721 return r ;
@@ -728,47 +728,54 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args)
728728
729729 uq_funcs = adev -> userq_funcs [args -> in .ip_type ];
730730 if (!uq_funcs ) {
731- drm_file_err (uq_mgr -> file , "Usermode queue is not supported for this IP (%u)\n" ,
732- args -> in .ip_type );
733731 r = - EINVAL ;
734732 goto err_pm_runtime ;
735733 }
736734
737735 queue = kzalloc_obj (struct amdgpu_usermode_queue );
738736 if (!queue ) {
739- drm_file_err (uq_mgr -> file , "Failed to allocate memory for queue\n" );
740737 r = - ENOMEM ;
741738 goto err_pm_runtime ;
742739 }
743740
741+ kref_init (& queue -> refcount );
744742 INIT_LIST_HEAD (& queue -> userq_va_list );
745743 queue -> doorbell_handle = args -> in .doorbell_handle ;
746744 queue -> queue_type = args -> in .ip_type ;
747745 queue -> vm = & fpriv -> vm ;
748746 queue -> priority = priority ;
749-
750- db_info .queue_type = queue -> queue_type ;
751- db_info .doorbell_handle = queue -> doorbell_handle ;
752- db_info .db_obj = & queue -> db_obj ;
753- db_info .doorbell_offset = args -> in .doorbell_offset ;
754-
755747 queue -> userq_mgr = uq_mgr ;
748+ INIT_DELAYED_WORK (& queue -> hang_detect_work ,
749+ amdgpu_userq_hang_detect_work );
756750
757- /* Validate the userq virtual address.*/
758- r = amdgpu_bo_reserve (fpriv -> vm .root .bo , false);
751+ mutex_init (& queue -> fence_drv_lock );
752+ xa_init_flags (& queue -> fence_drv_xa , XA_FLAGS_ALLOC );
753+ r = amdgpu_userq_fence_driver_alloc (adev , & queue -> fence_drv );
759754 if (r )
760755 goto free_queue ;
761756
762- if (amdgpu_userq_input_va_validate (adev , queue , args -> in .queue_va , args -> in .queue_size ) ||
763- amdgpu_userq_input_va_validate (adev , queue , args -> in .rptr_va , AMDGPU_GPU_PAGE_SIZE ) ||
764- amdgpu_userq_input_va_validate (adev , queue , args -> in .wptr_va , AMDGPU_GPU_PAGE_SIZE )) {
757+ /* Make sure the queue can actually run with those virtual addresses. */
758+ r = amdgpu_bo_reserve (fpriv -> vm .root .bo , false);
759+ if (r )
760+ goto free_fence_drv ;
761+
762+ if (amdgpu_userq_input_va_validate (adev , queue , args -> in .queue_va ,
763+ args -> in .queue_size ) ||
764+ amdgpu_userq_input_va_validate (adev , queue , args -> in .rptr_va ,
765+ AMDGPU_GPU_PAGE_SIZE ) ||
766+ amdgpu_userq_input_va_validate (adev , queue , args -> in .wptr_va ,
767+ AMDGPU_GPU_PAGE_SIZE )) {
765768 r = - EINVAL ;
766769 amdgpu_bo_unreserve (fpriv -> vm .root .bo );
767770 goto clean_mapping ;
768771 }
769772 amdgpu_bo_unreserve (fpriv -> vm .root .bo );
770773
771774 /* Convert relative doorbell offset into absolute doorbell index */
775+ db_info .queue_type = queue -> queue_type ;
776+ db_info .doorbell_handle = queue -> doorbell_handle ;
777+ db_info .db_obj = & queue -> db_obj ;
778+ db_info .doorbell_offset = args -> in .doorbell_offset ;
772779 index = amdgpu_userq_get_doorbell_index (uq_mgr , & db_info , filp );
773780 if (index == (uint64_t )- EINVAL ) {
774781 drm_file_err (uq_mgr -> file , "Failed to get doorbell for queue\n" );
@@ -777,85 +784,64 @@ amdgpu_userq_create(struct drm_file *filp, union drm_amdgpu_userq *args)
777784 }
778785
779786 queue -> doorbell_index = index ;
780- mutex_init (& queue -> fence_drv_lock );
781- xa_init_flags (& queue -> fence_drv_xa , XA_FLAGS_ALLOC );
782- r = amdgpu_userq_fence_driver_alloc (adev , & queue -> fence_drv );
783- if (r ) {
784- drm_file_err (uq_mgr -> file , "Failed to alloc fence driver\n" );
785- goto clean_mapping ;
786- }
787-
788787 r = uq_funcs -> mqd_create (queue , & args -> in );
789788 if (r ) {
790789 drm_file_err (uq_mgr -> file , "Failed to create Queue\n" );
791- goto clean_fence_driver ;
790+ goto clean_mapping ;
792791 }
793792
794793 /* Update VM owner at userq submit-time for page-fault attribution. */
795794 amdgpu_vm_set_task_info (& fpriv -> vm );
796795
796+ r = xa_err (xa_store_irq (& adev -> userq_doorbell_xa , index , queue ,
797+ GFP_KERNEL ));
798+ if (r )
799+ goto clean_mqd ;
800+
797801 amdgpu_userq_ensure_ev_fence (& fpriv -> userq_mgr , & fpriv -> evf_mgr );
798802
799803 /* don't map the queue if scheduling is halted */
800- if (adev -> userq_halt_for_enforce_isolation &&
801- ((queue -> queue_type == AMDGPU_HW_IP_GFX ) ||
802- (queue -> queue_type == AMDGPU_HW_IP_COMPUTE )))
803- skip_map_queue = true;
804- else
805- skip_map_queue = false;
806- if (!skip_map_queue ) {
804+ if (!adev -> userq_halt_for_enforce_isolation ||
805+ ((queue -> queue_type != AMDGPU_HW_IP_GFX ) &&
806+ (queue -> queue_type != AMDGPU_HW_IP_COMPUTE ))) {
807807 r = amdgpu_userq_map_helper (queue );
808808 if (r ) {
809809 drm_file_err (uq_mgr -> file , "Failed to map Queue\n" );
810- goto clean_mqd ;
810+ mutex_unlock (& uq_mgr -> userq_mutex );
811+ goto clean_doorbell ;
811812 }
812813 }
813814
814- /* drop this refcount during queue destroy */
815- kref_init (& queue -> refcount );
816-
817- /* Wait for mode-1 reset to complete */
818- down_read (& adev -> reset_domain -> sem );
815+ atomic_inc (& uq_mgr -> userq_count [queue -> queue_type ]);
816+ mutex_unlock (& uq_mgr -> userq_mutex );
819817
820818 r = xa_alloc (& uq_mgr -> userq_xa , & qid , queue ,
821- XA_LIMIT (1 , AMDGPU_MAX_USERQ_COUNT ), GFP_KERNEL );
822- if (r ) {
823- if (!skip_map_queue )
824- amdgpu_userq_unmap_helper (queue );
825- r = - ENOMEM ;
826- goto clean_reset_domain ;
827- }
828-
829- r = xa_err (xa_store_irq (& adev -> userq_doorbell_xa , index , queue , GFP_KERNEL ));
819+ XA_LIMIT (1 , AMDGPU_MAX_USERQ_COUNT ),
820+ GFP_KERNEL );
830821 if (r ) {
831- xa_erase (& uq_mgr -> userq_xa , qid );
832- if (!skip_map_queue )
833- amdgpu_userq_unmap_helper (queue );
834- goto clean_reset_domain ;
822+ /*
823+ * This drops the last reference which should take care of
824+ * all cleanup.
825+ */
826+ amdgpu_userq_put (queue );
827+ return r ;
835828 }
836- up_read (& adev -> reset_domain -> sem );
837829
838830 amdgpu_debugfs_userq_init (filp , queue , qid );
839- INIT_DELAYED_WORK (& queue -> hang_detect_work ,
840- amdgpu_userq_hang_detect_work );
841-
842831 args -> out .queue_id = qid ;
843- atomic_inc (& uq_mgr -> userq_count [queue -> queue_type ]);
844- mutex_unlock (& uq_mgr -> userq_mutex );
845832 return 0 ;
846833
847- clean_reset_domain :
848- up_read (& adev -> reset_domain -> sem );
834+ clean_doorbell :
835+ xa_erase_irq (& adev -> userq_doorbell_xa , index );
849836clean_mqd :
850- mutex_unlock (& uq_mgr -> userq_mutex );
851837 uq_funcs -> mqd_destroy (queue );
852- clean_fence_driver :
853- amdgpu_userq_fence_driver_free (queue );
854838clean_mapping :
855839 amdgpu_bo_reserve (fpriv -> vm .root .bo , true);
856840 amdgpu_userq_buffer_vas_list_cleanup (adev , queue );
857841 amdgpu_bo_unreserve (fpriv -> vm .root .bo );
858842 mutex_destroy (& queue -> fence_drv_lock );
843+ free_fence_drv :
844+ amdgpu_userq_fence_driver_free (queue );
859845free_queue :
860846 kfree (queue );
861847err_pm_runtime :
0 commit comments