[bug report] drm/amd/display: wait for fence without holding reservation lock

Kazlauskas, Nicholas Nicholas.Kazlauskas at amd.com
Thu May 2 12:56:27 UTC 2019


On 5/2/19 4:04 AM, Dan Carpenter wrote:
> [CAUTION: External Email]
> 
> Hello Christian König,
> 
> The patch 2fac0f53fe59: "drm/amd/display: wait for fence without
> holding reservation lock" from Apr 2, 2019, leads to the following
> static checker warning:
> 
>          drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c:5338 amdgpu_dm_commit_planes()
>          warn: 'r' unsigned <= 0
> 
> drivers/gpu/drm/amd/amdgpu/../display/amdgpu_dm/amdgpu_dm.c
>    5238  static void amdgpu_dm_commit_planes(struct drm_atomic_state *state,
>    5239                                      struct dc_state *dc_state,
>    5240                                      struct drm_device *dev,
>    5241                                      struct amdgpu_display_manager *dm,
>    5242                                      struct drm_crtc *pcrtc,
>    5243                                      bool wait_for_vblank)
>    5244  {
>    5245          uint32_t i, r;
>                  ^^^^^^^^    ^
> 
>    5246          uint64_t timestamp_ns;
>    5247          struct drm_plane *plane;
>    5248          struct drm_plane_state *old_plane_state, *new_plane_state;
>    5249          struct amdgpu_crtc *acrtc_attach = to_amdgpu_crtc(pcrtc);
>    5250          struct drm_crtc_state *new_pcrtc_state =
>    5251                          drm_atomic_get_new_crtc_state(state, pcrtc);
>    5252          struct dm_crtc_state *acrtc_state = to_dm_crtc_state(new_pcrtc_state);
>    5253          struct dm_crtc_state *dm_old_crtc_state =
>    5254                          to_dm_crtc_state(drm_atomic_get_old_crtc_state(state, pcrtc));
>    5255          int planes_count = 0, vpos, hpos;
>    5256          unsigned long flags;
>    5257          struct amdgpu_bo *abo;
>    5258          uint64_t tiling_flags;
>    5259          uint32_t target_vblank, last_flip_vblank;
>    5260          bool vrr_active = amdgpu_dm_vrr_active(acrtc_state);
>    5261          bool pflip_present = false;
>    5262          struct {
>    5263                  struct dc_surface_update surface_updates[MAX_SURFACES];
>    5264                  struct dc_plane_info plane_infos[MAX_SURFACES];
>    5265                  struct dc_scaling_info scaling_infos[MAX_SURFACES];
>    5266                  struct dc_flip_addrs flip_addrs[MAX_SURFACES];
>    5267                  struct dc_stream_update stream_update;
>    5268          } *bundle;
>    5269
>    5270          bundle = kzalloc(sizeof(*bundle), GFP_KERNEL);
>    5271
>    5272          if (!bundle) {
>    5273                  dm_error("Failed to allocate update bundle\n");
>    5274                  goto cleanup;
>    5275          }
>    5276
>    5277          /*
>    5278           * Disable the cursor first if we're disabling all the planes.
>    5279           * It'll remain on the screen after the planes are re-enabled
>    5280           * if we don't.
>    5281           */
>    5282          if (acrtc_state->active_planes == 0)
>    5283                  amdgpu_dm_commit_cursors(state);
>    5284
>    5285          /* update planes when needed */
>    5286          for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {
>    5287                  struct drm_crtc *crtc = new_plane_state->crtc;
>    5288                  struct drm_crtc_state *new_crtc_state;
>    5289                  struct drm_framebuffer *fb = new_plane_state->fb;
>    5290                  bool plane_needs_flip;
>    5291                  struct dc_plane_state *dc_plane;
>    5292                  struct dm_plane_state *dm_new_plane_state = to_dm_plane_state(new_plane_state);
>    5293
>    5294                  /* Cursor plane is handled after stream updates */
>    5295                  if (plane->type == DRM_PLANE_TYPE_CURSOR)
>    5296                          continue;
>    5297
>    5298                  if (!fb || !crtc || pcrtc != crtc)
>    5299                          continue;
>    5300
>    5301                  new_crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
>    5302                  if (!new_crtc_state->active)
>    5303                          continue;
>    5304
>    5305                  dc_plane = dm_new_plane_state->dc_state;
>    5306
>    5307                  bundle->surface_updates[planes_count].surface = dc_plane;
>    5308                  if (new_pcrtc_state->color_mgmt_changed) {
>    5309                          bundle->surface_updates[planes_count].gamma = dc_plane->gamma_correction;
>    5310                          bundle->surface_updates[planes_count].in_transfer_func = dc_plane->in_transfer_func;
>    5311                  }
>    5312
>    5313                  fill_dc_scaling_info(new_plane_state,
>    5314                                       &bundle->scaling_infos[planes_count]);
>    5315
>    5316                  bundle->surface_updates[planes_count].scaling_info =
>    5317                          &bundle->scaling_infos[planes_count];
>    5318
>    5319                  plane_needs_flip = old_plane_state->fb && new_plane_state->fb;
>    5320
>    5321                  pflip_present = pflip_present || plane_needs_flip;
>    5322
>    5323                  if (!plane_needs_flip) {
>    5324                          planes_count += 1;
>    5325                          continue;
>    5326                  }
>    5327
>    5328                  abo = gem_to_amdgpu_bo(fb->obj[0]);
>    5329
>    5330                  /*
>    5331                   * Wait for all fences on this FB. Do limited wait to avoid
>    5332                   * deadlock during GPU reset when this fence will not signal
>    5333                   * but we hold reservation lock for the BO.
>    5334                   */
>    5335                  r = reservation_object_wait_timeout_rcu(abo->tbo.resv, true,
>    5336                                                          false,
>    5337                                                          msecs_to_jiffies(5000));
>    5338                  if (unlikely(r <= 0))
>                              ^^^^^^^^^^^^^^^^
> 
> If reservation_object_wait_timeout_rcu() then r is unsigned.  Also this
> just prints an error instead of doing proper error handling so it's not
> really worth fixing?

Looks like that isn't even the only place in the function with this 
problem. There's that r != 0 check right below as well casted from an int.

I'll push a patch that fixes both of these up.

Nicholas Kazlauskas

> 
>    5339                          DRM_ERROR("Waiting for fences timed out or interrupted!");
>    5340
>    5341                  /*
>    5342                   * TODO This might fail and hence better not used, wait
>    5343                   * explicitly on fences instead
>    5344                   * and in general should be called for
>    5345                   * blocking commit to as per framework helpers
>    5346                   */
>    5347                  r = amdgpu_bo_reserve(abo, true);
>    5348                  if (unlikely(r != 0))
>    5349                          DRM_ERROR("failed to reserve buffer before flip\n");
>    5350
>    5351                  amdgpu_bo_get_tiling_flags(abo, &tiling_flags);
>    5352
>    5353                  amdgpu_bo_unreserve(abo);
> 
> regards,
> dan carpenter
> _______________________________________________
> amd-gfx mailing list
> amd-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/amd-gfx
> 



More information about the amd-gfx mailing list