From a0b2829f200288a85899884019c2aea530a95c46 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Wed, 30 Dec 2015 10:33:09 -0800 Subject: [PATCH] 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. --- src/vulkan/anv_allocator.c | 22 +++++++++++++++++++--- 1 file 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 -- 2.30.2