[Mesa-dev] [PATCH v5 03/12] gallium: add common pipe_screen reference counting functions

Marek Olšák maraeo at gmail.com
Wed Aug 9 19:18:01 UTC 2017


Hi Rob,

This is not enough to do screen reference counting. There are primary
FDs and render node FDs, and we want to have only one pipe_screen for
all kinds of FDs pointing to the same device.

Imagine someone creates a pipe_screen with a render node FD, and then
creates another pipe_screen with a primary FD. We want to return the
same pipe_screen instance in both cases.

The pipe_screen should use the render node FD for everything if it was
created first with that FD. However, it also needs to keep the primary
FD in order to be able to do GEM_FLINK when required.

libdrm_amdgpu handles all those cases correctly. It has "fd", which is
the main one, but also has "flink_fd" for GEM_FLINK. If "fd" is a
primary FD or there is no primary FD, "fd == flink_fd". If "fd" is a
render node and a primary FD has also been used to create the device
object, "fd" is the render node and "flink_fd" is the primary FD for
GEM_FLINK.

The code:
https://cgit.freedesktop.org/mesa/drm/tree/amdgpu/amdgpu_device.c

I can't accept this patch, because it effectively disables that
amdgpu_device code.

Marek


On Tue, Aug 8, 2017 at 12:58 AM, Rob Herring <robh at kernel.org> wrote:
> In order to prevent multiple pipe_screens being created in the same
> process, lookup of the DRM FD and reference counting of the pipe_screen
> are needed. Several implementations of this exist in various gallium
> drivers/winsys already. This creates a common version which is opt-in
> for winsys implementations.
>
> The callers of pipe_screen_{un}reference() functions are responsible for
> serializing the calls. Currently, this is done by the pipe-loader mutex.
>
> Signed-off-by: Rob Herring <robh at kernel.org>
> ---
>  src/gallium/auxiliary/Makefile.sources |   2 +
>  src/gallium/auxiliary/util/u_screen.c  | 112 +++++++++++++++++++++++++++++++++
>  src/gallium/auxiliary/util/u_screen.h  |  32 ++++++++++
>  src/gallium/include/pipe/p_screen.h    |   3 +
>  4 files changed, 149 insertions(+)
>  create mode 100644 src/gallium/auxiliary/util/u_screen.c
>  create mode 100644 src/gallium/auxiliary/util/u_screen.h
>
> diff --git a/src/gallium/auxiliary/Makefile.sources b/src/gallium/auxiliary/Makefile.sources
> index 9ae8e6c8ca53..f84bfec60fe7 100644
> --- a/src/gallium/auxiliary/Makefile.sources
> +++ b/src/gallium/auxiliary/Makefile.sources
> @@ -283,6 +283,8 @@ C_SOURCES := \
>         util/u_ringbuffer.h \
>         util/u_sampler.c \
>         util/u_sampler.h \
> +       util/u_screen.c \
> +       util/u_screen.h \
>         util/u_simple_shaders.c \
>         util/u_simple_shaders.h \
>         util/u_split_prim.h \
> diff --git a/src/gallium/auxiliary/util/u_screen.c b/src/gallium/auxiliary/util/u_screen.c
> new file mode 100644
> index 000000000000..dec83b736883
> --- /dev/null
> +++ b/src/gallium/auxiliary/util/u_screen.c
> @@ -0,0 +1,112 @@
> +/*
> + * Copyright 2016-2017 Linaro, Ltd., Rob Herring <robh at kernel.org>
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the
> + * "Software"), to deal in the Software without restriction, including
> + * without limitation the rights to use, copy, modify, merge, publish,
> + * distribute, sub license, and/or sell copies of the Software, and to
> + * permit persons to whom the Software is furnished to do so, subject to
> + * the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the
> + * next paragraph) shall be included in all copies or substantial portions
> + * of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
> + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
> + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
> + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
> + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
> + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
> + */
> +
> +/**
> + * Functions for managing pipe_screen's
> + */
> +
> +#include <sys/stat.h>
> +
> +#include "pipe/p_screen.h"
> +#include "util/u_hash_table.h"
> +#include "util/u_inlines.h"
> +#include "util/u_pointer.h"
> +#include "util/u_screen.h"
> +
> +static struct util_hash_table *fd_tab = NULL;
> +
> +static unsigned hash_fd(void *key)
> +{
> +   int fd = pointer_to_intptr(key);
> +   struct stat stat;
> +   fstat(fd, &stat);
> +
> +   return stat.st_dev ^ stat.st_ino ^ stat.st_rdev;
> +}
> +
> +static int compare_fd(void *key1, void *key2)
> +{
> +   int fd1 = pointer_to_intptr(key1);
> +   int fd2 = pointer_to_intptr(key2);
> +   struct stat stat1, stat2;
> +   fstat(fd1, &stat1);
> +   fstat(fd2, &stat2);
> +
> +   return stat1.st_dev != stat2.st_dev ||
> +         stat1.st_ino != stat2.st_ino ||
> +         stat1.st_rdev != stat2.st_rdev;
> +}
> +
> +struct pipe_screen *
> +pipe_screen_reference(int fd)
> +{
> +   struct pipe_screen *pscreen;
> +
> +   if (!fd_tab) {
> +      fd_tab = util_hash_table_create(hash_fd, compare_fd);
> +      return NULL;
> +   }
> +
> +   pscreen = util_hash_table_get(fd_tab, intptr_to_pointer(fd));
> +   if (pscreen)
> +      pipe_reference(NULL, &pscreen->reference);
> +
> +   return pscreen;
> +}
> +
> +boolean
> +pipe_screen_unreference(struct pipe_screen *pscreen)
> +{
> +   boolean destroy;
> +
> +   if (!pscreen)
> +      return FALSE;
> +
> +   /* Work-around until all pipe_screens have ref counting */
> +   if (!pipe_is_referenced(&pscreen->reference)) {
> +      pscreen->destroy(pscreen);
> +      return TRUE;
> +   }
> +
> +   destroy = pipe_reference(&pscreen->reference, NULL);
> +   if (destroy) {
> +      int fd = pscreen->fd;
> +
> +      pscreen->destroy(pscreen);
> +
> +      if (fd >= 0) {
> +         util_hash_table_remove(fd_tab, intptr_to_pointer(fd));
> +         close(fd);
> +      }
> +   }
> +   return destroy;
> +}
> +
> +
> +void pipe_screen_reference_init(struct pipe_screen *pscreen, int fd)
> +{
> +   pscreen->fd = fd;
> +   pipe_reference_init(&pscreen->reference, 1);
> +   util_hash_table_set(fd_tab, intptr_to_pointer(fd), pscreen);
> +}
> diff --git a/src/gallium/auxiliary/util/u_screen.h b/src/gallium/auxiliary/util/u_screen.h
> new file mode 100644
> index 000000000000..a7b1e9ff2787
> --- /dev/null
> +++ b/src/gallium/auxiliary/util/u_screen.h
> @@ -0,0 +1,32 @@
> +/*
> + * Copyright 2016-2017 Linaro, Ltd., Rob Herring <robh at kernel.org>
> + *
> + * Permission is hereby granted, free of charge, to any person obtaining a
> + * copy of this software and associated documentation files (the
> + * "Software"), to deal in the Software without restriction, including
> + * without limitation the rights to use, copy, modify, merge, publish,
> + * distribute, sub license, and/or sell copies of the Software, and to
> + * permit persons to whom the Software is furnished to do so, subject to
> + * the following conditions:
> + *
> + * The above copyright notice and this permission notice (including the
> + * next paragraph) shall be included in all copies or substantial portions
> + * of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
> + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
> + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
> + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
> + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
> + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
> + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
> + */
> +#include "pipe/p_defines.h"
> +
> +struct pipe_screen;
> +
> +struct pipe_screen *pipe_screen_reference(int fd);
> +
> +boolean pipe_screen_unreference(struct pipe_screen *pscreen);
> +
> +void pipe_screen_reference_init(struct pipe_screen *pscreen, int fd);
> diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h
> index b6623d1dd71e..dbb14ef882c0 100644
> --- a/src/gallium/include/pipe/p_screen.h
> +++ b/src/gallium/include/pipe/p_screen.h
> @@ -41,6 +41,7 @@
>  #include "pipe/p_compiler.h"
>  #include "pipe/p_format.h"
>  #include "pipe/p_defines.h"
> +#include "pipe/p_state.h"
>  #include "pipe/p_video_enums.h"
>
>
> @@ -68,6 +69,8 @@ struct driOptionCache;
>   * context.
>   */
>  struct pipe_screen {
> +   struct pipe_reference reference;
> +   int fd;
>     void (*destroy)( struct pipe_screen * );
>
>     const char *(*get_name)( struct pipe_screen * );
> --
> 2.11.0
>
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list