From nobody Tue Sep 9 21:32:25 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 E905F3002C4 for ; Fri, 5 Sep 2025 09:13:20 +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=1757063605; cv=none; b=p5hGWJUi6zeOzBVkge9GWCTSz+sbxnJYp7zmv6HDc0Gg20OFFYQ9VuccDbY7kgTUYqyMeV0oczqihqL2Hwt5Y4+H5O4bOta3FqEatnjk4F8QUxYm74LFtRwZAJJVjVm9Z/Dqr2kGQDr1SZQJJqgAnD0MQt+jsXyivhlE6L6YDM0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757063605; c=relaxed/simple; bh=Frd6GwooSdof8nNuNZxHvBdVaTZx4Y7N1yIn2UIPA8s=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=kBp8jWpfP5PsAtoxxKaxjD0LReiQCcs/bje4uKzGA8fQQPmrGVNqHJ0pd7+OBuBsVyeqODA7DP4E10+cf+w3yfvmkkq9HxsYBrv+vMBUHMUOAnHkRBkuZm6pqqYAOZIWp3pntFIJa0B2RmDvijbgnVBS5xaqcC5705XNFT0HlPo= 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=I5blnMG5; 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="I5blnMG5" Received: by mail-wr1-f73.google.com with SMTP id ffacd0b85a97d-3dbc72f8d32so872205f8f.3 for ; Fri, 05 Sep 2025 02:13:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1757063599; x=1757668399; 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=NCARSp5yJZb29xruE4z/z8womRw9NZliJ8kFXxzlGko=; b=I5blnMG5b9nGG03OZgU/14VHGgsG45oXDEwDWGsMwCbUQLwyjmmVM39DiInNwmcNR4 PMRjqC/TywLcXnoggEoF27zYHFIMCrbey72hBPsqgSr7vlyvQaH3TCX5GMuijzkpkIzd sWW4HwP74GU+B/cvu4FZ2Khiy3xTnAbQgNMT8MKJmvFKyqXfRBHKp3xgpUpuzXzmNeVM oZLbw1f0/9XrBnUKU2qL4FtsLV1Xm/S5SX/H8fy3Jaurv8IZu31KZdbPKfDivVFkvUBB 1Pam51ZLMhp/49FQ1zVZ3S5fbr3JqTLQTdn1+67VqaGEpx6Faq5RFbsiUpDSTVhzUmu8 4GCw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1757063599; x=1757668399; 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=NCARSp5yJZb29xruE4z/z8womRw9NZliJ8kFXxzlGko=; b=bR8hIJ029hrMPyKqeK/Ya8PobGm83MRXfCo5tsJVfM6qNq/ikozNxdbsKE4MKBSGuK mAZs0LY8n4IgRGao/fDXBFzn8P6Nf4actcMfP85tH1r8lxkp5R9frCzPpJcCqlqGFGLV cdYF4/9Y+TlmsIqTIpw8zAKDOEj8cZ0qQTSmyCThtFJHYXBky0mQNTjakLg5dXyPDtiF aTAlgoosc0OGMnpRjIvNSXpmtGEvH7GeVcAhbRl2YRaBnYYMEHo1GRn8TIh7TLfJLuKH ocpQoYd4/M4lDNUGtU2nN8AvkbpxU0Ds/NXVUju7gxCpUvuEQdqjmOAR1JhbDsEfPF/X yfJA== X-Forwarded-Encrypted: i=1; AJvYcCUdYG2U4Q+kjRN1W4y6S+JMp0QKSaqbSwpktcnOSkIMJvZ32I4JzNFufh+/ErMN7IfsCWBw71HhDhahNIA=@vger.kernel.org X-Gm-Message-State: AOJu0Yzpu1Ug3IE+n33kW+J9WJeCkIJ7doTlykTNVZHWfXFDaIlyHAWu /cxe9Wvpu1iDwt+EuE9Vknei8cAERPc1q1AYwEI7j2X6Vc4b7y+mdiaryqmurK8ZmSJVUX505xA V5zXAdpAnNmX92UPPyw== X-Google-Smtp-Source: AGHT+IFdjvd9YbF0LcsgygdwtjQqTzmMXnepimvtU+wFccNiQypo0RTmhnJrFKgdq8koqsxYDuFij8iqC4+bjOo= X-Received: from wrbck9.prod.google.com ([2002:a5d:5e89:0:b0:3df:219:ab7f]) (user=verhaegen job=prod-delivery.src-stubby-dispatcher) by 2002:a05:6000:2f84:b0:3e4:74dc:a3bb with SMTP id ffacd0b85a97d-3e474dcd583mr659094f8f.40.1757063599157; Fri, 05 Sep 2025 02:13:19 -0700 (PDT) Date: Fri, 5 Sep 2025 10:12:54 +0100 In-Reply-To: <20250905091301.2711705-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: <20250905091301.2711705-1-verhaegen@google.com> X-Mailer: git-send-email 2.51.0.355.g5224444f11-goog Message-ID: <20250905091301.2711705-2-verhaegen@google.com> Subject: [PATCH v5 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 Acked-by: Vinod Koul Reviewed-by: Charles Keepax Reviewed-by: Srinivas Kandagatla --- 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.51.0.355.g5224444f11-goog From nobody Tue Sep 9 21:32:25 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 2AADB30EF75 for ; Fri, 5 Sep 2025 09:13:27 +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=1757063609; cv=none; b=N03E7nUT49l6dvEfA/leiMoKHinYy/IwxsgFXqJ9QS/2aJ0Lr8t1CTvQ/fhrZA/Oev4QNz4HWqq7LORwVw2V97HzmZ2XR6ht7aSQm4Fyh5CZPPXW2JL+V+PJjJWYThhq+c5OXNrutwsCPMSAmdGnGSZgHXegg6JHfvQy7gwY6Mw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757063609; c=relaxed/simple; bh=iVtonefOAPJJXtXEymU00/Wa/QjhOPoMWLVIP8oLduE=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=tz+5VnBHGwdI+QbDtu7OQ/wycKZuYZk8fGrXd0MbxucLJCPUveFEktzPYiQ8P5KKRSHDmJbQMq0h5q6Vr2+Hd/5UYFL/Eo5+bqbSbBJ827M7MSYf8rjK/XfRhy/UlYf7gfvw4lH6Y/C2ptd3fRzkAcvO+Fujy1puQ1AYqXy+Rwk= 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=kano0pk1; 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="kano0pk1" Received: by mail-wr1-f73.google.com with SMTP id ffacd0b85a97d-3dacc10dd30so1384508f8f.0 for ; Fri, 05 Sep 2025 02:13:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1757063606; x=1757668406; 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=xDPGzsxAKKvH1GDMNj6CwOgMXSMzqp7fsMOzyvpH+nA=; b=kano0pk1+hMhCc4RkeuPGa4SbmPwSSP7TiBVaYCOdixCs5ysj+q3qvACCc+41dpg3j 2I5GNWasURk4YxZTxh3Qal2+F2bTPF+vwV1VGCBNdj8gc8GvTG7sApZKlDr0k+gmgK7w GTNGtf0i4hWOQEo7Ww+CAKYmp/PRH98Hiw32Td+gu+DInKnUnQo9kZ9p98QPMpspAhaQ 1KHNvs5yX/OrPN5T1r/uNuDHWVw9IVPkV4uRViuItzRoKeJcg0TERXSR8s1LKcDH5gCC fCUjBNKv3mkUjHB6UMEXXlP5FcJydlGoRBTiRFK96sAVGlIRz9W6GLaXDLxAr+Ewkiw0 yDiw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1757063606; x=1757668406; 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=xDPGzsxAKKvH1GDMNj6CwOgMXSMzqp7fsMOzyvpH+nA=; b=jlHWI9xbi4inA/q5DwcltV0PqMvt8iaB+dcGOr11N8Br9BkwI3cZjnptu9/vVFw134 QWGByKLhckM5s3NBArJXBwBz2IgsoGw2eAzSHVaK1pH5FK1pytWvfX33zsZK3giWIv3I J8Az5DE0iExMAyDGBiCX8dvnD4gGXXcB5Meu0aXBGAtF3FEG1OFHh/bCicVckWDeeN+O w3/IemqO5ItBsYkCQBt/E5M184571iU7PTJzC7VJDFUpLc3kl63MZCB3Ozei6F9KQ4Xg 0tx7BY3doLi1/rjHtiw1anaiRqhNLNrNRCe6zTZS/YgLqWsiiJ9Swb7KP3yazHG/uDbY xPhw== X-Forwarded-Encrypted: i=1; AJvYcCVgFT16oouu9cz6U4IpO0BzFB/JxnJxK1OXpl3Oc1Qm4PPZf/cPUtaTZdHYrI0FJdfoQwbjf76L+IUAjF4=@vger.kernel.org X-Gm-Message-State: AOJu0YxfFh9mc6AekCytQqNakebJzvrhMJRopOrVsUSAuXRPnxTGDfgM Wm56Lo+eb8YNxGSTAD+uIy2rLp1XbCZKLXAac8PKfMGiS6EeNmxyazzyf+kBnJX1BZrucCn4xKL MEZ/fGYsbpTTjxHUM9Q== X-Google-Smtp-Source: AGHT+IEyDlexP0RAVrpJVCl0chgZCWyPtv6v1WIav3zbUk2uYgIv0ZwyKau6Sc8ZZDKm6Mlu1EdrYFeaxTOrcP8= X-Received: from wmby11-n1.prod.google.com ([2002:a05:600c:c04b:10b0:45d:d179:882f]) (user=verhaegen job=prod-delivery.src-stubby-dispatcher) by 2002:a5d:5849:0:b0:3b7:9929:871c with SMTP id ffacd0b85a97d-3d1de5b09e9mr15575101f8f.37.1757063606306; Fri, 05 Sep 2025 02:13:26 -0700 (PDT) Date: Fri, 5 Sep 2025 10:12:55 +0100 In-Reply-To: <20250905091301.2711705-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: <20250905091301.2711705-1-verhaegen@google.com> X-Mailer: git-send-email 2.51.0.355.g5224444f11-goog Message-ID: <20250905091301.2711705-3-verhaegen@google.com> Subject: [PATCH v5 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 Acked-by: Vinod Koul 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.51.0.355.g5224444f11-goog From nobody Tue Sep 9 21:32:25 2025 Received: from mail-wr1-f74.google.com (mail-wr1-f74.google.com [209.85.221.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 76DDC30FC37 for ; Fri, 5 Sep 2025 09:13:36 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.74 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757063619; cv=none; b=g13nJqzd2VyUt8ydclcGVVtfTxZh+S+W7LLn5RPl7QICQ3ereNK+KFQBw3kik8YRR4MqWWt95d61bQAYyRcWWlLcyZYcsbdItu6qm+hXPP0sxmW6IGQtkpNTZZvBaNeNnSEMNEZAH40B1LZTCwSv//xVGH/cr1GGtjLCPPb5nTU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1757063619; c=relaxed/simple; bh=WzkaNV8OtrI5d68Jyxcv4C4JfQgfogIX2PIoGse17I0=; h=Date:In-Reply-To:Mime-Version:References:Message-ID:Subject:From: To:Cc:Content-Type; b=bCu/7QkxFiRGwDkrFyjr0QfN81gs1DGbHSKllZttRqWJpgPCazBo6likO4VVdcEQSeHzhRf1ZpBgzMK8RfRnhzObLofo+kjkNL3HSRDHob5NKKcD4JImw2QjUevHwzwKUv4Fyi0MVQdJeutAquxXJEKCgQWVp/D9Lz0losYhNfc= 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=qIrU7gYy; arc=none smtp.client-ip=209.85.221.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="qIrU7gYy" Received: by mail-wr1-f74.google.com with SMTP id ffacd0b85a97d-3df19a545c2so1216549f8f.3 for ; Fri, 05 Sep 2025 02:13:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20230601; t=1757063615; x=1757668415; 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=qe+QtpliqDAu4G9UaaRGSX2jMJxjWrnOYF63McD9Po4=; b=qIrU7gYyNNJ3tpKRwGAJeqkQYbwA+bY9+PXet7mxAAiBImV5JJc7PNm1KCD9Npzlzp d1hdxvqacJfeOyi4uS9QWoLChUAfWjBMa6vCNaP7Cr5wltKEThb5FnJUNNB71cNbC4Od WeLzBkSeyHcdrMz7B1+tmXluhL/R3ijrx/Pm099qQ8QOzt68CpzVjqyZCg9rwuKN/9Tk kTuYpqxJ7xn2twPH/ioE2Tvlqp96oeeDejWIjLExJnLPiLBRLlK8lhWPhF5AKdTzwH0j ezK8lJR3l6+UhfsdI2aynuDLVlfSH28YqNSripattjfHPzzXd2DWwy/jxqM9B7U1kfMa 9MUA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1757063615; x=1757668415; 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=qe+QtpliqDAu4G9UaaRGSX2jMJxjWrnOYF63McD9Po4=; b=s6cD4Qyp1jyYyKBOEwz1CEMkWAPQlLFQ3fi5cxCaW2f00rVoiTARNOVMBDd+4f4TK+ IwbuT2HYVKnigAjDq3Fzteo209/gQkncTaWBQ4c80+yevbZ48qoQbOpwYrnViMYtXKEN diHD5aUL7a2GdXR01AG65BDjioGb4dtpNpN9B1btmS+0Aou6WMoxPagh4wFyplcooZXp 7gMpynbqXJoVF/4CjQSLx9Szhuy7QKJQheMYHT6mphTa/jYwmx/oZvKIrGAvnVmf97cQ 9rVV2ApR9XyaOQFNcFxjc7XOXJepr642ELJtatusbJARw2lqkzD08SQNYSbDvBW+bup0 O0qA== X-Forwarded-Encrypted: i=1; AJvYcCWFdG1olbjv+seN/VwmvxWZDRovuPtiivtFrQ6FdNUog814i8WkAcOpt5TgEvvCAjaajL7oilmmvE8fLRM=@vger.kernel.org X-Gm-Message-State: AOJu0YwvcV2sm4UnlRM9MppCuOEo6YRYyhMSDaBFP3uAXBVvqXulJJnk WdYxM313sEXUNXRgTSsoLbPo6+N71jmdoAD4Xvik58y/OmfYfgy//JNNlJJAzDMDxTE81vvrTz0 ZSIoQatrPCSl+GdJlzA== X-Google-Smtp-Source: AGHT+IH6GdtZv6WB+m8+2uS3LHU1bwHgtnfflqQnjRCwjq5u4fTUKo/2dMs3/H7tVXLO84nhyhg5xInyYI4bI6o= X-Received: from wmbhg18.prod.google.com ([2002:a05:600c:5392:b0:45d:cfd2:c531]) (user=verhaegen job=prod-delivery.src-stubby-dispatcher) by 2002:adf:a3da:0:b0:3d2:2989:224 with SMTP id ffacd0b85a97d-3d229892c7dmr11529562f8f.7.1757063614797; Fri, 05 Sep 2025 02:13:34 -0700 (PDT) Date: Fri, 5 Sep 2025 10:12:56 +0100 In-Reply-To: <20250905091301.2711705-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: <20250905091301.2711705-1-verhaegen@google.com> X-Mailer: git-send-email 2.51.0.355.g5224444f11-goog Message-ID: <20250905091301.2711705-4-verhaegen@google.com> Subject: [PATCH v5 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 Acked-by: Vinod Koul Reviewed-by: Charles Keepax --- include/uapi/sound/compress_offload.h | 11 +++++++ sound/core/compress_offload.c | 43 +++++++++++++++++---------- 2 files changed, 39 insertions(+), 15 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..da514fef45bc 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 && @@ -237,28 +234,43 @@ static size_t snd_compr_calc_avail(struct snd_compr_s= tream *stream, 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.51.0.355.g5224444f11-goog