mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	Revert "remove mlock and use MAP_LOCKED"
This reverts commit ab91e94b59.
When no memory can be locked, the mmap fails with -EAGAIN.
Fixes #592
			
			
This commit is contained in:
		
							parent
							
								
									8c84c96fe1
								
							
						
					
					
						commit
						abfc67a3ca
					
				
					 4 changed files with 64 additions and 21 deletions
				
			
		| 
						 | 
				
			
			@ -87,6 +87,7 @@ struct globals {
 | 
			
		|||
};
 | 
			
		||||
 | 
			
		||||
static struct globals globals;
 | 
			
		||||
static bool mlock_warned = false;
 | 
			
		||||
 | 
			
		||||
#define OBJECT_CHUNK	8
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1722,8 +1723,6 @@ static int client_node_port_use_buffers(void *object,
 | 
			
		|||
		/* some apps write to the input buffer so we want everything readwrite */
 | 
			
		||||
		fl = PW_MEMMAP_FLAG_READWRITE;
 | 
			
		||||
	}
 | 
			
		||||
	if (c->allow_mlock)
 | 
			
		||||
		fl |= PW_MEMMAP_FLAG_LOCKED;
 | 
			
		||||
 | 
			
		||||
	/* clear previous buffers */
 | 
			
		||||
	clear_buffers(c, mix);
 | 
			
		||||
