[PATCH libdrm] etnaviv: Use hash table to track BO indexes
Marek Vasut
marex at denx.de
Sat Jun 29 00:50:48 UTC 2019
On 6/28/19 1:27 PM, Wladimir J. van der Laan wrote:
>> Maybe you want to look at
>> https://gitlab.freedesktop.org/mesa/mesa/merge_requests/1190
>>
>> I updated this patch against mesa master, apparently the libdrm-etnaviv
>> bits were folded into mesa now.
>
> Thanks!
>
>>>> stream->pipe = pipe;
>>>> stream->reset_notify = reset_notify;
>>>> stream->reset_notify_priv = priv;
>>>> + stream->seqno = ++dev->stream_cnt;
>>>
>>> Do we have to catch integer overflow here?
>>> It's very unlikely for there to have been 2^32 streams, but if it happens it might be good to at least
>>> warn.
>>
>> I don't think so.
>>
>> If you allocated (2^(machine word size))-1 streams, you would exhaust
>> your memory long before that. And this can actually roll over, since if
>> you were to allocate streams one after the other and then free them,
>> their numbers would just increment without colliding.
>>
>> I guess what could happen here would be something like, you allocate
>> stream #0 , then allocate/free (2^(machine word size)) - 2 streams and
>> then allocating the (2^(machine word size)) - 1th stream would end up
>> allocating new stream with the same stream count (?).
>
> This is the scenario that I was imagining, in which two separate streams could
> collide with the same seq no (resulting in weird glitches in bo tracking), but yes, it
> seems very unlikely.
So looking at the code, why do we even track some "seqno"s at all?
Wouldn't it be enough to replace int current_stream_seqno with struct
etna_cmd_stream *current_stream and just track the stream pointer
itself? Then all these seqno parts go away.
Like this:
diff --git a/src/etnaviv/drm/etnaviv_cmd_stream.c
b/src/etnaviv/drm/etnaviv_cmd_stream.c
index 9c25e4330c1..c4a26b2672c 100644
--- a/src/etnaviv/drm/etnaviv_cmd_stream.c
+++ b/src/etnaviv/drm/etnaviv_cmd_stream.c
@@ -87,7 +87,6 @@ struct etna_cmd_stream *etna_cmd_stream_new(struct
etna_pipe *pipe,
stream->pipe = pipe;
stream->reset_notify = reset_notify;
stream->reset_notify_priv = priv;
- stream->seqno = ++dev->stream_cnt;
return &stream->base;
@@ -152,7 +151,7 @@ static uint32_t bo2idx(struct etna_cmd_stream
*stream, struct etna_bo *bo,
pthread_mutex_lock(&idx_lock);
- if (bo->current_stream_seqno == priv->seqno) {
+ if (bo->current_stream == stream) {
idx = bo->idx;
} else {
void *val;
@@ -169,7 +168,7 @@ static uint32_t bo2idx(struct etna_cmd_stream
*stream, struct etna_bo *bo,
drmHashInsert(priv->bo_table, bo->handle, val);
}
- bo->current_stream_seqno = priv->seqno;
+ bo->current_stream = stream;
bo->idx = idx;
}
pthread_mutex_unlock(&idx_lock);
@@ -221,7 +220,7 @@ static void flush(struct etna_cmd_stream *stream,
int in_fence_fd,
for (uint32_t i = 0; i < priv->nr_bos; i++) {
struct etna_bo *bo = priv->bos[i];
- bo->current_stream_seqno = 0;
+ bo->current_stream = NULL;
etna_bo_del(bo);
}
diff --git a/src/etnaviv/drm/etnaviv_priv.h b/src/etnaviv/drm/etnaviv_priv.h
index ab69c37be62..4e400ae369b 100644
--- a/src/etnaviv/drm/etnaviv_priv.h
+++ b/src/etnaviv/drm/etnaviv_priv.h
@@ -106,7 +106,7 @@ struct etna_bo {
* last emitted on (since that will probably also be the next ring
* it is emitted on).
*/
- unsigned int current_stream_seqno;
+ struct etna_cmd_stream *current_stream;
uint32_t idx;
int reuse;
@@ -155,7 +155,6 @@ struct etna_cmd_stream_priv {
void (*reset_notify)(struct etna_cmd_stream *stream, void *priv);
void *reset_notify_priv;
- unsigned int seqno;
void *bo_table;
};
--
Best regards,
Marek Vasut
More information about the dri-devel
mailing list