Message ID | 20180405195035.24722-3-ville.syrjala@linux.intel.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On 04/05/2018 09:50 PM, Ville Syrjala wrote: > From: Ville Syrjälä <ville.syrjala@linux.intel.com> > > Instead of plane->fb (which we're going to deprecate for atomic drivers) > we need to look at plane->state->fb. The maze of code leading to > vmw_kms_helper_dirty() wasn't particularly clear, but my analysis > concluded that the calls originating from vmw_*_primary_plane_atomic_update() > all pass in the crtc which means we'll never end up in this branch > of the function. All other callers use drm_modeset_lock_all() somewhere > higher up, which means accessing plane->state is safe. We'll toss in > a lockdep assert to catch wrongdoers. > > Cc: Thomas Hellstrom <thellstrom@vmware.com> > Cc: Sinclair Yeh <syeh@vmware.com> > Cc: VMware Graphics <linux-graphics-maintainer@vmware.com> > Cc: Daniel Vetter <daniel.vetter@ffwll.ch> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> > --- > drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 15 ++++++++++++--- > 1 file changed, 12 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c > index a2a796b4cc23..5a824125c231 100644 > --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c > +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c > @@ -2326,9 +2326,18 @@ int vmw_kms_helper_dirty(struct vmw_private *dev_priv, > } else { > list_for_each_entry(crtc, &dev_priv->dev->mode_config.crtc_list, > head) { > - if (crtc->primary->fb != &framebuffer->base) > - continue; > - units[num_units++] = vmw_crtc_to_du(crtc); > + struct drm_plane *plane = crtc->primary; > + > + /* > + * vmw_*_primary_plane_atomic_update() pass in the crtc, > + * and so don't end up here. All other callers use > + * drm_modeset_lock_all(), hence we can access the > + * plane state safely. > + */ > + lockdep_assert_held(&plane->mutex); > + I think we can remove the comment (it's a helper, so current users may not be future users), but the lockdep assert should be OK. > + if (plane->state->fb != &framebuffer->base) > + units[num_units++] = vmw_crtc_to_du(crtc); This doesn't seem to do what the original code did... > } > } > /Thomas
On Thu, Apr 05, 2018 at 10:15:57PM +0200, Thomas Hellstrom wrote: > On 04/05/2018 09:50 PM, Ville Syrjala wrote: > > From: Ville Syrjälä <ville.syrjala@linux.intel.com> > > > > Instead of plane->fb (which we're going to deprecate for atomic drivers) > > we need to look at plane->state->fb. The maze of code leading to > > vmw_kms_helper_dirty() wasn't particularly clear, but my analysis > > concluded that the calls originating from vmw_*_primary_plane_atomic_update() > > all pass in the crtc which means we'll never end up in this branch > > of the function. All other callers use drm_modeset_lock_all() somewhere > > higher up, which means accessing plane->state is safe. We'll toss in > > a lockdep assert to catch wrongdoers. > > > > Cc: Thomas Hellstrom <thellstrom@vmware.com> > > Cc: Sinclair Yeh <syeh@vmware.com> > > Cc: VMware Graphics <linux-graphics-maintainer@vmware.com> > > Cc: Daniel Vetter <daniel.vetter@ffwll.ch> > > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> > > --- > > drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | 15 ++++++++++++--- > > 1 file changed, 12 insertions(+), 3 deletions(-) > > > > diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c > > index a2a796b4cc23..5a824125c231 100644 > > --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c > > +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c > > @@ -2326,9 +2326,18 @@ int vmw_kms_helper_dirty(struct vmw_private *dev_priv, > > } else { > > list_for_each_entry(crtc, &dev_priv->dev->mode_config.crtc_list, > > head) { > > - if (crtc->primary->fb != &framebuffer->base) > > - continue; > > - units[num_units++] = vmw_crtc_to_du(crtc); > > + struct drm_plane *plane = crtc->primary; > > + > > + /* > > + * vmw_*_primary_plane_atomic_update() pass in the crtc, > > + * and so don't end up here. All other callers use > > + * drm_modeset_lock_all(), hence we can access the > > + * plane state safely. > > + */ > > + lockdep_assert_held(&plane->mutex); > > + > I think we can remove the comment (it's a helper, so current users may > not be future users), > but the lockdep assert should be OK. OK. > > + if (plane->state->fb != &framebuffer->base) > > + units[num_units++] = vmw_crtc_to_du(crtc); > > This doesn't seem to do what the original code did... Whoops. Good catch. > > > } > > } > > > > /Thomas >
Hi Ville, Thank you for the patch! Yet something to improve: [auto build test ERROR on drm/drm-next] [also build test ERROR on next-20180405] [cannot apply to v4.16] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system] url: https://github.com/0day-ci/linux/commits/Ville-Syrjala/drm-arc-Stop-consulting-plane-fb/20180406-155056 base: git://people.freedesktop.org/~airlied/linux.git drm-next config: x86_64-randconfig-x010-201813 (attached as .config) compiler: gcc-7 (Debian 7.3.0-1) 7.3.0 reproduce: # save the attached .config to linux build tree make ARCH=x86_64 All error/warnings (new ones prefixed by >>): In file included from arch/x86/include/asm/bug.h:83:0, from include/linux/bug.h:5, from include/linux/debug_locks.h:7, from include/linux/lockdep.h:28, from include/linux/spinlock_types.h:18, from include/linux/mutex.h:16, from include/linux/kernfs.h:13, from include/linux/sysfs.h:16, from include/linux/kobject.h:20, from include/linux/cdev.h:5, from include/drm/drmP.h:36, from drivers/gpu/drm/vmwgfx/vmwgfx_kms.h:31, from drivers/gpu/drm/vmwgfx/vmwgfx_kms.c:28: drivers/gpu/drm/vmwgfx/vmwgfx_kms.c: In function 'vmw_kms_helper_dirty': >> include/linux/lockdep.h:347:52: error: 'struct drm_modeset_lock' has no member named 'dep_map' #define lockdep_is_held(lock) lock_is_held(&(lock)->dep_map) ^ include/asm-generic/bug.h:112:25: note: in definition of macro 'WARN_ON' int __ret_warn_on = !!(condition); \ ^~~~~~~~~ >> include/linux/lockdep.h:373:27: note: in expansion of macro 'lockdep_is_held' WARN_ON(debug_locks && !lockdep_is_held(l)); \ ^~~~~~~~~~~~~~~ >> drivers/gpu/drm/vmwgfx/vmwgfx_kms.c:2337:4: note: in expansion of macro 'lockdep_assert_held' lockdep_assert_held(&plane->mutex); ^~~~~~~~~~~~~~~~~~~ -- In file included from arch/x86/include/asm/bug.h:83:0, from include/linux/bug.h:5, from include/linux/debug_locks.h:7, from include/linux/lockdep.h:28, from include/linux/spinlock_types.h:18, from include/linux/mutex.h:16, from include/linux/kernfs.h:13, from include/linux/sysfs.h:16, from include/linux/kobject.h:20, from include/linux/cdev.h:5, from include/drm/drmP.h:36, from drivers/gpu//drm/vmwgfx/vmwgfx_kms.h:31, from drivers/gpu//drm/vmwgfx/vmwgfx_kms.c:28: drivers/gpu//drm/vmwgfx/vmwgfx_kms.c: In function 'vmw_kms_helper_dirty': >> include/linux/lockdep.h:347:52: error: 'struct drm_modeset_lock' has no member named 'dep_map' #define lockdep_is_held(lock) lock_is_held(&(lock)->dep_map) ^ include/asm-generic/bug.h:112:25: note: in definition of macro 'WARN_ON' int __ret_warn_on = !!(condition); \ ^~~~~~~~~ >> include/linux/lockdep.h:373:27: note: in expansion of macro 'lockdep_is_held' WARN_ON(debug_locks && !lockdep_is_held(l)); \ ^~~~~~~~~~~~~~~ drivers/gpu//drm/vmwgfx/vmwgfx_kms.c:2337:4: note: in expansion of macro 'lockdep_assert_held' lockdep_assert_held(&plane->mutex); ^~~~~~~~~~~~~~~~~~~ vim +/lockdep_assert_held +2337 drivers/gpu/drm/vmwgfx/vmwgfx_kms.c 2289 2290 /** 2291 * vmw_kms_helper_dirty - Helper to build commands and perform actions based 2292 * on a set of cliprects and a set of display units. 2293 * 2294 * @dev_priv: Pointer to a device private structure. 2295 * @framebuffer: Pointer to the framebuffer on which to perform the actions. 2296 * @clips: A set of struct drm_clip_rect. Either this os @vclips must be NULL. 2297 * Cliprects are given in framebuffer coordinates. 2298 * @vclips: A set of struct drm_vmw_rect cliprects. Either this or @clips must 2299 * be NULL. Cliprects are given in source coordinates. 2300 * @dest_x: X coordinate offset for the crtc / destination clip rects. 2301 * @dest_y: Y coordinate offset for the crtc / destination clip rects. 2302 * @num_clips: Number of cliprects in the @clips or @vclips array. 2303 * @increment: Integer with which to increment the clip counter when looping. 2304 * Used to skip a predetermined number of clip rects. 2305 * @dirty: Closure structure. See the description of struct vmw_kms_dirty. 2306 */ 2307 int vmw_kms_helper_dirty(struct vmw_private *dev_priv, 2308 struct vmw_framebuffer *framebuffer, 2309 const struct drm_clip_rect *clips, 2310 const struct drm_vmw_rect *vclips, 2311 s32 dest_x, s32 dest_y, 2312 int num_clips, 2313 int increment, 2314 struct vmw_kms_dirty *dirty) 2315 { 2316 struct vmw_display_unit *units[VMWGFX_NUM_DISPLAY_UNITS]; 2317 struct drm_crtc *crtc; 2318 u32 num_units = 0; 2319 u32 i, k; 2320 2321 dirty->dev_priv = dev_priv; 2322 2323 /* If crtc is passed, no need to iterate over other display units */ 2324 if (dirty->crtc) { 2325 units[num_units++] = vmw_crtc_to_du(dirty->crtc); 2326 } else { 2327 list_for_each_entry(crtc, &dev_priv->dev->mode_config.crtc_list, 2328 head) { 2329 struct drm_plane *plane = crtc->primary; 2330 2331 /* 2332 * vmw_*_primary_plane_atomic_update() pass in the crtc, 2333 * and so don't end up here. All other callers use 2334 * drm_modeset_lock_all(), hence we can access the 2335 * plane state safely. 2336 */ > 2337 lockdep_assert_held(&plane->mutex); 2338 2339 if (plane->state->fb != &framebuffer->base) 2340 units[num_units++] = vmw_crtc_to_du(crtc); 2341 } 2342 } 2343 2344 for (k = 0; k < num_units; k++) { 2345 struct vmw_display_unit *unit = units[k]; 2346 s32 crtc_x = unit->crtc.x; 2347 s32 crtc_y = unit->crtc.y; 2348 s32 crtc_width = unit->crtc.mode.hdisplay; 2349 s32 crtc_height = unit->crtc.mode.vdisplay; 2350 const struct drm_clip_rect *clips_ptr = clips; 2351 const struct drm_vmw_rect *vclips_ptr = vclips; 2352 2353 dirty->unit = unit; 2354 if (dirty->fifo_reserve_size > 0) { 2355 dirty->cmd = vmw_fifo_reserve(dev_priv, 2356 dirty->fifo_reserve_size); 2357 if (!dirty->cmd) { 2358 DRM_ERROR("Couldn't reserve fifo space " 2359 "for dirty blits.\n"); 2360 return -ENOMEM; 2361 } 2362 memset(dirty->cmd, 0, dirty->fifo_reserve_size); 2363 } 2364 dirty->num_hits = 0; 2365 for (i = 0; i < num_clips; i++, clips_ptr += increment, 2366 vclips_ptr += increment) { 2367 s32 clip_left; 2368 s32 clip_top; 2369 2370 /* 2371 * Select clip array type. Note that integer type 2372 * in @clips is unsigned short, whereas in @vclips 2373 * it's 32-bit. 2374 */ 2375 if (clips) { 2376 dirty->fb_x = (s32) clips_ptr->x1; 2377 dirty->fb_y = (s32) clips_ptr->y1; 2378 dirty->unit_x2 = (s32) clips_ptr->x2 + dest_x - 2379 crtc_x; 2380 dirty->unit_y2 = (s32) clips_ptr->y2 + dest_y - 2381 crtc_y; 2382 } else { 2383 dirty->fb_x = vclips_ptr->x; 2384 dirty->fb_y = vclips_ptr->y; 2385 dirty->unit_x2 = dirty->fb_x + vclips_ptr->w + 2386 dest_x - crtc_x; 2387 dirty->unit_y2 = dirty->fb_y + vclips_ptr->h + 2388 dest_y - crtc_y; 2389 } 2390 2391 dirty->unit_x1 = dirty->fb_x + dest_x - crtc_x; 2392 dirty->unit_y1 = dirty->fb_y + dest_y - crtc_y; 2393 2394 /* Skip this clip if it's outside the crtc region */ 2395 if (dirty->unit_x1 >= crtc_width || 2396 dirty->unit_y1 >= crtc_height || 2397 dirty->unit_x2 <= 0 || dirty->unit_y2 <= 0) 2398 continue; 2399 2400 /* Clip right and bottom to crtc limits */ 2401 dirty->unit_x2 = min_t(s32, dirty->unit_x2, 2402 crtc_width); 2403 dirty->unit_y2 = min_t(s32, dirty->unit_y2, 2404 crtc_height); 2405 2406 /* Clip left and top to crtc limits */ 2407 clip_left = min_t(s32, dirty->unit_x1, 0); 2408 clip_top = min_t(s32, dirty->unit_y1, 0); 2409 dirty->unit_x1 -= clip_left; 2410 dirty->unit_y1 -= clip_top; 2411 dirty->fb_x -= clip_left; 2412 dirty->fb_y -= clip_top; 2413 2414 dirty->clip(dirty); 2415 } 2416 2417 dirty->fifo_commit(dirty); 2418 } 2419 2420 return 0; 2421 } 2422 --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index a2a796b4cc23..5a824125c231 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c @@ -2326,9 +2326,18 @@ int vmw_kms_helper_dirty(struct vmw_private *dev_priv, } else { list_for_each_entry(crtc, &dev_priv->dev->mode_config.crtc_list, head) { - if (crtc->primary->fb != &framebuffer->base) - continue; - units[num_units++] = vmw_crtc_to_du(crtc); + struct drm_plane *plane = crtc->primary; + + /* + * vmw_*_primary_plane_atomic_update() pass in the crtc, + * and so don't end up here. All other callers use + * drm_modeset_lock_all(), hence we can access the + * plane state safely. + */ + lockdep_assert_held(&plane->mutex); + + if (plane->state->fb != &framebuffer->base) + units[num_units++] = vmw_crtc_to_du(crtc); } }