From nobody Sun Oct 5 16:18:47 2025 Received: from mail-ej1-f74.google.com (mail-ej1-f74.google.com [209.85.218.74]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 54B662253EC for ; Fri, 1 Aug 2025 09:28:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754040488; cv=none; b=aApYiGiXpaEAap6SZpWJas1zhO6ziGr+mOMp06fp7nhgxaOQ1A2Gg+GvQpZzZTNu1UXRM6NB2Z7qxJdJFRHyM/DEFBlm426pC1RyAGLNbPJJy/8I1U+jBBIG8UuDbTM50IAF7J5cB46YZNBve52xSNHHUJvG3Nyf0+9G1htb08E= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754040488; c=relaxed/simple; bh=MQ9xWJ7wXL9+vIspTMGijgBLPAqquSykLWJTPJPFWag=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=fFE8kzXPnkY+zxDjOkbughui34IeqisdlyTa89zhiqBBKhHmhaIlkLv+wFOsd5Fl2ZL4llkFaURkZazxrkh2NzhVRK2ZhUH6U1DjtoDCWPOHb6tIEwC978+/J+DwRhioqpxE2Gay7OCNwMgQp8uAZZ2pvgbJC6WeMsabAiCG/m4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--verhaegen.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=sn/FGGZH; arc=none smtp.client-ip=209.85.218.74 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--verhaegen.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="sn/FGGZH" Received: by mail-ej1-f74.google.com with SMTP id a640c23a62f3a-af938c56c5fso20285666b.1 for ; Fri, 01 Aug 2025 02:28:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1754040484; x=1754645284; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=fEpoCd/5Vrc0UsMdfyCsoV/QsKkhoj2J2AvTx0q7Wms=; b=sn/FGGZH6ff45xL4KZfeCdakGpbtcA0eSaSeUns/xE2oczOj5HefIFjCtLLabLUDib aN5BSmLSAIjSNzmITsHhaqYTswS2IuNWTWqTxDY2ppvYBgiyDyVyE8t0S6P95TRY0GPZ 3FvxOGnoDcasnESkIPa54sCvUBl5ckIfR9YBqjkqvrpeEaHgaVZt1bPOjXIm609Uv+FO ES4Sewfd52kYuRJf0rmniOqWq0oxU+vlx0mW8/3PuSV5kYXMU24GkGPfInYxxGU7QbKs I07Qiwms6NTyg4G0QmeI9GNfckHA0C72ftVofUR9uwcMdVxy+fZklF0IMYd/vyVccxop ensA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1754040484; x=1754645284; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=fEpoCd/5Vrc0UsMdfyCsoV/QsKkhoj2J2AvTx0q7Wms=; b=GW3BtpwC0w4jZDiaaue78TGu9mroFC4xVofr/mM5O9ezlWXIuOFSB79sFK0EzX+7Bg gvaspeJ+tZtFqA78UROTeyUS2H3C4C1XelpCWQoMLW7uEdqCF11R1h2CemdT/25K19A4 JYaw7PRKk0UHvXfQR67D7HgYRA1eT5rk/duzTHj9wR9OrPIk64BOcT5GMBdRseB6sWbH pyHEVG4ZiSj4lHI5xtM2VY/564gJFzP8ZNzbUfW7ivG9wFMMDx3pceteQC4ZVWvL6eVE g47GpyNzJLA/Zj2aHcZ73NTNGllSDsUt6VCVf0F19htVi0xbFSh3ylbFJBPBXNaIT1z1 5V8g== X-Forwarded-Encrypted: i=1; AJvYcCXspIvxtAYEMIhaZjtdngisDvhJXmujA9D53SqamoQQLI6pHsMbu4foSEhanHr4VMfUzfjaHNQRm9qzKNY=@vger.kernel.org X-Gm-Message-State: AOJu0YywfmZ2hOo2M2d//3insW0txI+mLvyrEYI7OO8bp2hkk7XCQDRs E3ayLeGKVJPD+o5rgcxmDV95W4xJ4CXVa3SHvVX+Wx1hSFwJxzCBG13ORWYkejGAoNh1pMPbNCs j7f0c1fTb9rWUW/kbnA== X-Google-Smtp-Source: AGHT+IEFW2c8DrOJXxM/pEGu/Zk7/Q2TM2c40KVL1RQYuNhiyI6hQCYywFePFABa7n7a+BI7NKD2lxFq89izcZ8= X-Received: from ejctb12.prod.google.com ([2002:a17:907:8b8c:b0:ae3:50a2:7d29]) (user=verhaegen job=prod-delivery.src-stubby-dispatcher) by 2002:a17:907:7b88:b0:ae0:d08b:e85 with SMTP id a640c23a62f3a-af93196d8f7mr206137366b.61.1754040483695; Fri, 01 Aug 2025 02:28:03 -0700 (PDT) Date: Fri, 1 Aug 2025 10:27:14 +0100 In-Reply-To: <20250801092720.1845282-1-verhaegen@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250801092720.1845282-1-verhaegen@google.com> X-Mailer: git-send-email 2.50.1.565.gc32cd1483b-goog Message-ID: <20250801092720.1845282-2-verhaegen@google.com> Subject: [PATCH v4 1/3] ALSA: compress_offload: Add 64-bit safe timestamp infrastructure From: Joris Verhaegen To: Vinod Koul , Jaroslav Kysela , Takashi Iwai , Liam Girdwood , Mark Brown , Cezary Rojewski , Peter Ujfalusi , Bard Liao , Ranjani Sridharan , Kai Vehmanen , Pierre-Louis Bossart , Srinivas Kandagatla , Daniel Baluta , Orson Zhai , Baolin Wang , Chunyan Zhang , Kunihiko Hayashi , Masami Hiramatsu Cc: Joris Verhaegen , kernel-team@android.com, linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org, patches@opensource.cirrus.com, linux-arm-msm@vger.kernel.org, sound-open-firmware@alsa-project.org, linux-arm-kernel@lists.infradead.org, Miller Liang Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The copied_total field in struct snd_compr_tstamp is a 32-bit value that can overflow on long-running high-bitrate streams, leading to incorrect calculations for buffer availablility. This patch adds a 64-bit safe timestamping mechanism. A new UAPI struct, snd_compr_tstamp64, is added which uses 64-bit types for byte counters. The relevant ops structures across the ASoC and core compress code are updated to use this new struct. ASoC drivers are updated to use u64 counters. Internal timestamps being u64 now, a compatibility function is added to convert the 64-bit timestamp back to the 32-bit format for legacy ioctl callers. Reviewed-by: Miller Liang Tested-by: Joris Verhaegen Signed-off-by: Joris Verhaegen Reviewed-by: Charles Keepax --- include/sound/compress_driver.h | 2 +- include/sound/soc-component.h | 4 +- include/sound/soc-dai.h | 7 +-- include/uapi/sound/compress_offload.h | 19 +++++++ sound/core/compress_offload.c | 52 +++++++++++++------ sound/soc/codecs/wm_adsp.c | 4 +- sound/soc/codecs/wm_adsp.h | 2 +- .../intel/atom/sst-mfld-platform-compress.c | 12 +++-- sound/soc/intel/atom/sst-mfld-platform.h | 2 +- sound/soc/intel/atom/sst/sst_drv_interface.c | 9 ++-- sound/soc/intel/avs/probes.c | 2 +- sound/soc/qcom/qdsp6/q6apm-dai.c | 26 ++++++---- sound/soc/qcom/qdsp6/q6asm-dai.c | 26 ++++++---- sound/soc/soc-component.c | 2 +- sound/soc/soc-compress.c | 2 +- sound/soc/soc-dai.c | 2 +- sound/soc/sof/amd/acp-probes.c | 2 +- sound/soc/sof/compress.c | 2 +- sound/soc/sof/intel/hda-probes.c | 2 +- sound/soc/sof/sof-client-probes.c | 2 +- sound/soc/sof/sof-client-probes.h | 4 +- sound/soc/sprd/sprd-pcm-compress.c | 6 +-- sound/soc/sprd/sprd-pcm-dma.h | 4 +- sound/soc/uniphier/aio-compress.c | 2 +- 24 files changed, 125 insertions(+), 72 deletions(-) diff --git a/include/sound/compress_driver.h b/include/sound/compress_drive= r.h index b55c9eeb2b54..9e3d801e45ec 100644 --- a/include/sound/compress_driver.h +++ b/include/sound/compress_driver.h @@ -161,7 +161,7 @@ struct snd_compr_ops { struct snd_compr_metadata *metadata); int (*trigger)(struct snd_compr_stream *stream, int cmd); int (*pointer)(struct snd_compr_stream *stream, - struct snd_compr_tstamp *tstamp); + struct snd_compr_tstamp64 *tstamp); int (*copy)(struct snd_compr_stream *stream, char __user *buf, size_t count); int (*mmap)(struct snd_compr_stream *stream, diff --git a/include/sound/soc-component.h b/include/sound/soc-component.h index 61534ac0edd1..754627c6361a 100644 --- a/include/sound/soc-component.h +++ b/include/sound/soc-component.h @@ -47,7 +47,7 @@ struct snd_compress_ops { struct snd_compr_stream *stream, int cmd); int (*pointer)(struct snd_soc_component *component, struct snd_compr_stream *stream, - struct snd_compr_tstamp *tstamp); + struct snd_compr_tstamp64 *tstamp); int (*copy)(struct snd_soc_component *component, struct snd_compr_stream *stream, char __user *buf, size_t count); @@ -499,7 +499,7 @@ int snd_soc_component_compr_get_codec_caps(struct snd_c= ompr_stream *cstream, struct snd_compr_codec_caps *codec); int snd_soc_component_compr_ack(struct snd_compr_stream *cstream, size_t b= ytes); int snd_soc_component_compr_pointer(struct snd_compr_stream *cstream, - struct snd_compr_tstamp *tstamp); + struct snd_compr_tstamp64 *tstamp); int snd_soc_component_compr_copy(struct snd_compr_stream *cstream, char __user *buf, size_t count); int snd_soc_component_compr_set_metadata(struct snd_compr_stream *cstream, diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h index d19ab5572d2b..38ee6e158102 100644 --- a/include/sound/soc-dai.h +++ b/include/sound/soc-dai.h @@ -256,7 +256,7 @@ int snd_soc_dai_compr_ack(struct snd_soc_dai *dai, size_t bytes); int snd_soc_dai_compr_pointer(struct snd_soc_dai *dai, struct snd_compr_stream *cstream, - struct snd_compr_tstamp *tstamp); + struct snd_compr_tstamp64 *tstamp); int snd_soc_dai_compr_set_metadata(struct snd_soc_dai *dai, struct snd_compr_stream *cstream, struct snd_compr_metadata *metadata); @@ -383,8 +383,9 @@ struct snd_soc_cdai_ops { struct snd_compr_metadata *, struct snd_soc_dai *); int (*trigger)(struct snd_compr_stream *, int, struct snd_soc_dai *); - int (*pointer)(struct snd_compr_stream *, - struct snd_compr_tstamp *, struct snd_soc_dai *); + int (*pointer)(struct snd_compr_stream *stream, + struct snd_compr_tstamp64 *tstamp, + struct snd_soc_dai *dai); int (*ack)(struct snd_compr_stream *, size_t, struct snd_soc_dai *); }; diff --git a/include/uapi/sound/compress_offload.h b/include/uapi/sound/com= press_offload.h index d62eb93af0ed..abd0ea3f86ee 100644 --- a/include/uapi/sound/compress_offload.h +++ b/include/uapi/sound/compress_offload.h @@ -56,6 +56,25 @@ struct snd_compr_tstamp { __u32 sampling_rate; } __attribute__((packed, aligned(4))); =20 +/** + * struct snd_compr_tstamp64 - timestamp descriptor with fields in 64 bit + * @byte_offset: Byte offset in ring buffer to DSP + * @copied_total: Total number of bytes copied from/to ring buffer to/by D= SP + * @pcm_frames: Frames decoded or encoded by DSP. This field will evolve by + * large steps and should only be used to monitor encoding/decoding + * progress. It shall not be used for timing estimates. + * @pcm_io_frames: Frames rendered or received by DSP into a mixer or an a= udio + * output/input. This field should be used for A/V sync or time estimates. + * @sampling_rate: sampling rate of audio + */ +struct snd_compr_tstamp64 { + __u32 byte_offset; + __u64 copied_total; + __u64 pcm_frames; + __u64 pcm_io_frames; + __u32 sampling_rate; +} __attribute__((packed, aligned(4))); + /** * struct snd_compr_avail - avail descriptor * @avail: Number of bytes available in ring buffer for writing/reading diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c index a66f258cafaa..d3164aa07158 100644 --- a/sound/core/compress_offload.c +++ b/sound/core/compress_offload.c @@ -176,14 +176,25 @@ static int snd_compr_free(struct inode *inode, struct= file *f) return 0; } =20 +static void +snd_compr_tstamp32_from_64(struct snd_compr_tstamp *tstamp32, + const struct snd_compr_tstamp64 *tstamp64) +{ + tstamp32->byte_offset =3D tstamp64->byte_offset; + tstamp32->copied_total =3D (u32)tstamp64->copied_total; + tstamp32->pcm_frames =3D (u32)tstamp64->pcm_frames; + tstamp32->pcm_io_frames =3D (u32)tstamp64->pcm_io_frames; + tstamp32->sampling_rate =3D tstamp64->sampling_rate; +} + static int snd_compr_update_tstamp(struct snd_compr_stream *stream, - struct snd_compr_tstamp *tstamp) + struct snd_compr_tstamp64 *tstamp) { if (!stream->ops->pointer) return -ENOTSUPP; stream->ops->pointer(stream, tstamp); - pr_debug("dsp consumed till %d total %d bytes\n", - tstamp->byte_offset, tstamp->copied_total); + pr_debug("dsp consumed till %u total %llu bytes\n", tstamp->byte_offset, + tstamp->copied_total); if (stream->direction =3D=3D SND_COMPRESS_PLAYBACK) stream->runtime->total_bytes_transferred =3D tstamp->copied_total; else @@ -194,8 +205,11 @@ static int snd_compr_update_tstamp(struct snd_compr_st= ream *stream, static size_t snd_compr_calc_avail(struct snd_compr_stream *stream, struct snd_compr_avail *avail) { + struct snd_compr_tstamp64 tstamp64 =3D { 0 }; + memset(avail, 0, sizeof(*avail)); - snd_compr_update_tstamp(stream, &avail->tstamp); + snd_compr_update_tstamp(stream, &tstamp64); + snd_compr_tstamp32_from_64(&avail->tstamp, &tstamp64); /* Still need to return avail even if tstamp can't be filled in */ =20 if (stream->runtime->total_bytes_available =3D=3D 0 && @@ -204,9 +218,9 @@ static size_t snd_compr_calc_avail(struct snd_compr_str= eam *stream, pr_debug("detected init and someone forgot to do a write\n"); return stream->runtime->buffer_size; } - pr_debug("app wrote %lld, DSP consumed %lld\n", - stream->runtime->total_bytes_available, - stream->runtime->total_bytes_transferred); + pr_debug("app wrote %llu, DSP consumed %llu\n", + stream->runtime->total_bytes_available, + stream->runtime->total_bytes_transferred); if (stream->runtime->total_bytes_available =3D=3D stream->runtime->total_bytes_transferred) { if (stream->direction =3D=3D SND_COMPRESS_PLAYBACK) { @@ -223,7 +237,7 @@ static size_t snd_compr_calc_avail(struct snd_compr_str= eam *stream, if (stream->direction =3D=3D SND_COMPRESS_PLAYBACK) avail->avail =3D stream->runtime->buffer_size - avail->avail; =20 - pr_debug("ret avail as %lld\n", avail->avail); + pr_debug("ret avail as %llu\n", avail->avail); return avail->avail; } =20 @@ -274,8 +288,7 @@ static int snd_compr_write_data(struct snd_compr_stream= *stream, (app_pointer * runtime->buffer_size); =20 dstn =3D runtime->buffer + app_pointer; - pr_debug("copying %ld at %lld\n", - (unsigned long)count, app_pointer); + pr_debug("copying %lu at %llu\n", (unsigned long)count, app_pointer); if (count < runtime->buffer_size - app_pointer) { if (copy_from_user(dstn, buf, count)) return -EFAULT; @@ -318,7 +331,7 @@ static ssize_t snd_compr_write(struct file *f, const ch= ar __user *buf, } =20 avail =3D snd_compr_get_avail(stream); - pr_debug("avail returned %ld\n", (unsigned long)avail); + pr_debug("avail returned %lu\n", (unsigned long)avail); /* calculate how much we can write to buffer */ if (avail > count) avail =3D count; @@ -374,7 +387,7 @@ static ssize_t snd_compr_read(struct file *f, char __us= er *buf, } =20 avail =3D snd_compr_get_avail(stream); - pr_debug("avail returned %ld\n", (unsigned long)avail); + pr_debug("avail returned %lu\n", (unsigned long)avail); /* calculate how much we can read from buffer */ if (avail > count) avail =3D count; @@ -443,7 +456,7 @@ static __poll_t snd_compr_poll(struct file *f, poll_tab= le *wait) #endif =20 avail =3D snd_compr_get_avail(stream); - pr_debug("avail is %ld\n", (unsigned long)avail); + pr_debug("avail is %lu\n", (unsigned long)avail); /* check if we have at least one fragment to fill */ switch (runtime->state) { case SNDRV_PCM_STATE_DRAINING: @@ -726,13 +739,18 @@ snd_compr_set_metadata(struct snd_compr_stream *strea= m, unsigned long arg) static inline int snd_compr_tstamp(struct snd_compr_stream *stream, unsigned long arg) { - struct snd_compr_tstamp tstamp =3D {0}; + struct snd_compr_tstamp64 tstamp64 =3D { 0 }; + struct snd_compr_tstamp tstamp32 =3D { 0 }; int ret; =20 - ret =3D snd_compr_update_tstamp(stream, &tstamp); - if (ret =3D=3D 0) + ret =3D snd_compr_update_tstamp(stream, &tstamp64); + if (ret =3D=3D 0) { + snd_compr_tstamp32_from_64(&tstamp32, &tstamp64); ret =3D copy_to_user((struct snd_compr_tstamp __user *)arg, - &tstamp, sizeof(tstamp)) ? -EFAULT : 0; + &tstamp32, sizeof(tstamp32)) ? + -EFAULT : + 0; + } return ret; } =20 diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c index 8a1d5cc75d6c..f197034fd594 100644 --- a/sound/soc/codecs/wm_adsp.c +++ b/sound/soc/codecs/wm_adsp.c @@ -173,7 +173,7 @@ struct wm_adsp_compr { struct snd_compressed_buffer size; =20 u32 *raw_buf; - unsigned int copied_total; + u64 copied_total; =20 unsigned int sample_rate; =20 @@ -1860,7 +1860,7 @@ static int wm_adsp_buffer_reenable_irq(struct wm_adsp= _compr_buf *buf) =20 int wm_adsp_compr_pointer(struct snd_soc_component *component, struct snd_compr_stream *stream, - struct snd_compr_tstamp *tstamp) + struct snd_compr_tstamp64 *tstamp) { struct wm_adsp_compr *compr =3D stream->runtime->private_data; struct wm_adsp *dsp =3D compr->dsp; diff --git a/sound/soc/codecs/wm_adsp.h b/sound/soc/codecs/wm_adsp.h index 25210d404bf1..8035fda71f8d 100644 --- a/sound/soc/codecs/wm_adsp.h +++ b/sound/soc/codecs/wm_adsp.h @@ -131,7 +131,7 @@ int wm_adsp_compr_trigger(struct snd_soc_component *com= ponent, int wm_adsp_compr_handle_irq(struct wm_adsp *dsp); int wm_adsp_compr_pointer(struct snd_soc_component *component, struct snd_compr_stream *stream, - struct snd_compr_tstamp *tstamp); + struct snd_compr_tstamp64 *tstamp); int wm_adsp_compr_copy(struct snd_soc_component *component, struct snd_compr_stream *stream, char __user *buf, size_t count); diff --git a/sound/soc/intel/atom/sst-mfld-platform-compress.c b/sound/soc/= intel/atom/sst-mfld-platform-compress.c index 89c9c5ad6b21..9dfb0a814b94 100644 --- a/sound/soc/intel/atom/sst-mfld-platform-compress.c +++ b/sound/soc/intel/atom/sst-mfld-platform-compress.c @@ -18,6 +18,7 @@ #include #include #include +#include #include "sst-mfld-platform.h" =20 /* compress stream operations */ @@ -202,15 +203,16 @@ static int sst_platform_compr_trigger(struct snd_soc_= component *component, =20 static int sst_platform_compr_pointer(struct snd_soc_component *component, struct snd_compr_stream *cstream, - struct snd_compr_tstamp *tstamp) + struct snd_compr_tstamp64 *tstamp) { struct sst_runtime_stream *stream; + u64 temp_copied_total =3D tstamp->copied_total; =20 - stream =3D cstream->runtime->private_data; + stream =3D cstream->runtime->private_data; stream->compr_ops->tstamp(sst->dev, stream->id, tstamp); - tstamp->byte_offset =3D tstamp->copied_total % - (u32)cstream->runtime->buffer_size; - pr_debug("calc bytes offset/copied bytes as %d\n", tstamp->byte_offset); + tstamp->byte_offset =3D + do_div(temp_copied_total, cstream->runtime->buffer_size); + pr_debug("calc bytes offset/copied bytes as %u\n", tstamp->byte_offset); return 0; } =20 diff --git a/sound/soc/intel/atom/sst-mfld-platform.h b/sound/soc/intel/ato= m/sst-mfld-platform.h index 8b5777d3229a..a0e33f7f01c5 100644 --- a/sound/soc/intel/atom/sst-mfld-platform.h +++ b/sound/soc/intel/atom/sst-mfld-platform.h @@ -105,7 +105,7 @@ struct compress_sst_ops { int (*stream_pause_release)(struct device *dev, unsigned int str_id); =20 int (*tstamp)(struct device *dev, unsigned int str_id, - struct snd_compr_tstamp *tstamp); + struct snd_compr_tstamp64 *tstamp); int (*ack)(struct device *dev, unsigned int str_id, unsigned long bytes); int (*close)(struct device *dev, unsigned int str_id); diff --git a/sound/soc/intel/atom/sst/sst_drv_interface.c b/sound/soc/intel= /atom/sst/sst_drv_interface.c index 8bb27f86eb65..2646c4632ca1 100644 --- a/sound/soc/intel/atom/sst/sst_drv_interface.c +++ b/sound/soc/intel/atom/sst/sst_drv_interface.c @@ -326,7 +326,7 @@ static int sst_cdev_stream_partial_drain(struct device = *dev, } =20 static int sst_cdev_tstamp(struct device *dev, unsigned int str_id, - struct snd_compr_tstamp *tstamp) + struct snd_compr_tstamp64 *tstamp) { struct snd_sst_tstamp fw_tstamp =3D {0,}; struct stream_info *stream; @@ -349,10 +349,11 @@ static int sst_cdev_tstamp(struct device *dev, unsign= ed int str_id, (u64)stream->num_ch * SST_GET_BYTES_PER_SAMPLE(24)); tstamp->sampling_rate =3D fw_tstamp.sampling_frequency; =20 - dev_dbg(dev, "PCM =3D %u\n", tstamp->pcm_io_frames); - dev_dbg(dev, "Ptr Query on strid =3D %d copied_total %d, decodec %d\n", + dev_dbg(dev, "PCM =3D %llu\n", tstamp->pcm_io_frames); + dev_dbg(dev, + "Ptr Query on strid =3D %d copied_total %llu, decodec %llu\n", str_id, tstamp->copied_total, tstamp->pcm_frames); - dev_dbg(dev, "rendered %d\n", tstamp->pcm_io_frames); + dev_dbg(dev, "rendered %llu\n", tstamp->pcm_io_frames); =20 return 0; } diff --git a/sound/soc/intel/avs/probes.c b/sound/soc/intel/avs/probes.c index a42736b9aa55..b5b4b0754b71 100644 --- a/sound/soc/intel/avs/probes.c +++ b/sound/soc/intel/avs/probes.c @@ -213,7 +213,7 @@ static int avs_probe_compr_trigger(struct snd_compr_str= eam *cstream, int cmd, } =20 static int avs_probe_compr_pointer(struct snd_compr_stream *cstream, - struct snd_compr_tstamp *tstamp, struct snd_soc_dai *dai) + struct snd_compr_tstamp64 *tstamp, struct snd_soc_dai *dai) { struct hdac_ext_stream *host_stream =3D avs_compr_get_host_stream(cstream= ); struct snd_soc_pcm_stream *pstream; diff --git a/sound/soc/qcom/qdsp6/q6apm-dai.c b/sound/soc/qcom/qdsp6/q6apm-= dai.c index 2cd522108221..09da26f712a6 100644 --- a/sound/soc/qcom/qdsp6/q6apm-dai.c +++ b/sound/soc/qcom/qdsp6/q6apm-dai.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -65,9 +66,9 @@ struct q6apm_dai_rtd { unsigned int pcm_size; unsigned int pcm_count; unsigned int periods; - unsigned int bytes_sent; - unsigned int bytes_received; - unsigned int copied_total; + uint64_t bytes_sent; + uint64_t bytes_received; + uint64_t copied_total; uint16_t bits_per_sample; snd_pcm_uframes_t queue_ptr; bool next_track; @@ -575,15 +576,17 @@ static int q6apm_dai_compr_get_codec_caps(struct snd_= soc_component *component, =20 static int q6apm_dai_compr_pointer(struct snd_soc_component *component, struct snd_compr_stream *stream, - struct snd_compr_tstamp *tstamp) + struct snd_compr_tstamp64 *tstamp) { struct snd_compr_runtime *runtime =3D stream->runtime; struct q6apm_dai_rtd *prtd =3D runtime->private_data; unsigned long flags; + uint64_t temp_copied_total; =20 spin_lock_irqsave(&prtd->lock, flags); tstamp->copied_total =3D prtd->copied_total; - tstamp->byte_offset =3D prtd->copied_total % prtd->pcm_size; + temp_copied_total =3D tstamp->copied_total; + tstamp->byte_offset =3D do_div(temp_copied_total, prtd->pcm_size); spin_unlock_irqrestore(&prtd->lock, flags); =20 return 0; @@ -760,21 +763,24 @@ static int q6apm_compr_copy(struct snd_soc_component = *component, size_t copy; u32 wflags =3D 0; u32 app_pointer; - u32 bytes_received; + uint64_t bytes_received; + uint64_t temp_bytes_received; uint32_t bytes_to_write; - int avail, bytes_in_flight =3D 0; + uint64_t avail, bytes_in_flight =3D 0; =20 bytes_received =3D prtd->bytes_received; + temp_bytes_received =3D bytes_received; =20 /** * Make sure that next track data pointer is aligned at 32 bit boundary * This is a Mandatory requirement from DSP data buffers alignment */ - if (prtd->next_track) + if (prtd->next_track) { bytes_received =3D ALIGN(prtd->bytes_received, prtd->pcm_count); + temp_bytes_received =3D bytes_received; + } =20 - app_pointer =3D bytes_received/prtd->pcm_size; - app_pointer =3D bytes_received - (app_pointer * prtd->pcm_size); + app_pointer =3D do_div(temp_bytes_received, prtd->pcm_size); dstn =3D prtd->dma_buffer.area + app_pointer; =20 if (count < prtd->pcm_size - app_pointer) { diff --git a/sound/soc/qcom/qdsp6/q6asm-dai.c b/sound/soc/qcom/qdsp6/q6asm-= dai.c index a400c9a31fea..b616ce316d2f 100644 --- a/sound/soc/qcom/qdsp6/q6asm-dai.c +++ b/sound/soc/qcom/qdsp6/q6asm-dai.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -59,9 +60,9 @@ struct q6asm_dai_rtd { unsigned int pcm_count; unsigned int pcm_irq_pos; /* IRQ position */ unsigned int periods; - unsigned int bytes_sent; - unsigned int bytes_received; - unsigned int copied_total; + uint64_t bytes_sent; + uint64_t bytes_received; + uint64_t copied_total; uint16_t bits_per_sample; uint16_t source; /* Encoding source bit mask */ struct audio_client *audio_client; @@ -1026,16 +1027,18 @@ static int q6asm_dai_compr_trigger(struct snd_soc_c= omponent *component, =20 static int q6asm_dai_compr_pointer(struct snd_soc_component *component, struct snd_compr_stream *stream, - struct snd_compr_tstamp *tstamp) + struct snd_compr_tstamp64 *tstamp) { struct snd_compr_runtime *runtime =3D stream->runtime; struct q6asm_dai_rtd *prtd =3D runtime->private_data; unsigned long flags; + uint64_t temp_copied_total; =20 spin_lock_irqsave(&prtd->lock, flags); =20 tstamp->copied_total =3D prtd->copied_total; - tstamp->byte_offset =3D prtd->copied_total % prtd->pcm_size; + temp_copied_total =3D tstamp->copied_total; + tstamp->byte_offset =3D do_div(temp_copied_total, prtd->pcm_size); =20 spin_unlock_irqrestore(&prtd->lock, flags); =20 @@ -1050,23 +1053,26 @@ static int q6asm_compr_copy(struct snd_soc_componen= t *component, struct q6asm_dai_rtd *prtd =3D runtime->private_data; unsigned long flags; u32 wflags =3D 0; - int avail, bytes_in_flight =3D 0; + uint64_t avail, bytes_in_flight =3D 0; void *dstn; size_t copy; u32 app_pointer; - u32 bytes_received; + uint64_t bytes_received; + uint64_t temp_bytes_received; =20 bytes_received =3D prtd->bytes_received; + temp_bytes_received =3D bytes_received; =20 /** * Make sure that next track data pointer is aligned at 32 bit boundary * This is a Mandatory requirement from DSP data buffers alignment */ - if (prtd->next_track) + if (prtd->next_track) { bytes_received =3D ALIGN(prtd->bytes_received, prtd->pcm_count); + temp_bytes_received =3D bytes_received; + } =20 - app_pointer =3D bytes_received/prtd->pcm_size; - app_pointer =3D bytes_received - (app_pointer * prtd->pcm_size); + app_pointer =3D do_div(temp_bytes_received, prtd->pcm_size); dstn =3D prtd->dma_buffer.area + app_pointer; =20 if (count < prtd->pcm_size - app_pointer) { diff --git a/sound/soc/soc-component.c b/sound/soc/soc-component.c index 25f5e543ae8d..7976953b20f0 100644 --- a/sound/soc/soc-component.c +++ b/sound/soc/soc-component.c @@ -637,7 +637,7 @@ int snd_soc_component_compr_ack(struct snd_compr_stream= *cstream, size_t bytes) EXPORT_SYMBOL_GPL(snd_soc_component_compr_ack); =20 int snd_soc_component_compr_pointer(struct snd_compr_stream *cstream, - struct snd_compr_tstamp *tstamp) + struct snd_compr_tstamp64 *tstamp) { struct snd_soc_pcm_runtime *rtd =3D cstream->private_data; struct snd_soc_component *component; diff --git a/sound/soc/soc-compress.c b/sound/soc/soc-compress.c index 01d1d6bee28c..7b81dffc6a93 100644 --- a/sound/soc/soc-compress.c +++ b/sound/soc/soc-compress.c @@ -457,7 +457,7 @@ static int soc_compr_ack(struct snd_compr_stream *cstre= am, size_t bytes) } =20 static int soc_compr_pointer(struct snd_compr_stream *cstream, - struct snd_compr_tstamp *tstamp) + struct snd_compr_tstamp64 *tstamp) { struct snd_soc_pcm_runtime *rtd =3D cstream->private_data; int ret; diff --git a/sound/soc/soc-dai.c b/sound/soc/soc-dai.c index a210089747d0..ff82effa48e5 100644 --- a/sound/soc/soc-dai.c +++ b/sound/soc/soc-dai.c @@ -772,7 +772,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dai_compr_ack); =20 int snd_soc_dai_compr_pointer(struct snd_soc_dai *dai, struct snd_compr_stream *cstream, - struct snd_compr_tstamp *tstamp) + struct snd_compr_tstamp64 *tstamp) { int ret =3D 0; =20 diff --git a/sound/soc/sof/amd/acp-probes.c b/sound/soc/sof/amd/acp-probes.c index 0d0f8ec4aed8..ce51ed108a47 100644 --- a/sound/soc/sof/amd/acp-probes.c +++ b/sound/soc/sof/amd/acp-probes.c @@ -108,7 +108,7 @@ static int acp_probes_compr_trigger(struct sof_client_d= ev *cdev, =20 static int acp_probes_compr_pointer(struct sof_client_dev *cdev, struct snd_compr_stream *cstream, - struct snd_compr_tstamp *tstamp, + struct snd_compr_tstamp64 *tstamp, struct snd_soc_dai *dai) { struct acp_dsp_stream *stream =3D cstream->runtime->private_data; diff --git a/sound/soc/sof/compress.c b/sound/soc/sof/compress.c index d7b044f33d79..90b932ae3bab 100644 --- a/sound/soc/sof/compress.c +++ b/sound/soc/sof/compress.c @@ -361,7 +361,7 @@ static int sof_compr_copy(struct snd_soc_component *com= ponent, =20 static int sof_compr_pointer(struct snd_soc_component *component, struct snd_compr_stream *cstream, - struct snd_compr_tstamp *tstamp) + struct snd_compr_tstamp64 *tstamp) { struct snd_sof_pcm *spcm; struct snd_soc_pcm_runtime *rtd =3D cstream->private_data; diff --git a/sound/soc/sof/intel/hda-probes.c b/sound/soc/sof/intel/hda-pro= bes.c index c645346c2c84..b06933cebc45 100644 --- a/sound/soc/sof/intel/hda-probes.c +++ b/sound/soc/sof/intel/hda-probes.c @@ -112,7 +112,7 @@ static int hda_probes_compr_trigger(struct sof_client_d= ev *cdev, =20 static int hda_probes_compr_pointer(struct sof_client_dev *cdev, struct snd_compr_stream *cstream, - struct snd_compr_tstamp *tstamp, + struct snd_compr_tstamp64 *tstamp, struct snd_soc_dai *dai) { struct hdac_ext_stream *hext_stream =3D hda_compr_get_stream(cstream); diff --git a/sound/soc/sof/sof-client-probes.c b/sound/soc/sof/sof-client-p= robes.c index aff9ce980429..71930a922c29 100644 --- a/sound/soc/sof/sof-client-probes.c +++ b/sound/soc/sof/sof-client-probes.c @@ -137,7 +137,7 @@ static int sof_probes_compr_trigger(struct snd_compr_st= ream *cstream, int cmd, } =20 static int sof_probes_compr_pointer(struct snd_compr_stream *cstream, - struct snd_compr_tstamp *tstamp, + struct snd_compr_tstamp64 *tstamp, struct snd_soc_dai *dai) { struct snd_soc_card *card =3D snd_soc_component_get_drvdata(dai->componen= t); diff --git a/sound/soc/sof/sof-client-probes.h b/sound/soc/sof/sof-client-p= robes.h index da04d65b8d99..8713b69cda4b 100644 --- a/sound/soc/sof/sof-client-probes.h +++ b/sound/soc/sof/sof-client-probes.h @@ -4,7 +4,7 @@ #define __SOF_CLIENT_PROBES_H =20 struct snd_compr_stream; -struct snd_compr_tstamp; +struct snd_compr_tstamp64; struct snd_compr_params; struct sof_client_dev; struct snd_soc_dai; @@ -24,7 +24,7 @@ struct sof_probes_host_ops { int (*trigger)(struct sof_client_dev *cdev, struct snd_compr_stream *cstr= eam, int cmd, struct snd_soc_dai *dai); int (*pointer)(struct sof_client_dev *cdev, struct snd_compr_stream *cstr= eam, - struct snd_compr_tstamp *tstamp, + struct snd_compr_tstamp64 *tstamp, struct snd_soc_dai *dai); }; =20 diff --git a/sound/soc/sprd/sprd-pcm-compress.c b/sound/soc/sprd/sprd-pcm-c= ompress.c index 57bd1a0728ac..4b6ebfa5b033 100644 --- a/sound/soc/sprd/sprd-pcm-compress.c +++ b/sound/soc/sprd/sprd-pcm-compress.c @@ -85,9 +85,9 @@ struct sprd_compr_stream { int info_size; =20 /* Data size copied to IRAM buffer */ - int copied_total; + u64 copied_total; /* Total received data size from userspace */ - int received_total; + u64 received_total; /* Stage 0 IRAM buffer received data size */ int received_stage0; /* Stage 1 DDR buffer received data size */ @@ -513,7 +513,7 @@ static int sprd_platform_compr_trigger(struct snd_soc_c= omponent *component, =20 static int sprd_platform_compr_pointer(struct snd_soc_component *component, struct snd_compr_stream *cstream, - struct snd_compr_tstamp *tstamp) + struct snd_compr_tstamp64 *tstamp) { struct snd_compr_runtime *runtime =3D cstream->runtime; struct sprd_compr_stream *stream =3D runtime->private_data; diff --git a/sound/soc/sprd/sprd-pcm-dma.h b/sound/soc/sprd/sprd-pcm-dma.h index be5e385f5e42..c5935a1367e6 100644 --- a/sound/soc/sprd/sprd-pcm-dma.h +++ b/sound/soc/sprd/sprd-pcm-dma.h @@ -19,7 +19,7 @@ struct sprd_compr_playinfo { int total_time; int current_time; int total_data_length; - int current_data_offset; + u64 current_data_offset; }; =20 struct sprd_compr_params { @@ -46,7 +46,7 @@ struct sprd_compr_ops { int (*stop)(int str_id); int (*pause)(int str_id); int (*pause_release)(int str_id); - int (*drain)(int received_total); + int (*drain)(u64 received_total); int (*set_params)(int str_id, struct sprd_compr_params *params); }; =20 diff --git a/sound/soc/uniphier/aio-compress.c b/sound/soc/uniphier/aio-com= press.c index 4a19d4908ffd..b18af98a552b 100644 --- a/sound/soc/uniphier/aio-compress.c +++ b/sound/soc/uniphier/aio-compress.c @@ -249,7 +249,7 @@ static int uniphier_aio_compr_trigger(struct snd_soc_co= mponent *component, =20 static int uniphier_aio_compr_pointer(struct snd_soc_component *component, struct snd_compr_stream *cstream, - struct snd_compr_tstamp *tstamp) + struct snd_compr_tstamp64 *tstamp) { struct snd_soc_pcm_runtime *rtd =3D cstream->private_data; struct snd_compr_runtime *runtime =3D cstream->runtime; --=20 2.50.1.565.gc32cd1483b-goog From nobody Sun Oct 5 16:18:47 2025 Received: from mail-wr1-f73.google.com (mail-wr1-f73.google.com [209.85.221.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 906F92264CF for ; Fri, 1 Aug 2025 09:28:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754040494; cv=none; b=jGdpsY7NuyCfMO6ed+NMLwPMpPaqzA1x04t2AP97jz2u8/o6C4YdKqNC/84XEYjejFyE8nlquXHR1DWnsyREWoJO01xJWhnyY+ba6mdkfYwKdAhxMwRXJejQqHG8Aept6L2Dz5UACySarxFrjjW7g3fEfFId32kqUaQi7Mx4QQE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754040494; c=relaxed/simple; bh=iEUlnm6UcU71O3qhqf8+Qaoj6tGlW/0LywzXO/lxfGs=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=U6+9PwbO8ScEm3UFwo9TDPuAtUDVuH/LEsbizX00cGY1ZCb8nw4dGSHNPrzMWXaE3nrpFLGl+N0VyAhWyoQ9smaCssKSEgoVBoYo4rB53U56lsZi2b2oNCeNdiiyEe41ySrNxSApwUKVs4eImduJvlh4E9ls51TJK86OlOAUoYM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--verhaegen.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=Q5rYz8b7; arc=none smtp.client-ip=209.85.221.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--verhaegen.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="Q5rYz8b7" Received: by mail-wr1-f73.google.com with SMTP id ffacd0b85a97d-3b783265641so1140040f8f.1 for ; Fri, 01 Aug 2025 02:28:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1754040491; x=1754645291; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=CE0yUTi8vaWBOP+ptSGUlpWi9dFsFhf4ychTYVoaqcU=; b=Q5rYz8b7Jgp5EoZjF9iPxAT1GSJlQk00ZkDVh8Up7g86KVUqQ5JjW9AdKveHcPCtF0 9SwNKGEaHUyj0CCXzenQIFbZBgucls7MWfRj57jFojo0sXYI0SGSb8IgcWTflUxeuT8L KkobWrc2T8D/8p+EREcQxOTyEHio3V8/GW8OemfNVySmXHh36CbLi6ns+xBe5/j/hEJf Gq4G9K4JWueyU2Uo+sWjYb4EAJJ8GuMW7AgKQafqcXVUSe1zyMbun1wkPOW9VcjaiiJt dTXq9Rgnimr/VwXU1L7DRrVMh4jfHzp+sIP/Vc26osegum99mlcyNw6komZIVmrR+Trd sx4A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1754040491; x=1754645291; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=CE0yUTi8vaWBOP+ptSGUlpWi9dFsFhf4ychTYVoaqcU=; b=C7WUnES7/1sCQmPScv84BuhIKM1uSzIGatAHs4gnR4mcJoKTME+NLB3lQ33lklE8pJ uY7x0bqn2VrgQtUIaTMwZ4IOH82dLHSisPvOLDJskSsr3LzyumPz42VW1/fk6Kl5y4Go GDaH1X7EC6mMEJVBHnyQhG2OzhHq0mSLMF02AlSpu1l+x9SC7u0GuxG8aGs7zTUvSp25 cg9qdssalIxkEzw3m5yNmHmvfLOi8vbrOdpDzuO6G8Cul2WXyvB4ARixyuDUDrpyz2RA j915k4nSuhhHYOQ70q1MxCEVd3GNxmK4luLwDOXYXFsgoDNLq0rtZA4ldOoZPepQlNFF Yu/g== X-Forwarded-Encrypted: i=1; AJvYcCU9fugkBydChl5A/qQBZHTMn7b7yl4wpZIkpN1KoK523UfNFqFWcZru51PQpEK73bvq8JPkK9M3NwQ4kNk=@vger.kernel.org X-Gm-Message-State: AOJu0Yz6WES+tsRixxCIaZ/4uH++ZK7ePBExWeO8LX3GS/hhoksSZuiP HDq1D2HaJTwu15KyDkBbzLZn9NiHHl8V66HFjpCbvJtKzH6grdu68ZlcQE+UwKPKyOlHT1rr3eg oKrPPnWi+y430OEgjog== X-Google-Smtp-Source: AGHT+IGclLlFV2GkuMwBDGhI/am9e4aUyiArGDfT6eX1AfmQulH6DcrQSI5ElTu2oPPFAXeEXjf99dWLtJ2pyZY= X-Received: from wrpa8.prod.google.com ([2002:adf:eec8:0:b0:3b7:8342:dc50]) (user=verhaegen job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6000:2311:b0:3b4:9b82:d44c with SMTP id ffacd0b85a97d-3b794fc3115mr8167881f8f.22.1754040490843; Fri, 01 Aug 2025 02:28:10 -0700 (PDT) Date: Fri, 1 Aug 2025 10:27:15 +0100 In-Reply-To: <20250801092720.1845282-1-verhaegen@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250801092720.1845282-1-verhaegen@google.com> X-Mailer: git-send-email 2.50.1.565.gc32cd1483b-goog Message-ID: <20250801092720.1845282-3-verhaegen@google.com> Subject: [PATCH v4 2/3] ALSA: compress_offload: Add SNDRV_COMPRESS_TSTAMP64 ioctl From: Joris Verhaegen To: Vinod Koul , Jaroslav Kysela , Takashi Iwai , Liam Girdwood , Mark Brown , Cezary Rojewski , Peter Ujfalusi , Bard Liao , Ranjani Sridharan , Kai Vehmanen , Pierre-Louis Bossart , Srinivas Kandagatla , Daniel Baluta , Orson Zhai , Baolin Wang , Chunyan Zhang , Kunihiko Hayashi , Masami Hiramatsu Cc: Joris Verhaegen , kernel-team@android.com, linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org, patches@opensource.cirrus.com, linux-arm-msm@vger.kernel.org, sound-open-firmware@alsa-project.org, linux-arm-kernel@lists.infradead.org, Miller Liang Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The previous patch introduced the internal infrastructure for handling 64-bit timestamps. This patch exposes this capability to user-space. Define the new ioctl command SNDRV_COMPRESS_TSTAMP64, which allows applications to fetch the overflow-safe struct snd_compr_tstamp64. The ioctl dispatch table is updated to handle the new command by calling a new snd_compr_tstamp64 handler, while the legacy path is renamed to snd_compr_tstamp32 for clarity. This patch bumps the SNDRV_COMPRESS_VERSION to 0.4.0. Reviewed-by: Miller Liang Tested-by: Joris Verhaegen Signed-off-by: Joris Verhaegen Reviewed-by: Charles Keepax --- include/uapi/sound/compress_offload.h | 5 +++-- sound/core/compress_offload.c | 19 +++++++++++++------ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/include/uapi/sound/compress_offload.h b/include/uapi/sound/com= press_offload.h index abd0ea3f86ee..70b8921601f9 100644 --- a/include/uapi/sound/compress_offload.h +++ b/include/uapi/sound/compress_offload.h @@ -13,8 +13,7 @@ #include #include =20 - -#define SNDRV_COMPRESS_VERSION SNDRV_PROTOCOL_VERSION(0, 3, 0) +#define SNDRV_COMPRESS_VERSION SNDRV_PROTOCOL_VERSION(0, 4, 0) /** * struct snd_compressed_buffer - compressed buffer * @fragment_size: size of buffer fragment in bytes @@ -208,6 +207,7 @@ struct snd_compr_task_status { * Note: only codec params can be changed runtime and stream params cant be * SNDRV_COMPRESS_GET_PARAMS: Query codec params * SNDRV_COMPRESS_TSTAMP: get the current timestamp value + * SNDRV_COMPRESS_TSTAMP64: get the current timestamp value in 64 bit form= at * SNDRV_COMPRESS_AVAIL: get the current buffer avail value. * This also queries the tstamp properties * SNDRV_COMPRESS_PAUSE: Pause the running stream @@ -230,6 +230,7 @@ struct snd_compr_task_status { struct snd_compr_metadata) #define SNDRV_COMPRESS_TSTAMP _IOR('C', 0x20, struct snd_compr_tstamp) #define SNDRV_COMPRESS_AVAIL _IOR('C', 0x21, struct snd_compr_avail) +#define SNDRV_COMPRESS_TSTAMP64 _IOR('C', 0x22, struct snd_compr_tstamp64) #define SNDRV_COMPRESS_PAUSE _IO('C', 0x30) #define SNDRV_COMPRESS_RESUME _IO('C', 0x31) #define SNDRV_COMPRESS_START _IO('C', 0x32) diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c index d3164aa07158..445220fdb6a0 100644 --- a/sound/core/compress_offload.c +++ b/sound/core/compress_offload.c @@ -736,18 +736,23 @@ snd_compr_set_metadata(struct snd_compr_stream *strea= m, unsigned long arg) return retval; } =20 -static inline int -snd_compr_tstamp(struct snd_compr_stream *stream, unsigned long arg) +static inline int snd_compr_tstamp(struct snd_compr_stream *stream, + unsigned long arg, bool is_32bit) { struct snd_compr_tstamp64 tstamp64 =3D { 0 }; struct snd_compr_tstamp tstamp32 =3D { 0 }; + const void *copy_from =3D &tstamp64; + size_t copy_size =3D sizeof(tstamp64); int ret; =20 ret =3D snd_compr_update_tstamp(stream, &tstamp64); if (ret =3D=3D 0) { - snd_compr_tstamp32_from_64(&tstamp32, &tstamp64); - ret =3D copy_to_user((struct snd_compr_tstamp __user *)arg, - &tstamp32, sizeof(tstamp32)) ? + if (is_32bit) { + snd_compr_tstamp32_from_64(&tstamp32, &tstamp64); + copy_from =3D &tstamp32; + copy_size =3D sizeof(tstamp32); + } + ret =3D copy_to_user((void __user *)arg, copy_from, copy_size) ? -EFAULT : 0; } @@ -1327,7 +1332,9 @@ static long snd_compr_ioctl(struct file *f, unsigned = int cmd, unsigned long arg) =20 switch (cmd) { case SNDRV_COMPRESS_TSTAMP: - return snd_compr_tstamp(stream, arg); + return snd_compr_tstamp(stream, arg, true); + case SNDRV_COMPRESS_TSTAMP64: + return snd_compr_tstamp(stream, arg, false); case SNDRV_COMPRESS_AVAIL: return snd_compr_ioctl_avail(stream, arg); case SNDRV_COMPRESS_PAUSE: --=20 2.50.1.565.gc32cd1483b-goog From nobody Sun Oct 5 16:18:47 2025 Received: from mail-wr1-f73.google.com (mail-wr1-f73.google.com [209.85.221.73]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 46FA52236FB for ; Fri, 1 Aug 2025 09:28:19 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.73 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754040501; cv=none; b=IvLoZY44dRp3k1gZuysDk6rcvONs1Prcl9ejs6SsLMrFT3eM7U9WJhMN87xsGmlMPbeBXhp7v6VbP8GQKoGVg+bYx9ReOvltqcVRrv+MVd5XoebFBecBvVDfdnHdW4YA5WecUTkPtx2xCtDE8C3dcBhMQCEP8lDt2l5De4vQvVg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754040501; c=relaxed/simple; bh=gk2nf5/MPwZnRVOVR7/JwKNQsjmgQi916LQ5DollH1k=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=r6xkd1Y3khxUNCO1hzkyn1Y7ZwfYmLHhWj47eed2TzpEPD0KBJbnqzyrBXRFt4sLPLJXTIrXt+5bRaaQFFt1yGJOcfRwYXAUMbiJ5BFqPjEavHIf37BAUfosGXa1bOji08wlRc8IthelIghTzCYbg4qQQYY2iy/xgTlLgcMRM74= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com; spf=pass smtp.mailfrom=flex--verhaegen.bounces.google.com; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b=smkrr9v8; arc=none smtp.client-ip=209.85.221.73 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=google.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=flex--verhaegen.bounces.google.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=google.com header.i=@google.com header.b="smkrr9v8" Received: by mail-wr1-f73.google.com with SMTP id ffacd0b85a97d-3b7931d3d76so10953f8f.1 for ; Fri, 01 Aug 2025 02:28:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1754040498; x=1754645298; darn=vger.kernel.org; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=sGqJwcIIXGX6gPFmMrFyOlEh3bYkZD3CtGlIUbK7Bvs=; b=smkrr9v8Sko9RF0p6/j681o9u2bDA7DnsG2rxIDUIR0PUmcsKIv4qN2jdVkpmbjn2q CyX564xaHhQ70we3Ypi0jGAfDCZG5qUi3Wje2o6CTzMH/J3lo3FQf+e02/wSsKIfRVSU cIwjF3nyq/4tryrprHblfTzBbodVxFlhD7gXqkKTZ8UQrSdVljY9kkYr13aKRyeAwGkD K+mIml5nZPr4EppqQ3rqozwXaN8peWji2Y7eHjGx2eZ2h8wG+dJYoUsQjMVh5CsD9NfI aVJaZQ8eVF9D+fd4DThickvYds53suJh42GdRsLaAHuoNxN2ng3nQM9ULhxQxX26pmVP opaw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1754040498; x=1754645298; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=sGqJwcIIXGX6gPFmMrFyOlEh3bYkZD3CtGlIUbK7Bvs=; b=peQuWGlu5PHyjQVWm55bSvXDBGTYXJcXl1t1BLr6tVKhRgjdg7t/xDuNPXnHkkCAjP bajpxlPkhh9Aoinhepu4H4rv4+4GZ4WlLs/oz8NwMKrvptdimm3B5A//Fyt65x7z6SnV 8u7bYJJMzw9g+gVDpRCB3cclyb0pEovEOdJeqRrLe4KiSgOFg0KmPYVUwVgejv6CIHmj QGxfyDIsKfGizT95JRArUSfYMXHEv21kydRS3NRUIwsy0gIN+L5Nrbhw2rnerKKbVs5L GSD9zVkYP6Ux7xI/2bPjddhCQ9OLQ2Mv+nIMC9bpesbjJo73WpOtJd91+B6GfP3zkj5l qN4Q== X-Forwarded-Encrypted: i=1; AJvYcCWdozzGPDRhjyDpYfMbNRHNJnktoQ+Z+GkVB+Apbiyq+NH9opSzEJvAzo1D9kmGJr/LoUEJwzlMEGsH8Zs=@vger.kernel.org X-Gm-Message-State: AOJu0YzAiWUZBh2bJZHNt9YQsaQLM0jg5UPglo3b0R7IHGPGM1bI7q7X 5UznjG6woFk9EZYI8wWBnjpvVLAbQmAHgGF3qLX5hwr4WjNIJ+uS8LbjaihNLvcxOeZGAquNSgp krE6MvXN3Qw+u6Z8uiA== X-Google-Smtp-Source: AGHT+IGuGJWlXT1GgrSFR5jnLb7A8Xwc1RjU3pAVlVHHLd9Rq5DVeyg7S8YW7qeBp1u7A9f0qGgaXcOFCxNv/1A= X-Received: from wmsp28.prod.google.com ([2002:a05:600c:1d9c:b0:456:1518:6d6e]) (user=verhaegen job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6000:40df:b0:3b8:d5cb:ae1c with SMTP id ffacd0b85a97d-3b8d5cbb0dfmr948024f8f.28.1754040497655; Fri, 01 Aug 2025 02:28:17 -0700 (PDT) Date: Fri, 1 Aug 2025 10:27:16 +0100 In-Reply-To: <20250801092720.1845282-1-verhaegen@google.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Mime-Version: 1.0 References: <20250801092720.1845282-1-verhaegen@google.com> X-Mailer: git-send-email 2.50.1.565.gc32cd1483b-goog Message-ID: <20250801092720.1845282-4-verhaegen@google.com> Subject: [PATCH v4 3/3] ALSA: compress_offload: Add SNDRV_COMPRESS_AVAIL64 ioctl From: Joris Verhaegen To: Vinod Koul , Jaroslav Kysela , Takashi Iwai , Liam Girdwood , Mark Brown , Cezary Rojewski , Peter Ujfalusi , Bard Liao , Ranjani Sridharan , Kai Vehmanen , Pierre-Louis Bossart , Srinivas Kandagatla , Daniel Baluta , Orson Zhai , Baolin Wang , Chunyan Zhang , Kunihiko Hayashi , Masami Hiramatsu Cc: Joris Verhaegen , kernel-team@android.com, linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org, patches@opensource.cirrus.com, linux-arm-msm@vger.kernel.org, sound-open-firmware@alsa-project.org, linux-arm-kernel@lists.infradead.org, Miller Liang Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" The previous patch introduced a 64-bit timestamp ioctl (SNDRV_COMPRESS_TSTAMP64). To provide a consistent API, this patch adds a corresponding 64-bit version of the SNDRV_COMPRESS_AVAIL ioctl. A new struct snd_compr_avail64 is added to the UAPI, which includes the 64-bit timestamp. The existing ioctl implementation is refactored to handle both the 32-bit and 64-bit variants. Reviewed-by: Miller Liang Tested-by: Joris Verhaegen Signed-off-by: Joris Verhaegen Reviewed-by: Charles Keepax --- include/uapi/sound/compress_offload.h | 11 +++++++ sound/core/compress_offload.c | 45 +++++++++++++++++---------- 2 files changed, 40 insertions(+), 16 deletions(-) diff --git a/include/uapi/sound/compress_offload.h b/include/uapi/sound/com= press_offload.h index 70b8921601f9..26f756cc2e62 100644 --- a/include/uapi/sound/compress_offload.h +++ b/include/uapi/sound/compress_offload.h @@ -84,6 +84,16 @@ struct snd_compr_avail { struct snd_compr_tstamp tstamp; } __attribute__((packed, aligned(4))); =20 +/** + * struct snd_compr_avail64 - avail descriptor with tstamp in 64 bit format + * @avail: Number of bytes available in ring buffer for writing/reading + * @tstamp: timestamp information + */ +struct snd_compr_avail64 { + __u64 avail; + struct snd_compr_tstamp64 tstamp; +} __attribute__((packed, aligned(4))); + enum snd_compr_direction { SND_COMPRESS_PLAYBACK =3D 0, SND_COMPRESS_CAPTURE, @@ -231,6 +241,7 @@ struct snd_compr_task_status { #define SNDRV_COMPRESS_TSTAMP _IOR('C', 0x20, struct snd_compr_tstamp) #define SNDRV_COMPRESS_AVAIL _IOR('C', 0x21, struct snd_compr_avail) #define SNDRV_COMPRESS_TSTAMP64 _IOR('C', 0x22, struct snd_compr_tstamp64) +#define SNDRV_COMPRESS_AVAIL64 _IOR('C', 0x23, struct snd_compr_avail64) #define SNDRV_COMPRESS_PAUSE _IO('C', 0x30) #define SNDRV_COMPRESS_RESUME _IO('C', 0x31) #define SNDRV_COMPRESS_START _IO('C', 0x32) diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c index 445220fdb6a0..4d3cf49c0c47 100644 --- a/sound/core/compress_offload.c +++ b/sound/core/compress_offload.c @@ -203,13 +203,10 @@ static int snd_compr_update_tstamp(struct snd_compr_s= tream *stream, } =20 static size_t snd_compr_calc_avail(struct snd_compr_stream *stream, - struct snd_compr_avail *avail) + struct snd_compr_avail64 *avail) { - struct snd_compr_tstamp64 tstamp64 =3D { 0 }; - memset(avail, 0, sizeof(*avail)); - snd_compr_update_tstamp(stream, &tstamp64); - snd_compr_tstamp32_from_64(&avail->tstamp, &tstamp64); + snd_compr_update_tstamp(stream, &avail->tstamp); /* Still need to return avail even if tstamp can't be filled in */ =20 if (stream->runtime->total_bytes_available =3D=3D 0 && @@ -233,32 +230,47 @@ static size_t snd_compr_calc_avail(struct snd_compr_s= tream *stream, } =20 avail->avail =3D stream->runtime->total_bytes_available - - stream->runtime->total_bytes_transferred; + stream->runtime->total_bytes_transferred; if (stream->direction =3D=3D SND_COMPRESS_PLAYBACK) avail->avail =3D stream->runtime->buffer_size - avail->avail; =20 - pr_debug("ret avail as %llu\n", avail->avail); + pr_debug("ret avail as %zu\n", (size_t)avail->avail); return avail->avail; } =20 static inline size_t snd_compr_get_avail(struct snd_compr_stream *stream) { - struct snd_compr_avail avail; + struct snd_compr_avail64 avail; =20 return snd_compr_calc_avail(stream, &avail); } =20 -static int -snd_compr_ioctl_avail(struct snd_compr_stream *stream, unsigned long arg) +static void snd_compr_avail32_from_64(struct snd_compr_avail *avail32, + const struct snd_compr_avail64 *avail64) { - struct snd_compr_avail ioctl_avail; + avail32->avail =3D avail64->avail; + snd_compr_tstamp32_from_64(&avail32->tstamp, &avail64->tstamp); +} + +static int snd_compr_ioctl_avail(struct snd_compr_stream *stream, + unsigned long arg, bool is_32bit) +{ + struct snd_compr_avail64 ioctl_avail64; + struct snd_compr_avail ioctl_avail32; size_t avail; + const void *copy_from =3D &ioctl_avail64; + size_t copy_size =3D sizeof(ioctl_avail64); =20 if (stream->direction =3D=3D SND_COMPRESS_ACCEL) return -EBADFD; =20 - avail =3D snd_compr_calc_avail(stream, &ioctl_avail); - ioctl_avail.avail =3D avail; + avail =3D snd_compr_calc_avail(stream, &ioctl_avail64); + ioctl_avail64.avail =3D avail; + if (is_32bit) { + snd_compr_avail32_from_64(&ioctl_avail32, &ioctl_avail64); + copy_from =3D &ioctl_avail32; + copy_size =3D sizeof(ioctl_avail32); + } =20 switch (stream->runtime->state) { case SNDRV_PCM_STATE_OPEN: @@ -269,8 +281,7 @@ snd_compr_ioctl_avail(struct snd_compr_stream *stream, = unsigned long arg) break; } =20 - if (copy_to_user((__u64 __user *)arg, - &ioctl_avail, sizeof(ioctl_avail))) + if (copy_to_user((__u64 __user *)arg, copy_from, copy_size)) return -EFAULT; return 0; } @@ -1336,7 +1347,9 @@ static long snd_compr_ioctl(struct file *f, unsigned = int cmd, unsigned long arg) case SNDRV_COMPRESS_TSTAMP64: return snd_compr_tstamp(stream, arg, false); case SNDRV_COMPRESS_AVAIL: - return snd_compr_ioctl_avail(stream, arg); + return snd_compr_ioctl_avail(stream, arg, true); + case SNDRV_COMPRESS_AVAIL64: + return snd_compr_ioctl_avail(stream, arg, false); case SNDRV_COMPRESS_PAUSE: return snd_compr_pause(stream); case SNDRV_COMPRESS_RESUME: --=20 2.50.1.565.gc32cd1483b-goog