mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2026-01-03 11:09:08 -05:00
remote: improve mapped memory tracking
This commit is contained in:
parent
008df86c8f
commit
c9fb320987
1 changed files with 38 additions and 32 deletions
|
|
@ -48,19 +48,23 @@ struct remote {
|
||||||
struct spa_hook core_listener;
|
struct spa_hook core_listener;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct mapping {
|
||||||
|
void *ptr;
|
||||||
|
struct pw_map_range map;
|
||||||
|
int prot;
|
||||||
|
};
|
||||||
|
|
||||||
struct mem {
|
struct mem {
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
int fd;
|
int fd;
|
||||||
uint32_t flags;
|
uint32_t flags;
|
||||||
uint32_t ref;
|
uint32_t ref;
|
||||||
struct pw_map_range map;
|
struct mapping map;
|
||||||
void *ptr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct buffer_mem {
|
struct buffer_mem {
|
||||||
void *ptr;
|
|
||||||
struct pw_map_range map;
|
|
||||||
uint32_t mem_id;
|
uint32_t mem_id;
|
||||||
|
struct mapping map;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct buffer {
|
struct buffer {
|
||||||
|
|
@ -539,25 +543,29 @@ static struct mem *find_mem_ptr(struct node_data *data, void *ptr)
|
||||||
{
|
{
|
||||||
struct mem *m;
|
struct mem *m;
|
||||||
pw_array_for_each(m, &data->mems) {
|
pw_array_for_each(m, &data->mems) {
|
||||||
if (m->ptr == ptr)
|
if (m->map.ptr == ptr)
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *mem_map(struct node_data *data, struct pw_map_range *range,
|
static void *mem_map(struct node_data *data, struct mapping *map,
|
||||||
int fd, int prot, uint32_t offset, uint32_t size)
|
int fd, int prot, uint32_t offset, uint32_t size)
|
||||||
{
|
{
|
||||||
|
struct mapping m;
|
||||||
void *ptr;
|
void *ptr;
|
||||||
|
|
||||||
pw_map_range_init(range, offset, size, data->core->sc_pagesize);
|
pw_map_range_init(&m.map, offset, size, data->core->sc_pagesize);
|
||||||
|
|
||||||
ptr = mmap(NULL, range->size, prot, MAP_SHARED, fd, range->offset);
|
if (map->ptr == NULL || map->map.offset != m.map.offset || map->map.size != m.map.size) {
|
||||||
if (ptr == MAP_FAILED) {
|
map->ptr = mmap(map->ptr, m.map.size, prot, MAP_SHARED, fd, m.map.offset);
|
||||||
pw_log_error("remote %p: Failed to mmap memory %d: %m", data, size);
|
if (map->ptr == MAP_FAILED) {
|
||||||
return NULL;
|
pw_log_error("remote %p: Failed to mmap memory %d: %m", data, size);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
map->map = m.map;
|
||||||
}
|
}
|
||||||
ptr = SPA_MEMBER(ptr, range->start, void);
|
ptr = SPA_MEMBER(map->ptr, map->map.start, void);
|
||||||
pw_log_debug("remote %p: fd %d mapped %d %d %p", data, fd, offset, size, ptr);
|
pw_log_debug("remote %p: fd %d mapped %d %d %p", data, fd, offset, size, ptr);
|
||||||
|
|
||||||
return ptr;
|
return ptr;
|
||||||
|
|
@ -592,7 +600,7 @@ static void clear_mem(struct node_data *data, struct mem *m)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!has_ref) {
|
if (!has_ref) {
|
||||||
m->ptr = mem_unmap(data, m->ptr, &m->map);
|
m->map.ptr = mem_unmap(data, m->map.ptr, &m->map.map);
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -730,8 +738,8 @@ static void client_node_add_mem(void *object,
|
||||||
m->fd = memfd;
|
m->fd = memfd;
|
||||||
m->flags = flags;
|
m->flags = flags;
|
||||||
m->ref = 0;
|
m->ref = 0;
|
||||||
m->map = PW_MAP_RANGE_INIT;
|
m->map.map = PW_MAP_RANGE_INIT;
|
||||||
m->ptr = NULL;
|
m->map.ptr = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void client_node_transport(void *object, uint32_t node_id,
|
static void client_node_transport(void *object, uint32_t node_id,
|
||||||
|
|
@ -1006,15 +1014,15 @@ client_node_port_use_buffers(void *object,
|
||||||
bid = pw_array_add(&mix->buffers, sizeof(struct buffer));
|
bid = pw_array_add(&mix->buffers, sizeof(struct buffer));
|
||||||
|
|
||||||
bmem.mem_id = m->id;
|
bmem.mem_id = m->id;
|
||||||
bmem.ptr = mem_map(data, &bmem.map, m->fd, prot,
|
bmem.map.ptr = mem_map(data, &bmem.map, m->fd, prot,
|
||||||
buffers[i].offset, buffers[i].size);
|
buffers[i].offset, buffers[i].size);
|
||||||
if (bmem.ptr == NULL) {
|
if (bmem.map.ptr == NULL) {
|
||||||
res = -errno;
|
res = -errno;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
if (mlock(bmem.ptr, bmem.map.size) < 0)
|
if (mlock(bmem.map.ptr, bmem.map.map.size) < 0)
|
||||||
pw_log_warn("Failed to mlock memory %u %u: %m",
|
pw_log_warn("Failed to mlock memory %u %u: %m",
|
||||||
bmem.map.offset, bmem.map.size);
|
bmem.map.map.offset, bmem.map.map.size);
|
||||||
|
|
||||||
size = sizeof(struct spa_buffer);
|
size = sizeof(struct spa_buffer);
|
||||||
size += sizeof(struct buffer_mem);
|
size += sizeof(struct buffer_mem);
|
||||||
|
|
@ -1048,13 +1056,13 @@ client_node_port_use_buffers(void *object,
|
||||||
pw_log_warn("unexpected id %u found, expected %u", bid->id, len);
|
pw_log_warn("unexpected id %u found, expected %u", bid->id, len);
|
||||||
}
|
}
|
||||||
pw_log_debug("add buffer %d %d %u %u", m->id,
|
pw_log_debug("add buffer %d %d %u %u", m->id,
|
||||||
bid->id, bmem.map.offset, bmem.map.size);
|
bid->id, bmem.map.map.offset, bmem.map.map.size);
|
||||||
|
|
||||||
offset = 0;
|
offset = 0;
|
||||||
for (j = 0; j < b->n_metas; j++) {
|
for (j = 0; j < b->n_metas; j++) {
|
||||||
struct spa_meta *m = &b->metas[j];
|
struct spa_meta *m = &b->metas[j];
|
||||||
memcpy(m, &buffers[i].buffer->metas[j], sizeof(struct spa_meta));
|
memcpy(m, &buffers[i].buffer->metas[j], sizeof(struct spa_meta));
|
||||||
m->data = SPA_MEMBER(bmem.ptr, offset, void);
|
m->data = SPA_MEMBER(bmem.map.ptr, offset, void);
|
||||||
offset += m->size;
|
offset += m->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1063,7 +1071,7 @@ client_node_port_use_buffers(void *object,
|
||||||
|
|
||||||
memcpy(d, &buffers[i].buffer->datas[j], sizeof(struct spa_data));
|
memcpy(d, &buffers[i].buffer->datas[j], sizeof(struct spa_data));
|
||||||
d->chunk =
|
d->chunk =
|
||||||
SPA_MEMBER(bmem.ptr, offset + sizeof(struct spa_chunk) * j,
|
SPA_MEMBER(bmem.map.ptr, offset + sizeof(struct spa_chunk) * j,
|
||||||
struct spa_chunk);
|
struct spa_chunk);
|
||||||
|
|
||||||
if (d->type == t->data.MemFd || d->type == t->data.DmaBuf) {
|
if (d->type == t->data.MemFd || d->type == t->data.DmaBuf) {
|
||||||
|
|
@ -1080,15 +1088,15 @@ client_node_port_use_buffers(void *object,
|
||||||
d->fd = bm->fd;
|
d->fd = bm->fd;
|
||||||
bm->ref++;
|
bm->ref++;
|
||||||
bm2.mem_id = bm->id;
|
bm2.mem_id = bm->id;
|
||||||
bm2.ptr = NULL;
|
bm2.map.ptr = NULL;
|
||||||
d->data = bm2.ptr;
|
d->data = bm2.map.ptr;
|
||||||
|
|
||||||
bid->mem[bid->n_mem++] = bm2;
|
bid->mem[bid->n_mem++] = bm2;
|
||||||
|
|
||||||
pw_log_debug(" data %d %u -> fd %d", j, bm->id, bm->fd);
|
pw_log_debug(" data %d %u -> fd %d", j, bm->id, bm->fd);
|
||||||
} else if (d->type == t->data.MemPtr) {
|
} else if (d->type == t->data.MemPtr) {
|
||||||
int offs = SPA_PTR_TO_INT(d->data);
|
int offs = SPA_PTR_TO_INT(d->data);
|
||||||
d->data = SPA_MEMBER(bmem.ptr, offs, void);
|
d->data = SPA_MEMBER(bmem.map.ptr, offs, void);
|
||||||
d->fd = -1;
|
d->fd = -1;
|
||||||
pw_log_debug(" data %d %u -> mem %p", j, bid->id, d->data);
|
pw_log_debug(" data %d %u -> mem %p", j, bid->id, d->data);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1160,14 +1168,12 @@ client_node_port_set_io(void *object,
|
||||||
pw_log_warn("unknown memory id %u", memid);
|
pw_log_warn("unknown memory id %u", memid);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (m->ptr == NULL) {
|
ptr = mem_map(data, &m->map, m->fd,
|
||||||
m->ptr = mem_map(data, &m->map, m->fd,
|
PROT_READ|PROT_WRITE, offset, size);
|
||||||
PROT_READ|PROT_WRITE, offset, size);
|
if (ptr == NULL)
|
||||||
if (m->ptr == NULL)
|
return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
m->ref++;
|
m->ref++;
|
||||||
ptr = m->ptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pw_log_debug("port %p: set io %s %p", mix->port,
|
pw_log_debug("port %p: set io %s %p", mix->port,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue