[LTP] [PATCH v4 3/3] syscalls/pipe2_03: Add new test for pipe2 O_DIRECT flag

Yang Xu xuyang2018.jy@cn.fujitsu.com
Thu Apr 23 10:45:00 CEST 2020


Hi Li

> 
> 
> On Wed, Apr 22, 2020 at 6:47 PM Yang Xu <xuyang2018.jy@cn.fujitsu.com 
> <mailto:xuyang2018.jy@cn.fujitsu.com>> wrote:
> 
>     Signed-off-by: Yang Xu <xuyang2018.jy@cn.fujitsu.com
>     <mailto:xuyang2018.jy@cn.fujitsu.com>>
>     ---
>       runtest/syscalls                           |   1 +
>       testcases/kernel/syscalls/pipe2/.gitignore |   1 +
>       testcases/kernel/syscalls/pipe2/pipe2_03.c | 172 +++++++++++++++++++++
>       3 files changed, 174 insertions(+)
>       create mode 100644 testcases/kernel/syscalls/pipe2/pipe2_03.c
> 
>     diff --git a/runtest/syscalls b/runtest/syscalls
>     index 9bb72beb2..16add02d3 100644
>     --- a/runtest/syscalls
>     +++ b/runtest/syscalls
>     @@ -916,6 +916,7 @@ pipe13 pipe13
> 
>       pipe2_01 pipe2_01
>       pipe2_02 pipe2_02
>     +pipe2_03 pipe2_03
>       pipe2_04 pipe2_04
> 
>       pivot_root01 pivot_root01
>     diff --git a/testcases/kernel/syscalls/pipe2/.gitignore
>     b/testcases/kernel/syscalls/pipe2/.gitignore
>     index 773450a48..ede1da65e 100644
>     --- a/testcases/kernel/syscalls/pipe2/.gitignore
>     +++ b/testcases/kernel/syscalls/pipe2/.gitignore
>     @@ -1,3 +1,4 @@
>       /pipe2_01
>       /pipe2_02
>     +/pipe2_03
>       /pipe2_04
>     diff --git a/testcases/kernel/syscalls/pipe2/pipe2_03.c
>     b/testcases/kernel/syscalls/pipe2/pipe2_03.c
>     new file mode 100644
>     index 000000000..0314f9eda
>     --- /dev/null
>     +++ b/testcases/kernel/syscalls/pipe2/pipe2_03.c
>     @@ -0,0 +1,172 @@
>     +// SPDX-License-Identifier: GPL-2.0-or-later
>     +/*
>     + * Copyright (c) 2020 FUJITSU LIMITED. All rights reserved.
>     + * Author: Yang Xu <xuyang2018.jy@cn.fujitsu.com
>     <mailto:xuyang2018.jy@cn.fujitsu.com>>
>     + *
>     + * This case is designed to test the basic functionality about the
>     + * O_DIRECT flag of pipe2.
>     + *
>     + * It includes three sub tests.
>     + * 1) Each write(2) to the pipe is dealt with as a separate packet, and
>     + * read(2)s from the pipe will read one packet at a time.
>     + * 2) Writes of greater than PIPE_BUF bytes (see pipe(7)) will be split
>     + * into multiple packet.
>     + * 3)If a read(2) specifies a buffer size that is smaller than the next
>     + * packet, then the requested number of bytes are read, and the excess
>     + * bytes in the packet are discarded.
>     + */
>     +#define _GNU_SOURCE
>     +#include <stdio.h>
>     +#include <unistd.h>
>     +#include <stdlib.h>
>     +#include <linux/limits.h>
>     +#include "lapi/fcntl.h"
>     +#include "tst_test.h"
>     +
>     +static int fds[2], packet_num, pipe_size;
>     +static char *wrbuf;
>     +static char *rdbuf;
>     +static void check_peer_rw(void);
>     +static void check_split(void);
>     +static void check_discard(void);
>     +
>     +static void (*test_func[])(void) = {check_peer_rw, check_split,
>     check_discard};
>     +
>     +static void check_peer_rw(void)
>     +{
>     +       int i, pid;
>     +
>     +       SAFE_PIPE2(fds, O_DIRECT | O_NONBLOCK);
>     +
>     +       pid = SAFE_FORK();
>     +       if (!pid) {
>     +               SAFE_CLOSE(fds[1]);
>     +               memset(rdbuf, 0, pipe_size);
>     +               TST_CHECKPOINT_WAIT(0);
>     +               for (i = 0; i < packet_num; i++) {
>     +                       TEST(SAFE_READ(0, fds[0], rdbuf, pipe_size));
>     +                       if (TST_RET != 1)
>     +                               tst_res(TFAIL,
>     +                                       "Each read(2) doesn't read a
>     separate packet, return %ld", TST_RET);
>     +               }
>     +               tst_res(TPASS, "Each read(2) reads a separate packet");
>     +                _exit(0);
>     +       }
>     +
>     +       SAFE_CLOSE(fds[0]);
>     +       for (i = 0; i < packet_num; i++)
>     +               SAFE_WRITE(1, fds[1], "x", 1);
>     +
> 
> 
> I got a failure on the ppc64le platform(page size: 65536kB).
> 
> # ./pipe2_03
> tst_test.c:1246: INFO: Timeout per run is 0h 05m 00s
> pipe_size = 1048576
> PIPE_BUF = 4096
> packet_num = 256
> safe_macros.c:457: BROK: pipe2_03.c:58: 
> write(4,0x1001d2b8,18446744073709551615) failed: EAGAIN/EWOULDBLOCK (11)
I think we should remove PIPE_BUF and use page_size  because we use a 
page to store data not a fixed size buffer in kernel. as below(also, 
man-pages[1] is need to update):

-#include <linux/limits.h>
  #include "lapi/fcntl.h"
  #include "tst_test.h"

-static int fds[2], packet_num, pipe_size;
+static int fds[2], packet_num, pipe_size, page_size;
  static char *wrbuf;
  static char *rdbuf;
  static void check_peer_rw(void);
@@ -84,15 +83,15 @@ static void check_split(void)
                 TST_CHECKPOINT_WAIT(0);
                 for (i = 0; i < 2; i++) {
                         TEST(SAFE_READ(0, fds[0], rdbuf, pipe_size));
-                       if (TST_RET != PIPE_BUF)
+                       if (TST_RET != page_size)
                                 tst_res(TFAIL,
-                                       "write(higner than PIPE_BUF) 
split into multiple packet, return %ld", TST_RET);
+                                       "write(higner than page_size) 
split into multiple packet, return %ld", TST_RET);
                 }
-               tst_res(TPASS, "write(higner than PIPE_BUF) split into 
multiple packet");
+               tst_res(TPASS, "write(higner than page_size) split into 
multiple packet");
                  _exit(0);
         }
         SAFE_CLOSE(fds[0]);
-       SAFE_WRITE(1, fds[1], wrbuf, PIPE_BUF * 2);
+       SAFE_WRITE(1, fds[1], wrbuf, page_size * 2);
         TST_CHECKPOINT_WAKE(0);
         tst_reap_children();
         SAFE_CLOSE(fds[1]);
@@ -126,7 +125,7 @@ static void check_discard(void)
                  _exit(0);
         }
         SAFE_CLOSE(fds[0]);
-       SAFE_WRITE(1, fds[1], wrbuf, PIPE_BUF);
+       SAFE_WRITE(1, fds[1], wrbuf, page_size);
         SAFE_WRITE(1, fds[1], "1", 1);
         TST_CHECKPOINT_WAKE(0);
         tst_reap_children();
@@ -142,10 +141,11 @@ static void setup(void)
  {
         SAFE_PIPE2(fds, O_DIRECT);
         pipe_size = SAFE_FCNTL(fds[1], F_GETPIPE_SZ);
-       wrbuf = SAFE_MALLOC(PIPE_BUF * 2);
+       page_size = getpagesize();
+       wrbuf = SAFE_MALLOC(page_size * 2);
         rdbuf = SAFE_MALLOC(pipe_size);
-       memset(wrbuf, 'x', PIPE_BUF * 2);
-       packet_num = pipe_size / PIPE_BUF;
+       memset(wrbuf, 'x', page_size * 2);
+       packet_num = pipe_size / page_size;

I have tested this on aarch64 system(64kb page size) and it pass.

[1]https://git.kernel.org/pub/scm/docs/man-pages/man-pages.git/tree/man7/pipe.7#n260
> -- 
> Regards,
> Li Wang




More information about the ltp mailing list