summaryrefslogtreecommitdiffstats
path: root/src/vulkan
diff options
context:
space:
mode:
authorJason Ekstrand <[email protected]>2015-12-30 10:33:09 -0800
committerJason Ekstrand <[email protected]>2015-12-30 10:36:19 -0800
commita0b2829f200288a85899884019c2aea530a95c46 (patch)
treea207b105a9dc72dbfa71f7d4df5cf0d0b82bb7a2 /src/vulkan
parent91d93f79083596d761a245643647c4c0066556b3 (diff)
anv/stream_alloc: Properly manage valgrind NOACCESS and UNDEFINED status
When I first did the valgrindifying for stream allocators, I misunderstood some things about valgrind's expectations for NOACCESS and UNDEFINED. First off, valgrind expects things to be marked NOACCESS before you allocate out of them. Since our blocks came from a pool backed by a mmapped memfd, they came in as UNDEFINED; we needed to mark them as NOACCESS. Also, I didn't realize that VALGRIND_MEMPOOL_CHANGE only updated the mempool allocation state and didn't actually change definedness; we had to add a VALGRIND_MAKE_MEM_UNDEFINED to get rid of the NOACCESS on the newly allocated portion.
Diffstat (limited to 'src/vulkan')
-rw-r--r--src/vulkan/anv_allocator.c22
1 files changed, 19 insertions, 3 deletions
diff --git a/src/vulkan/anv_allocator.c b/src/vulkan/anv_allocator.c
index 4cff84131aa..e87538cac5c 100644
--- a/src/vulkan/anv_allocator.c
+++ b/src/vulkan/anv_allocator.c
@@ -682,6 +682,14 @@ struct stream_block {
void *current_map;
#ifdef HAVE_VALGRIND
+ /* The pointer pointing to the beginning of the user portion of the
+ * block. More specifically, this value is:
+ *
+ * current_map + ALIGN(sizeof(stream_block), first_chunk_alignment)
+ *
+ * where first_chunk_alignment is the alignment of the first chunk
+ * allocated out of this particular block.
+ */
void *_vg_ptr;
#endif
};
@@ -733,9 +741,13 @@ anv_state_stream_alloc(struct anv_state_stream *stream,
block = anv_block_pool_alloc(stream->block_pool);
void *current_map = stream->block_pool->map;
sb = current_map + block;
- VG_NOACCESS_WRITE(&sb->current_map, current_map);
- VG_NOACCESS_WRITE(&sb->next, stream->current_block);
- VG(VG_NOACCESS_WRITE(&sb->_vg_ptr, 0));
+ sb->current_map = current_map;
+ sb->next = stream->current_block;
+ VG(sb->_vg_ptr = NULL);
+
+ /* Blocks come in from the block_pool as UNDEFINED */
+ VG(VALGRIND_MAKE_MEM_NOACCESS(sb, stream->block_pool->block_size));
+
stream->current_block = block;
stream->next = block + sizeof(*sb);
stream->end = block + stream->block_pool->block_size;
@@ -759,8 +771,12 @@ anv_state_stream_alloc(struct anv_state_stream *stream,
ptrdiff_t vg_offset = vg_ptr - current_map;
assert(vg_offset >= stream->current_block &&
vg_offset < stream->end);
+ /* This only updates the mempool. The newly allocated chunk is still
+ * marked as NOACCESS. */
VALGRIND_MEMPOOL_CHANGE(stream, vg_ptr, vg_ptr,
(state.offset + size) - vg_offset);
+ /* Mark the newly allocated chunk as undefined */
+ VALGRIND_MAKE_MEM_UNDEFINED(state.map, state.alloc_size);
}
#endif