[PATCH 2/2] randr: cleanup provider properly
Peter Hutterer
peter.hutterer at who-t.net
Thu Jan 10 15:02:37 PST 2013
On Wed, Jan 09, 2013 at 01:14:55PM +1000, Dave Airlie wrote:
> From: Dave Airlie <airlied at redhat.com>
>
> So in the cold plug server shutdown case, we reap the resources
> before we call CloseScreen handlers, so the config->randr_provider
> is a dangling pointer when the xf86CrtcCloseScreen handler is called,
>
> however in the hot screen unplug case, we can't rely on automatically
> reaped resources, so we need to clean up the provider in the xf86CrtcCloseScreen
> case.
>
> This patch provides a cleanup callback from the randr provider removal
> into the DDX so it can cleanup properly, this then gets called by the automatic
> code for cold plug, or if hot unplug it gets called explicitly.
>
> Fixes a number of random server crashes on shutdown
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=58174
> Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=891140
>
> Signed-off-by: Dave Airlie <airlied at redhat.com>
seems correct, as far as I understand this code
Reviewed-by: Peter Hutterer <peter.hutterer at who-t.net>
Cheers,
Peter
> ---
> hw/xfree86/modes/xf86Crtc.c | 12 ++----------
> hw/xfree86/modes/xf86RandR12.c | 22 ++++++++++++++++++++++
> randr/randrstr.h | 6 ++++++
> randr/rrprovider.c | 2 ++
> 4 files changed, 32 insertions(+), 10 deletions(-)
>
> diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
> index 45764fc..1905b18 100644
> --- a/hw/xfree86/modes/xf86Crtc.c
> +++ b/hw/xfree86/modes/xf86Crtc.c
> @@ -743,16 +743,8 @@ xf86CrtcCloseScreen(ScreenPtr screen)
> }
> /* detach any providers */
> if (config->randr_provider) {
> - if (config->randr_provider->offload_sink) {
> - DetachOffloadGPU(screen);
> - config->randr_provider->offload_sink = NULL;
> - }
> - else if (config->randr_provider->output_source) {
> - DetachOutputGPU(screen);
> - config->randr_provider->output_source = NULL;
> - }
> - else if (screen->current_master)
> - DetachUnboundGPU(screen);
> + RRProviderDestroy(config->randr_provider);
> + config->randr_provider = NULL;
> }
> return TRUE;
> }
> diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
> index 3530abf..01fc9c5 100644
> --- a/hw/xfree86/modes/xf86RandR12.c
> +++ b/hw/xfree86/modes/xf86RandR12.c
> @@ -1885,6 +1885,27 @@ xf86RandR13ConstrainCursorHarder(DeviceIntPtr dev, ScreenPtr screen, int mode, i
> }
> }
>
> +static void
> +xf86RandR14ProviderDestroy(ScreenPtr screen, RRProviderPtr provider)
> +{
> + ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
> + xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
> +
> + if (config->randr_provider == provider) {
> + if (config->randr_provider->offload_sink) {
> + DetachOffloadGPU(screen);
> + config->randr_provider->offload_sink = NULL;
> + }
> + else if (config->randr_provider->output_source) {
> + DetachOutputGPU(screen);
> + config->randr_provider->output_source = NULL;
> + }
> + else if (screen->current_master)
> + DetachUnboundGPU(screen);
> + }
> + config->randr_provider = NULL;
> +}
> +
> static Bool
> xf86RandR12Init12(ScreenPtr pScreen)
> {
> @@ -1914,6 +1935,7 @@ xf86RandR12Init12(ScreenPtr pScreen)
> rp->rrProviderSetProperty = xf86RandR14ProviderSetProperty;
> rp->rrProviderGetProperty = xf86RandR14ProviderGetProperty;
> rp->rrCrtcSetScanoutPixmap = xf86CrtcSetScanoutPixmap;
> + rp->rrProviderDestroy = xf86RandR14ProviderDestroy;
>
> pScrn->PointerMoved = xf86RandR12PointerMoved;
> pScrn->ChangeGamma = xf86RandR12ChangeGamma;
> diff --git a/randr/randrstr.h b/randr/randrstr.h
> index a16302f..cc3ab1d 100644
> --- a/randr/randrstr.h
> +++ b/randr/randrstr.h
> @@ -232,6 +232,9 @@ typedef Bool (*RRProviderSetOffloadSinkProcPtr)(ScreenPtr pScreen,
> RRProviderPtr offload_sink);
>
>
> +typedef void (*RRProviderDestroyProcPtr)(ScreenPtr pScreen,
> + RRProviderPtr provider);
> +
> /* These are for 1.0 compatibility */
>
> typedef struct _rrRefresh {
> @@ -330,6 +333,9 @@ typedef struct _rrScrPriv {
> Bool discontiguous;
>
> RRProviderPtr provider;
> +
> + RRProviderDestroyProcPtr rrProviderDestroy;
> +
> } rrScrPrivRec, *rrScrPrivPtr;
>
> extern _X_EXPORT DevPrivateKeyRec rrPrivKeyRec;
> diff --git a/randr/rrprovider.c b/randr/rrprovider.c
> index c4ed515..b321e62 100644
> --- a/randr/rrprovider.c
> +++ b/randr/rrprovider.c
> @@ -389,6 +389,8 @@ RRProviderDestroyResource (pointer value, XID pid)
> {
> rrScrPriv(pScreen);
>
> + if (pScrPriv->rrProviderDestroy)
> + (*pScrPriv->rrProviderDestroy)(pScreen, provider);
> pScrPriv->provider = NULL;
> }
> free(provider);
> --
> 1.8.1
More information about the xorg-devel
mailing list