diff --git a/drivers/char/adsprpc.c b/drivers/char/adsprpc.c index 39bdf863b597..ee38e227a93a 100644 --- a/drivers/char/adsprpc.c +++ b/drivers/char/adsprpc.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2012-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2022-2025 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ /* Uncomment this block to log an error on every VERIFY failure */ @@ -444,6 +444,7 @@ struct smq_invoke_ctx { uint32_t sc_interrupted; struct fastrpc_file *fl_interrupted; uint32_t handle_interrupted; + struct timespec64 invoke_start_time; /* submission timestamp for async perf */ }; struct fastrpc_ctx_lst { @@ -3362,6 +3363,15 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode, inv_args(ctx); PERF_END); + /* + * Store submission timestamp in ctx before sending to DSP. + * For async invokes, perf->invoke will be updated in the collector + * thread (fastrpc_wait_on_async_queue) where ctx is still valid, + * measuring full end-to-end latency consistent with the sync path. + */ + if (fl->profile && isasyncinvoke) + ctx->invoke_start_time = invoket; + PERF(fl->profile, GET_COUNTER(perf_counter, PERF_LINK), VERIFY(err, 0 == (err = fastrpc_invoke_send(ctx, kernel, invoke->handle))); @@ -3423,9 +3433,6 @@ static int fastrpc_internal_invoke(struct fastrpc_file *fl, uint32_t mode, err = -ECONNRESET; invoke_end: - if (fl->profile && !interrupted && isasyncinvoke) - fastrpc_update_invoke_count(invoke->handle, perf_counter, - &invoket); return err; } @@ -3495,6 +3502,15 @@ bail: async_res->result = ierr; if (ctx) { if (fl->profile && ctx->perf && ctx->handle > FASTRPC_STATIC_HANDLE_MAX) { + /* + * Update invoke/count perf counters here where ctx->perf is + * guaranteed valid. This measures full end-to-end async latency + * (submit → DSP → collect), consistent with the sync path. + * invoke_start_time was stored in ctx before fastrpc_invoke_send + * in fastrpc_internal_invoke. + */ + fastrpc_update_invoke_count(ctx->handle, perf_counter, + &ctx->invoke_start_time); trace_fastrpc_perf_counters(ctx->handle, ctx->sc, ctx->perf->count, ctx->perf->flush, ctx->perf->map, ctx->perf->copy, ctx->perf->link, ctx->perf->getargs,