Re: [PATCH] Revert "drm: add a locked version of drm_is_current_master"

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Jun 22, 2021 at 09:54:09AM +0200, Daniel Vetter wrote:
> This reverts commit 1815d9c86e3090477fbde066ff314a7e9721ee0f.
> 
> Unfortunately this inverts the locking hierarchy, so back to the
> drawing board. Full lockdep splat below:
> 
> ======================================================
> WARNING: possible circular locking dependency detected
> 5.13.0-rc7-CI-CI_DRM_10254+ #1 Not tainted
> ------------------------------------------------------
> kms_frontbuffer/1087 is trying to acquire lock:
> ffff88810dcd01a8 (&dev->master_mutex){+.+.}-{3:3}, at: drm_is_current_master+0x1b/0x40
> but task is already holding lock:
> ffff88810dcd0488 (&dev->mode_config.mutex){+.+.}-{3:3}, at: drm_mode_getconnector+0x1c6/0x4a0
> which lock already depends on the new lock.
> the existing dependency chain (in reverse order) is:
> -> #2 (&dev->mode_config.mutex){+.+.}-{3:3}:
>        __mutex_lock+0xab/0x970
>        drm_client_modeset_probe+0x22e/0xca0
>        __drm_fb_helper_initial_config_and_unlock+0x42/0x540
>        intel_fbdev_initial_config+0xf/0x20 [i915]
>        async_run_entry_fn+0x28/0x130
>        process_one_work+0x26d/0x5c0
>        worker_thread+0x37/0x380
>        kthread+0x144/0x170
>        ret_from_fork+0x1f/0x30
> -> #1 (&client->modeset_mutex){+.+.}-{3:3}:
>        __mutex_lock+0xab/0x970
>        drm_client_modeset_commit_locked+0x1c/0x180
>        drm_client_modeset_commit+0x1c/0x40
>        __drm_fb_helper_restore_fbdev_mode_unlocked+0x88/0xb0
>        drm_fb_helper_set_par+0x34/0x40
>        intel_fbdev_set_par+0x11/0x40 [i915]
>        fbcon_init+0x270/0x4f0
>        visual_init+0xc6/0x130
>        do_bind_con_driver+0x1e5/0x2d0
>        do_take_over_console+0x10e/0x180
>        do_fbcon_takeover+0x53/0xb0
>        register_framebuffer+0x22d/0x310
>        __drm_fb_helper_initial_config_and_unlock+0x36c/0x540
>        intel_fbdev_initial_config+0xf/0x20 [i915]
>        async_run_entry_fn+0x28/0x130
>        process_one_work+0x26d/0x5c0
>        worker_thread+0x37/0x380
>        kthread+0x144/0x170
>        ret_from_fork+0x1f/0x30
> -> #0 (&dev->master_mutex){+.+.}-{3:3}:
>        __lock_acquire+0x151e/0x2590
>        lock_acquire+0xd1/0x3d0
>        __mutex_lock+0xab/0x970
>        drm_is_current_master+0x1b/0x40
>        drm_mode_getconnector+0x37e/0x4a0
>        drm_ioctl_kernel+0xa8/0xf0
>        drm_ioctl+0x1e8/0x390
>        __x64_sys_ioctl+0x6a/0xa0
>        do_syscall_64+0x39/0xb0
>        entry_SYSCALL_64_after_hwframe+0x44/0xae
> other info that might help us debug this:
> Chain exists of: &dev->master_mutex --> &client->modeset_mutex --> &dev->mode_config.mutex
>  Possible unsafe locking scenario:
>        CPU0                    CPU1
>        ----                    ----
>   lock(&dev->mode_config.mutex);
>                                lock(&client->modeset_mutex);
>                                lock(&dev->mode_config.mutex);
>   lock(&dev->master_mutex);
> *** DEADLOCK ***
> 1 lock held by kms_frontbuffer/1087:
>  #0: ffff88810dcd0488 (&dev->mode_config.mutex){+.+.}-{3:3}, at: drm_mode_getconnector+0x1c6/0x4a0
> stack backtrace:
> CPU: 7 PID: 1087 Comm: kms_frontbuffer Not tainted 5.13.0-rc7-CI-CI_DRM_10254+ #1
> Hardware name: Intel Corporation Ice Lake Client Platform/IceLake U DDR4 SODIMM PD RVP TLC, BIOS ICLSFWR1.R00.3234.A01.1906141750 06/14/2019
> Call Trace:
>  dump_stack+0x7f/0xad
>  check_noncircular+0x12e/0x150
>  __lock_acquire+0x151e/0x2590
>  lock_acquire+0xd1/0x3d0
>  __mutex_lock+0xab/0x970
>  drm_is_current_master+0x1b/0x40
>  drm_mode_getconnector+0x37e/0x4a0
>  drm_ioctl_kernel+0xa8/0xf0
>  drm_ioctl+0x1e8/0x390
>  __x64_sys_ioctl+0x6a/0xa0
>  do_syscall_64+0x39/0xb0
>  entry_SYSCALL_64_after_hwframe+0x44/0xae
> 
> daniel@phenom:~/linux/drm-misc-fixes$ dim fixes 1815d9c86e3090477fbde066ff314a7e9721ee0f
> Fixes: 1815d9c86e30 ("drm: add a locked version of drm_is_current_master")
> Cc: Desmond Cheong Zhi Xi <desmondcheongzx@xxxxxxxxx>
> Cc: Emil Velikov <emil.l.velikov@xxxxxxxxx>
> Cc: stable@xxxxxxxxxxxxxxx
> Signed-off-by: Daniel Vetter <daniel.vetter@xxxxxxxxx>
> Cc: Maarten Lankhorst <maarten.lankhorst@xxxxxxxxxxxxxxx>
> Cc: Maxime Ripard <mripard@xxxxxxxxxx>
> Cc: Thomas Zimmermann <tzimmermann@xxxxxxx>
> Cc: David Airlie <airlied@xxxxxxxx>
> Cc: Daniel Vetter <daniel@xxxxxxxx>