| 
						 | 
				
			
			@ -1806,6 +1805,16 @@ static int client_node_port_use_buffers(void *object,
 | 
			
		|||
			} else {
 | 
			
		||||
				pw_log_warn("unknown buffer data type %d", d->type);
 | 
			
		||||
			}
 | 
			
		||||
			if (c->allow_mlock && mlock(d->data, d->maxsize) < 0) {
 | 
			
		||||
				if (errno != ENOMEM  || !mlock_warned) {
 | 
			
		||||
					pw_log_warn(NAME" %p: Failed to mlock memory %p %u: %s", c,
 | 
			
		||||
						d->data, d->maxsize,
 | 
			
		||||
						errno == ENOMEM ?
 | 
			
		||||
						"This is not a problem but for best performance, "
 | 
			
		||||
						"consider increasing RLIMIT_MEMLOCK" : strerror(errno));
 | 
			
		||||
					mlock_warned |= errno == ENOMEM;
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		SPA_FLAG_SET(b->flags, BUFFER_FLAG_OUT);
 | 
			
		||||
		if (direction == SPA_DIRECTION_OUTPUT)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -44,6 +44,8 @@
 | 
			
		|||
#define MAX_MIX	4096
 | 
			
		||||
 | 
			
		||||
/** \cond */
 | 
			
		||||
static bool mlock_warned = false;
 | 
			
		||||
 | 
			
		||||
struct buffer {
 | 
			
		||||
	uint32_t id;
 | 
			
		||||
	struct spa_buffer *buf;
 | 
			
		||||
| 
						 | 
				
			
			@ -77,6 +79,7 @@ struct node_data {
 | 
			
		|||
	unsigned int do_free:1;
 | 
			
		||||
	unsigned int have_transport:1;
 | 
			
		||||
	unsigned int allow_mlock:1;
 | 
			
		||||
	unsigned int warn_mlock:1;
 | 
			
		||||
 | 
			
		||||
	struct pw_client_node *client_node;
 | 
			
		||||
	struct spa_hook client_node_listener;
 | 
			
		||||
| 
						 | 
				
			
			@ -615,8 +618,6 @@ client_node_port_use_buffers(void *object,
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	prot = PW_MEMMAP_FLAG_READWRITE;
 | 
			
		||||
	if (data->allow_mlock)
 | 
			
		||||
		prot |= PW_MEMMAP_FLAG_LOCKED;
 | 
			
		||||
 | 
			
		||||
	/* clear previous buffers */
 | 
			
		||||
	clear_buffers(data, mix);
 | 
			
		||||
| 
						 | 
				
			
			@ -643,6 +644,17 @@ client_node_port_use_buffers(void *object,
 | 
			
		|||
		bid->id = i;
 | 
			
		||||
		bid->mem = mm;
 | 
			
		||||
 | 
			
		||||
		if (data->allow_mlock && mlock(mm->ptr, mm->size) < 0)
 | 
			
		||||
			if (errno != ENOMEM || !mlock_warned) {
 | 
			
		||||
				pw_log(data->warn_mlock ? SPA_LOG_LEVEL_WARN : SPA_LOG_LEVEL_DEBUG,
 | 
			
		||||
						"Failed to mlock memory %p %u: %s",
 | 
			
		||||
						mm->ptr, mm->size,
 | 
			
		||||
						errno == ENOMEM ?
 | 
			
		||||
						"This is not a problem but for best performance, "
 | 
			
		||||
						"consider increasing RLIMIT_MEMLOCK" : strerror(errno));
 | 
			
		||||
				mlock_warned |= errno == ENOMEM;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
		size = sizeof(struct spa_buffer);
 | 
			
		||||
		for (j = 0; j < buffers[i].buffer->n_metas; j++)
 | 
			
		||||
			size += sizeof(struct spa_meta);
 | 
			
		||||
| 
						 | 
				
			
			@ -1206,6 +1218,10 @@ static struct pw_proxy *node_export(struct pw_core *core, void *object, bool do_
 | 
			
		|||
	if ((str = pw_properties_get(node->properties, "mem.allow-mlock")) != NULL)
 | 
			
		||||
		data->allow_mlock = pw_properties_parse_bool(str);
 | 
			
		||||
 | 
			
		||||
	data->warn_mlock = true;
 | 
			
		||||
	if ((str = pw_properties_get(node->properties, "mem.warn-mlock")) != NULL)
 | 
			
		||||
		data->warn_mlock = pw_properties_parse_bool(str);
 | 
			
		||||
 | 
			
		||||
	node->exported = true;
 | 
			
		||||
 | 
			
		||||
	spa_list_init(&data->free_mix);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -51,6 +51,7 @@
 | 
			
		|||
#define MAX_PORTS	1024
 | 
			
		||||
 | 
			
		||||
static float empty[MAX_SAMPLES];
 | 
			
		||||
static bool mlock_warned = false;
 | 
			
		||||
 | 
			
		||||
static uint32_t mappable_dataTypes = (1<<SPA_DATA_MemFd);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -149,7 +150,7 @@ struct filter {
 | 
			
		|||
	unsigned int subscribe:1;
 | 
			
		||||
	unsigned int draining:1;
 | 
			
		||||
	unsigned int allow_mlock:1;
 | 
			
		||||
	unsigned int process_rt:1;
 | 
			
		||||
	unsigned int warn_mlock:1;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static int get_param_index(uint32_t id)
 | 
			
		||||
| 
						 | 
				
			
			@ -566,15 +567,10 @@ static int map_data(struct filter *impl, struct spa_data *data, int prot)
 | 
			
		|||
{
 | 
			
		||||
	void *ptr;
 | 
			
		||||
	struct pw_map_range range;
 | 
			
		||||
	int flags;
 | 
			
		||||
 | 
			
		||||
	pw_map_range_init(&range, data->mapoffset, data->maxsize, impl->context->sc_pagesize);
 | 
			
		||||
 | 
			
		||||
	flags = MAP_SHARED;
 | 
			
		||||
	if (impl->allow_mlock)
 | 
			
		||||
		flags |= MAP_LOCKED;
 | 
			
		||||
 | 
			
		||||
	ptr = mmap(NULL, range.size, prot, flags, data->fd, range.offset);
 | 
			
		||||
	ptr = mmap(NULL, range.size, prot, MAP_SHARED, data->fd, range.offset);
 | 
			
		||||
	if (ptr == MAP_FAILED) {
 | 
			
		||||
		pw_log_error(NAME" %p: failed to mmap buffer mem: %m", impl);
 | 
			
		||||
		return -errno;
 | 
			
		||||
| 
						 | 
				
			
			@ -583,6 +579,17 @@ static int map_data(struct filter *impl, struct spa_data *data, int prot)
 | 
			
		|||
	pw_log_debug(NAME" %p: fd %"PRIi64" mapped %d %d %p", impl, data->fd,
 | 
			
		||||
			range.offset, range.size, data->data);
 | 
			
		||||
 | 
			
		||||
	if (impl->allow_mlock && mlock(data->data, data->maxsize) < 0) {
 | 
			
		||||
		if (errno != ENOMEM || !mlock_warned) {
 | 
			
		||||
			pw_log(impl->warn_mlock ? SPA_LOG_LEVEL_WARN : SPA_LOG_LEVEL_DEBUG,
 | 
			
		||||
					NAME" %p: Failed to mlock memory %p %u: %s", impl,
 | 
			
		||||
					data->data, data->maxsize,
 | 
			
		||||
					errno == ENOMEM ?
 | 
			
		||||
					"This is not a problem but for best performance, "
 | 
			
		||||
					"consider increasing RLIMIT_MEMLOCK" : strerror(errno));
 | 
			
		||||
			mlock_warned |= errno == ENOMEM;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -784,7 +791,7 @@ static void call_process(struct filter *impl)
 | 
			
		|||
{
 | 
			
		||||
	struct pw_filter *filter = &impl->this;
 | 
			
		||||
	pw_log_trace(NAME" %p: call process", impl);
 | 
			
		||||
	if (impl->process_rt) {
 | 
			
		||||
	if (SPA_FLAG_IS_SET(impl->flags, PW_FILTER_FLAG_RT_PROCESS)) {
 | 
			
		||||
		pw_filter_emit_process(filter, impl->rt.position);
 | 
			
		||||
	}
 | 
			
		||||
	else {
 | 
			
		||||
| 
						 | 
				
			
			@ -1234,6 +1241,10 @@ pw_filter_connect(struct pw_filter *filter,
 | 
			
		|||
	pw_log_debug(NAME" %p: connect", filter);
 | 
			
		||||
	impl->flags = flags;
 | 
			
		||||
 | 
			
		||||
	impl->warn_mlock = SPA_FLAG_IS_SET(flags, PW_FILTER_FLAG_RT_PROCESS);
 | 
			
		||||
	pw_properties_set(filter->properties, "mem.warn-mlock",
 | 
			
		||||
			impl->warn_mlock ? "true" : "false");
 | 
			
		||||
 | 
			
		||||
	impl->impl_node.iface = SPA_INTERFACE_INIT(
 | 
			
		||||
			SPA_TYPE_INTERFACE_Node,
 | 
			
		||||
			SPA_VERSION_NODE,
 | 
			
		||||
| 
						 | 
				
			
			@ -1244,12 +1255,10 @@ pw_filter_connect(struct pw_filter *filter,
 | 
			
		|||
		SPA_NODE_CHANGE_MASK_PROPS |
 | 
			
		||||
		SPA_NODE_CHANGE_MASK_PARAMS;
 | 
			
		||||
 | 
			
		||||
	impl->process_rt = SPA_FLAG_IS_SET(flags, PW_STREAM_FLAG_RT_PROCESS);
 | 
			
		||||
 | 
			
		||||
	impl->info = SPA_NODE_INFO_INIT();
 | 
			
		||||
	impl->info.max_input_ports = MAX_PORTS;
 | 
			
		||||
	impl->info.max_output_ports = MAX_PORTS;
 | 
			
		||||
	impl->info.flags = impl->process_rt ? SPA_NODE_FLAG_RT : 0;
 | 
			
		||||
	impl->info.flags = impl->warn_mlock ? SPA_NODE_FLAG_RT : 0;
 | 
			
		||||
	impl->info.props = &filter->properties->dict;
 | 
			
		||||
	impl->params[0] = SPA_PARAM_INFO(SPA_PARAM_EnumFormat, 0);
 | 
			
		||||
	impl->params[1] = SPA_PARAM_INFO(SPA_PARAM_Meta, 0);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -49,6 +49,8 @@
 | 
			
		|||
#define MASK_BUFFERS	(MAX_BUFFERS-1)
 | 
			
		||||
#define MAX_PORTS	1
 | 
			
		||||
 | 
			
		||||
static bool mlock_warned = false;
 | 
			
		||||
 | 
			
		||||
static uint32_t mappable_dataTypes = (1<<SPA_DATA_MemFd);
 | 
			
		||||
 | 
			
		||||
struct buffer {
 | 
			
		||||
| 
						 | 
				
			
			@ -576,15 +578,10 @@ static int map_data(struct stream *impl, struct spa_data *data, int prot)
 | 
			
		|||
{
 | 
			
		||||
	void *ptr;
 | 
			
		||||
	struct pw_map_range range;
 | 
			
		||||
	int flags;
 | 
			
		||||
 | 
			
		||||
	pw_map_range_init(&range, data->mapoffset, data->maxsize, impl->context->sc_pagesize);
 | 
			
		||||
 | 
			
		||||
	flags = MAP_SHARED;
 | 
			
		||||
	if (impl->allow_mlock)
 | 
			
		||||
		flags |= MAP_LOCKED;
 | 
			
		||||
 | 
			
		||||
	ptr = mmap(NULL, range.size, prot, flags, data->fd, range.offset);
 | 
			
		||||
	ptr = mmap(NULL, range.size, prot, MAP_SHARED, data->fd, range.offset);
 | 
			
		||||
	if (ptr == MAP_FAILED) {
 | 
			
		||||
		pw_log_error(NAME" %p: failed to mmap buffer mem: %m", impl);
 | 
			
		||||
		return -errno;
 | 
			
		||||
| 
						 | 
				
			
			@ -594,6 +591,17 @@ static int map_data(struct stream *impl, struct spa_data *data, int prot)
 | 
			
		|||
	pw_log_debug(NAME" %p: fd %"PRIi64" mapped %d %d %p", impl, data->fd,
 | 
			
		||||
			range.offset, range.size, data->data);
 | 
			
		||||
 | 
			
		||||
	if (impl->allow_mlock && mlock(data->data, data->maxsize) < 0) {
 | 
			
		||||
		if (errno != ENOMEM || !mlock_warned) {
 | 
			
		||||
			pw_log(impl->process_rt ? SPA_LOG_LEVEL_WARN : SPA_LOG_LEVEL_DEBUG,
 | 
			
		||||
					NAME" %p: Failed to mlock memory %p %u: %s", impl,
 | 
			
		||||
					data->data, data->maxsize,
 | 
			
		||||
					errno == ENOMEM ?
 | 
			
		||||
					"This is not a problem but for best performance, "
 | 
			
		||||
					"consider increasing RLIMIT_MEMLOCK" : strerror(errno));
 | 
			
		||||
			mlock_warned |= errno == ENOMEM;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1537,6 +1545,7 @@ pw_stream_connect(struct pw_stream *stream,
 | 
			
		|||
		pw_properties_set(stream->properties, PW_KEY_NODE_DONT_RECONNECT, "true");
 | 
			
		||||
 | 
			
		||||
	impl->process_rt = SPA_FLAG_IS_SET(flags, PW_STREAM_FLAG_RT_PROCESS);
 | 
			
		||||
	pw_properties_set(stream->properties, "mem.warn-mlock", impl->process_rt ? "true" : "false");
 | 
			
		||||
 | 
			
		||||
	if ((pw_properties_get(stream->properties, PW_KEY_MEDIA_CLASS) == NULL)) {
 | 
			
		||||
		const char *media_type = pw_properties_get(stream->properties, PW_KEY_MEDIA_TYPE);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue