Intel-XE Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Thomas Zimmermann <tzimmermann@suse.de>
To: "Cavitt, Jonathan" <jonathan.cavitt@intel.com>,
	"simona@ffwll.ch" <simona@ffwll.ch>,
	"airlied@gmail.com" <airlied@gmail.com>,
	"javierm@redhat.com" <javierm@redhat.com>,
	"jfalempe@redhat.com" <jfalempe@redhat.com>
Cc: "dri-devel@lists.freedesktop.org"
	<dri-devel@lists.freedesktop.org>,
	"amd-gfx@lists.freedesktop.org" <amd-gfx@lists.freedesktop.org>,
	"intel-gfx@lists.freedesktop.org"
	<intel-gfx@lists.freedesktop.org>,
	"intel-xe@lists.freedesktop.org" <intel-xe@lists.freedesktop.org>
Subject: Re: [PATCH v3 07/12] drm/client: Move suspend/resume into DRM client callbacks
Date: Mon, 14 Oct 2024 09:07:53 +0200	[thread overview]
Message-ID: <062b4b40-60d3-40c5-87b7-e7c94223d482@suse.de> (raw)
In-Reply-To: <CH0PR11MB5444C981845CAE455287FCF5E57E2@CH0PR11MB5444.namprd11.prod.outlook.com>

Hi

Am 08.10.24 um 23:21 schrieb Cavitt, Jonathan:
> -----Original Message-----
> From: Intel-xe <intel-xe-bounces@lists.freedesktop.org> On Behalf Of Thomas Zimmermann
> Sent: Tuesday, October 8, 2024 4:59 AM
> To: simona@ffwll.ch; airlied@gmail.com; javierm@redhat.com; jfalempe@redhat.com
> Cc: dri-devel@lists.freedesktop.org; amd-gfx@lists.freedesktop.org; intel-gfx@lists.freedesktop.org; intel-xe@lists.freedesktop.org; Thomas Zimmermann <tzimmermann@suse.de>
> Subject: [PATCH v3 07/12] drm/client: Move suspend/resume into DRM client callbacks
>> Suspend and resume is still tied to fbdev emulation. Modeset helpers
>> and several drivers call drm_fb_helper_set_suspend_unlocked() to inform
>> the fbdev client about suspend/resume events.
>>
>> To make it work with arbitrary clients, add per-client callback
>> functions for suspend and resume. Implement them for fbdev emulation
>> with the existing drm_fb_helper_set_suspend_unlocked(). Then update
>> DRM's modeset helpers to call the new interface.
>>
>> Clients that are not fbdev can now implement suspend/resume to their
>> requirements.
>>
>> Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
> Some questions below, but nothing blocking.
>
> Reviewed-by: Jonathan Cavitt <jonathan.cavitt@intel.com>

Thanks for reviewing this series.

>
>> ---
>>   drivers/gpu/drm/drm_client_event.c   | 60 ++++++++++++++++++++++++++++
>>   drivers/gpu/drm/drm_fbdev_client.c   | 30 +++++++++++++-
>>   drivers/gpu/drm/drm_modeset_helper.c | 14 ++++---
>>   include/drm/drm_client.h             | 35 ++++++++++++++++
>>   include/drm/drm_client_event.h       |  2 +
>>   5 files changed, 133 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/drm_client_event.c b/drivers/gpu/drm/drm_client_event.c
>> index d13d44320c5c..c52e93643672 100644
>> --- a/drivers/gpu/drm/drm_client_event.c
>> +++ b/drivers/gpu/drm/drm_client_event.c
>> @@ -107,6 +107,66 @@ void drm_client_dev_restore(struct drm_device *dev)
>>   	mutex_unlock(&dev->clientlist_mutex);
>>   }
>>   
>> +static int drm_client_suspend(struct drm_client_dev *client, bool holds_console_lock)
>> +{
>> +	struct drm_device *dev = client->dev;
>> +	int ret = 0;
>> +
>> +	if (drm_WARN_ON_ONCE(dev, client->suspended))
>> +		return 0;
>> +
>> +	if (client->funcs && client->funcs->suspend)
>> +		ret = client->funcs->suspend(client, holds_console_lock);
>> +	drm_dbg_kms(dev, "%s: ret=%d\n", client->name, ret);
>> +
>> +	client->suspended = true;
>> +
>> +	return ret;
>> +}
>> +
>> +void drm_client_dev_suspend(struct drm_device *dev, bool holds_console_lock)
>> +{
>> +	struct drm_client_dev *client;
>> +
>> +	mutex_lock(&dev->clientlist_mutex);
>> +	list_for_each_entry(client, &dev->clientlist, list) {
>> +		if (!client->suspended)
>> +			drm_client_suspend(client, holds_console_lock);
>> +	}
>> +	mutex_unlock(&dev->clientlist_mutex);
>> +}
>> +EXPORT_SYMBOL(drm_client_dev_suspend);
>> +
>> +static int drm_client_resume(struct drm_client_dev *client, bool holds_console_lock)
>> +{
>> +	struct drm_device *dev = client->dev;
>> +	int ret = 0;
>> +
>> +	if (drm_WARN_ON_ONCE(dev, !client->suspended))
>> +		return 0;
>> +
>> +	if (client->funcs && client->funcs->resume)
>> +		ret = client->funcs->resume(client, holds_console_lock);
>> +	drm_dbg_kms(dev, "%s: ret=%d\n", client->name, ret);
>> +
>> +	client->suspended = false;
>> +
>> +	return ret;
>> +}
>> +
>> +void drm_client_dev_resume(struct drm_device *dev, bool holds_console_lock)
>> +{
>> +	struct drm_client_dev *client;
>> +
>> +	mutex_lock(&dev->clientlist_mutex);
>> +	list_for_each_entry(client, &dev->clientlist, list) {
>> +		if  (client->suspended)
>> +			drm_client_resume(client, holds_console_lock);
>> +	}
>> +	mutex_unlock(&dev->clientlist_mutex);
>> +}
>> +EXPORT_SYMBOL(drm_client_dev_resume);
> I had to double check, as it seemed a bit weird to have a Boolean "holds_console_lock"
> if it was always going to be False in the use cases presented in this patch, but we do set
> it to True in the Radeon use case in patch 10, so that makes more sense.

I can mention this in the commit message.

>
>> +
>>   #ifdef CONFIG_DEBUG_FS
>>   static int drm_client_debugfs_internal_clients(struct seq_file *m, void *data)
>>   {
>> diff --git a/drivers/gpu/drm/drm_fbdev_client.c b/drivers/gpu/drm/drm_fbdev_client.c
>> index a09382afe2fb..246fb63ab250 100644
>> --- a/drivers/gpu/drm/drm_fbdev_client.c
>> +++ b/drivers/gpu/drm/drm_fbdev_client.c
>> @@ -61,11 +61,37 @@ static int drm_fbdev_client_hotplug(struct drm_client_dev *client)
>>   	return ret;
>>   }
>>   
>> +static int drm_fbdev_client_suspend(struct drm_client_dev *client, bool holds_console_lock)
>> +{
>> +	struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
>> +
>> +	if (holds_console_lock)
>> +		drm_fb_helper_set_suspend(fb_helper, true);
>> +	else
>> +		drm_fb_helper_set_suspend_unlocked(fb_helper, true);
>> +
>> +	return 0;
>> +}
>> +
>> +static int drm_fbdev_client_resume(struct drm_client_dev *client, bool holds_console_lock)
>> +{
>> +	struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
>> +
>> +	if (holds_console_lock)
>> +		drm_fb_helper_set_suspend(fb_helper, false);
>> +	else
>> +		drm_fb_helper_set_suspend_unlocked(fb_helper, false);
>> +
>> +	return 0;
>> +}
>> +
>>   static const struct drm_client_funcs drm_fbdev_client_funcs = {
>>   	.owner		= THIS_MODULE,
>>   	.unregister	= drm_fbdev_client_unregister,
>>   	.restore	= drm_fbdev_client_restore,
>>   	.hotplug	= drm_fbdev_client_hotplug,
>> +	.suspend	= drm_fbdev_client_suspend,
>> +	.resume		= drm_fbdev_client_resume,
>>   };
> Just a question for my own understanding:
>
>
> The expected order of operations here is:
>
> drm_mode_config_helper_suspend calls drm_client_dev_suspend
>
> drm_client_dev_suspend calls drm_client_suspend
>
> drm_client_suspend calls client->funcs->suspend, which for fbdev is
> drm_fbdev_client_suspend
>
> drm_fbdev_client_suspend calls drm_fb_helper_set_suspend(_unlocked)
>
> And, circling back to the start, drm_mode_config_helper_suspend is called by
> several drivers in the suspend case.
>
>
> Is this correct?

Yes, that's what's happening. This patch pushes the driver's direct call 
to drm_fb_helper_() interfaces into a callback of the client. That 
releases the module dependency and other clients can be used as well.

>
>>   
>>   /**
>> @@ -76,8 +102,8 @@ static const struct drm_client_funcs drm_fbdev_client_funcs = {
>>    *
>>    * This function sets up fbdev emulation. Restore, hotplug events and
>>    * teardown are all taken care of. Drivers that do suspend/resume need
>> - * to call drm_fb_helper_set_suspend_unlocked() themselves. Simple
>> - * drivers might use drm_mode_config_helper_suspend().
>> + * to call drm_client_dev_suspend() and drm_client_dev_resume() by
>> + * themselves. Simple drivers might use drm_mode_config_helper_suspend().
>>    *
>>    * This function is safe to call even when there are no connectors present.
>>    * Setup will be retried on the next hotplug event.
>> diff --git a/drivers/gpu/drm/drm_modeset_helper.c b/drivers/gpu/drm/drm_modeset_helper.c
>> index 2c582020cb42..5565464c1734 100644
>> --- a/drivers/gpu/drm/drm_modeset_helper.c
>> +++ b/drivers/gpu/drm/drm_modeset_helper.c
>> @@ -21,7 +21,7 @@
>>    */
>>   
>>   #include <drm/drm_atomic_helper.h>
>> -#include <drm/drm_fb_helper.h>
>> +#include <drm/drm_client_event.h>
>>   #include <drm/drm_fourcc.h>
>>   #include <drm/drm_framebuffer.h>
>>   #include <drm/drm_modeset_helper.h>
>> @@ -185,7 +185,7 @@ EXPORT_SYMBOL(drm_crtc_init);
>>    * Zero on success, negative error code on error.
>>    *
>>    * See also:
>> - * drm_kms_helper_poll_disable() and drm_fb_helper_set_suspend_unlocked().
>> + * drm_kms_helper_poll_disable() and drm_client_dev_suspend().
>>    */
>>   int drm_mode_config_helper_suspend(struct drm_device *dev)
>>   {
>> @@ -199,10 +199,11 @@ int drm_mode_config_helper_suspend(struct drm_device *dev)
>>   	if (dev->mode_config.poll_enabled)
>>   		drm_kms_helper_poll_disable(dev);
>>   
>> -	drm_fb_helper_set_suspend_unlocked(dev->fb_helper, 1);
>> +	drm_client_dev_suspend(dev, false);
>>   	state = drm_atomic_helper_suspend(dev);
>>   	if (IS_ERR(state)) {
>> -		drm_fb_helper_set_suspend_unlocked(dev->fb_helper, 0);
>> +		drm_client_dev_resume(dev, false);
>> +
>>   		/*
>>   		 * Don't enable polling if it was never initialized
>>   		 */
>> @@ -230,7 +231,7 @@ EXPORT_SYMBOL(drm_mode_config_helper_suspend);
>>    * Zero on success, negative error code on error.
>>    *
>>    * See also:
>> - * drm_fb_helper_set_suspend_unlocked() and drm_kms_helper_poll_enable().
>> + * drm_client_dev_resume() and drm_kms_helper_poll_enable().
>>    */
>>   int drm_mode_config_helper_resume(struct drm_device *dev)
>>   {
>> @@ -247,7 +248,8 @@ int drm_mode_config_helper_resume(struct drm_device *dev)
>>   		DRM_ERROR("Failed to resume (%d)\n", ret);
>>   	dev->mode_config.suspend_state = NULL;
>>   
>> -	drm_fb_helper_set_suspend_unlocked(dev->fb_helper, 0);
>> +	drm_client_dev_resume(dev, false);
>> +
>>   	/*
>>   	 * Don't enable polling if it is not initialized
>>   	 */
>> diff --git a/include/drm/drm_client.h b/include/drm/drm_client.h
>> index dfd5afcc9463..c03c4b0f3e94 100644
>> --- a/include/drm/drm_client.h
>> +++ b/include/drm/drm_client.h
>> @@ -63,6 +63,34 @@ struct drm_client_funcs {
>>   	 * This callback is optional.
>>   	 */
>>   	int (*hotplug)(struct drm_client_dev *client);
>> +
>> +	/**
>> +	 * @suspend:
>> +	 *
>> +	 * Called when suspending the device.
>> +	 *
>> +	 * This callback is optional.
>> +	 *
>> +	 * FIXME: Some callers hold the console lock when invoking this
>> +	 *        function. This interferes with fbdev emulation, which
>> +	 *        also tries to acquire the lock. Push the console lock
>> +	 *        into the callback and remove 'holds_console_lock'.
>> +	 */
> Is there an estimated time for the fix to this FIXME?  It's out of scope
> for this series, so I won't insist on fixing it immediately, but if it's a
> "quick" fix (relatively speaking), then we should definitely try to get
> this FIXME resolved in short order.

There's no quick fix AFAICT. Radeon, i915 and xe call 
drm_fb_helper_set_suspend() from various places. These drivers always 
had their own code, so they likely need some work to make the change to 
the _unlocked() helper.

Best regards
Thomas

>
> -Jonathan Cavitt
>
>> +	int (*suspend)(struct drm_client_dev *client, bool holds_console_lock);
>> +
>> +	/**
>> +	 * @resume:
>> +	 *
>> +	 * Called when resuming the device from suspend.
>> +	 *
>> +	 * This callback is optional.
>> +	 *
>> +	 * FIXME: Some callers hold the console lock when invoking this
>> +	 *        function. This interferes with fbdev emulation, which
>> +	 *        also tries to acquire the lock. Push the console lock
>> +	 *        into the callback and remove 'holds_console_lock'.
>> +	 */
>> +	int (*resume)(struct drm_client_dev *client, bool holds_console_lock);
>>   };
>>   
>>   /**
>> @@ -107,6 +135,13 @@ struct drm_client_dev {
>>   	 */
>>   	struct drm_mode_set *modesets;
>>   
>> +	/**
>> +	 * @suspended:
>> +	 *
>> +	 * The client has been suspended.
>> +	 */
>> +	bool suspended;
>> +
>>   	/**
>>   	 * @hotplug_failed:
>>   	 *
>> diff --git a/include/drm/drm_client_event.h b/include/drm/drm_client_event.h
>> index 2c8915241120..72c97d111169 100644
>> --- a/include/drm/drm_client_event.h
>> +++ b/include/drm/drm_client_event.h
>> @@ -8,5 +8,7 @@ struct drm_device;
>>   void drm_client_dev_unregister(struct drm_device *dev);
>>   void drm_client_dev_hotplug(struct drm_device *dev);
>>   void drm_client_dev_restore(struct drm_device *dev);
>> +void drm_client_dev_suspend(struct drm_device *dev, bool holds_console_lock);
>> +void drm_client_dev_resume(struct drm_device *dev, bool holds_console_lock);
>>   
>>   #endif
>> -- 
>> 2.46.0
>>
>>

-- 
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)


  reply	other threads:[~2024-10-14  7:08 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-10-08 11:59 [PATCH v3 00/12] drm: Introduce DRM client library Thomas Zimmermann
2024-10-08 11:59 ` [PATCH v3 01/12] drm/i915: Select DRM_CLIENT_SELECTION Thomas Zimmermann
2024-10-08 20:54   ` Cavitt, Jonathan
2024-10-08 11:59 ` [PATCH v3 02/12] drm/xe: " Thomas Zimmermann
2024-10-08 20:54   ` Cavitt, Jonathan
2024-10-08 11:59 ` [PATCH v3 03/12] drm/fbdev-dma: Select FB_DEFERRED_IO Thomas Zimmermann
2024-10-08 20:55   ` Cavitt, Jonathan
2024-10-08 11:59 ` [PATCH v3 04/12] drm/fbdev: Select fbdev I/O helpers from modules that require them Thomas Zimmermann
2024-10-08 20:55   ` Cavitt, Jonathan
2024-10-08 11:59 ` [PATCH v3 05/12] drm/fbdev: Store fbdev module parameters in separate file Thomas Zimmermann
2024-10-08 20:56   ` Cavitt, Jonathan
2024-10-08 11:59 ` [PATCH v3 06/12] drm/client: Move client event handlers to drm_client_event.c Thomas Zimmermann
2024-10-08 21:11   ` Cavitt, Jonathan
2024-10-08 11:59 ` [PATCH v3 07/12] drm/client: Move suspend/resume into DRM client callbacks Thomas Zimmermann
2024-10-08 21:21   ` Cavitt, Jonathan
2024-10-14  7:07     ` Thomas Zimmermann [this message]
2024-10-08 11:59 ` [PATCH v3 08/12] drm/amdgpu: Suspend and resume internal clients with client helpers Thomas Zimmermann
2024-10-08 21:37   ` Cavitt, Jonathan
2024-10-08 11:59 ` [PATCH v3 09/12] drm/nouveau: Suspend and resume " Thomas Zimmermann
2024-10-08 21:38   ` Cavitt, Jonathan
2024-10-08 11:59 ` [PATCH v3 10/12] drm/radeon: " Thomas Zimmermann
2024-10-08 21:40   ` Cavitt, Jonathan
2024-10-08 11:59 ` [PATCH v3 11/12] drm/client: Make client support optional Thomas Zimmermann
2024-10-08 21:41   ` Cavitt, Jonathan
2024-10-08 11:59 ` [PATCH v3 12/12] drm/client: Add client-lib module Thomas Zimmermann
2024-10-08 21:42   ` Cavitt, Jonathan
2024-10-08 12:12 ` ✓ CI.Patch_applied: success for drm: Introduce DRM client library (rev3) Patchwork
2024-10-08 12:13 ` ✗ CI.checkpatch: warning " Patchwork
2024-10-08 12:14 ` ✓ CI.KUnit: success " Patchwork
2024-10-08 12:27 ` ✓ CI.Build: " Patchwork
2024-10-08 12:29 ` ✓ CI.Hooks: " Patchwork
2024-10-08 12:30 ` ✗ CI.checksparse: warning " Patchwork
2024-10-08 12:58 ` ✓ CI.BAT: success " Patchwork
2024-10-08 19:04 ` ✗ CI.FULL: failure " Patchwork

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=062b4b40-60d3-40c5-87b7-e7c94223d482@suse.de \
    --to=tzimmermann@suse.de \
    --cc=airlied@gmail.com \
    --cc=amd-gfx@lists.freedesktop.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=intel-xe@lists.freedesktop.org \
    --cc=javierm@redhat.com \
    --cc=jfalempe@redhat.com \
    --cc=jonathan.cavitt@intel.com \
    --cc=simona@ffwll.ch \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox