All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dan Carpenter <dan.carpenter@oracle.com>
To: mario.kleiner.de@gmail.com
Cc: dri-devel@lists.freedesktop.org
Subject: re: drm/amdgpu: Don't hang in amdgpu_flip_work_func on disabled crtc.
Date: Mon, 29 Feb 2016 23:10:07 +0300	[thread overview]
Message-ID: <20160229201007.GA32069@mwanda> (raw)

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
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

             reply	other threads:[~2016-02-29 20:10 UTC|newest]

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

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=20160229201007.GA32069@mwanda \
    --to=dan.carpenter@oracle.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=mario.kleiner.de@gmail.com \
    /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.