diff mbox series

[v3,v4l-utils] common: Use posix_memalign for allocating userptr buffers

Message ID 20240625112425.37172-1-fusibrandon13@gmail.com
State New
Headers show
Series [v3,v4l-utils] common: Use posix_memalign for allocating userptr buffers | expand

Commit Message

Brandon Cheo Fusi June 25, 2024, 11:24 a.m. UTC
When dealing with a userptr pointing to a buffer in userspace,
videobuf2 swaps the corresponding physical pages with other pages
so we have a contiguous area of memory for DMA. This only works if
the userptr is page aligned.

The current way of allocating user buffers using malloc only
guarantees alignment up to `alignof(max_align_t)`, which is usually
16. So replace malloc with posix_memalign to ensure the returned
pointer is on a page boundary.

Signed-off-by: Brandon Cheo Fusi <fusibrandon13@gmail.com>
---
 utils/common/v4l-helpers.h | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

Comments

Hans Verkuil Oct. 17, 2024, 10:51 a.m. UTC | #1
Hi Brandon,

On 25/06/2024 13:24, Brandon Cheo Fusi wrote:
> When dealing with a userptr pointing to a buffer in userspace,
> videobuf2 swaps the corresponding physical pages with other pages
> so we have a contiguous area of memory for DMA. This only works if
> the userptr is page aligned.
> 
> The current way of allocating user buffers using malloc only
> guarantees alignment up to `alignof(max_align_t)`, which is usually
> 16. So replace malloc with posix_memalign to ensure the returned
> pointer is on a page boundary.

With which driver is this tested? USERPTR is really supposed to work
with malloc()ed memory.

There have been drivers in the past that used contiguous DMA but still
allowed USERPTR, but that was a hack and these days you would use DMABUF.

Regards,

	Hans

> 
> Signed-off-by: Brandon Cheo Fusi <fusibrandon13@gmail.com>
> ---
>  utils/common/v4l-helpers.h | 9 +++++----
>  1 file changed, 5 insertions(+), 4 deletions(-)
> 
> diff --git a/utils/common/v4l-helpers.h b/utils/common/v4l-helpers.h
> index cf0e92d..aa9ee26 100644
> --- a/utils/common/v4l-helpers.h
> +++ b/utils/common/v4l-helpers.h
> @@ -1661,10 +1661,11 @@ static inline int v4l_queue_alloc_bufs(struct v4l_fd *f,
>  		return 0;
>  	for (b = from; b < v4l_queue_g_buffers(q); b++) {
>  		for (p = 0; p < v4l_queue_g_num_planes(q); p++) {
> -			void *m = malloc(v4l_queue_g_length(q, p));
> -
> -			if (m == NULL)
> -				return errno;
> +			void *m;
> +			int ret = posix_memalign(&m, getpagesize(),
> +						v4l_queue_g_length(q, p));
> +			if (ret)
> +				return ret;
>  			v4l_queue_s_userptr(q, b, p, m);
>  		}
>  	}
diff mbox series

Patch

diff --git a/utils/common/v4l-helpers.h b/utils/common/v4l-helpers.h
index cf0e92d..aa9ee26 100644
--- a/utils/common/v4l-helpers.h
+++ b/utils/common/v4l-helpers.h
@@ -1661,10 +1661,11 @@  static inline int v4l_queue_alloc_bufs(struct v4l_fd *f,
 		return 0;
 	for (b = from; b < v4l_queue_g_buffers(q); b++) {
 		for (p = 0; p < v4l_queue_g_num_planes(q); p++) {
-			void *m = malloc(v4l_queue_g_length(q, p));
-
-			if (m == NULL)
-				return errno;
+			void *m;
+			int ret = posix_memalign(&m, getpagesize(),
+						v4l_queue_g_length(q, p));
+			if (ret)
+				return ret;
 			v4l_queue_s_userptr(q, b, p, m);
 		}
 	}