Skip to content

Commit d45fa59

Browse files
checkupuplgirdwood
authored andcommitted
dax: set instance lifespan from prepare to reset
At present, dax instance is initialized and allocated inner buffer on module_init(), and released on module_free(). The memory requirement for the inner buffer per instance is quite large. The existing implementation has 2 pipelines containing dax. Even though the host is restricted from processing stream on both pipelines simultaneously, they may coexist with each other under some circumstances e.g. the interim when switching PCM device from one to the other, which may drain out the memory. This commit changes the timing of instance allocation/deallocation to module_prepare()/reset() respectively. That is, dax instance only occupies the inner buffer memory when processing. Reported-by: Johny Lin <johnylin@google.com> Signed-off-by: Jun Lai <jun.lai@dolby.com>
1 parent 4f39a7c commit d45fa59

File tree

3 files changed

+112
-39
lines changed

3 files changed

+112
-39
lines changed

app/overlays/mtl/dax_overlay.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ CONFIG_COMP_DOLBY_DAX_AUDIO_PROCESSING=y
33
CONFIG_COMP_DOLBY_DAX_AUDIO_PROCESSING_MOCK=n
44
CONFIG_KCPS_DYNAMIC_CLOCK_CONTROL=n
55
CONFIG_SOF_STACK_SIZE=8192
6+
CONFIG_IDC_TIMEOUT_US=50000
67

78
# LLEXT
89
CONFIG_LLEXT_HEAP_SIZE=32

app/overlays/ptl/dax_overlay.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ CONFIG_COMP_DOLBY_DAX_AUDIO_PROCESSING=y
33
CONFIG_COMP_DOLBY_DAX_AUDIO_PROCESSING_MOCK=n
44
CONFIG_KCPS_DYNAMIC_CLOCK_CONTROL=n
55
CONFIG_SOF_STACK_SIZE=8192
6+
CONFIG_IDC_TIMEOUT_US=50000
67

78
# LLEXT
89
CONFIG_LLEXT_HEAP_SIZE=32

src/audio/module_adapter/module/dolby/dax.c

Lines changed: 110 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ SOF_DEFINE_REG_UUID(dolby_dax_audio_processing);
2727
#define DAX_CP_MASK 0x8
2828
#define DAX_VOLUME_MASK 0x10
2929
#define DAX_CTC_MASK 0x20
30+
#define DAX_PROCESSING_MASK 0x10000
31+
#define DAX_RESET_MASK 0x20000
32+
#define DAX_FREE_MASK 0x40000
3033

3134
#define DAX_SWITCH_ENABLE_CONTROL_ID 0
3235
#define DAX_SWITCH_CP_CONTROL_ID 1
@@ -181,6 +184,53 @@ static void dax_buffer_produce(struct dax_buffer *dax_buff, uint32_t bytes)
181184
dax_buff->free = dax_buff->size - dax_buff->avail;
182185
}
183186

187+
static void destroy_instance(struct processing_module *mod)
188+
{
189+
struct sof_dax *dax_ctx = module_get_private_data(mod);
190+
191+
dax_free(dax_ctx); /* free internal dax instance in dax_ctx */
192+
dax_buffer_release(mod, &dax_ctx->persist_buffer);
193+
dax_buffer_release(mod, &dax_ctx->scratch_buffer);
194+
}
195+
196+
static int establish_instance(struct processing_module *mod)
197+
{
198+
int ret = 0;
199+
struct comp_dev *dev = mod->dev;
200+
struct sof_dax *dax_ctx = module_get_private_data(mod);
201+
uint32_t persist_sz;
202+
uint32_t scratch_sz;
203+
204+
persist_sz = dax_query_persist_memory(dax_ctx);
205+
if (dax_buffer_alloc(mod, &dax_ctx->persist_buffer, persist_sz) != 0) {
206+
comp_err(dev, "allocate %u bytes failed for persist", persist_sz);
207+
ret = -ENOMEM;
208+
goto err;
209+
}
210+
scratch_sz = dax_query_scratch_memory(dax_ctx);
211+
if (dax_buffer_alloc(mod, &dax_ctx->scratch_buffer, scratch_sz) != 0) {
212+
comp_err(dev, "allocate %u bytes failed for scratch", scratch_sz);
213+
ret = -ENOMEM;
214+
goto err;
215+
}
216+
ret = dax_init(dax_ctx);
217+
if (ret != 0) {
218+
comp_err(dev, "dax instance initialization failed, ret %d", ret);
219+
goto err;
220+
}
221+
222+
/* set DAX_ENABLE_MASK bit to trigger the fully update of kcontrol values */
223+
dax_ctx->update_flags |= DAX_ENABLE_MASK;
224+
225+
comp_info(dev, "allocated: persist %u, scratch %u. version: %s",
226+
persist_sz, scratch_sz, dax_get_version());
227+
return 0;
228+
229+
err:
230+
destroy_instance(mod);
231+
return ret;
232+
}
233+
184234
static int set_tuning_file(struct processing_module *mod, void *value, uint32_t size)
185235
{
186236
int ret = 0;
@@ -463,33 +513,63 @@ static void check_and_update_settings(struct processing_module *mod)
463513
}
464514
}
465515

