From c5a656818492d3f772f2236cd5cbb407616cd188 Mon Sep 17 00:00:00 2001 From: Rob Clark Date: Wed, 9 May 2018 07:40:29 -0400 Subject: [PATCH] freedreno: add fd_pipe refcounting In mesa/gallium, a pipe_fence can outlive the pipe_context it was created from. But to wait on the fence we need to know the submit- queue (ie. the fd_pipe). The most straightforward way to fix this is to add reference counting to the fd_pipe and let the fence hold a reference to the pipe (rather than hanging on to the context, which might have been destroyed before the fence). Signed-off-by: Rob Clark --- freedreno/freedreno-symbol-check | 1 + freedreno/freedreno_drmif.h | 1 + freedreno/freedreno_pipe.c | 9 +++++++++ freedreno/freedreno_priv.h | 1 + 4 files changed, 12 insertions(+) diff --git a/freedreno/freedreno-symbol-check b/freedreno/freedreno-symbol-check index 3b119528..e6e5719d 100755 --- a/freedreno/freedreno-symbol-check +++ b/freedreno/freedreno-symbol-check @@ -36,6 +36,7 @@ fd_pipe_del fd_pipe_get_param fd_pipe_new fd_pipe_new2 +fd_pipe_ref fd_pipe_wait fd_pipe_wait_timeout fd_ringbuffer_cmd_count diff --git a/freedreno/freedreno_drmif.h b/freedreno/freedreno_drmif.h index 2711518b..c95c21be 100644 --- a/freedreno/freedreno_drmif.h +++ b/freedreno/freedreno_drmif.h @@ -104,6 +104,7 @@ enum fd_version fd_device_version(struct fd_device *dev); struct fd_pipe * fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id); struct fd_pipe * fd_pipe_new2(struct fd_device *dev, enum fd_pipe_id id, uint32_t prio); +struct fd_pipe * fd_pipe_ref(struct fd_pipe *pipe); void fd_pipe_del(struct fd_pipe *pipe); int fd_pipe_get_param(struct fd_pipe *pipe, enum fd_param_id param, uint64_t *value); diff --git a/freedreno/freedreno_pipe.c b/freedreno/freedreno_pipe.c index 77b160e7..30d231c7 100644 --- a/freedreno/freedreno_pipe.c +++ b/freedreno/freedreno_pipe.c @@ -57,6 +57,7 @@ fd_pipe_new2(struct fd_device *dev, enum fd_pipe_id id, uint32_t prio) pipe->dev = dev; pipe->id = id; + atomic_set(&pipe->refcnt, 1); fd_pipe_get_param(pipe, FD_GPU_ID, &val); pipe->gpu_id = val; @@ -70,8 +71,16 @@ fd_pipe_new(struct fd_device *dev, enum fd_pipe_id id) return fd_pipe_new2(dev, id, 1); } +struct fd_pipe * fd_pipe_ref(struct fd_pipe *pipe) +{ + atomic_inc(&pipe->refcnt); + return pipe; +} + void fd_pipe_del(struct fd_pipe *pipe) { + if (!atomic_dec_and_test(&pipe->refcnt)) + return; pipe->funcs->destroy(pipe); } diff --git a/freedreno/freedreno_priv.h b/freedreno/freedreno_priv.h index 6c9e509f..b0a48adf 100644 --- a/freedreno/freedreno_priv.h +++ b/freedreno/freedreno_priv.h @@ -125,6 +125,7 @@ struct fd_pipe { struct fd_device *dev; enum fd_pipe_id id; uint32_t gpu_id; + atomic_t refcnt; const struct fd_pipe_funcs *funcs; };