Re: [PATCH] v4l2-compliance: detect no-mmu systems

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Dillon,

On 27/11/2021 12:13, Dillon Min wrote:
> Hi Hans,
> 
> On Thu, 25 Nov 2021 at 22:12, Hans Verkuil <hverkuil-cisco@xxxxxxxxx> wrote:
>>
>> On 25/11/2021 14:33, Dillon Min wrote:
>>> Hi Hans,
>>>
>>> On Thu, 25 Nov 2021 at 21:14, Hans Verkuil <hverkuil-cisco@xxxxxxxxx> wrote:
>>>>
>>>> Check if the OS has an MMU. If not, then skip tests that only work for
>>>> systems that have an MMU.
>>>>
>>>> The safest and most generic method I found is the FIONBIO ioctl that is
>>>> available for any file descriptor and is a write-only ioctl, so no memory
>>>> will be accidentally written. On a MMU system this will return EFAULT, and
>>>> on a ucLinux system this will return 0.
>>>>
>>>> Signed-off-by: Hans Verkuil <hverkuil-cisco@xxxxxxxxx>
>>>> ---
>>>> Dillon, the original RFC patch (1) I posted to fix this in the kernel is not
>>>> the correct method. See:
>>>>
>>>> https://stackoverflow.com/questions/24755103/how-to-handle-null-pointer-argument-to-ioctl-system-call
>>>
>>> Thanks for the detailed information.
>>>
>>>>
>>>> So instead I try to detect if there is an MMU in v4l2-compliance and, if not,
>>>> just skip those tests that require an MMU.
>>>>
>>>> Can you test this patch?
>>>
>>> Sure, I'll test it then update the result.
>>
>> Note that v4l2-compliance should say at the top that it detects a no-MMU system:
>>
>>>> @@ -152,8 +153,21 @@ static struct option long_options[] = {
>>>>
>>>>  static void print_sha()
>>>>  {
>>>> +       int fd = open("/dev/null", O_RDONLY);
>>>> +
>>>> +       if (fd >= 0) {
>>>> +               // FIONBIO is a write-only ioctl that takes an int argument that
>>>> +               // enables (!= 0) or disables (== 0) nonblocking mode of a fd.
>>>> +               //
>>>> +               // Passing a nullptr should return EFAULT on MMU capable machines,
>>>> +               // and it works if there is no MMU.
>>>> +               has_mmu = ioctl(fd, FIONBIO, nullptr);
>>>> +               close(fd);
>>>> +       }
>>>>         printf("v4l2-compliance %s%s, ", PACKAGE_VERSION, STRING(GIT_COMMIT_CNT));
>>>> -       printf("%zd bits, %zd-bit time_t\n", sizeof(void *) * 8, sizeof(time_t) * 8);
>>>> +       printf("%zd bits, %zd-bit time_t%s\n",
>>>> +              sizeof(void *) * 8, sizeof(time_t) * 8,
>>>> +              has_mmu ? "" : ", has no MMU");
>>
>>                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>>
>> Please verify that it actually does that. I hope it does :-)
> 
> Yes, it works.

Thank you for testing this. I merged this patch.

> 
> ~ # v4l2-compliance -f -d /dev/video0
> v4l2-compliance 1.23.0-4896, 32 bits, 32-bit time_t, has no MMU
> v4l2-compliance SHA: 7858281c1cd1 2021-11-27 09:43:32
> 
> Compliance test for stm-dma2d device /dev/video0:
> 
> I added some extra changes for v4l-utils to make the configure step
> working on no-mmu platform, just share here , my change just make the
> compiler happy, i guess you have a more correct way here: )

Can you post this as a separate patch to the mailinglist? That makes it
easier to handle.

Note that fork can't be converted to vfork in v4l2-test-controls.cpp, so
instead it needs to know if fork is available and put the test under a
#ifdef HAVE_FORK or something like that.

Regards,

	Hans

