@@ -89,6 +89,16 @@ static u32 amdgpu_fence_read(struct amdgpu_ring *ring)
8989 return seq ;
9090}
9191
92+ static void amdgpu_fence_save_fence_wptr_start (struct amdgpu_fence * af )
93+ {
94+ af -> fence_wptr_start = af -> ring -> wptr ;
95+ }
96+
97+ static void amdgpu_fence_save_fence_wptr_end (struct amdgpu_fence * af )
98+ {
99+ af -> fence_wptr_end = af -> ring -> wptr ;
100+ }
101+
92102/**
93103 * amdgpu_fence_emit - emit a fence on the requested ring
94104 *
@@ -116,8 +126,10 @@ int amdgpu_fence_emit(struct amdgpu_ring *ring, struct amdgpu_fence *af,
116126 & ring -> fence_drv .lock ,
117127 adev -> fence_context + ring -> idx , seq );
118128
129+ amdgpu_fence_save_fence_wptr_start (af );
119130 amdgpu_ring_emit_fence (ring , ring -> fence_drv .gpu_addr ,
120131 seq , flags | AMDGPU_FENCE_FLAG_INT );
132+ amdgpu_fence_save_fence_wptr_end (af );
121133 amdgpu_fence_save_wptr (af );
122134 pm_runtime_get_noresume (adev_to_drm (adev )-> dev );
123135 ptr = & ring -> fence_drv .fences [seq & ring -> fence_drv .num_fences_mask ];
@@ -709,6 +721,7 @@ void amdgpu_fence_driver_guilty_force_completion(struct amdgpu_fence *af)
709721 struct amdgpu_ring * ring = af -> ring ;
710722 unsigned long flags ;
711723 u32 seq , last_seq ;
724+ bool reemitted = false;
712725
713726 last_seq = amdgpu_fence_read (ring ) & ring -> fence_drv .num_fences_mask ;
714727 seq = ring -> fence_drv .sync_seq & ring -> fence_drv .num_fences_mask ;
@@ -726,17 +739,22 @@ void amdgpu_fence_driver_guilty_force_completion(struct amdgpu_fence *af)
726739 if (unprocessed && !dma_fence_is_signaled_locked (unprocessed )) {
727740 fence = container_of (unprocessed , struct amdgpu_fence , base );
728741
729- if (fence == af )
742+ if (fence -> reemitted > 1 )
743+ reemitted = true;
744+ else if (fence == af )
730745 dma_fence_set_error (& fence -> base , - ETIME );
731746 else if (fence -> context == af -> context )
732747 dma_fence_set_error (& fence -> base , - ECANCELED );
733748 }
734749 rcu_read_unlock ();
735750 } while (last_seq != seq );
736751 spin_unlock_irqrestore (& ring -> fence_drv .lock , flags );
737- /* signal the guilty fence */
738- amdgpu_fence_write (ring , (u32 )af -> base .seqno );
739- amdgpu_fence_process (ring );
752+
753+ if (reemitted ) {
754+ /* if we've already reemitted once then just cancel everything */
755+ amdgpu_fence_driver_force_completion (af -> ring );
756+ af -> ring -> ring_backup_entries_to_copy = 0 ;
757+ }
740758}
741759
742760void amdgpu_fence_save_wptr (struct amdgpu_fence * af )
@@ -784,10 +802,18 @@ void amdgpu_ring_backup_unprocessed_commands(struct amdgpu_ring *ring,
784802 /* save everything if the ring is not guilty, otherwise
785803 * just save the content from other contexts.
786804 */
787- if (!guilty_fence || (fence -> context != guilty_fence -> context ))
805+ if (!fence -> reemitted &&
806+ (!guilty_fence || (fence -> context != guilty_fence -> context ))) {
788807 amdgpu_ring_backup_unprocessed_command (ring , wptr ,
789808 fence -> wptr );
809+ } else if (!fence -> reemitted ) {
810+ /* always save the fence */
811+ amdgpu_ring_backup_unprocessed_command (ring ,
812+ fence -> fence_wptr_start ,
813+ fence -> fence_wptr_end );
814+ }
790815 wptr = fence -> wptr ;
816+ fence -> reemitted ++ ;
791817 }
792818 rcu_read_unlock ();
793819 } while (last_seq != seq );
0 commit comments