Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE
alsa.6660
0025-pcm-dmix-Allow-disabling-x86-optimizations...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0025-pcm-dmix-Allow-disabling-x86-optimizations.patch of Package alsa.6660
From 22eca6468b4aea47c783770ec0739d1e13bf3bfc Mon Sep 17 00:00:00 2001 From: Takashi Iwai <tiwai@suse.de> Date: Fri, 10 Feb 2017 12:16:12 +0100 Subject: [PATCH 25/43] pcm: dmix: Allow disabling x86 optimizations The dmix plugin has some optimized implementations for x86 using the direct memory accesses, which was rather the original version, in addition to the "generic" implementation using the semaphore blocking. The x86 implementation relies on the memory coherency *and* the fast read/write on it. For other architectures, this has been always disabled just because of memory coherency. But, the recent LPE audio development revealed that, even on x86 platforms, the read/write performance might become extremely bad when the buffer is marked as uncached. Some drivers already know the buffer is uncached, we need to switch to the generic mode in such a case. This patch introduces yet another flag to dmix configuration, direct_memory_access, that indicates whether the x86-specific optimization can be used or not. Each driver can set the flag in its cards config namespace, and the default dmix config refers to it. As of this patch, only HDMI LPE Audio driver sets it. Signed-off-by: Takashi Iwai <tiwai@suse.de> --- src/conf/cards/HdmiLpeAudio.conf | 3 +++ src/conf/pcm/dmix.conf | 15 +++++++++++++++ src/pcm/pcm_direct.c | 8 ++++++++ src/pcm/pcm_direct.h | 2 ++ src/pcm/pcm_dmix.c | 1 + src/pcm/pcm_dmix_i386.c | 5 +++++ src/pcm/pcm_dmix_x86_64.c | 5 +++++ 7 files changed, 39 insertions(+) --- a/src/conf/cards/HdmiLpeAudio.conf +++ b/src/conf/cards/HdmiLpeAudio.conf @@ -20,6 +20,9 @@ HdmiLpeAudio.pcm.front.0 { } } +# uncached memory reads have a high penalty +HdmiLpeAudio.dmix.direct_memory_access false + # default with dmix+softvol HdmiLpeAudio.pcm.default { @args [ CARD ] --- a/src/conf/pcm/dmix.conf +++ b/src/conf/pcm/dmix.conf @@ -49,6 +49,21 @@ pcm.!dmix { @func refer name defaults.pcm.ipc_perm } + direct_memory_access { + @func refer + name { + @func concat + strings [ + "cards." + { + @func card_driver + card $CARD + } + ".dmix.direct_memory_access" + ] + } + default true + } slave { pcm { type hw --- a/src/pcm/pcm_direct.c +++ b/src/pcm/pcm_direct.c @@ -1861,6 +1861,7 @@ int snd_pcm_direct_parse_open_conf(snd_c rec->slowptr = 1; rec->max_periods = 0; rec->var_periodsize = 1; + rec->direct_memory_access = 1; /* read defaults */ if (snd_config_search(root, "defaults.pcm.dmix_max_periods", &n) >= 0) { @@ -1974,6 +1975,13 @@ int snd_pcm_direct_parse_open_conf(snd_c rec->var_periodsize = err; continue; } + if (strcmp(id, "direct_memory_access") == 0) { + err = snd_config_get_bool(n); + if (err < 0) + return err; + rec->direct_memory_access = err; + continue; + } SNDERR("Unknown field %s", id); return -EINVAL; } --- a/src/pcm/pcm_direct.h +++ b/src/pcm/pcm_direct.h @@ -159,6 +159,7 @@ struct snd_pcm_direct { unsigned int channels; /* client's channels */ unsigned int *bindings; unsigned int recoveries; /* mirror of executed recoveries on slave */ + int direct_memory_access; /* use arch-optimized buffer RW */ union { struct { int shmid_sum; /* IPC global sum ring buffer memory identification */ @@ -340,6 +341,7 @@ struct snd_pcm_direct_open_conf { int slowptr; int max_periods; int var_periodsize; + int direct_memory_access; snd_config_t *slave; snd_config_t *bindings; }; --- a/src/pcm/pcm_dmix.c +++ b/src/pcm/pcm_dmix.c @@ -1065,6 +1065,7 @@ int snd_pcm_dmix_open(snd_pcm_t **pcmp, dmix->max_periods = opts->max_periods; dmix->var_periodsize = opts->var_periodsize; dmix->sync_ptr = snd_pcm_dmix_sync_ptr; + dmix->direct_memory_access = opts->direct_memory_access; retry: if (first_instance) { --- a/src/pcm/pcm_dmix_i386.c +++ b/src/pcm/pcm_dmix_i386.c @@ -87,6 +87,11 @@ static void mix_select_callbacks(snd_pcm { static int smp = 0, mmx = 0, cmov = 0; + if (!dmix->direct_memory_access) { + generic_mix_select_callbacks(dmix); + return; + } + if (!((1ULL<< dmix->shmptr->s.format) & i386_dmix_supported_format)) { generic_mix_select_callbacks(dmix); return; --- a/src/pcm/pcm_dmix_x86_64.c +++ b/src/pcm/pcm_dmix_x86_64.c @@ -70,6 +70,11 @@ static void mix_select_callbacks(snd_pcm { static int smp = 0; + if (!dmix->direct_memory_access) { + generic_mix_select_callbacks(dmix); + return; + } + if (!((1ULL<< dmix->shmptr->s.format) & x86_64_dmix_supported_format)) { generic_mix_select_callbacks(dmix); return;
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor