diff options
author | Jason Ekstrand <[email protected]> | 2015-12-30 10:33:09 -0800 |
---|---|---|
committer | Jason Ekstrand <[email protected]> | 2015-12-30 10:36:19 -0800 |
commit | a0b2829f200288a85899884019c2aea530a95c46 (patch) | |
tree | a207b105a9dc72dbfa71f7d4df5cf0d0b82bb7a2 /src/vulkan | |
parent | 91d93f79083596d761a245643647c4c0066556b3 (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.c | 22 |
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 |