From 796d0133bf47e9a02a4b7a9120eeab3d4ad68ebb Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 29 Jul 2019 17:06:07 +0200 Subject: [PATCH] Add function to import block and track memory region Make a new function that we can use to track mappings of imported memory. --- src/pipewire/mem.c | 61 ++++++++++++++++++++++++++++++++++++++++++---- src/pipewire/mem.h | 3 +++ 2 files changed, 59 insertions(+), 5 deletions(-) diff --git a/src/pipewire/mem.c b/src/pipewire/mem.c index 8ffa06bb4..6d2937dc3 100644 --- a/src/pipewire/mem.c +++ b/src/pipewire/mem.c @@ -115,6 +115,7 @@ struct mapping { int ref; uint32_t offset; uint32_t size; + unsigned int do_unmap:1; struct spa_list link; void *ptr; }; @@ -271,10 +272,11 @@ static struct mapping * memblock_map(struct memblock *b, prot |= PROT_WRITE; if (flags & PW_MEMMAP_FLAG_TWICE) { - errno = -ENOTSUP; + errno = ENOTSUP; return NULL; } + ptr = mmap(NULL, size, prot, MAP_SHARED, b->this.fd, offset); if (ptr == MAP_FAILED) { pw_log_error("pool %p: Failed to mmap memory fd:%d offset:%u size:%u: %m", @@ -288,6 +290,7 @@ static struct mapping * memblock_map(struct memblock *b, return NULL; } m->ptr = ptr; + m->do_unmap = true; m->block = b; m->offset = offset; m->size = size; @@ -305,9 +308,11 @@ static void mapping_unmap(struct mapping *m) struct memblock *b = m->block; struct mempool *p = SPA_CONTAINER_OF(b->this.pool, struct mempool, this); - pw_log_debug("pool %p: mapping:%p fd:%d ptr:%p size:%d", p, m, b->this.fd, m->ptr, m->size); + pw_log_debug("pool %p: mapping:%p fd:%d ptr:%p size:%d block-ref:%d", + p, m, b->this.fd, m->ptr, m->size, b->this.ref); - munmap(m->ptr, m->size); + if (m->do_unmap) + munmap(m->ptr, m->size); spa_list_remove(&m->link); free(m); @@ -416,6 +421,8 @@ struct pw_memblock * pw_mempool_alloc(struct pw_mempool *pool, enum pw_memblock_ b->this.ref = 1; b->this.pool = pool; b->this.flags = flags; + b->this.type = type; + b->this.size = size; spa_list_init(&b->mappings); spa_list_init(&b->maps); @@ -450,8 +457,6 @@ struct pw_memblock * pw_mempool_alloc(struct pw_mempool *pool, enum pw_memblock_ } } #endif - b->this.type = type; - if (flags & PW_MEMBLOCK_FLAG_MAP && size > 0) { enum pw_memmap_flags fl = 0; @@ -545,6 +550,52 @@ struct pw_memblock * pw_mempool_import_block(struct pw_mempool *pool, mem->type, mem->fd); } +SPA_EXPORT +struct pw_memmap * pw_mempool_import_map(struct pw_mempool *pool, + struct pw_mempool *other, void *data, uint32_t size, uint32_t tag[5]) +{ + struct pw_memblock *old, *block; + struct memblock *b; + struct pw_memmap *map; + struct mapping *m; + uint32_t offset; + + old = pw_mempool_find_ptr(other, data); + if (old == NULL || old->map == NULL) { + errno = EFAULT; + return NULL; + } + + block = pw_mempool_import_block(pool, old); + if (block == NULL) + return NULL; + + if (block->ref == 1) { + b = SPA_CONTAINER_OF(block, struct memblock, this); + + m = calloc(1, sizeof(struct mapping)); + if (m == NULL) { + pw_memblock_unref(block); + return NULL; + } + m->ptr = old->map->ptr; + m->block = b; + m->offset = old->map->offset; + m->size = old->map->size; + spa_list_append(&b->mappings, &m->link); + } else { + block->ref--; + } + + offset = SPA_PTRDIFF(data, old->map->ptr); + + map = pw_memblock_map(block, block->flags, offset, size, tag); + if (map == NULL) + return NULL; + + return map; +} + int pw_mempool_unref_id(struct pw_mempool *pool, uint32_t id) { diff --git a/src/pipewire/mem.h b/src/pipewire/mem.h index 9e0793153..a9c22d87d 100644 --- a/src/pipewire/mem.h +++ b/src/pipewire/mem.h @@ -153,6 +153,9 @@ struct pw_memmap * pw_mempool_map_id(struct pw_mempool *pool, uint32_t id, enum pw_memmap_flags flags, uint32_t offset, uint32_t size, uint32_t tag[5]); +struct pw_memmap * pw_mempool_import_map(struct pw_mempool *pool, + struct pw_mempool *other, void *data, uint32_t size, uint32_t tag[5]); + /** find a map with the given tag */ struct pw_memmap * pw_mempool_find_tag(struct pw_mempool *pool, uint32_t tag[5]);