diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/pulse/client-conf.c | 1 | ||||
-rw-r--r-- | src/pulse/client-conf.h | 2 | ||||
-rw-r--r-- | src/pulse/context.c | 44 | ||||
-rw-r--r-- | src/pulse/internal.h | 3 | ||||
-rw-r--r-- | src/pulsecore/mem.h | 9 | ||||
-rw-r--r-- | src/pulsecore/protocol-native.c | 28 |
6 files changed, 80 insertions, 7 deletions
diff --git a/src/pulse/client-conf.c b/src/pulse/client-conf.c index c23aa6bf6..a3c9486d4 100644 --- a/src/pulse/client-conf.c +++ b/src/pulse/client-conf.c @@ -141,6 +141,7 @@ void pa_client_conf_load(pa_client_conf *c, bool load_from_x11, bool load_from_e { "cookie-file", pa_config_parse_string, &c->cookie_file_from_client_conf, 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 }, { "shm-size-bytes", pa_config_parse_size, &c->shm_size, NULL }, { "auto-connect-localhost", pa_config_parse_bool, &c->auto_connect_localhost, NULL }, { "auto-connect-display", pa_config_parse_bool, &c->auto_connect_display, NULL }, diff --git a/src/pulse/client-conf.h b/src/pulse/client-conf.h index eac705a58..7691ec79d 100644 --- a/src/pulse/client-conf.h +++ b/src/pulse/client-conf.h @@ -37,7 +37,7 @@ typedef struct pa_client_conf { bool cookie_from_x11_valid; char *cookie_file_from_application; char *cookie_file_from_client_conf; - bool autospawn, disable_shm, auto_connect_localhost, auto_connect_display; + bool autospawn, disable_shm, disable_memfd, auto_connect_localhost, auto_connect_display; size_t shm_size; } pa_client_conf; diff --git a/src/pulse/context.c b/src/pulse/context.c index ef3941604..69be5f497 100644 --- a/src/pulse/context.c +++ b/src/pulse/context.c @@ -173,7 +173,12 @@ pa_context *pa_context_new_with_proplist(pa_mainloop_api *mainloop, const char * c->srb_template.readfd = -1; c->srb_template.writefd = -1; - type = !c->conf->disable_shm ? PA_MEM_TYPE_SHARED_POSIX : PA_MEM_TYPE_PRIVATE; + c->memfd_on_local = (!c->conf->disable_memfd && pa_memfd_is_locally_supported()); + + type = (c->conf->disable_shm) ? PA_MEM_TYPE_PRIVATE : + ((!c->memfd_on_local) ? + PA_MEM_TYPE_SHARED_POSIX : PA_MEM_TYPE_SHARED_MEMFD); + if (!(c->mempool = pa_mempool_new(type, c->conf->shm_size, true))) { if (!c->conf->disable_shm) { @@ -482,6 +487,7 @@ static void setup_complete_callback(pa_pdispatch *pd, uint32_t command, uint32_t case PA_CONTEXT_AUTHORIZING: { pa_tagstruct *reply; bool shm_on_remote = false; + bool memfd_on_remote = false; if (pa_tagstruct_getu32(t, &c->version) < 0 || !pa_tagstruct_eof(t)) { @@ -500,7 +506,15 @@ static void setup_complete_callback(pa_pdispatch *pd, uint32_t command, uint32_t not. */ if (c->version >= 13) { shm_on_remote = !!(c->version & 0x80000000U); - c->version &= 0x7FFFFFFFU; + + /* Starting with protocol version 31, the second MSB of the version + * tag reflects whether memfd is supported on the other PA end. */ + if (c->version >= 31) + memfd_on_remote = !!(c->version & 0x40000000U); + + /* Reserve the two most-significant _bytes_ of the version tag + * for flags. */ + c->version &= 0x0000FFFFU; } pa_log_debug("Protocol version: remote %u, local %u", c->version, PA_PROTOCOL_VERSION); @@ -526,6 +540,26 @@ static void setup_complete_callback(pa_pdispatch *pd, uint32_t command, uint32_t pa_log_debug("Negotiated SHM: %s", pa_yes_no(c->do_shm)); pa_pstream_enable_shm(c->pstream, c->do_shm); + c->shm_type = PA_MEM_TYPE_PRIVATE; + if (c->do_shm) { + if (c->version >= 31 && memfd_on_remote && c->memfd_on_local) { + const char *reason; + + pa_pstream_enable_memfd(c->pstream); + if (pa_mempool_is_memfd_backed(c->mempool)) + if (pa_pstream_register_memfd_mempool(c->pstream, c->mempool, &reason)) + pa_log("Failed to regester memfd mempool. Reason: %s", reason); + + /* Even if memfd pool registration fails, the negotiated SHM type + * shall remain memfd as both endpoints claim to support it. */ + c->shm_type = PA_MEM_TYPE_SHARED_MEMFD; + } else + c->shm_type = PA_MEM_TYPE_SHARED_POSIX; + } + + pa_log_debug("Memfd possible: %s", pa_yes_no(c->memfd_on_local)); + pa_log_debug("Negotiated SHM type: %s", pa_mem_type_to_string(c->shm_type)); + reply = pa_tagstruct_command(c, PA_COMMAND_SET_CLIENT_NAME, &tag); if (c->version >= 13) { @@ -593,8 +627,10 @@ static void setup_context(pa_context *c, pa_iochannel *io) { pa_log_debug("SHM possible: %s", pa_yes_no(c->do_shm)); /* Starting with protocol version 13 we use the MSB of the version - * tag for informing the other side if we could do SHM or not */ - pa_tagstruct_putu32(t, PA_PROTOCOL_VERSION | (c->do_shm ? 0x80000000U : 0)); + * tag for informing the other side if we could do SHM or not. + * Starting from version 31, second MSB is used to flag memfd support. */ + pa_tagstruct_putu32(t, PA_PROTOCOL_VERSION | (c->do_shm ? 0x80000000U : 0) | + (c->memfd_on_local ? 0x40000000 : 0)); pa_tagstruct_put_arbitrary(t, cookie, sizeof(cookie)); #ifdef HAVE_CREDS diff --git a/src/pulse/internal.h b/src/pulse/internal.h index eefd18185..9bbb903bc 100644 --- a/src/pulse/internal.h +++ b/src/pulse/internal.h @@ -88,6 +88,7 @@ struct pa_context { bool is_local:1; bool do_shm:1; + bool memfd_on_local:1; bool server_specified:1; bool no_fail:1; bool do_autospawn:1; @@ -95,6 +96,8 @@ struct pa_context { bool filter_added:1; pa_spawn_api spawn_api; + pa_mem_type_t shm_type; + pa_strlist *server_list; char *server; diff --git a/src/pulsecore/mem.h b/src/pulsecore/mem.h index 11a808620..cba141048 100644 --- a/src/pulsecore/mem.h +++ b/src/pulsecore/mem.h @@ -22,6 +22,7 @@ #include <stdbool.h> +#include <pulsecore/creds.h> #include <pulsecore/macro.h> typedef enum pa_mem_type { @@ -48,4 +49,12 @@ static inline bool pa_mem_type_is_shared(pa_mem_type_t t) { return (t == PA_MEM_TYPE_SHARED_POSIX) || (t == PA_MEM_TYPE_SHARED_MEMFD); } +static inline bool pa_memfd_is_locally_supported() { +#if defined(HAVE_CREDS) && defined(HAVE_MEMFD) + return true; +#else + return false; +#endif +} + #endif diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index 93a7ce091..566ba6f1e 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -48,6 +48,7 @@ #include <pulsecore/core-scache.h> #include <pulsecore/core-subscribe.h> #include <pulsecore/log.h> +#include <pulsecore/mem.h> #include <pulsecore/strlist.h> #include <pulsecore/shared.h> #include <pulsecore/sample-util.h> @@ -2681,7 +2682,9 @@ 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; pa_tagstruct *reply; + pa_mem_type_t shm_type; bool shm_on_remote = false, do_shm; pa_native_connection_assert_ref(c); @@ -2705,7 +2708,15 @@ static void command_auth(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_ta not. */ if (c->version >= 13) { shm_on_remote = !!(c->version & 0x80000000U); - c->version &= 0x7FFFFFFFU; + + /* Starting with protocol version 31, the second MSB of the version + * tag reflects whether memfd is supported on the other PA end. */ + if (c->version >= 31) + memfd_on_remote = !!(c->version & 0x40000000U); + + /* Reserve the two most-significant _bytes_ of the version tag + * for flags. */ + c->version &= 0x0000FFFFU; } pa_log_debug("Protocol version: remote %u, local %u", c->version, PA_PROTOCOL_VERSION); @@ -2792,8 +2803,21 @@ 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); + shm_type = PA_MEM_TYPE_PRIVATE; + if (do_shm) { + if (c->version >= 31 && memfd_on_remote && pa_memfd_is_locally_supported()) { + pa_pstream_enable_memfd(c->pstream); + shm_type = PA_MEM_TYPE_SHARED_MEMFD; + } else + shm_type = PA_MEM_TYPE_SHARED_POSIX; + + pa_log_debug("Memfd possible: %s", pa_yes_no(pa_memfd_is_locally_supported())); + pa_log_debug("Negotiated SHM type: %s", pa_mem_type_to_string(shm_type)); + } + reply = reply_new(tag); - pa_tagstruct_putu32(reply, PA_PROTOCOL_VERSION | (do_shm ? 0x80000000 : 0)); + pa_tagstruct_putu32(reply, PA_PROTOCOL_VERSION | (do_shm ? 0x80000000 : 0) | + (pa_memfd_is_locally_supported() ? 0x40000000 : 0)); #ifdef HAVE_CREDS { |