dri-devel.lists.freedesktop.org archive mirror
 help / color / mirror / Atom feed
From: Andrzej Hajda <a.hajda@samsung.com>
To: Daniel Vetter <daniel@ffwll.ch>
Cc: "Rafael J. Wysocki" <rafael@kernel.org>,
	Daniel Vetter <daniel.vetter@ffwll.ch>,
	Intel Graphics Development <intel-gfx@lists.freedesktop.org>,
	DRI Development <dri-devel@lists.freedesktop.org>,
	Laurent Pinchart <laurent.pinchart@ideasonboard.com>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Daniel Vetter <daniel.vetter@intel.com>
Subject: Re: [PATCH 03/51] drm: add managed resources tied to drm_device
Date: Wed, 26 Feb 2020 15:38:55 +0100	[thread overview]
Message-ID: <1bff1216-7b83-9a31-1c51-1d9b903398ab@samsung.com> (raw)
In-Reply-To: <20200226102118.GS2363188@phenom.ffwll.local>

On 26.02.2020 11:21, Daniel Vetter wrote:
> On Wed, Feb 26, 2020 at 10:21:17AM +0100, Andrzej Hajda wrote:
>> On 25.02.2020 16:03, Daniel Vetter wrote:
>>> On Tue, Feb 25, 2020 at 11:27 AM Andrzej Hajda <a.hajda@samsung.com> wrote:
>>>> Hi Daniel,
>>>>
>>>>
>>>> The patchset looks interesting.
>>>>
>>>>
>>>> On 21.02.2020 22:02, Daniel Vetter wrote:
>>>>> We have lots of these. And the cleanup code tends to be of dubious
>>>>> quality. The biggest wrong pattern is that developers use devm_, which
>>>>> ties the release action to the underlying struct device, whereas
>>>>> all the userspace visible stuff attached to a drm_device can long
>>>>> outlive that one (e.g. after a hotunplug while userspace has open
>>>>> files and mmap'ed buffers). Give people what they want, but with more
>>>>> correctness.
>>>> I am not familiar with this stuff, so forgive me stupid questions.
>>>>
>>>> Is it documented how uapi should behave in such case?
>>>>
>>>> I guess the general rule is to return errors on most ioctls (ENODEV,
>>>> EIO?), and wait until userspace releases everything, as there is not
>>>> much more to do.
>>>>
>>>> If that is true what is the point of keeping these structs anyway -
>>>> trivial functions with small context data should do the job.
>>>>
>>>> I suspect I am missing something but I do not know what :)
>>> We could do the above (also needs unmapping of all mmaps, so userspace
>>> then gets SIGSEGV everywhere) and watch userspace crash&burn.
>>> Essentially if the kernel can't do this properly, then there's no hope
>>> that userspace will be any better.
>>
>> We do not want to crash userspace. We just need to tell userspace that
>> the kernel objects userspace has references to are not valid.
>>
>> For this two mechanism should be enough:
>>
>> - signal hot-unplug,
>>
>> - report error (ENODEV for example) on any userspace requests (ioctls)
>> on invalid objects.
>>
>> Expecting from userspace properly handling ioctl errors seems to be fair.
> The trouble is that maybe it's fair, practice says it's just not going to
> happen.


So what? Bad API usage causes bad things, crashes will force developers
to fix it, if not we can assume it is not so harmful.

The gain is that kernel side is simpler and don't need to lie :)


>> Regarding mmap I am not sure how to properly handle disappearing
>> devices, but this is common problem regardless which solution we use.
> signal handler wrapped around every mmap access. Which doesn't compose
> across libraries, so is essentially impossible.
>
> Note that e.g. GL's robustness extensions works exactly like this here
> too: GPU dies, kernel kills all your objects and contexts and everything.
> But the driver keeps "working". The only way to get information that
> everything is actually dead is by querying the robustness extension, which
> then will tell you what's happened.
>
> Again this is because it's impossible to make sure userspace actually
> checks error codes every where. It's also prohibitively expensive. vk goes
> as far as outright removing all error validation (at least as much as
> possible).


vk is different story, and is for me counter-example - it has clear
policy - user should take care of proper API handling otherwise it risks
undefined behavior/crash. In your proposition I see opposition: lets
baby-sit user and protect him from his mistakes.


>
>>> Hence the idea is that we keep everything userspace facing still
>>> around, except it doesn't do much anymore. So connectors still there,
>>> but they look disconnected.
>>
>> It looks like lying to userspace that physical connectors still exists.
>> If we want to lie we need good reason for that. What is that reason?
>>
>> Why not just tell connectors are gone?
> Userspace sucks at handling hotunplugged connectors. Most of it is special
> case code for DP MST connectors only.
>
>>> Userspace can then hopefully eventually
>>> get around to processing the sysfs hotunplug event and remove the
>>> device from all its list. So the long-term idea is that a lot of stuff
>>> keeps working, except the driver doesn't talk to the hardware anymore.
>>> And we just sit around waiting for userspace to clean things up.
>>
>> What does it mean "lot of stuff keeps working"? What drm driver can do
>> without hardware? Could you show some examples?
> Nothing will "work", the goal is simply for userspace to not explode in
> fire and take the entire desktop down with it.


And why do we need to keep whole drm device for this task? What exactly
causes userspace explosion?


>
>>> I guess once we have a bunch of the panel/usb drivers converted over
>>> we could indeed document how this is all supposed to work from an uapi
>>> pov. But right now a lot of this is all rather aspirational, I think
>>> only the recent simple display pipe based drivers implement this as
>>> described above.
>>>
>>>>> Mostly copied from devres.c, with types adjusted to fit drm_device and
>>>>> a few simplifications - I didn't (yet) copy over everything. Since
>>>>> the types don't match code sharing looked like a hopeless endeavour.
>>>>>
>>>>> For now it's only super simplified, no groups, you can't remove
>>>>> actions (but kfree exists, we'll need that soon). Plus all specific to
>>>>> drm_device ofc, including the logging. Which I didn't bother to make
>>>>> compile-time optional, since none of the other drm logging is compile
>>>>> time optional either.
>>>> I saw in v1 thread that copy/paste is OK and merging back devres and
>>>> drmres can be done later, but experience shows that after short time
>>>> things get de-synchronized and merging process becomes quite painful.
>>>>
>>>> On the other side I guess it shouldn't be difficult to split devres into
>>>> consumer agnostic core and "struct device" helpers and then use the core
>>>> in drm.
>>>>
>>>> For example currently devres uses two fields from struct device:
>>>>
>>>>     spinlock_t        devres_lock;
>>>>     struct list_head    devres_head;
>>>>
>>>> Lets put it into separate struct:
>>>>
>>>> struct devres {
>>>>
>>>>     spinlock_t        lock;
>>>>     struct list_head    head;
>>>>
>>>> };
>>>>
>>>> And embed this struct into "struct device".
>>>>
>>>> Then convert all core devres functions to take "struct devres *"
>>>> argument instead of "struct device *" and then these core functions can
>>>> be usable in drm.
>>>>
>>>> Looks quite simple separation of abstraction (devres) and its consumer
>>>> (struct device).
>>>>
>>>> After such split one could think about changing name devres to something
>>>> more reliable.
>>> There was a long discussion on v1 exactly about this, Greg's
>>> suggestion was to "just share a struct device". So we're not going to
>>> do this here, and the struct device seems like slight overkill and not
>>> a good enough fit here.
>>
>> But my proposition is different, I want to get rid of "struct device"
>> from devres core - devres has nothing to do with device, it was bound to
>> it probably because it was convenient as device was the only client of
>> devres (I guess). Now if we want to have more devres clients abstracting
>> out devres from device seems quite natural. This way we will have proper
>> abstractions without code duplication.
>>
>> Examples of devres related code according to my proposition:
>>
>> // devres core
>>
>> void devres_add(struct devres_head *dh, void *res)
>> {
>>
>>    struct devres *dr = container_of(res, struct devres, data);
>>
>>     unsigned long flags;
>>
>>     spin_lock_irqsave(&dh->lock, flags);
>>     add_dr(dev, &dr->node);
>>     spin_unlock_irqrestore(&dh->lock, flags);
>> }
>>
>> // device devres helper (non core)
>>
>> struct clk *devm_clk_get(struct device *dev, const char *id)
>> {
>>     struct clk **ptr, *clk;
>>
>>     ptr = devres_alloc(devm_clk_release, sizeof(*ptr), GFP_KERNEL);
>>     if (!ptr)
>>         return ERR_PTR(-ENOMEM);
>>
>>     clk = clk_get(dev, id);
>>     if (!IS_ERR(clk)) {
>>         *ptr = clk;
>>         devres_add(&dev->devres, ptr);
>>     } else {
>>         devres_free(ptr);
>>     }
>>
>>     return clk;
>> }
>>
>>
>> Changes are cosmetic. But then you can easily add devres to drmdev:
>>
>> struct drm_device {
>>
>>    ...
>>
>> +   struct devres_head devres;
>>
>> };
>>
>> // then copy/modify from your patch:
>>
>> +void *drmm_kmalloc(struct drm_device *dev, size_t size, gfp_t gfp)
>> +{
>> +	struct drmres *dr;
>> +
>> +	dr = alloc_dr(NULL, size, gfp, dev_to_node(dev->dev));
>> +	if (!dr)
>> +		return NULL;
>> +	dr->node.name = "kmalloc";
>> +
>> +	devres_add(&dev->devres, dr); // the only change is here
>> +
>> +	return dr->data;
>> +}
>>
>>
>> Btw, reimplemented add_dr is different of original add_dr and is similar
>> to original devres_add, so your implementation differs already from
>> original one, merging back these two will be painfull :)
> Oh I know, I guess I could go more into details about why exactly. One
> reason is that I want type-checking, so struct drm_device * instead of
> something else. At least for the userspace callbacks. That's going to be
> tough with your approach - kmalloc is easy, it's the _add_action which
> gets nasty with the type checking.