516+
static int sof_dax_reset(struct processing_module *mod)
517+
{
518+
struct sof_dax *dax_ctx = module_get_private_data(mod);
519+
520+
/* dax instance will be established on prepare(), and destroyed on reset() */
521+
if (dax_ctx) {
522+
if (dax_ctx->update_flags & DAX_PROCESSING_MASK) {
523+
dax_ctx->update_flags |= DAX_RESET_MASK;
524+
} else {
525+
destroy_instance(mod);
526+
dax_buffer_release(mod, &dax_ctx->input_buffer);
527+
dax_buffer_release(mod, &dax_ctx->output_buffer);
528+
}
529+
}
530+
531+
return 0;
532+
}
533+
466534
static int sof_dax_free(struct processing_module *mod)
467535
{
468536
struct sof_dax *dax_ctx = module_get_private_data(mod);
469537

470538
if (dax_ctx) {
471-
dax_free(dax_ctx);
472-
dax_buffer_release(mod, &dax_ctx->persist_buffer);
473-
dax_buffer_release(mod, &dax_ctx->scratch_buffer);
474-
dax_buffer_release(mod, &dax_ctx->tuning_file_buffer);
475-
dax_buffer_release(mod, &dax_ctx->input_buffer);
476-
dax_buffer_release(mod, &dax_ctx->output_buffer);
477-
mod_data_blob_handler_free(mod, dax_ctx->blob_handler);
478-
dax_ctx->blob_handler = NULL;
479-
mod_free(mod, dax_ctx);
480-
module_set_private_data(mod, NULL);
539+
if (dax_ctx->update_flags & DAX_PROCESSING_MASK) {
540+
dax_ctx->update_flags |= DAX_FREE_MASK;
541+
} else {
542+
sof_dax_reset(mod);
543+
dax_buffer_release(mod, &dax_ctx->tuning_file_buffer);
544+
mod_data_blob_handler_free(mod, dax_ctx->blob_handler);
545+
dax_ctx->blob_handler = NULL;
546+
mod_free(mod, dax_ctx);
547+
module_set_private_data(mod, NULL);
548+
}
481549
}
482550
return 0;
483551
}
484552

553+
static void check_and_update_state(struct processing_module *mod)
554+
{
555+
struct sof_dax *dax_ctx = module_get_private_data(mod);
556+
557+
if (!dax_ctx)
558+
return;
559+
560+
if (dax_ctx->update_flags & DAX_FREE_MASK) {
561+
sof_dax_free(mod);
562+
} else if (dax_ctx->update_flags & DAX_RESET_MASK) {
563+
sof_dax_reset(mod);
564+
dax_ctx->update_flags &= ~DAX_RESET_MASK;
565+
}
566+
}
567+
485568
static int sof_dax_init(struct processing_module *mod)
486569
{
487-
int ret;
488570
struct comp_dev *dev = mod->dev;
489571
struct module_data *md = &mod->priv;
490572
struct sof_dax *dax_ctx;
491-
uint32_t persist_sz;
492-
uint32_t scratch_sz;
493573

494574
md->private = mod_zalloc(mod, sizeof(struct sof_dax));
495575
if (!md->private) {
@@ -509,35 +589,12 @@ static int sof_dax_init(struct processing_module *mod)
509589
dax_ctx->blob_handler = mod_data_blob_handler_new(mod);
510590
if (!dax_ctx->blob_handler) {
511591
comp_err(dev, "create blob handler failed");
512-
ret = -ENOMEM;
513-
goto err;
514-
}
515-
516-
persist_sz = dax_query_persist_memory(dax_ctx);
517-
if (dax_buffer_alloc(mod, &dax_ctx->persist_buffer, persist_sz) != 0) {
518-
comp_err(dev, "allocate %u bytes failed for persist", persist_sz);
519-
ret = -ENOMEM;
520-
goto err;
521-
}
522-
scratch_sz = dax_query_scratch_memory(dax_ctx);
523-
if (dax_buffer_alloc(mod, &dax_ctx->scratch_buffer, scratch_sz) != 0) {
524-
comp_err(dev, "allocate %u bytes failed for scratch", scratch_sz);
525-
ret = -ENOMEM;
526-
goto err;
527-
}
528-
ret = dax_init(dax_ctx);
529-
if (ret != 0) {
530-
comp_err(dev, "dax instance initialization failed, ret %d", ret);
531-
goto err;
592+
mod_free(mod, dax_ctx);
593+
module_set_private_data(mod, NULL);
594+
return -ENOMEM;
532595
}
533596

534-
comp_info(dev, "allocated: persist %u, scratch %u. version: %s",
535-
persist_sz, scratch_sz, dax_get_version());
536597
return 0;
537-
538-
err:
539-
sof_dax_free(mod);
540-
return ret;
541598
}
542599

543600
static int check_media_format(struct processing_module *mod)
@@ -631,6 +688,11 @@ static int sof_dax_prepare(struct processing_module *mod, struct sof_source **so
631688
if (ret != 0)
632689
return ret;
633690

691+
/* dax instance will be established on prepare(), and destroyed on reset() */
692+
ret = establish_instance(mod);
693+
if (ret != 0)
694+
return ret;
695+
634696
dax_ctx->sof_period_bytes = dev->frames *
635697
dax_ctx->output_media_format.num_channels *
636698
dax_ctx->output_media_format.bytes_per_sample;
@@ -680,6 +742,12 @@ static int sof_dax_process(struct processing_module *mod, struct sof_source **so
680742
struct dax_buffer *dax_output_buffer = &dax_ctx->output_buffer;
681743
uint32_t consumed_bytes, processed_bytes, produced_bytes;
682744

745+
if (!dax_ctx) {
746+
comp_err(mod->dev, "invalid dax context");
747+
return -EINVAL;
748+
}
749+
750+
dax_ctx->update_flags |= DAX_PROCESSING_MASK;
683751
/* source stream -> internal input buffer */
684752
consumed_bytes = MIN(source_get_data_available(source), dax_input_buffer->free);
685753
source_get_data(source, consumed_bytes, (void *)&buf, (void *)&bufstart, &bufsz);
@@ -711,6 +779,8 @@ static int sof_dax_process(struct processing_module *mod, struct sof_source **so
711779
dax_buffer_consume(dax_output_buffer, produced_bytes);
712780
sink_commit_buffer(sink, produced_bytes);
713781
}
782+
dax_ctx->update_flags &= ~DAX_PROCESSING_MASK;
783+
check_and_update_state(mod);
714784

715785
return 0;
716786
}
@@ -855,6 +925,7 @@ static const struct module_interface dolby_dax_audio_processing_interface = {
855925
.prepare = sof_dax_prepare,
856926
.process = sof_dax_process,
857927
.set_configuration = sof_dax_set_configuration,
928+
.reset = sof_dax_reset,
858929
.free = sof_dax_free,
859930
};
860931

0 commit comments

Comments
 (0)