From 537078144f71167b71b7f3b7ceebd7de18a3c093 Mon Sep 17 00:00:00 2001 From: Pratyush Meduri Date: Sun, 2 Aug 2026 19:26:29 +0530 Subject: [PATCH 1/3] ar_osal/linux: Add DMA-BUF CPU access sync helpers Add shared-memory sync APIs that use DMA_BUF_IOCTL_SYNC START/END for DMA-BUF-backed DSP allocations. The helpers bracket CPU access to out-of-band payload buffers so the dma-buf exporter can perform the required CPU cache maintenance before CPU reads or writes and before device access. Track the current CPU access state to avoid duplicate sync calls. Keep apps-side allocations as no-ops because they do not use this DSP DMA-BUF synchronization path. Signed-off-by: Pratyush Meduri --- ar_osal/api/ar_osal_shmem.h | 25 +++++++- ar_osal/src/linux/qcom/ar_osal_shmem.c | 10 ++++ ar_osal/src/linux/qcom/ar_osal_shmem_db.c | 66 ++++++++++++++++++++++ ar_osal/src/linux/qcom/ar_osal_shmem_dsp.h | 2 + 4 files changed, 102 insertions(+), 1 deletion(-) diff --git a/ar_osal/api/ar_osal_shmem.h b/ar_osal/api/ar_osal_shmem.h index b3198d2..e0390f7 100644 --- a/ar_osal/api/ar_osal_shmem.h +++ b/ar_osal/api/ar_osal_shmem.h @@ -283,6 +283,30 @@ int32_t ar_shmem_hyp_assign_phys(ar_shmem_hyp_assign_phys_info *info); */ int32_t ar_shmem_get_uid(uint64_t alloc_handle, uint64_t *uid); +/** + * \brief End CPU access for a DMA-BUF-backed shared memory buffer. + * + * The dma-buf exporter may perform CPU cache maintenance before device access. + * + * \param[in] info: pointer to ar_shmem_info returned by ar_shmem_alloc(). + * \return + * 0 -- Success + * Nonzero -- Failure + */ +int32_t ar_shmem_sync_for_device(ar_shmem_info *info); + +/** + * \brief Start CPU access for a DMA-BUF-backed shared memory buffer. + * + * The dma-buf exporter may perform CPU cache maintenance before CPU reads or writes. + * + * \param[in] info: pointer to ar_shmem_info returned by ar_shmem_alloc(). + * \return + * 0 -- Success + * Nonzero -- Failure + */ +int32_t ar_shmem_sync_for_cpu(ar_shmem_info *info); + /** * \brief ar_shmem_deinit. * @@ -297,4 +321,3 @@ int32_t ar_shmem_deinit(void); #endif /*__cplusplus*/ #endif /* #ifndef AR_OSAL_SHMEM_H */ - diff --git a/ar_osal/src/linux/qcom/ar_osal_shmem.c b/ar_osal/src/linux/qcom/ar_osal_shmem.c index 9bcc27b..95f3535 100644 --- a/ar_osal/src/linux/qcom/ar_osal_shmem.c +++ b/ar_osal/src/linux/qcom/ar_osal_shmem.c @@ -70,6 +70,16 @@ int32_t ar_shmem_get_uid(uint64_t alloc_handle, uint64_t *uid) return AR_EUNSUPPORTED; } +int32_t ar_shmem_sync_for_device(ar_shmem_info *info) +{ + return are_on_apps ? AR_EOK : ar_shmem_dsp_sync_for_device(info); +} + +int32_t ar_shmem_sync_for_cpu(ar_shmem_info *info) +{ + return are_on_apps ? AR_EOK : ar_shmem_dsp_sync_for_cpu(info); +} + int32_t ar_shmem_deinit(void) { int32_t rc = are_on_apps ? ar_shmem_ap_deinit() : ar_shmem_dsp_deinit(); diff --git a/ar_osal/src/linux/qcom/ar_osal_shmem_db.c b/ar_osal/src/linux/qcom/ar_osal_shmem_db.c index 2ce5325..8f23cc6 100644 --- a/ar_osal/src/linux/qcom/ar_osal_shmem_db.c +++ b/ar_osal/src/linux/qcom/ar_osal_shmem_db.c @@ -80,6 +80,72 @@ static ar_shmem_pdata_t *pdata = NULL; static pthread_mutex_t ar_shmem_lock = PTHREAD_MUTEX_INITIALIZER; +static int32_t ar_shmem_dsp_sync_dma_buf(ar_shmem_info *info, + uint64_t sync_flags, bool cpu_access) +{ + int32_t status = AR_EOK; + ar_shmem_handle_data_t *shmem_handle = NULL; + struct dma_buf_sync sync; + + memset(&sync, 0, sizeof(sync)); + + pthread_mutex_lock(&ar_shmem_lock); + + if (pdata == NULL) { + AR_LOG_ERR(AR_OSAL_SHMEM_LOG_TAG, "%s:not in init state\n", __func__); + status = AR_EBADPARAM; + goto end; + } + + if (info == NULL || info->metadata == 0) { + AR_LOG_ERR(AR_OSAL_SHMEM_LOG_TAG, + "%s:invalid info %pK metadata 0x%llx\n", + __func__, info, info ? (unsigned long long)info->metadata : 0); + status = AR_EBADPARAM; + goto end; + } + + shmem_handle = (ar_shmem_handle_data_t *)(intptr_t)info->metadata; + if (shmem_handle == NULL || shmem_handle->heap_fd < 0) { + AR_LOG_ERR(AR_OSAL_SHMEM_LOG_TAG, + "%s:invalid shmem handle %pK fd %d\n", + __func__, shmem_handle, shmem_handle ? shmem_handle->heap_fd : -1); + status = AR_EBADPARAM; + goto end; + } + + if (shmem_handle->dma_sync_flag == cpu_access) + goto end; + + sync.flags = sync_flags; + status = ioctl(shmem_handle->heap_fd, DMA_BUF_IOCTL_SYNC, &sync); + if (status) { + AR_LOG_ERR(AR_OSAL_SHMEM_LOG_TAG, + "%s: DMA heap sync failed, errno: %d status:%d\n", + __func__, errno, status); + status = AR_EUNEXPECTED; + goto end; + } + + shmem_handle->dma_sync_flag = cpu_access; + +end: + pthread_mutex_unlock(&ar_shmem_lock); + return status; +} + +int32_t ar_shmem_dsp_sync_for_device(ar_shmem_info *info) +{ + return ar_shmem_dsp_sync_dma_buf(info, + DMA_BUF_SYNC_END | DMA_BUF_SYNC_RW, false); +} + +int32_t ar_shmem_dsp_sync_for_cpu(ar_shmem_info *info) +{ + return ar_shmem_dsp_sync_dma_buf(info, + DMA_BUF_SYNC_START | DMA_BUF_SYNC_RW, true); +} + /** * \brief ar_shmem_validate_sys_id * internal function to validate supported SYS IDs. diff --git a/ar_osal/src/linux/qcom/ar_osal_shmem_dsp.h b/ar_osal/src/linux/qcom/ar_osal_shmem_dsp.h index b9a40f2..b8acacb 100644 --- a/ar_osal/src/linux/qcom/ar_osal_shmem_dsp.h +++ b/ar_osal/src/linux/qcom/ar_osal_shmem_dsp.h @@ -22,4 +22,6 @@ int32_t ar_shmem_dsp_free(ar_shmem_info *info); int32_t ar_shmem_dsp_map(ar_shmem_info *info); int32_t ar_shmem_dsp_unmap(ar_shmem_info *info); int32_t ar_shmem_dsp_hyp_assign_phys(ar_shmem_hyp_assign_phys_info *info); +int32_t ar_shmem_dsp_sync_for_device(ar_shmem_info *info); +int32_t ar_shmem_dsp_sync_for_cpu(ar_shmem_info *info); int32_t ar_shmem_dsp_deinit(void); From 29f27af22651f8dae3b0f57560f2d57b611c51cb Mon Sep 17 00:00:00 2001 From: Pratyush Meduri Date: Sun, 2 Aug 2026 19:26:29 +0530 Subject: [PATCH 2/3] gsl: Sync OOB shared memory around graph commands Use the shared-memory sync helpers when GSL builds and sends out-of-band graph command payloads to the DSP. The sync calls bracket CPU access around graph command payloads: after allocation before CPU writes, before command dispatch after CPU writes, and before consuming GET_CFG responses. This lets the dma-buf exporter perform CPU cache maintenance so MDSP observes updated payloads and the CPU sees DSP-written response data. Signed-off-by: Pratyush Meduri --- gsl/inc/gsl_shmem_mgr.h | 4 ++++ gsl/src/gsl_graph.c | 47 +++++++++++++++++++++++++++++++++++++++ gsl/src/gsl_msg_builder.c | 8 +++++++ gsl/src/gsl_shmem_mgr.c | 24 ++++++++++++++++++++ 4 files changed, 83 insertions(+) diff --git a/gsl/inc/gsl_shmem_mgr.h b/gsl/inc/gsl_shmem_mgr.h index a44410a..2da3972 100644 --- a/gsl/inc/gsl_shmem_mgr.h +++ b/gsl/inc/gsl_shmem_mgr.h @@ -90,6 +90,10 @@ int32_t gsl_shmem_map_dynamic_pd(struct gsl_shmem_alloc_data *alloc_data, uint32_t flags, uint32_t ss_mask, uint32_t master_proc_id); int32_t gsl_shmem_unmap_dynamic_pd(struct gsl_shmem_alloc_data *alloc_data, uint32_t ss_mask, uint32_t master_proc_id); +int32_t gsl_shmem_sync_for_device( + const struct gsl_shmem_alloc_data *alloc_data); +int32_t gsl_shmem_sync_for_cpu( + const struct gsl_shmem_alloc_data *alloc_data); void gsl_shmem_cache_pending_memmap_packets(uint32_t master_proc_id, void *gpr_packet); uint32_t gsl_shmem_check_and_unmap_cache_pending_packets(uint32_t master_proc_id); diff --git a/gsl/src/gsl_graph.c b/gsl/src/gsl_graph.c index 7b795a4..0172f72 100644 --- a/gsl/src/gsl_graph.c +++ b/gsl/src/gsl_graph.c @@ -26,6 +26,7 @@ #include "gsl_subgraph_pool.h" #include "gsl_common.h" #include "gsl_msg_builder.h" +#include "gsl_shmem_mgr.h" #include "gsl_spf_ss_state.h" #include "gsl_mdf_utils.h" @@ -43,6 +44,22 @@ struct gsl_blob { void *buf; /**< pointer to the blob */ }; +static int32_t gsl_msg_sync_oob_for_device(gsl_msg_t *msg) +{ + if (!msg || !msg->shmem.handle) + return AR_EOK; + + return gsl_shmem_sync_for_device(&msg->shmem); +} + +static int32_t gsl_msg_sync_oob_for_cpu(gsl_msg_t *msg) +{ + if (!msg || !msg->shmem.handle) + return AR_EOK; + + return gsl_shmem_sync_for_cpu(&msg->shmem); +} + /* Used to return tags and module info data sorted by processor id to client */ struct gsl_module_id_proc_info_entry { uint32_t proc_domain_id; // process the modules are running on @@ -544,6 +561,10 @@ static int32_t gsl_apm_config_oob(struct gsl_graph *graph, sizeof(*gsl_msg.gpr_packet) + sizeof(*cmd_header), gsl_msg.payload, payload_size); + rc = gsl_msg_sync_oob_for_device(&gsl_msg); + if (rc) + goto free_msg; + rc = gsl_send_spf_cmd(&gsl_msg.gpr_packet, &graph->graph_signal[GRAPH_CTRL_GRP2_CMD_SIG], &rsp_pkt); if (rc) { @@ -552,6 +573,10 @@ static int32_t gsl_apm_config_oob(struct gsl_graph *graph, } if (opcode == APM_CMD_GET_CFG) { + rc = gsl_msg_sync_oob_for_cpu(&gsl_msg); + if (rc) + goto free_msg; + get_cfg_rsp = GPR_PKT_GET_PAYLOAD(struct apm_cmd_rsp_get_cfg_t, rsp_pkt); /* @@ -881,6 +906,10 @@ static int32_t gsl_graph_send_nonpersist_cal(struct gsl_graph *graph, sizeof(*gsl_msg.gpr_packet) + sizeof(*cmd_header), gsl_msg.payload, cmd_header->payload_size); + rc = gsl_msg_sync_oob_for_device(&gsl_msg); + if (rc) + goto exit; + rc = gsl_send_spf_cmd_wait_for_basic_rsp(&gsl_msg.gpr_packet, &graph->graph_signal[GRAPH_CTRL_GRP2_CMD_SIG]); if (rc) @@ -2408,12 +2437,17 @@ static int32_t gsl_graph_close_sgids_and_connections(struct gsl_graph *graph, sizeof(*gsl_msg.gpr_packet) + sizeof(*cmd_header), gsl_msg.payload, close_pld_size); + rc = gsl_msg_sync_oob_for_device(&gsl_msg); + if (rc) + goto free_msg; + rc = gsl_send_spf_cmd_wait_for_basic_rsp(&gsl_msg.gpr_packet, &graph->graph_signal[GRAPH_CTRL_GRP3_CMD_SIG]); if (rc) GSL_ERR("Graph close failed:%d", rc); } +free_msg: gsl_msg_free(&gsl_msg); exit: @@ -3234,6 +3268,10 @@ static int32_t gsl_graph_open_sgids_and_connections(struct gsl_graph *graph, sizeof(*gsl_msg.gpr_packet) + sizeof(*open_cmd), gsl_msg.payload, graph_open_size); + rc = gsl_msg_sync_oob_for_device(&gsl_msg); + if (rc) + goto free_gsl_msg; + rc = gsl_send_spf_cmd_wait_for_basic_rsp(&gsl_msg.gpr_packet, &graph->graph_signal[GRAPH_CTRL_GRP1_CMD_SIG]); if (rc) { @@ -3793,6 +3831,10 @@ int32_t gsl_graph_set_config(struct gsl_graph *graph, GSL_LOG_PKT("send_pkt", graph->src_port, gsl_msg.gpr_packet, sizeof(*gsl_msg.gpr_packet) + sizeof(*cmd_header), gsl_msg.payload, cmd_header->payload_size); + rc = gsl_msg_sync_oob_for_device(&gsl_msg); + if (rc) + goto free_msg; + rc = gsl_send_spf_cmd_wait_for_basic_rsp(&gsl_msg.gpr_packet, &graph->graph_signal[GRAPH_CTRL_GRP2_CMD_SIG]); if (rc) @@ -5352,11 +5394,16 @@ int32_t gsl_graph_change_set_config_helper(struct gsl_graph *graph, GSL_LOG_PKT("send_pkt", graph->src_port, gsl_msg.gpr_packet, sizeof(*gsl_msg.gpr_packet) + sizeof(*cmd_header), gsl_msg.payload, cmd_header->payload_size); + rc = gsl_msg_sync_oob_for_device(&gsl_msg); + if (rc) + goto free_msg; + rc = gsl_send_spf_cmd_wait_for_basic_rsp(&gsl_msg.gpr_packet, &graph->graph_signal[GRAPH_CTRL_GRP2_CMD_SIG]); if (rc) GSL_ERR("Graph set config failed %d", rc); +free_msg: gsl_msg_free(&gsl_msg); exit: return rc; diff --git a/gsl/src/gsl_msg_builder.c b/gsl/src/gsl_msg_builder.c index 93811f5..7a5d688 100644 --- a/gsl/src/gsl_msg_builder.c +++ b/gsl/src/gsl_msg_builder.c @@ -104,6 +104,14 @@ int32_t gsl_msg_alloc_ext(uint32_t opcode, uint32_t src_port, oob_payload_size); goto exit; } + rc = gsl_shmem_sync_for_cpu(&msg->shmem); + if (rc) { + __gpr_cmd_free(msg->gpr_packet); + gsl_shmem_free(&msg->shmem); + GSL_ERR("Failed to sync shared mem for cpu size %d rc %d", + oob_payload_size, rc); + goto exit; + } } msg->payload = msg->shmem.v_addr; } diff --git a/gsl/src/gsl_shmem_mgr.c b/gsl/src/gsl_shmem_mgr.c index 7ca3a04..e6ca159 100644 --- a/gsl/src/gsl_shmem_mgr.c +++ b/gsl/src/gsl_shmem_mgr.c @@ -1217,6 +1217,30 @@ int32_t gsl_shmem_alloc_ext(uint32_t size_bytes, uint32_t spf_ss_mask, return rc; } +int32_t gsl_shmem_sync_for_device( + const struct gsl_shmem_alloc_data *alloc_data) +{ + struct gsl_shmem_page *page; + + if (!alloc_data || !alloc_data->handle) + return AR_EBADPARAM; + + page = alloc_data->handle; + return ar_shmem_sync_for_device(&page->shmem_info); +} + +int32_t gsl_shmem_sync_for_cpu( + const struct gsl_shmem_alloc_data *alloc_data) +{ + struct gsl_shmem_page *page; + + if (!alloc_data || !alloc_data->handle) + return AR_EBADPARAM; + + page = alloc_data->handle; + return ar_shmem_sync_for_cpu(&page->shmem_info); +} + int32_t gsl_shmem_free(struct gsl_shmem_alloc_data *alloc_data) { struct gsl_shmem_page *page; From 5c07df7069271f65915f6f1ac10d3edea87ce896 Mon Sep 17 00:00:00 2001 From: Pratyush Meduri Date: Fri, 7 Aug 2026 17:58:08 +0530 Subject: [PATCH 3/3] audioreach-graphservices: add MDSP processor configure option Add a --with-mdsp-proc configure option and use it to define MDSP_PROC for the ar_osal and gsl libraries. This keeps the MDSP-specific build flag controlled by graphservices configure logic instead of requiring external recipes to inject CFLAGS. Signed-off-by: Pratyush Meduri --- ar_osal/Makefile.am | 4 ++++ configure.ac | 6 ++++++ gsl/Makefile.am | 4 ++++ 3 files changed, 14 insertions(+) diff --git a/ar_osal/Makefile.am b/ar_osal/Makefile.am index 02de8e8..1542ff0 100644 --- a/ar_osal/Makefile.am +++ b/ar_osal/Makefile.am @@ -66,6 +66,10 @@ if LIBDIAG_HEADERS AM_CFLAGS += -DUSE_LIBDIAG_HEADERS endif +if MDSP_PROC +AM_CFLAGS += -DMDSP_PROC +endif + if ARGS_USE_SYSLOG AM_CFLAGS += -DAR_OSAL_USE_SYSLOG endif diff --git a/configure.ac b/configure.ac index 3814ba7..04950bf 100644 --- a/configure.ac +++ b/configure.ac @@ -97,6 +97,12 @@ AC_ARG_WITH([audio_dma_support], [with_audio_dma_support=no]) AM_CONDITIONAL([AUDIO_DMA_SUPPORT], [test "x${with_audio_dma_support}" = "xyes"]) +AC_ARG_WITH([mdsp-proc], + AS_HELP_STRING([--with-mdsp-proc],[Enable MDSP processor support (default is no)]), + [with_mdsp_proc=$withval], + [with_mdsp_proc=no]) +AM_CONDITIONAL([MDSP_PROC], [test "x${with_mdsp_proc}" = "xyes"]) + AC_ARG_WITH([libdiag_headers], AS_HELP_STRING([--with-libdiag_headers],[use libdiag headers only (default is no)]), [with_libdiag_headers=$withval], diff --git a/gsl/Makefile.am b/gsl/Makefile.am index d4dd1a9..53752a1 100644 --- a/gsl/Makefile.am +++ b/gsl/Makefile.am @@ -65,6 +65,10 @@ libar_gsl_la_SOURCES = $(gsl_c_sources) libar_gsl_la_CFLAGS = $(AM_CFLAGS) libar_gsl_la_LDFLAGS = -shared -version-number @LT_VERSION_NUMBER@ +if MDSP_PROC +libar_gsl_la_CFLAGS += -DMDSP_PROC +endif + if USES_ATS_DATA_LOGGING libar_gsl_la_CFLAGS += -DATS_DATA_LOGGING libar_gsl_la_CPPFLAGS = -DATS_DATA_LOGGING