freedreno/msm: use hashtable to track bo idx
Note: cache the last ring the bo was emitted on, to avoid excess hashtable lookups. We do this by tracking ring seqno to avoid problems with dangling pointers. Signed-off-by: Rob Clark <robclark@freedesktop.org>main
parent
419a154dbe
commit
6a23bd4b3c
|
@ -40,6 +40,7 @@
|
|||
struct msm_device {
|
||||
struct fd_device base;
|
||||
struct fd_bo_cache ring_cache;
|
||||
unsigned ring_cnt;
|
||||
};
|
||||
|
||||
static inline struct msm_device * to_msm_device(struct fd_device *x)
|
||||
|
@ -72,18 +73,11 @@ struct msm_bo {
|
|||
struct fd_bo base;
|
||||
uint64_t offset;
|
||||
uint64_t presumed;
|
||||
/* in the common case, a bo won't be referenced by more than a single
|
||||
* (parent) ring[*]. So to avoid looping over all the bo's in the
|
||||
* reloc table to find the idx of a bo that might already be in the
|
||||
* table, we cache the idx in the bo. But in order to detect the
|
||||
* slow-path where bo is ref'd in multiple rb's, we also must track
|
||||
* the current_ring for which the idx is valid. See bo2idx().
|
||||
*
|
||||
* [*] in case multiple ringbuffers, ie. one toplevel and other rb(s)
|
||||
* used for IB target(s), the toplevel rb is the parent which is
|
||||
* tracking bo's for the submit
|
||||
/* to avoid excess hashtable lookups, cache the ring this bo was
|
||||
* last emitted on (since that will probably also be the next ring
|
||||
* it is emitted on)
|
||||
*/
|
||||
struct fd_ringbuffer *current_ring;
|
||||
unsigned current_ring_seqno;
|
||||
uint32_t idx;
|
||||
};
|
||||
|
||||
|
|
|
@ -92,6 +92,11 @@ struct msm_ringbuffer {
|
|||
|
||||
int is_growable;
|
||||
unsigned cmd_count;
|
||||
|
||||
unsigned seqno;
|
||||
|
||||
/* maps fd_bo to idx: */
|
||||
void *bo_table;
|
||||
};
|
||||
|
||||
static inline struct msm_ringbuffer * to_msm_ringbuffer(struct fd_ringbuffer *x)
|
||||
|
@ -217,21 +222,24 @@ static uint32_t bo2idx(struct fd_ringbuffer *ring, struct fd_bo *bo, uint32_t fl
|
|||
struct msm_bo *msm_bo = to_msm_bo(bo);
|
||||
uint32_t idx;
|
||||
pthread_mutex_lock(&idx_lock);
|
||||
if (!msm_bo->current_ring) {
|
||||
idx = append_bo(ring, bo);
|
||||
msm_bo->current_ring = ring;
|
||||
msm_bo->idx = idx;
|
||||
} else if (msm_bo->current_ring == ring) {
|
||||
if (msm_bo->current_ring_seqno == msm_ring->seqno) {
|
||||
idx = msm_bo->idx;
|
||||
} else {
|
||||
/* slow-path: */
|
||||
for (idx = 0; idx < msm_ring->nr_bos; idx++)
|
||||
if (msm_ring->bos[idx] == bo)
|
||||
break;
|
||||
if (idx == msm_ring->nr_bos) {
|
||||
/* not found */
|
||||
void *val;
|
||||
|
||||
if (!msm_ring->bo_table)
|
||||
msm_ring->bo_table = drmHashCreate();
|
||||
|
||||
if (!drmHashLookup(msm_ring->bo_table, bo->handle, &val)) {
|
||||
/* found */
|
||||
idx = (uint32_t)val;
|
||||
} else {
|
||||
idx = append_bo(ring, bo);
|
||||
val = (void *)idx;
|
||||
drmHashInsert(msm_ring->bo_table, bo->handle, val);
|
||||
}
|
||||
msm_bo->current_ring_seqno = msm_ring->seqno;
|
||||
msm_bo->idx = idx;
|
||||
}
|
||||
pthread_mutex_unlock(&idx_lock);
|
||||
if (flags & FD_RELOC_READ)
|
||||
|
@ -318,7 +326,7 @@ static void flush_reset(struct fd_ringbuffer *ring)
|
|||
|
||||
for (i = 0; i < msm_ring->nr_bos; i++) {
|
||||
struct msm_bo *msm_bo = to_msm_bo(msm_ring->bos[i]);
|
||||
msm_bo->current_ring = NULL;
|
||||
msm_bo->current_ring_seqno = 0;
|
||||
fd_bo_del(&msm_bo->base);
|
||||
}
|
||||
|
||||
|
@ -333,6 +341,11 @@ static void flush_reset(struct fd_ringbuffer *ring)
|
|||
msm_ring->nr_cmds = 0;
|
||||
msm_ring->nr_bos = 0;
|
||||
|
||||
if (msm_ring->bo_table) {
|
||||
drmHashDestroy(msm_ring->bo_table);
|
||||
msm_ring->bo_table = NULL;
|
||||
}
|
||||
|
||||
if (msm_ring->is_growable) {
|
||||
delete_cmds(msm_ring);
|
||||
} else {
|
||||
|
@ -551,6 +564,7 @@ drm_private struct fd_ringbuffer * msm_ringbuffer_new(struct fd_pipe *pipe,
|
|||
}
|
||||
|
||||
list_inithead(&msm_ring->cmd_list);
|
||||
msm_ring->seqno = ++to_msm_device(pipe->dev)->ring_cnt;
|
||||
|
||||
ring = &msm_ring->base;
|
||||
ring->funcs = &funcs;
|
||||
|
|
Loading…
Reference in New Issue