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 <robclark@freedesktop.org>
main
Rob Clark 2018-05-09 07:40:29 -04:00
parent 1ac3ecde2f
commit c5a6568184
4 changed files with 12 additions and 0 deletions

View File

@ -36,6 +36,7 @@ fd_pipe_del
fd_pipe_get_param fd_pipe_get_param
fd_pipe_new fd_pipe_new
fd_pipe_new2 fd_pipe_new2
fd_pipe_ref
fd_pipe_wait fd_pipe_wait
fd_pipe_wait_timeout fd_pipe_wait_timeout
fd_ringbuffer_cmd_count fd_ringbuffer_cmd_count

View File

@ -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_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_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); void fd_pipe_del(struct fd_pipe *pipe);
int fd_pipe_get_param(struct fd_pipe *pipe, enum fd_param_id param, int fd_pipe_get_param(struct fd_pipe *pipe, enum fd_param_id param,
uint64_t *value); uint64_t *value);

View File

@ -57,6 +57,7 @@ fd_pipe_new2(struct fd_device *dev, enum fd_pipe_id id, uint32_t prio)
pipe->dev = dev; pipe->dev = dev;
pipe->id = id; pipe->id = id;
atomic_set(&pipe->refcnt, 1);
fd_pipe_get_param(pipe, FD_GPU_ID, &val); fd_pipe_get_param(pipe, FD_GPU_ID, &val);
pipe->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); 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) void fd_pipe_del(struct fd_pipe *pipe)
{ {
if (!atomic_dec_and_test(&pipe->refcnt))
return;
pipe->funcs->destroy(pipe); pipe->funcs->destroy(pipe);
} }

View File

@ -125,6 +125,7 @@ struct fd_pipe {
struct fd_device *dev; struct fd_device *dev;
enum fd_pipe_id id; enum fd_pipe_id id;
uint32_t gpu_id; uint32_t gpu_id;
atomic_t refcnt;
const struct fd_pipe_funcs *funcs; const struct fd_pipe_funcs *funcs;
}; };