On 02/29/2016 09:10 PM, Dan Carpenter wrote: > Hello Mario Kleiner, > > The patch e1d09dc0ccc6: "drm/amdgpu: Don't hang in > amdgpu_flip_work_func on disabled crtc." from Feb 19, 2016, leads to > the following static checker warning: > > drivers/gpu/drm/amd/amdgpu/amdgpu_display.c:127 amdgpu_flip_work_func() > warn: should this be 'repcnt == -1' > drivers/gpu/drm/amd/amdgpu/amdgpu_display.c:136 amdgpu_flip_work_func() > error: double unlock 'spin_lock:&crtc->dev->event_lock' > drivers/gpu/drm/amd/amdgpu/amdgpu_display.c:136 amdgpu_flip_work_func() > error: double unlock 'irqsave:flags' > > > drivers/gpu/drm/amd/amdgpu/amdgpu_display.c > 64 static void amdgpu_flip_work_func(struct work_struct *__work) > 65 { > 66 struct amdgpu_flip_work *work = > 67 container_of(__work, struct amdgpu_flip_work, > flip_work); > 68 struct amdgpu_device *adev = work->adev; > 69 struct amdgpu_crtc *amdgpuCrtc = > adev->mode_info.crtcs[work->crtc_id]; > 70 > 71 struct drm_crtc *crtc = &amdgpuCrtc->base; > 72 unsigned long flags; > 73 unsigned i, repcnt = 4; > 74 int vpos, hpos, stat, min_udelay = 0; > 75 struct drm_vblank_crtc *vblank = > &crtc->dev->vblank[work->crtc_id]; > 76 > 77 if (amdgpu_flip_handle_fence(work, &work->excl)) > 78 return; > 79 > 80 for (i = 0; i < work->shared_count; ++i) > 81 if (amdgpu_flip_handle_fence(work, &work->shared[i])) > 82 return; > 83 > 84 /* We borrow the event spin lock for protecting flip_status > */ > 85 spin_lock_irqsave(&crtc->dev->event_lock, flags); > 86 > 87 /* If this happens to execute within the "virtually > extended" vblank > 88 * interval before the start of the real vblank interval > then it needs > 89 * to delay programming the mmio flip until the real vblank > is entered. > 90 * This prevents completing a flip too early due to the way > we fudge > 91 * our vblank counter and vblank timestamps in order to work > around the > 92 * problem that the hw fires vblank interrupts before actual > start of > 93 * vblank (when line buffer refilling is done for a frame). > It > 94 * complements the fudging logic in > amdgpu_get_crtc_scanoutpos() for > 95 * timestamping and amdgpu_get_vblank_counter_kms() for > vblank counts. > 96 * > 97 * In practice this won't execute very often unless on very > fast > 98 * machines because the time window for this to happen is > very small. > 99 */ > 100 while (amdgpuCrtc->enabled && repcnt--) { > ^^^^^^^^ > Exists the loop with spin_lock held and repcnt == -1. > > > 101 /* GET_DISTANCE_TO_VBLANKSTART returns distance to > real vblank > 102 * start in hpos, and to the "fudged earlier" vblank > start in > 103 * vpos. > 104 */ > 105 stat = amdgpu_get_crtc_scanoutpos(adev->ddev, > work->crtc_id, > 106 > GET_DISTANCE_TO_VBLANKSTART, > 107 &vpos, &hpos, > NULL, NULL, > 108 &crtc->hwmode); > 109 > 110 if ((stat & (DRM_SCANOUTPOS_VALID | > DRM_SCANOUTPOS_ACCURATE)) != > 111 (DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE) > || > 112 !(vpos >= 0 && hpos <= 0)) > 113 break; > 114 > 115 /* Sleep at least until estimated real start of hw > vblank */ > 116 spin_unlock_irqrestore(&crtc->dev->event_lock, > flags); > 117 min_udelay = (-hpos + 1) * max(vblank->linedur_ns / > 1000, 5); > 118 if (min_udelay > vblank->framedur_ns / 2000) { > 119 /* Don't wait ridiculously long - something > is wrong */ > 120 repcnt = 0; > > Exit with spin_lock released and repcnt == 0. > > 121 break; > 122 } > 123 usleep_range(min_udelay, 2 * min_udelay); > 124 spin_lock_irqsave(&crtc->dev->event_lock, flags); > 125 }; > 126 > 127 if (!repcnt) > ^^^^^^ > Assumes exit with zero. > > 128 DRM_DEBUG_DRIVER("Delay problem on crtc %d: > min_udelay %d, " > 129 "framedur %d, linedur %d, stat %d, > vpos %d, " > 130 "hpos %d\n", work->crtc_id, > min_udelay, > 131 vblank->framedur_ns / 1000, > 132 vblank->linedur_ns / 1000, stat, > vpos, hpos); > 133 > 134 /* set the flip status */ > 135 amdgpuCrtc->pflip_status = AMDGPU_FLIP_SUBMITTED; > 136 spin_unlock_irqrestore(&crtc->dev->event_lock, flags); > > Assumes lock held. > > 137 > 138 /* Do the flip (mmio) */ > 139 adev->mode_info.funcs->page_flip(adev, work->crtc_id, > work->base); > 140 } > > regards, > dan carpenter >
Errors during error handling, my favorite bugs. Thanks for spotting this! Patches are out for review. -mario