You have your "dim fixes" command line in the commit message.

This goes through Intel's CI shortly, if it agrees with this then

Testcase: igt/debugfs_test/read_all_entries
Acked-by: Petri Latvala <petri.latvala@xxxxxxxxx>


> ---
>  drivers/gpu/drm/drm_auth.c | 51 ++++++++++++++------------------------
>  1 file changed, 19 insertions(+), 32 deletions(-)
> 
> diff --git a/drivers/gpu/drm/drm_auth.c b/drivers/gpu/drm/drm_auth.c
> index 86d4b72e95cb..232abbba3686 100644
> --- a/drivers/gpu/drm/drm_auth.c
> +++ b/drivers/gpu/drm/drm_auth.c
> @@ -61,35 +61,6 @@
>   * trusted clients.
>   */
>  
> -static bool drm_is_current_master_locked(struct drm_file *fpriv)
> -{
> -	lockdep_assert_held_once(&fpriv->master->dev->master_mutex);
> -
> -	return fpriv->is_master && drm_lease_owner(fpriv->master) == fpriv->minor->dev->master;
> -}
> -
> -/**
> - * drm_is_current_master - checks whether @priv is the current master
> - * @fpriv: DRM file private
> - *
> - * Checks whether @fpriv is current master on its device. This decides whether a
> - * client is allowed to run DRM_MASTER IOCTLs.
> - *
> - * Most of the modern IOCTL which require DRM_MASTER are for kernel modesetting
> - * - the current master is assumed to own the non-shareable display hardware.
> - */
> -bool drm_is_current_master(struct drm_file *fpriv)
> -{
> -	bool ret;
> -
> -	mutex_lock(&fpriv->master->dev->master_mutex);
> -	ret = drm_is_current_master_locked(fpriv);
> -	mutex_unlock(&fpriv->master->dev->master_mutex);
> -
> -	return ret;
> -}
> -EXPORT_SYMBOL(drm_is_current_master);
> -
>  int drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv)
>  {
>  	struct drm_auth *auth = data;
> @@ -252,7 +223,7 @@ int drm_setmaster_ioctl(struct drm_device *dev, void *data,
>  	if (ret)
>  		goto out_unlock;
>  
> -	if (drm_is_current_master_locked(file_priv))
> +	if (drm_is_current_master(file_priv))
>  		goto out_unlock;
>  
>  	if (dev->master) {
> @@ -301,7 +272,7 @@ int drm_dropmaster_ioctl(struct drm_device *dev, void *data,
>  	if (ret)
>  		goto out_unlock;
>  
> -	if (!drm_is_current_master_locked(file_priv)) {
> +	if (!drm_is_current_master(file_priv)) {
>  		ret = -EINVAL;
>  		goto out_unlock;
>  	}
> @@ -350,7 +321,7 @@ void drm_master_release(struct drm_file *file_priv)
>  	if (file_priv->magic)
>  		idr_remove(&file_priv->master->magic_map, file_priv->magic);
>  
> -	if (!drm_is_current_master_locked(file_priv))
> +	if (!drm_is_current_master(file_priv))
>  		goto out;
>  
>  	drm_legacy_lock_master_cleanup(dev, master);
> @@ -371,6 +342,22 @@ void drm_master_release(struct drm_file *file_priv)
>  	mutex_unlock(&dev->master_mutex);
>  }
>  
> +/**
> + * drm_is_current_master - checks whether @priv is the current master
> + * @fpriv: DRM file private
> + *
> + * Checks whether @fpriv is current master on its device. This decides whether a
> + * client is allowed to run DRM_MASTER IOCTLs.
> + *
> + * Most of the modern IOCTL which require DRM_MASTER are for kernel modesetting
> + * - the current master is assumed to own the non-shareable display hardware.
> + */
> +bool drm_is_current_master(struct drm_file *fpriv)
> +{
> +	return fpriv->is_master && drm_lease_owner(fpriv->master) == fpriv->minor->dev->master;
> +}
> +EXPORT_SYMBOL(drm_is_current_master);
> +
>  /**
>   * drm_master_get - reference a master pointer
>   * @master: &struct drm_master
> -- 
> 2.32.0.rc2
> 



[Index of Archives]     [Linux Kernel]     [Kernel Development Newbies]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Hiking]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux