[PATCH wayland] shm: add a note about shm pool base address changing
Derek Foreman
derekf at osg.samsung.com
Tue Feb 9 22:13:18 UTC 2016
On 09/02/16 05:56 AM, Pekka Paalanen wrote:
> On Mon, 08 Feb 2016 12:23:58 -0600
> Derek Foreman <derekf at osg.samsung.com> wrote:
>
>> On 05/02/16 08:50 AM, Derek Foreman wrote:
>>> On 05/02/16 07:25 AM, Pekka Paalanen wrote:
>>>> From: Pekka Paalanen <pekka.paalanen at collabora.co.uk>
>>>>
>>>> Since shm_pool_resize() uses mremap(MREMAP_MAYMOVE), the pool's base
>>>> address may change at that point.
>>>>
>>>> If a compositor stores the pointer and a client enlarges the pool, the
>>>> compositor will have a stale pointer.
>>>>
>>>> Signed-off-by: Pekka Paalanen <pekka.paalanen at collabora.co.uk>
>>>
>>> Looks good to me,
>>> Reviewed-by: Derek Foreman <derekf at osg.samsung.com>
>>
>> Been thinking about this lately, and this *really* screws up
>> Enlightenment's asynchronous renderer - and I guess anyone else that
>> tries to render from a thread while dispatching in another.
>>
>> If we don't have any way to prevent this from happening out from under
>> us, our renderer can be killed intentionally by any client - this is not
>> good.
>>
>> Even the shm pool reference counting functions I added don't give us a
>> way out of this right now, as a resize will still change all the
>> pointers we've gathered before firing off the async rendering thread.
>>
>> Any suggestions on resolving this?
>
> Hi Derek,
>
> I can't see any, except "don't do that"...
>
> Or would it be possible to delay the mremap() call?
I think that would fix things up perfectly.
> I presume you are happy executing any mremap()'s while your rendering
> thread is not busy, and while the rendering thread is busy nothing
> will need data from wl_buffers committed after the rendering was
> launched?
Completely true. I don't think it would be sane any other way - if it
is then the patches I've just posted need a rethink...
> Would it be possible to use the explicit buffer referencing API you
> added to also count explicitly referenced buffers in a pool and delay
> mremap() until the count drops to zero the next time?
Yes, easily.
> This should probably be accompanied with a patch to make
> wl_shm_buffer_get_data() warn when the count is non-zero and there is a
> pending mremap().
Ah, I haven't done that yet but it's a good idea. Will follow up with that.
>> I'd be happy changing the pool resize semantics to only allow it when
>> there are no unreleased buffers in the pool. (or only allow it when the
>> compositor doesn't have a reference - but unreleased buffers would be
>> the only way a client could infer that...)
>
> How would you know if there are unreleased buffers? Or when a
> compositor has a reference?
>
> libwayland-server's shm implementation does not know anything about
> them. It only knows about wl_buffers getting created and destroyed.
>
> Or you mean implement that in compositors? Ah, I assume so.
I'd have inferred it based on whether explicit references were taken or
not. Irrelevant now, since the deferred mremap approach seems to solve
this all quite nicely.
>> Actually, I wouldn't be surprised if the only user of pool resize right
>> now is libwayland-cursor, and it does all its resizing before it ever
>> submits a buffer - I'd be quite happy to make that the required way to
>> use resize. ;)
>
> By submit, you mean attach and commit?
Yes - some time after I said that I did a quick google search for other
uses of resize, and it appears there may be some that don't do it that
way. :)
> All that seems quite tricky to implement and would need implementing in
> each compositor. It would also need to be implemented in every
> compositor tentatively and tested in the wild for a period before we
> could assume no-one is using it in any awkward way.
Nod - I assumed only E would ever implement anything like this since I
don't think anyone else is using a separate render thread.
>> We really *really* need to be able to store pointers over dispatch to do
>> async rendering, so while this has never actually been possible, it has
>> at least not been documented as impossible yet.
>
> I suppose you don't like the suggestion "make your own implementation
> of wl_shm instead of using libwayland-server's". :-P
Haha, not my favourite suggestion, but certainly a possibility. :)
Really not at all hard, so if you think I'm making things too ugly by
trying to make it work for Enlightenment, I can do that.
>> I think I need to retract this too-speedy Reviewed-by... :/
>
> Darn.
>
> A yak here, and a yak there...
Thanks for helping shave this one. :D
>
> Thanks,
> pq
>
>
>>>> ---
>>>> src/wayland-shm.c | 4 ++++
>>>> 1 file changed, 4 insertions(+)
>>>>
>>>> diff --git a/src/wayland-shm.c b/src/wayland-shm.c
>>>> index a4343a4..7e42dcb 100644
>>>> --- a/src/wayland-shm.c
>>>> +++ b/src/wayland-shm.c
>>>> @@ -348,6 +348,10 @@ wl_shm_buffer_get_stride(struct wl_shm_buffer *buffer)
>>>> * to crash you should call wl_shm_buffer_begin_access and
>>>> * wl_shm_buffer_end_access around code that reads from the memory.
>>>> *
>>>> + * @note The return value of this function must not be stored across
>>>> + * dispatching client requests. If a client resizes the underlying shm pool,
>>>> + * the resize request handler will remap, and the pool base address may change.
>>>> + *
>>>> * \memberof wl_shm_buffer
>>>> */
>>>> WL_EXPORT void *
>>>>
>>>>
>>>>
>>>> _______________________________________________
>>>> wayland-devel mailing list
>>>> wayland-devel at lists.freedesktop.org
>>>> https://lists.freedesktop.org/mailman/listinfo/wayland-devel
More information about the wayland-devel
mailing list