Sth like this:


+static void drmm_action_release(struct devres_head *dh, void *res)
+{
+	struct drm_action_devres *devres = res;
+       struct drm_device *dev = container_of(dh, struct drm_device, devres);
+
+	devres->action(dev, devres->data);
+}
+
+int __drmm_add_action(struct drm_device *dev,
+		      drmres_release_t action,
+		      void *data, const char *name)
+{
+	struct action_devres *devres;
+
+	devres = devres_alloc(drmm_action_release,
+			      sizeof(struct drm_action_devres), GFP_KERNEL);
+	if (!devres)
+		return -ENOMEM;
+
+	devres->data = data;
+	devres->action = action;
+
+	devres_add(dev, devres);
+	return 0;
+}


Regards

Andrzej


_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel

  reply	other threads:[~2020-02-26 14:38 UTC|newest]

Thread overview: 92+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-02-21 21:02 [PATCH 00/51] drm managed resources, v2 Daniel Vetter
2020-02-21 21:02 ` [PATCH 01/51] mm/sl[uo]b: export __kmalloc_track(_node)_caller Daniel Vetter
2020-02-21 21:02 ` [PATCH 02/51] drm/i915: Don't clear drvdata in ->release Daniel Vetter
2020-02-21 21:36   ` Chris Wilson
2020-02-22  9:48     ` Daniel Vetter
2020-02-22  9:50       ` Daniel Vetter
2020-02-21 21:02 ` [PATCH 03/51] drm: add managed resources tied to drm_device Daniel Vetter
2020-02-25 10:27   ` Andrzej Hajda
2020-02-25 15:03     ` Daniel Vetter
2020-02-26  9:21       ` Andrzej Hajda
2020-02-26 10:21         ` Daniel Vetter
2020-02-26 14:38           ` Andrzej Hajda [this message]
2020-02-21 21:02 ` [PATCH 04/51] drm: Set final_kfree in drm_dev_alloc Daniel Vetter
2020-02-21 21:02 ` [PATCH 05/51] drm/mipi_dbi: Use drmm_add_final_kfree in all drivers Daniel Vetter
2020-02-21 21:02 ` [PATCH 06/51] drm/udl: Use drmm_add_final_kfree Daniel Vetter
2020-02-21 21:02 ` [PATCH 07/51] drm/qxl: " Daniel Vetter
2020-02-21 21:02 ` [PATCH 08/51] drm/i915: " Daniel Vetter
2020-02-21 21:02 ` [PATCH 09/51] drm/cirrus: " Daniel Vetter
2020-02-21 21:02 ` [PATCH 10/51] drm/v3d: " Daniel Vetter
2020-02-21 21:02 ` [PATCH 11/51] drm/tidss: " Daniel Vetter
2020-02-23 18:50   ` Jyri Sarha
2020-02-21 21:02 ` [PATCH 12/51] drm/mcde: " Daniel Vetter
2020-02-21 21:02 ` [PATCH 13/51] drm/vgem: " Daniel Vetter
2020-02-21 21:02 ` [PATCH 14/51] drm/vkms: " Daniel Vetter
2020-02-21 21:02 ` [PATCH 15/51] drm/repaper: " Daniel Vetter
2020-02-21 21:02 ` [PATCH 16/51] drm/inigenic: " Daniel Vetter
2020-02-21 21:02 ` [PATCH 17/51] drm/gm12u320: " Daniel Vetter
2020-02-22 11:36   ` Hans de Goede
2020-02-21 21:02 ` [PATCH 18/51] drm/<drivers>: " Daniel Vetter
2020-02-22 15:16   ` Russell King - ARM Linux admin
2020-02-27 17:46     ` Daniel Vetter
2020-02-21 21:02 ` [PATCH 19/51] drm: Cleanups after drmm_add_final_kfree rollout Daniel Vetter
2020-02-21 21:02 ` [PATCH 20/51] drm: Handle dev->unique with drmm_ Daniel Vetter
2020-02-21 21:02 ` [PATCH 21/51] drm: Use drmm_ for drm_dev_init cleanup Daniel Vetter
2020-02-21 21:02 ` [PATCH 22/51] drm: manage drm_minor cleanup with drmm_ Daniel Vetter
2020-02-21 21:02 ` [PATCH 23/51] drm: Manage drm_gem_init " Daniel Vetter
2020-02-21 21:02 ` [PATCH 24/51] drm: Manage drm_vblank_cleanup " Daniel Vetter
2020-02-21 21:02 ` [PATCH 25/51] drm: Garbage collect drm_dev_fini Daniel Vetter
2020-02-21 21:02 ` [PATCH 26/51] drm: Manage drm_mode_config_init with drmm_ Daniel Vetter
2020-02-23 15:17   ` Noralf Trønnes
2020-02-21 21:02 ` [PATCH 27/51] drm/bochs: Remove leftover drm_atomic_helper_shutdown Daniel Vetter
2020-02-21 21:02 ` [PATCH 28/51] drm/bochs: Drop explicit drm_mode_config_cleanup Daniel Vetter
2020-02-21 21:02 ` [PATCH 29/51] drm/cirrus: Drop explicit drm_mode_config_cleanup call Daniel Vetter
2020-02-21 21:02 ` [PATCH 30/51] drm/cirrus: Fully embrace devm_ Daniel Vetter
2020-02-21 21:02 ` [PATCH 31/51] drm/ingenic: Drop explicit drm_mode_config_cleanup call Daniel Vetter
2020-02-21 21:03 ` [PATCH 32/51] drm/mcde: " Daniel Vetter
2020-02-21 21:03 ` [PATCH 33/51] drm/mcde: More devm_drm_dev_init Daniel Vetter
2020-02-21 21:03 ` [PATCH 34/51] drm/meson: Drop explicit drm_mode_config_cleanup call Daniel Vetter
2020-02-21 21:03 ` [PATCH 35/51] drm/pl111: " Daniel Vetter
2020-02-21 21:03 ` [PATCH 36/51] drm/rcar-du: " Daniel Vetter
2020-02-21 21:03 ` [PATCH 37/51] drm/rockchip: " Daniel Vetter
2020-02-24 19:13   ` Francesco Lavra
2020-02-24 20:37     ` Daniel Vetter
2020-02-21 21:03 ` [PATCH 38/51] drm/stm: " Daniel Vetter
2020-02-21 21:03 ` [PATCH 39/51] drm/shmob: " Daniel Vetter
2020-02-21 21:03 ` [PATCH 40/51] drm/mtk: " Daniel Vetter
2020-02-21 21:03 ` [PATCH 41/51] drm/tidss: " Daniel Vetter
2020-02-23 18:50   ` Jyri Sarha
2020-02-21 21:03 ` [PATCH 42/51] drm/gm12u320: More drmm_ Daniel Vetter
2020-02-22 12:10   ` Hans de Goede
2020-02-21 21:03 ` [PATCH 43/51] drm/gm12u320: Use devm_drm_dev_init Daniel Vetter
2020-02-22 12:10   ` Hans de Goede
2020-02-21 21:03 ` [PATCH 44/51] drm/gm12u320: Use helpers for shutdown/suspend/resume Daniel Vetter
2020-02-22 12:10   ` Hans de Goede
2020-02-21 21:03 ` [PATCH 45/51] drm/gm12u320: Simplify upload work Daniel Vetter
2020-02-22 12:30   ` Hans de Goede
2020-02-22 13:00     ` Daniel Vetter
2020-02-21 21:03 ` [PATCH 46/51] drm/repaper: Drop explicit drm_mode_config_cleanup call Daniel Vetter
2020-02-21 21:03 ` [PATCH 47/51] drm/mipi-dbi: Move drm_mode_config_init into mipi library Daniel Vetter
2020-02-21 21:03 ` [PATCH 48/51] drm/mipi-dbi: Drop explicit drm_mode_config_cleanup call Daniel Vetter
2020-02-21 21:03 ` [PATCH 49/51] drm/udl: " Daniel Vetter
2020-02-21 21:03 ` [PATCH 50/51] drm/udl: drop drm_driver.release hook Daniel Vetter
2020-02-21 21:03 ` [PATCH 51/51] drm: Add docs for managed resources Daniel Vetter
2020-02-27 18:14 [PATCH 00/51] drm managed resources, v3 Daniel Vetter
2020-02-27 18:14 ` [PATCH 03/51] drm: add managed resources tied to drm_device Daniel Vetter
2020-02-28 22:45   ` Sam Ravnborg
2020-02-28 23:14     ` Daniel Vetter
2020-02-29 11:17       ` Sam Ravnborg
2020-02-29 11:28         ` Daniel Vetter
2020-03-02  9:22           ` Jani Nikula
2020-03-02  9:36             ` Daniel Vetter
2020-03-02  9:39             ` Daniel Vetter
2020-03-02 16:34               ` Sam Ravnborg
2020-03-02 22:25 [PATCH 00/51] drm_device managed resources, v4 Daniel Vetter
2020-03-02 22:25 ` [PATCH 03/51] drm: add managed resources tied to drm_device Daniel Vetter
2020-03-03  8:04   ` Dan Carpenter
2020-03-03  8:25     ` Daniel Vetter
2020-03-11  9:07   ` Thomas Zimmermann
2020-03-11  9:47     ` Thomas Zimmermann
2020-03-16  8:45     ` Daniel Vetter
2020-03-11  9:14   ` Thomas Zimmermann
2020-03-16  8:50     ` Daniel Vetter
2020-03-23 14:48 [PATCH 00/51] drm_device managed resources, v5 Daniel Vetter
2020-03-23 14:49 ` [PATCH 03/51] drm: add managed resources tied to drm_device Daniel Vetter
2020-03-23 18:36   ` Sam Ravnborg

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=1bff1216-7b83-9a31-1c51-1d9b903398ab@samsung.com \
    --to=a.hajda@samsung.com \
    --cc=daniel.vetter@ffwll.ch \
    --cc=daniel.vetter@intel.com \
    --cc=daniel@ffwll.ch \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=laurent.pinchart@ideasonboard.com \
    --cc=rafael@kernel.org \
    /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;
as well as URLs for NNTP newsgroup(s).