[Mesa-dev,v5,06/12] etnaviv: use common pipe_screen ref counting

Submitted by Rob Herring on Aug. 7, 2017, 10:58 p.m.

Details

Message ID 20170807225819.13831-9-robh@kernel.org
State New
Headers show
Series "Common pipe screen ref counting" ( rev: 5 ) in Mesa

Not browsing as part of any series.

Commit Message

Rob Herring Aug. 7, 2017, 10:58 p.m.
Use the common pipe_screen ref counting and fd hashing functions.
The mutex can be dropped as the pipe loader serializes the
create_screen() and destroy() calls.

Signed-off-by: Rob Herring <robh@kernel.org>
Cc: Christian Gmeiner <christian.gmeiner@gmail.com>
Cc: Wladimir J. van der Laan <laanwj@gmail.com>
Cc: Lucas Stach <l.stach@pengutronix.de>
---
 src/gallium/drivers/etnaviv/etnaviv_screen.c       |  1 -
 src/gallium/drivers/etnaviv/etnaviv_screen.h       |  4 --
 .../winsys/etnaviv/drm/etnaviv_drm_winsys.c        | 81 +++-------------------
 3 files changed, 8 insertions(+), 78 deletions(-)

Patch hide | download patch | download mbox

diff --git a/src/gallium/drivers/etnaviv/etnaviv_screen.c b/src/gallium/drivers/etnaviv/etnaviv_screen.c
index 9aca90642c37..92950c3bfbb5 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_screen.c
+++ b/src/gallium/drivers/etnaviv/etnaviv_screen.c
@@ -806,7 +806,6 @@  etna_screen_create(struct etna_device *dev, struct etna_gpu *gpu,
    screen->dev = dev;
    screen->gpu = gpu;
    screen->ro = renderonly_dup(ro);
-   screen->refcnt = 1;
 
    if (!screen->ro) {
       DBG("could not create renderonly object");
diff --git a/src/gallium/drivers/etnaviv/etnaviv_screen.h b/src/gallium/drivers/etnaviv/etnaviv_screen.h
index dc57a38dbb80..74b8e98d1695 100644
--- a/src/gallium/drivers/etnaviv/etnaviv_screen.h
+++ b/src/gallium/drivers/etnaviv/etnaviv_screen.h
@@ -30,7 +30,6 @@ 
 
 #include "etnaviv_internal.h"
 
-#include "os/os_thread.h"
 #include "pipe/p_screen.h"
 #include "renderonly/renderonly.h"
 #include "util/slab.h"
@@ -59,9 +58,6 @@  enum viv_features_word {
 struct etna_screen {
    struct pipe_screen base;
 
-   int refcnt;
-   void *winsys_priv;
-
    struct etna_device *dev;
    struct etna_gpu *gpu;
    struct etna_pipe *pipe;
diff --git a/src/gallium/winsys/etnaviv/drm/etnaviv_drm_winsys.c b/src/gallium/winsys/etnaviv/drm/etnaviv_drm_winsys.c
index 8e3f7a06a9a0..09b20389810b 100644
--- a/src/gallium/winsys/etnaviv/drm/etnaviv_drm_winsys.c
+++ b/src/gallium/winsys/etnaviv/drm/etnaviv_drm_winsys.c
@@ -28,6 +28,7 @@ 
 
 #include "util/u_hash_table.h"
 #include "util/u_memory.h"
+#include "util/u_screen.h"
 
 #include "etnaviv/etnaviv_screen.h"
 #include "etnaviv/hw/common.xml.h"
@@ -67,85 +68,19 @@  screen_create(struct renderonly *ro)
    return etna_screen_create(dev, gpu, ro);
 }
 
-static struct util_hash_table *etna_tab = NULL;
-
-static mtx_t etna_screen_mutex = _MTX_INITIALIZER_NP;
-
-static void
-etna_drm_screen_destroy(struct pipe_screen *pscreen)
-{
-   struct etna_screen *screen = etna_screen(pscreen);
-   boolean destroy;
-
-   mtx_lock(&etna_screen_mutex);
-   destroy = --screen->refcnt == 0;
-   if (destroy) {
-      int fd = etna_device_fd(screen->dev);
-      util_hash_table_remove(etna_tab, intptr_to_pointer(fd));
-   }
-   mtx_unlock(&etna_screen_mutex);
-
-   if (destroy) {
-      pscreen->destroy = screen->winsys_priv;
-      pscreen->destroy(pscreen);
-   }
-}
-
-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 *
 etna_drm_screen_create_renderonly(struct renderonly *ro)
 {
-   struct pipe_screen *pscreen = NULL;
+   struct etna_screen *screen;
+   struct pipe_screen *pscreen = pipe_screen_reference(ro->gpu_fd);
 
-   mtx_lock(&etna_screen_mutex);
-   if (!etna_tab) {
-      etna_tab = util_hash_table_create(hash_fd, compare_fd);
-      if (!etna_tab)
-         goto unlock;
-   }
+   if (pscreen)
+      return pscreen;
 
-   pscreen = util_hash_table_get(etna_tab, intptr_to_pointer(ro->gpu_fd));
-   if (pscreen) {
-      etna_screen(pscreen)->refcnt++;
-   } else {
-      pscreen = screen_create(ro);
-      if (pscreen) {
-         int fd = etna_device_fd(etna_screen(pscreen)->dev);
-         util_hash_table_set(etna_tab, intptr_to_pointer(fd), pscreen);
-
-         /* Bit of a hack, to avoid circular linkage dependency,
-         * ie. pipe driver having to call in to winsys, we
-         * override the pipe drivers screen->destroy() */
-         etna_screen(pscreen)->winsys_priv = pscreen->destroy;
-      pscreen->destroy = etna_drm_screen_destroy;
-      }
-   }
+   pscreen = screen_create(ro);
 
-unlock:
-   mtx_unlock(&etna_screen_mutex);
+   screen = etna_screen(pscreen);
+   pipe_screen_reference_init(pscreen, etna_device_fd(screen->dev));
    return pscreen;
 }
 

Comments

On Tue, Aug 8, 2017 at 12:58 AM, Rob Herring <robh@kernel.org> wrote:
> Use the common pipe_screen ref counting and fd hashing functions.
> The mutex can be dropped as the pipe loader serializes the
> create_screen() and destroy() calls.
>
> Signed-off-by: Rob Herring <robh@kernel.org>
> Cc: Christian Gmeiner <christian.gmeiner@gmail.com>
> Cc: Wladimir J. van der Laan <laanwj@gmail.com>
> Cc: Lucas Stach <l.stach@pengutronix.de>

This sure cleans up a lot.

Reviewed-by: Wladimir J. van der Laan <laanwj@gmail.com>
(will test)

> ---
>  src/gallium/drivers/etnaviv/etnaviv_screen.c       |  1 -
>  src/gallium/drivers/etnaviv/etnaviv_screen.h       |  4 --
>  .../winsys/etnaviv/drm/etnaviv_drm_winsys.c        | 81 +++-------------------
>  3 files changed, 8 insertions(+), 78 deletions(-)
>
> diff --git a/src/gallium/drivers/etnaviv/etnaviv_screen.c b/src/gallium/drivers/etnaviv/etnaviv_screen.c
> index 9aca90642c37..92950c3bfbb5 100644
> --- a/src/gallium/drivers/etnaviv/etnaviv_screen.c
> +++ b/src/gallium/drivers/etnaviv/etnaviv_screen.c
> @@ -806,7 +806,6 @@ etna_screen_create(struct etna_device *dev, struct etna_gpu *gpu,
>     screen->dev = dev;
>     screen->gpu = gpu;
>     screen->ro = renderonly_dup(ro);
> -   screen->refcnt = 1;
>
>     if (!screen->ro) {
>        DBG("could not create renderonly object");
> diff --git a/src/gallium/drivers/etnaviv/etnaviv_screen.h b/src/gallium/drivers/etnaviv/etnaviv_screen.h
> index dc57a38dbb80..74b8e98d1695 100644
> --- a/src/gallium/drivers/etnaviv/etnaviv_screen.h
> +++ b/src/gallium/drivers/etnaviv/etnaviv_screen.h
> @@ -30,7 +30,6 @@
>
>  #include "etnaviv_internal.h"
>
> -#include "os/os_thread.h"
>  #include "pipe/p_screen.h"
>  #include "renderonly/renderonly.h"
>  #include "util/slab.h"
> @@ -59,9 +58,6 @@ enum viv_features_word {
>  struct etna_screen {
>     struct pipe_screen base;
>
> -   int refcnt;
> -   void *winsys_priv;
> -
>     struct etna_device *dev;
>     struct etna_gpu *gpu;
>     struct etna_pipe *pipe;
> diff --git a/src/gallium/winsys/etnaviv/drm/etnaviv_drm_winsys.c b/src/gallium/winsys/etnaviv/drm/etnaviv_drm_winsys.c
> index 8e3f7a06a9a0..09b20389810b 100644
> --- a/src/gallium/winsys/etnaviv/drm/etnaviv_drm_winsys.c
> +++ b/src/gallium/winsys/etnaviv/drm/etnaviv_drm_winsys.c
> @@ -28,6 +28,7 @@
>
>  #include "util/u_hash_table.h"
>  #include "util/u_memory.h"
> +#include "util/u_screen.h"
>
>  #include "etnaviv/etnaviv_screen.h"
>  #include "etnaviv/hw/common.xml.h"
> @@ -67,85 +68,19 @@ screen_create(struct renderonly *ro)
>     return etna_screen_create(dev, gpu, ro);
>  }
>
> -static struct util_hash_table *etna_tab = NULL;
> -
> -static mtx_t etna_screen_mutex = _MTX_INITIALIZER_NP;
> -
> -static void
> -etna_drm_screen_destroy(struct pipe_screen *pscreen)
> -{
> -   struct etna_screen *screen = etna_screen(pscreen);
> -   boolean destroy;
> -
> -   mtx_lock(&etna_screen_mutex);
> -   destroy = --screen->refcnt == 0;
> -   if (destroy) {
> -      int fd = etna_device_fd(screen->dev);
> -      util_hash_table_remove(etna_tab, intptr_to_pointer(fd));
> -   }
> -   mtx_unlock(&etna_screen_mutex);
> -
> -   if (destroy) {
> -      pscreen->destroy = screen->winsys_priv;
> -      pscreen->destroy(pscreen);
> -   }
> -}
> -
> -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 *
>  etna_drm_screen_create_renderonly(struct renderonly *ro)
>  {
> -   struct pipe_screen *pscreen = NULL;
> +   struct etna_screen *screen;
> +   struct pipe_screen *pscreen = pipe_screen_reference(ro->gpu_fd);
>
> -   mtx_lock(&etna_screen_mutex);
> -   if (!etna_tab) {
> -      etna_tab = util_hash_table_create(hash_fd, compare_fd);
> -      if (!etna_tab)
> -         goto unlock;
> -   }
> +   if (pscreen)
> +      return pscreen;
>
> -   pscreen = util_hash_table_get(etna_tab, intptr_to_pointer(ro->gpu_fd));
> -   if (pscreen) {
> -      etna_screen(pscreen)->refcnt++;
> -   } else {
> -      pscreen = screen_create(ro);
> -      if (pscreen) {
> -         int fd = etna_device_fd(etna_screen(pscreen)->dev);
> -         util_hash_table_set(etna_tab, intptr_to_pointer(fd), pscreen);
> -
> -         /* Bit of a hack, to avoid circular linkage dependency,
> -         * ie. pipe driver having to call in to winsys, we
> -         * override the pipe drivers screen->destroy() */
> -         etna_screen(pscreen)->winsys_priv = pscreen->destroy;
> -      pscreen->destroy = etna_drm_screen_destroy;
> -      }
> -   }
> +   pscreen = screen_create(ro);
>
> -unlock:
> -   mtx_unlock(&etna_screen_mutex);
> +   screen = etna_screen(pscreen);
> +   pipe_screen_reference_init(pscreen, etna_device_fd(screen->dev));
>     return pscreen;
>  }
>
> --
> 2.11.0
>