[Intel-gfx] [PATCH] drm/atomic: protect crtc|connector->state with rcu
Maarten Lankhorst
maarten.lankhorst at linux.intel.com
Fri Mar 17 16:52:32 UTC 2017
Op 16-03-17 om 21:15 schreef Daniel Vetter:
> On Thu, Mar 16, 2017 at 5:09 PM, Maarten Lankhorst
> <maarten.lankhorst at linux.intel.com> wrote:
>> Op 16-03-17 om 16:52 schreef Daniel Vetter:
>>> The vblank code really wants to look at crtc->state without having to
>>> take a ww_mutex. One option might be to take one of the vblank locks
>>> right when assigning crtc->state, which would ensure that the vblank
>>> code doesn't race and access freed memory.
>> I'm not sure this is the right approach for vblank.
> It's not, it's just that I've had to resurrect this patch quickly
> before leaving and accidentally left the vblank stuff in.
>
>> crtc->state might not be the same as the current state in case of a nonblocking
>> modeset that hasn't even disabled the old crtc yet.
>>> But userspace tends to poke the vblank_ioctl to query the current
>>> vblank timestamp rather often, and going all in with rcu would help a
>>> bit. We're not there yet, but also doesn't really hurt.
>>>
>>> v2: Maarten needs this to make connector properties atomic, so he can
>>> peek at state from the various ->mode_valid hooks.
>>>
>>> Cc: Maarten Lankhorst <maarten.lankhorst at linux.intel.com>
>>> Signed-off-by: Daniel Vetter <daniel.vetter at intel.com>
>>> ---
>>> drivers/gpu/drm/drm_atomic.c | 26 +++++++++++++++++---------
>>> drivers/gpu/drm/drm_atomic_helper.c | 2 +-
>>> include/drm/drm_atomic.h | 5 +++++
>>> include/drm/drm_connector.h | 13 ++++++++++++-
>>> include/drm/drm_crtc.h | 9 ++++++++-
>>> 5 files changed, 43 insertions(+), 12 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
>>> index 9b892af7811a..ba11e31ff9ba 100644
>>> --- a/drivers/gpu/drm/drm_atomic.c
>>> +++ b/drivers/gpu/drm/drm_atomic.c
>>> @@ -213,16 +213,10 @@ void drm_atomic_state_clear(struct drm_atomic_state *state)
>>> }
>>> EXPORT_SYMBOL(drm_atomic_state_clear);
>>>
>>> -/**
>>> - * __drm_atomic_state_free - free all memory for an atomic state
>>> - * @ref: This atomic state to deallocate
>>> - *
>>> - * This frees all memory associated with an atomic state, including all the
>>> - * per-object state for planes, crtcs and connectors.
>>> - */
>>> -void __drm_atomic_state_free(struct kref *ref)
>>> +void ___drm_atomic_state_free(struct rcu_head *rhead)
>>> {
>>> - struct drm_atomic_state *state = container_of(ref, typeof(*state), ref);
>>> + struct drm_atomic_state *state =
>>> + container_of(rhead, typeof(*state), rhead);
>>> struct drm_mode_config *config = &state->dev->mode_config;
>>>
>>> drm_atomic_state_clear(state);
>>> @@ -236,6 +230,20 @@ void __drm_atomic_state_free(struct kref *ref)
>>> kfree(state);
>>> }
>>> }
>> whatisRCU.txt:
>> "This function invokes func(head) after a grace period has elapsed.
>> This invocation might happen from either softirq or process context,
>> so the function is not permitted to block."
>>
>> Looking at
>> commit 6f0f02dc56f18760b46dc1bf5b3f7386869d4162
>> Author: Chris Wilson <chris at chris-wilson.co.uk>
>> Date: Mon Jan 23 21:29:39 2017 +0000
>>
>> drm/i915: Move atomic state free from out of fence release
>>
>> I would say that drm_atomic_state_free would definitely block..
>>
>> The only thing that makes sense IMO is doing kfree_rcu on the object_states.
>> But I don't think RCU is the answer here, it won't protect you against using
>> the wrong crtc state.
>>
>> I think I would try to use the crtc ww_mutex in the vblank code and serialize it to pending commits, if at all possible.
> Oops. I guess it should have come with "totally untested". In that
> case we need a workter which does a synchronize_rcu() before
> releasing. I don't just want to do a simple kfree_rcu() because by
> that point we've (partially) destroyed the state alreayd (so it's
> already unsafe to access, and special ruels are ugly). And doing it
> here before we release anything in the core would avoid the need for
> drivers to bother with kfree_rcu().
>
> I'll try to respin something less obviously buggy tomorrow :-)
It will still be buggy tomorrow, since you have no way to know if the current hardware crtc_state is anything like crtc->state.
:(
More information about the Intel-gfx
mailing list