diff options
author | Ahmed S. Darwish <darwish.07@gmail.com> | 2016-04-15 23:07:36 +0200 |
---|---|---|
committer | Arun Raghavan <git@arunraghavan.net> | 2016-04-27 18:37:08 +0530 |
commit | d2a6afcab31f9f8122200ce383fdd5479ca0ebd1 (patch) | |
tree | 0d99cc24fe698380b388204e5bd740e7ef2662da /src | |
parent | b1d47d60fc3f5dcc098f0ccc52a0f29dca8ce29e (diff) |
core: Support memfd transport; bump protocol version
Now that all layers in the stack support memfd blocks, add memfd
support for the daemon's global core mempool. Also introduce
"enable-memfd=" daemon argument and configuration option.
For now, memfd support is an opt-in feature to be activated only
when daemon's enable-memfd= is set to yes.
Signed-off-by: Ahmed S. Darwish <darwish.07@gmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/daemon/cmdline.c | 13 | ||||
-rw-r--r-- | src/daemon/daemon-conf.c | 2 | ||||
-rw-r--r-- | src/daemon/daemon-conf.h | 1 | ||||
-rw-r--r-- | src/daemon/main.c | 4 | ||||
-rw-r--r-- | src/pulsecore/core.c | 9 | ||||
-rw-r--r-- | src/pulsecore/core.h | 2 | ||||
-rw-r--r-- | src/pulsecore/protocol-native.c | 49 |
7 files changed, 63 insertions, 17 deletions
diff --git a/src/daemon/cmdline.c b/src/daemon/cmdline.c index 117147dd8..0454b6d84 100644 --- a/src/daemon/cmdline.c +++ b/src/daemon/cmdline.c @@ -63,6 +63,7 @@ enum { ARG_CHECK, ARG_NO_CPU_LIMIT, ARG_DISABLE_SHM, + ARG_ENABLE_MEMFD, ARG_DUMP_RESAMPLE_METHODS, ARG_SYSTEM, ARG_CLEANUP_SHM, @@ -100,6 +101,7 @@ static const struct option long_options[] = { {"system", 2, 0, ARG_SYSTEM}, {"no-cpu-limit", 2, 0, ARG_NO_CPU_LIMIT}, {"disable-shm", 2, 0, ARG_DISABLE_SHM}, + {"enable-memfd", 2, 0, ARG_ENABLE_MEMFD}, {"dump-resample-methods", 2, 0, ARG_DUMP_RESAMPLE_METHODS}, {"cleanup-shm", 2, 0, ARG_CLEANUP_SHM}, {NULL, 0, 0, 0} @@ -152,7 +154,8 @@ void pa_cmdline_help(const char *argv0) { " --use-pid-file[=BOOL] Create a PID file\n" " --no-cpu-limit[=BOOL] Do not install CPU load limiter on\n" " platforms that support it.\n" - " --disable-shm[=BOOL] Disable shared memory support.\n\n" + " --disable-shm[=BOOL] Disable shared memory support.\n" + " --enable-memfd[=BOOL] Enable memfd shared memory support.\n\n" "STARTUP SCRIPT:\n" " -L, --load=\"MODULE ARGUMENTS\" Load the specified plugin module with\n" @@ -389,6 +392,14 @@ int pa_cmdline_parse(pa_daemon_conf *conf, int argc, char *const argv [], int *d conf->disable_shm = !!b; break; + case ARG_ENABLE_MEMFD: + if ((b = optarg ? pa_parse_boolean(optarg) : 1) < 0) { + pa_log(_("--enable-memfd expects boolean argument")); + goto fail; + } + conf->disable_memfd = !b; + break; + default: goto fail; } diff --git a/src/daemon/daemon-conf.c b/src/daemon/daemon-conf.c index 288aed2b2..965a5c802 100644 --- a/src/daemon/daemon-conf.c +++ b/src/daemon/daemon-conf.c @@ -92,6 +92,7 @@ static const pa_daemon_conf default_conf = { #endif .no_cpu_limit = true, .disable_shm = false, + .disable_memfd = true, .lock_memory = false, .deferred_volume = true, .default_n_fragments = 4, @@ -526,6 +527,7 @@ int pa_daemon_conf_load(pa_daemon_conf *c, const char *filename) { { "cpu-limit", pa_config_parse_not_bool, &c->no_cpu_limit, NULL }, { "disable-shm", pa_config_parse_bool, &c->disable_shm, NULL }, { "enable-shm", pa_config_parse_not_bool, &c->disable_shm, NULL }, + { "enable-memfd", pa_config_parse_not_bool, &c->disable_memfd, NULL }, { "flat-volumes", pa_config_parse_bool, &c->flat_volumes, NULL }, { "lock-memory", pa_config_parse_bool, &c->lock_memory, NULL }, { "enable-deferred-volume", pa_config_parse_bool, &c->deferred_volume, NULL }, diff --git a/src/daemon/daemon-conf.h b/src/daemon/daemon-conf.h index 458784c98..82b619fa6 100644 --- a/src/daemon/daemon-conf.h +++ b/src/daemon/daemon-conf.h @@ -66,6 +66,7 @@ typedef struct pa_daemon_conf { system_instance, no_cpu_limit, disable_shm, + disable_memfd, disable_remixing, disable_lfe_remixing, load_default_script_file, diff --git a/src/daemon/main.c b/src/daemon/main.c index c2f47b69a..ae1185d31 100644 --- a/src/daemon/main.c +++ b/src/daemon/main.c @@ -1017,7 +1017,9 @@ int main(int argc, char *argv[]) { pa_assert_se(mainloop = pa_mainloop_new()); - if (!(c = pa_core_new(pa_mainloop_get_api(mainloop), !conf->disable_shm, conf->shm_size))) { + if (!(c = pa_core_new(pa_mainloop_get_api(mainloop), !conf->disable_shm, + !conf->disable_shm && !conf->disable_memfd && pa_memfd_is_locally_supported(), + conf->shm_size))) { pa_log(_("pa_core_new() failed.")); goto finish; } diff --git a/src/pulsecore/core.c b/src/pulsecore/core.c index 56cbe9df0..6d102f58a 100644 --- a/src/pulsecore/core.c +++ b/src/pulsecore/core.c @@ -61,16 +61,19 @@ static int core_process_msg(pa_msgobject *o, int code, void *userdata, int64_t o static void core_free(pa_object *o); -pa_core* pa_core_new(pa_mainloop_api *m, bool shared, size_t shm_size) { +pa_core* pa_core_new(pa_mainloop_api *m, bool shared, bool enable_memfd, size_t shm_size) { pa_core* c; pa_mempool *pool; + pa_mem_type_t type; int j; pa_assert(m); if (shared) { - if (!(pool = pa_mempool_new(PA_MEM_TYPE_SHARED_POSIX, shm_size, false))) { - pa_log_warn("Failed to allocate shared memory pool. Falling back to a normal memory pool."); + type = (enable_memfd) ? PA_MEM_TYPE_SHARED_MEMFD : PA_MEM_TYPE_SHARED_POSIX; + if (!(pool = pa_mempool_new(type, shm_size, false))) { + pa_log_warn("Failed to allocate %s memory pool. Falling back to a normal memory pool.", + pa_mem_type_to_string(type)); shared = false; } } diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h index 9f5c44532..1a3c4902e 100644 --- a/src/pulsecore/core.h +++ b/src/pulsecore/core.h @@ -218,7 +218,7 @@ enum { PA_CORE_MESSAGE_MAX }; -pa_core* pa_core_new(pa_mainloop_api *m, bool shared, size_t shm_size); +pa_core* pa_core_new(pa_mainloop_api *m, bool shared, bool enable_memfd, size_t shm_size); /* Check whether no one is connected to this core */ void pa_core_check_idle(pa_core *c); diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index 566ba6f1e..5619b9c20 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -2598,7 +2598,7 @@ static void command_exit(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_ta pa_pstream_send_simple_ack(c->pstream, tag); /* nonsense */ } -static void setup_srbchannel(pa_native_connection *c) { +static void setup_srbchannel(pa_native_connection *c, pa_mem_type_t shm_type) { pa_srbchannel_template srbt; pa_srbchannel *srb; pa_memchunk mc; @@ -2631,20 +2631,25 @@ static void setup_srbchannel(pa_native_connection *c) { return; } - if (!(c->rw_mempool = pa_mempool_new(PA_MEM_TYPE_SHARED_POSIX, c->protocol->core->shm_size, true))) { + if (!(c->rw_mempool = pa_mempool_new(shm_type, c->protocol->core->shm_size, true))) { pa_log_warn("Disabling srbchannel, reason: Failed to allocate shared " "writable memory pool."); return; } + + if (shm_type == PA_MEM_TYPE_SHARED_MEMFD) { + const char *reason; + if (pa_pstream_register_memfd_mempool(c->pstream, c->rw_mempool, &reason)) { + pa_log_warn("Disabling srbchannel, reason: Failed to register memfd mempool: %s", reason); + goto fail; + } + } pa_mempool_set_is_remote_writable(c->rw_mempool, true); srb = pa_srbchannel_new(c->protocol->core->mainloop, c->rw_mempool); if (!srb) { pa_log_debug("Failed to create srbchannel"); - - pa_mempool_unref(c->rw_mempool); - c->rw_mempool = NULL; - return; + goto fail; } pa_log_debug("Enabling srbchannel..."); pa_srbchannel_export(srb, &srbt); @@ -2664,6 +2669,13 @@ static void setup_srbchannel(pa_native_connection *c) { pa_pstream_send_memblock(c->pstream, 0, 0, 0, &mc); c->srbpending = srb; + return; + +fail: + if (c->rw_mempool) { + pa_mempool_unref(c->rw_mempool); + c->rw_mempool = NULL; + } } static void command_enable_srbchannel(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { @@ -2682,7 +2694,7 @@ static void command_enable_srbchannel(pa_pdispatch *pd, uint32_t command, uint32 static void command_auth(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { pa_native_connection *c = PA_NATIVE_CONNECTION(userdata); const void*cookie; - bool memfd_on_remote = false; + bool memfd_on_remote = false, do_memfd = false; pa_tagstruct *reply; pa_mem_type_t shm_type; bool shm_on_remote = false, do_shm; @@ -2777,7 +2789,7 @@ static void command_auth(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_ta } } - /* Enable shared memory support if possible */ + /* Enable shared memory and memfd support if possible */ do_shm = pa_mempool_is_shared(c->protocol->core->mempool) && c->is_local; @@ -2803,9 +2815,12 @@ static void command_auth(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_ta pa_log_debug("Negotiated SHM: %s", pa_yes_no(do_shm)); pa_pstream_enable_shm(c->pstream, do_shm); + do_memfd = + do_shm && pa_mempool_is_memfd_backed(c->protocol->core->mempool); + shm_type = PA_MEM_TYPE_PRIVATE; if (do_shm) { - if (c->version >= 31 && memfd_on_remote && pa_memfd_is_locally_supported()) { + if (c->version >= 31 && memfd_on_remote && do_memfd) { pa_pstream_enable_memfd(c->pstream); shm_type = PA_MEM_TYPE_SHARED_MEMFD; } else @@ -2817,7 +2832,7 @@ static void command_auth(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_ta reply = reply_new(tag); pa_tagstruct_putu32(reply, PA_PROTOCOL_VERSION | (do_shm ? 0x80000000 : 0) | - (pa_memfd_is_locally_supported() ? 0x40000000 : 0)); + (do_memfd ? 0x40000000 : 0)); #ifdef HAVE_CREDS { @@ -2834,7 +2849,19 @@ static void command_auth(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_ta pa_pstream_send_tagstruct(c->pstream, reply); #endif - setup_srbchannel(c); + /* The client enables memfd transport on its pstream only after + * inspecting our version flags to see if we support memfds too. + * + * Thus register any pools after sending the server's version + * flags and _never_ before it. */ + if (shm_type == PA_MEM_TYPE_SHARED_MEMFD) { + const char *reason; + + if (pa_pstream_register_memfd_mempool(c->pstream, c->protocol->core->mempool, &reason)) + pa_log("Failed to register memfd mempool. Reason: %s", reason); + } + + setup_srbchannel(c, shm_type); } static void command_register_memfd_shmid(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { |