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 <millerliang@google.com>
Tested-by: Joris Verhaegen <verhaegen@google.com>
Signed-off-by: Joris Verhaegen <verhaegen@google.com>
---
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/compress_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)));
+/**
+ * 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 = 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_stream *stream,
}
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 = { 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 */
if (stream->runtime->total_bytes_available == 0 &&
@@ -233,32 +230,47 @@ static size_t snd_compr_calc_avail(struct snd_compr_stream *stream,
}
avail->avail = stream->runtime->total_bytes_available -
- stream->runtime->total_bytes_transferred;
+ stream->runtime->total_bytes_transferred;
if (stream->direction == SND_COMPRESS_PLAYBACK)
avail->avail = stream->runtime->buffer_size - avail->avail;
- pr_debug("ret avail as %llu\n", avail->avail);
+ pr_debug("ret avail as %zu\n", (size_t)avail->avail);
return avail->avail;
}
static inline size_t snd_compr_get_avail(struct snd_compr_stream *stream)
{
- struct snd_compr_avail avail;
+ struct snd_compr_avail64 avail;
return snd_compr_calc_avail(stream, &avail);
}
-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 = 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 = &ioctl_avail64;
+ size_t copy_size = sizeof(ioctl_avail64);
if (stream->direction == SND_COMPRESS_ACCEL)
return -EBADFD;
- avail = snd_compr_calc_avail(stream, &ioctl_avail);
- ioctl_avail.avail = avail;
+ avail = snd_compr_calc_avail(stream, &ioctl_avail64);
+ ioctl_avail64.avail = avail;
+ if (is_32bit) {
+ snd_compr_avail32_from_64(&ioctl_avail32, &ioctl_avail64);
+ copy_from = &ioctl_avail32;
+ copy_size = sizeof(ioctl_avail32);
+ }
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;
}
- 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:
--
2.50.1.565.gc32cd1483b-goog
On 01-08-25, 10:27, Joris Verhaegen wrote: > 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 <millerliang@google.com> > Tested-by: Joris Verhaegen <verhaegen@google.com> > Signed-off-by: Joris Verhaegen <verhaegen@google.com> > --- > 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/compress_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))); > > +/** > + * 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 = 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_stream *stream, > } > > 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 = { 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 */ > > if (stream->runtime->total_bytes_available == 0 && > @@ -233,32 +230,47 @@ static size_t snd_compr_calc_avail(struct snd_compr_stream *stream, > } > > avail->avail = stream->runtime->total_bytes_available - > - stream->runtime->total_bytes_transferred; > + stream->runtime->total_bytes_transferred; Lets not do formatting changes in current patch please > if (stream->direction == SND_COMPRESS_PLAYBACK) > avail->avail = stream->runtime->buffer_size - avail->avail; > > - pr_debug("ret avail as %llu\n", avail->avail); > + pr_debug("ret avail as %zu\n", (size_t)avail->avail); > return avail->avail; > } > > static inline size_t snd_compr_get_avail(struct snd_compr_stream *stream) > { > - struct snd_compr_avail avail; > + struct snd_compr_avail64 avail; > > return snd_compr_calc_avail(stream, &avail); > } > > -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 = 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 = &ioctl_avail64; > + size_t copy_size = sizeof(ioctl_avail64); > > if (stream->direction == SND_COMPRESS_ACCEL) > return -EBADFD; > > - avail = snd_compr_calc_avail(stream, &ioctl_avail); > - ioctl_avail.avail = avail; > + avail = snd_compr_calc_avail(stream, &ioctl_avail64); > + ioctl_avail64.avail = avail; > + if (is_32bit) { > + snd_compr_avail32_from_64(&ioctl_avail32, &ioctl_avail64); > + copy_from = &ioctl_avail32; > + copy_size = sizeof(ioctl_avail32); > + } Same comment as previous patch > > 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; > } > > - 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: > -- > 2.50.1.565.gc32cd1483b-goog -- ~Vinod
On Tue, 5 Aug 2025 at 06:50, Vinod Koul <vkoul@kernel.org> wrote: > > 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 = { 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 */ > > > > if (stream->runtime->total_bytes_available == 0 && > > @@ -233,32 +230,47 @@ static size_t snd_compr_calc_avail(struct snd_compr_stream *stream, > > } > > > > avail->avail = stream->runtime->total_bytes_available - > > - stream->runtime->total_bytes_transferred; > > + stream->runtime->total_bytes_transferred; > > Lets not do formatting changes in current patch please I'm happy to revert the formatting changes. Are you only referring to the alignment of the subtraction operation (avail->avail), or something else too? Note that the second line of the function signature of snd_compr_calc_avail got re-aligned by clang-format due to an actual change (type change to struct snd_compr_avail64) so I assume the re-alignment here is OK, but please confirm. > > if (stream->direction == SND_COMPRESS_PLAYBACK) > > avail->avail = stream->runtime->buffer_size - avail->avail; > > > > - pr_debug("ret avail as %llu\n", avail->avail); > > + pr_debug("ret avail as %zu\n", (size_t)avail->avail); > > return avail->avail; > > } > > > > static inline size_t snd_compr_get_avail(struct snd_compr_stream *stream) > > { > > - struct snd_compr_avail avail; > > + struct snd_compr_avail64 avail; > > > > return snd_compr_calc_avail(stream, &avail); > > } > > > > -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 = 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 = &ioctl_avail64; > > + size_t copy_size = sizeof(ioctl_avail64); > > > > if (stream->direction == SND_COMPRESS_ACCEL) > > return -EBADFD; > > > > - avail = snd_compr_calc_avail(stream, &ioctl_avail); > > - ioctl_avail.avail = avail; > > + avail = snd_compr_calc_avail(stream, &ioctl_avail64); > > + ioctl_avail64.avail = avail; > > + if (is_32bit) { > > + snd_compr_avail32_from_64(&ioctl_avail32, &ioctl_avail64); > > + copy_from = &ioctl_avail32; > > + copy_size = sizeof(ioctl_avail32); > > + } > > Same comment as previous patch As agreed in the previous patch, will leave as is. Thanks, George
© 2016 - 2025 Red Hat, Inc.