> 
> - add --without-argp options for configure.
> 
> diff --git a/configure.ac b/configure.ac
> index 0529898..3e87b5a 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -330,14 +330,23 @@ dl_saved_libs=$LIBS
>    AC_SUBST([DLOPEN_LIBS])
>  LIBS=$dl_saved_libs
> 
> -AC_CHECK_HEADER([argp.h],,AC_MSG_ERROR(Cannot continue: argp.h not found))
> +AC_ARG_WITH([argp],
> +           AS_HELP_STRING([--without-argp], [Do not use argp.h]),
> +           [],
> +           [with_argp=yes])
>  argp_saved_libs=$LIBS
> -  AC_SEARCH_LIBS([argp_parse],
> -                 [argp],
> -                 [test "$ac_cv_search_argp_parse" = "none required"
> || ARGP_LIBS=$ac_cv_search_argp_parse],
> -                 [AC_MSG_ERROR([unable to find the argp_parse() function])])
> -  AC_SUBST([ARGP_LIBS])
> +AS_IF([test "x$with_argp" != xno],
> +      [
> +               AC_CHECK_HEADER([argp.h],,AC_MSG_ERROR(Cannot
> continue: argp.h not found))]
> +      AC_SEARCH_LIBS([argp_parse],
> +                    [argp],
> +                    [test "$ac_cv_search_argp_parse" = "none
> required" || ARGP_LIBS=$ac_cv_search_argp_parse],
> +                    [AC_MSG_ERROR([unable to find the argp_parse() function])])
> +      AC_SUBST([ARGP_LIBS])
> +      ],
> +      )
>  LIBS=$argp_saved_libs
> +AM_CONDITIONAL([HAVE_ARGP], [test "x$with_argp" != xno])
> 
>  AC_CHECK_FUNCS([fork],
> AC_DEFINE([HAVE_LIBV4LCONVERT_HELPERS],[1],[whether to use
> libv4lconvert helpers]))
>  AM_CONDITIONAL([HAVE_LIBV4LCONVERT_HELPERS], [test x$ac_cv_func_fork = xyes])
> @@ -561,7 +570,7 @@ AM_CONDITIONAL([WITH_GCONV],        [test
> x$enable_gconv = xyes -a x$enable_shar
>  AM_CONDITIONAL([WITH_V4L2_CTL_LIBV4L], [test
> x${enable_v4l2_ctl_libv4l} != xno])
>  AM_CONDITIONAL([WITH_V4L2_CTL_STREAM_TO], [test
> x${enable_v4l2_ctl_stream_to} != xno])
>  AM_CONDITIONAL([WITH_V4L2_CTL_32], [test x${enable_v4l2_ctl_32} = xyes])
> -AM_CONDITIONAL([WITH_V4L2_COMPLIANCE], [test x$ac_cv_func_fork = xyes])
> +AM_CONDITIONAL([WITH_V4L2_COMPLIANCE], [test x$ac_cv_func_fork = xno])
>  AM_CONDITIONAL([WITH_V4L2_COMPLIANCE_LIBV4L], [test x$ac_cv_func_fork
> = xyes -a x${enable_v4l2_compliance_libv4l} != xno])
>  AM_CONDITIONAL([WITH_V4L2_COMPLIANCE_32], [test x$ac_cv_func_fork =
> xyes -a x${enable_v4l2_compliance_32} = xyes])
>  PKG_CHECK_MODULES([LIBBPF], [libbpf], [bpf_pc=yes], [bpf_pc=no])
> diff --git a/contrib/test/Makefile.am b/contrib/test/Makefile.am
> index 5771ee4..8197e6d 100644
> --- a/contrib/test/Makefile.am
> +++ b/contrib/test/Makefile.am
> @@ -2,9 +2,7 @@ noinst_PROGRAMS = \
>         ioctl-test              \
>         sliced-vbi-test         \
>         sliced-vbi-detect       \
> -       v4l2grab                \
>         driver-test             \
> -       mc_nextgen_test         \
>         stress-buffer           \
>         capture-example
> 
> @@ -13,8 +11,15 @@ noinst_PROGRAMS += pixfmt-test
>  endif
> 
>  if HAVE_GLU
> +if HAVE_ARGP
>  noinst_PROGRAMS += v4l2gl
>  endif
> +endif
> +
> +if HAVE_ARGP
> +noinst_PROGRAMS += mc_nextgen_test.c \
> +                  v4l2grab
> +endif
> 
> - change fork to vfork
> 
> diff --git a/utils/v4l2-compliance/v4l2-test-controls.cpp
> b/utils/v4l2-compliance/v4l2-test-controls.cpp
> index 8731c9e..68b2c92 100644
> --- a/utils/v4l2-compliance/v4l2-test-controls.cpp
> +++ b/utils/v4l2-compliance/v4l2-test-controls.cpp
> @@ -978,7 +978,7 @@ int testVividDisconnect(struct node *node)
>         // This can only be tested with the vivid driver that enabled
>         // the DISCONNECT control.
> 
> -       pid_t pid = fork();
> +       pid_t pid = vfork();
>         if (pid == 0) {
>                 struct timeval tv = { 5, 0 };
>                 fd_set fds;
> @@ -1010,7 +1010,7 @@ int testVividDisconnect(struct node *node)
> 
>         node->reopen();
> 
> -       pid = fork();
> +       pid = vfork();
>         if (pid == 0) {
>                 struct epoll_event ep_ev;
>                 int epollfd = epoll_create1(0);
> 
> Best Regards
> Dillon
> 
>>
>> Regards,
>>
>>         Hans
>>
>>>>         if (strlen(STRING(GIT_SHA)))
>>>>                 printf("v4l2-compliance SHA: %s %s\n",
>>>>                        STRING(GIT_SHA), STRING(GIT_COMMIT_DATE));




[Index of Archives]     [Linux Input]     [Video for Linux]     [Gstreamer Embedded]     [Mplayer Users]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux