All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mario Kleiner <mario.kleiner.de@gmail.com>
To: Dan Carpenter <dan.carpenter@oracle.com>
Cc: dri-devel@lists.freedesktop.org
Subject: Re: drm/amdgpu: Don't hang in amdgpu_flip_work_func on disabled crtc.
Date: Tue, 1 Mar 2016 21:35:21 +0100	[thread overview]
Message-ID: <56D5FD09.1060803@gmail.com> (raw)
In-Reply-To: <20160229201007.GA32069@mwanda>

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

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

      reply	other threads:[~2016-03-01 20:35 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-02-29 20:10 drm/amdgpu: Don't hang in amdgpu_flip_work_func on disabled crtc Dan Carpenter
2016-03-01 20:35 ` Mario Kleiner [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=56D5FD09.1060803@gmail.com \
    --to=mario.kleiner.de@gmail.com \
    --cc=dan.carpenter@oracle.com \
    --cc=dri-devel@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.