From: "Ville Syrjälä" <ville.syrjala@linux.intel.com>
To: Thomas Zimmermann <tzimmermann@suse.de>
Cc: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org
Subject: Re: [PATCH 4/8] drm/client: Make copies of modes
Date: Tue, 8 Oct 2024 22:33:44 +0300 [thread overview]
Message-ID: <ZwWJGGh-ys9CtrsE@intel.com> (raw)
In-Reply-To: <d6678cad-7017-4d46-914f-27126d894b91@suse.de>
On Mon, Oct 07, 2024 at 09:36:13AM +0200, Thomas Zimmermann wrote:
> Hi
>
> Am 03.10.24 um 13:33 schrieb Ville Syrjala:
> > From: Ville Syrjälä <ville.syrjala@linux.intel.com>
> >
> > drm_client_firmware_config() is currently picking up the current
> > mode of the crtc via the legacy crtc->mode, which is not supposed
> > to be used by atomic drivers at all. We can't simply switch over
> > to the proper crtc->state->mode because we drop the crtc->mutex
> > (which protects crtc->state) before the mode gets used.
> >
> > The most straightforward solution to extend the lifetime of
> > modes[] seem to be to make full copies of the modes instead
> > of just storing pointers. We do have to replace the NULL checks
> > with something else though. Checking that mode->clock!=0
> > should be sufficient.
> >
> > And with this we can undo also commit 3eadd887dbac
> > ("drm/client:Fully protect modes[] with dev->mode_config.mutex")
> > as the lifetime of modes[] no longer has anything to do with
> > that lock.
>
> I think it would be a lot better to first build that mode list while
> holding the mutex, and afterwards copy the resulting modes before
> releasing the lock. The code below is convoluted with drm_mode_copy().
My first thought was to make copies but still keep track
of pointers. That idea was a complete disaster because you
now had to carefully free the modes on the list.
I then considred some kind of double list approach, but that
too seemed more complicated/confusing than the (IMO fairly
straightforward) apporach I ended up with. I'd prefer to reduce
the nummber of arrays this thing uses rather than increase them.
>
> >
> > Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
> > ---
> > drivers/gpu/drm/drm_client_modeset.c | 80 +++++++++++++++-------------
> > 1 file changed, 43 insertions(+), 37 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/drm_client_modeset.c b/drivers/gpu/drm/drm_client_modeset.c
> > index 888323137a6a..d413e119db3f 100644
> > --- a/drivers/gpu/drm/drm_client_modeset.c
> > +++ b/drivers/gpu/drm/drm_client_modeset.c
> > @@ -265,10 +265,15 @@ static void drm_client_connectors_enabled(struct drm_connector *connectors[],
> > enabled[i] = drm_connector_enabled(connectors[i], false);
> > }
> >
> > +static bool mode_valid(const struct drm_display_mode *mode)
> > +{
> > + return mode->clock != 0;
>
> A mode's clock isn't always known and not all drivers might set it
> correctly. At least in simpledrm/ofdrm, we have to make up a clock value
> for the firmware framebuffer. Otherwise some of our userspace would oops.
>
> The test for clock != 0 makes sense, but it's maybe the wrong place to
> do this. Would a test for hdisplay/vdisplay != 0 work instead?
That would work as well. drm_mode_validate_basic() rejects
everything with clock/hdisplay/vdisplay==0.
>
> > +}
> > +
> > static bool drm_client_target_cloned(struct drm_device *dev,
> > struct drm_connector *connectors[],
> > unsigned int connector_count,
> > - const struct drm_display_mode *modes[],
> > + struct drm_display_mode modes[],
> > struct drm_client_offset offsets[],
> > bool enabled[], int width, int height)
> > {
> > @@ -296,15 +301,16 @@ static bool drm_client_target_cloned(struct drm_device *dev,
> > for (i = 0; i < connector_count; i++) {
> > if (!enabled[i])
> > continue;
> > - modes[i] = drm_connector_pick_cmdline_mode(connectors[i]);
> > - if (!modes[i]) {
> > +
> > + drm_mode_copy(&modes[i], drm_connector_pick_cmdline_mode(connectors[i]));
> > + if (!mode_valid(&modes[i])) {
>
> You're copying and only then test for validity?
I thought drm_mode_copy() is a nop for NULL. Turns out I was wrong,
hence the v2.
For this specific case I suppose one could also write something like
if (whatever_mode())
drm_mode_copy(&modes[i], whatever_mode());
here, but having to repeat oneself is not so great.
We could of course avoid that with
mode = whatever_mode();
if (mode)
drm_mode_copy(&modes[i], mode);
with the downside of needing yet another local
variable.
--
Ville Syrjälä
Intel
next prev parent reply other threads:[~2024-10-08 19:33 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-10-03 11:32 [PATCH 0/8] drm/client: Stop using legacy crtc->mode and a bunch of cleanups Ville Syrjala
2024-10-03 11:32 ` [PATCH 1/8] drm/client: Constify modes Ville Syrjala
2024-10-04 23:59 ` kernel test robot
2024-10-05 0:19 ` kernel test robot
2024-10-03 11:32 ` [PATCH 2/8] drm/client: Use array notation for function arguments Ville Syrjala
2024-10-03 11:32 ` [PATCH 3/8] drm/client: Streamline mode selection debugs Ville Syrjala
2024-10-03 11:33 ` [PATCH 4/8] drm/client: Make copies of modes Ville Syrjala
2024-10-03 16:45 ` Ville Syrjälä
2024-10-03 18:15 ` [PATCH v2 " Ville Syrjala
2024-10-07 7:36 ` [PATCH " Thomas Zimmermann
2024-10-08 19:33 ` Ville Syrjälä [this message]
2024-10-10 19:28 ` Ville Syrjälä
2024-10-09 14:09 ` kernel test robot
2024-10-03 11:33 ` [PATCH 5/8] drm/client: Stop using the legacy crtc->mode Ville Syrjala
2024-10-03 18:16 ` [PATCH v2 " Ville Syrjala
2024-10-03 11:33 ` [PATCH 6/8] drm/client: s/new_crtc/crtc/ Ville Syrjala
2024-10-03 18:17 ` [PATCH v2 " Ville Syrjala
2024-10-03 11:33 ` [PATCH 7/8] drm/client: Move variables to tighter scope Ville Syrjala
2024-10-03 14:59 ` Ville Syrjälä
2024-10-03 11:33 ` [PATCH 8/8] drm/client: s/unsigned int i/int i/ Ville Syrjala
2024-10-07 7:43 ` Thomas Zimmermann
2024-10-08 19:12 ` Ville Syrjälä
2024-10-09 14:32 ` Jani Nikula
2024-10-03 17:57 ` ✗ Fi.CI.CHECKPATCH: warning for drm/client: Stop using legacy crtc->mode and a bunch of cleanups Patchwork
2024-10-03 18:07 ` ✗ Fi.CI.BAT: failure " Patchwork
2024-10-03 21:40 ` ✗ Fi.CI.CHECKPATCH: warning for drm/client: Stop using legacy crtc->mode and a bunch of cleanups (rev4) Patchwork
2024-10-03 21:49 ` ✓ Fi.CI.BAT: success " Patchwork
2024-10-08 6:36 ` ✓ Fi.CI.IGT: " 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=ZwWJGGh-ys9CtrsE@intel.com \
--to=ville.syrjala@linux.intel.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=intel-gfx@lists.freedesktop.org \
--cc=tzimmermann@suse.de \
/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.