* [LTP] [PATCH v3 0/2] new restcases: readahead01/02 @ 2012-10-15 7:54 Jan Stancek 2012-10-15 7:54 ` [LTP] [PATCH v3 1/2] new syscall test: readahead01 Jan Stancek 2012-10-15 7:54 ` [LTP] [PATCH v3 2/2] new syscall test: readahead02 Jan Stancek 0 siblings, 2 replies; 6+ messages in thread From: Jan Stancek @ 2012-10-15 7:54 UTC (permalink / raw) To: ltp-list Changes in v3: remove unused argv parameter from setup -> setup(void) add parentheses to else blocks where needed free tmp buffer before TBROK Jan Stancek (2): new syscall test: readahead01 new syscall test: readahead02 runtest/syscalls | 3 + testcases/kernel/syscalls/readahead/Makefile | 22 ++ testcases/kernel/syscalls/readahead/readahead01.c | 172 ++++++++++ testcases/kernel/syscalls/readahead/readahead02.c | 378 +++++++++++++++++++++ 4 files changed, 575 insertions(+), 0 deletions(-) create mode 100644 testcases/kernel/syscalls/readahead/Makefile create mode 100644 testcases/kernel/syscalls/readahead/readahead01.c create mode 100644 testcases/kernel/syscalls/readahead/readahead02.c ------------------------------------------------------------------------------ Don't let slow site performance ruin your business. Deploy New Relic APM Deploy New Relic app performance management and know exactly what is happening inside your Ruby, Python, PHP, Java, and .NET app Try New Relic at no cost today and get our sweet Data Nerd shirt too! http://p.sf.net/sfu/newrelic-dev2dev _______________________________________________ Ltp-list mailing list Ltp-list@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/ltp-list ^ permalink raw reply [flat|nested] 6+ messages in thread
* [LTP] [PATCH v3 1/2] new syscall test: readahead01 2012-10-15 7:54 [LTP] [PATCH v3 0/2] new restcases: readahead01/02 Jan Stancek @ 2012-10-15 7:54 ` Jan Stancek 2012-10-15 9:56 ` Wanlong Gao 2012-10-15 15:50 ` chrubis 2012-10-15 7:54 ` [LTP] [PATCH v3 2/2] new syscall test: readahead02 Jan Stancek 1 sibling, 2 replies; 6+ messages in thread From: Jan Stancek @ 2012-10-15 7:54 UTC (permalink / raw) To: ltp-list errno testcase for readahead(2). Signed-off-by: Jan Stancek <jstancek@redhat.com> --- runtest/syscalls | 2 + testcases/kernel/syscalls/readahead/Makefile | 22 +++ testcases/kernel/syscalls/readahead/readahead01.c | 172 +++++++++++++++++++++ 3 files changed, 196 insertions(+), 0 deletions(-) create mode 100644 testcases/kernel/syscalls/readahead/Makefile create mode 100644 testcases/kernel/syscalls/readahead/readahead01.c diff --git a/runtest/syscalls b/runtest/syscalls index edf6c1e..e754c60 100644 --- a/runtest/syscalls +++ b/runtest/syscalls @@ -767,6 +767,8 @@ read02 read02 read03 read03 read04 read04 +readahead01 readahead01 + readdir01 readdir01 readdir02 readdir02 diff --git a/testcases/kernel/syscalls/readahead/Makefile b/testcases/kernel/syscalls/readahead/Makefile new file mode 100644 index 0000000..45a3bbc --- /dev/null +++ b/testcases/kernel/syscalls/readahead/Makefile @@ -0,0 +1,22 @@ +# +# Copyright (C) 2012 Linux Test Project, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See +# the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +# + +top_srcdir ?= ../../../.. + +include $(top_srcdir)/include/mk/testcases.mk +include $(top_srcdir)/include/mk/generic_leaf_target.mk diff --git a/testcases/kernel/syscalls/readahead/readahead01.c b/testcases/kernel/syscalls/readahead/readahead01.c new file mode 100644 index 0000000..c9b5202 --- /dev/null +++ b/testcases/kernel/syscalls/readahead/readahead01.c @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2012 Linux Test Project, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it + * is free of the rightful claim of any third person regarding + * infringement or the like. Any license provided herein, whether + * implied or otherwise, applies only to this software file. Patent + * licenses, if any, provided herein do not apply to combinations of + * this program with other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +/* + * errno tests for readahead() syscall + */ +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/syscall.h> +#include <sys/socket.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include "config.h" +#include "test.h" +#include "usctest.h" +#include "safe_macros.h" +#include "linux_syscall_numbers.h" + +char *TCID = "readahead01"; +int TST_TOTAL = 1; + +option_t options[] = { + { NULL, NULL, NULL } +}; + +#if defined(__NR_readahead) +static void setup(void); +static void cleanup(void); + +static int check_ret(long expected_ret) +{ + if (expected_ret == TEST_RETURN) { + tst_resm(TPASS, "expected ret success - " + "returned value = %ld", TEST_RETURN); + return 0; + } + tst_resm(TFAIL, "unexpected failure - " + "returned value = %ld, expected: %ld", + TEST_RETURN, expected_ret); + return 1; +} + +static int check_errno(long expected_errno) +{ + if (TEST_ERRNO == expected_errno) { + tst_resm(TPASS|TTERRNO, "expected failure"); + return 0; + } + + if (TEST_ERRNO == 0) + tst_resm(TFAIL, "call succeeded unexpectedly"); + else + tst_resm(TFAIL|TTERRNO, "unexpected failure - " + "expected = %ld : %s, actual", + expected_errno, strerror(expected_errno)); + return 1; +} + +static void test_bad_fd(void) +{ + char tempname[PATH_MAX] = "readahead01_XXXXXX"; + int fd; + + tst_resm(TINFO, "test_bad_fd -1"); + TEST(syscall(__NR_readahead, -1, 0, getpagesize())); + check_ret(-1); + check_errno(EBADF); + + tst_resm(TINFO, "test_bad_fd O_WRONLY"); + fd = mkstemp(tempname); + if (fd == -1) + tst_resm(TBROK|TERRNO, "mkstemp failed"); + close(fd); + fd = open(tempname, O_WRONLY); + if (fd == -1) + tst_resm(TBROK|TERRNO, "Failed to open testfile"); + TEST(syscall(__NR_readahead, fd, 0, getpagesize())); + check_ret(-1); + check_errno(EBADF); + close(fd); + unlink(tempname); +} + +static void test_invalid_fd(void) +{ + int fd[2]; + + tst_resm(TINFO, "test_invalid_fd pipe"); + if (pipe(fd) < 0) + tst_resm(TBROK|TERRNO, "Failed to create pipe"); + TEST(syscall(__NR_readahead, fd[0], 0, getpagesize())); + check_ret(-1); + check_errno(EINVAL); + close(fd[0]); + close(fd[1]); + + tst_resm(TINFO, "test_invalid_fd socket"); + fd[0] = socket(AF_INET, SOCK_STREAM, 0); + if (fd[0] < 0) + tst_resm(TBROK|TERRNO, "Failed to create socket"); + TEST(syscall(__NR_readahead, fd[0], 0, getpagesize())); + check_ret(-1); + check_errno(EINVAL); + close(fd[0]); +} + +int main(int argc, char *argv[]) +{ + char *msg; + int lc; + + msg = parse_opts(argc, argv, options, NULL); + if (msg != NULL) + tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); + + setup(); + for (lc = 0; TEST_LOOPING(lc); lc++) { + Tst_count = 0; + test_bad_fd(); + test_invalid_fd(); + } + cleanup(); + tst_exit(); +} + +static void setup(void) +{ + tst_require_root(NULL); + tst_tmpdir(); + + /* check if readahead syscall is supported */ + syscall(__NR_readahead, 0, 0, 0); + + TEST_PAUSE; +} + +static void cleanup(void) +{ + TEST_CLEANUP; + tst_rmdir(); +} + +#else /* __NR_readahead */ +int main(void) +{ + tst_brkm(TCONF, NULL, "System doesn't support __NR_readahead"); +} +#endif + -- 1.7.1 ------------------------------------------------------------------------------ Don't let slow site performance ruin your business. Deploy New Relic APM Deploy New Relic app performance management and know exactly what is happening inside your Ruby, Python, PHP, Java, and .NET app Try New Relic at no cost today and get our sweet Data Nerd shirt too! http://p.sf.net/sfu/newrelic-dev2dev _______________________________________________ Ltp-list mailing list Ltp-list@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/ltp-list ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [LTP] [PATCH v3 1/2] new syscall test: readahead01 2012-10-15 7:54 ` [LTP] [PATCH v3 1/2] new syscall test: readahead01 Jan Stancek @ 2012-10-15 9:56 ` Wanlong Gao 2012-10-15 15:50 ` chrubis 1 sibling, 0 replies; 6+ messages in thread From: Wanlong Gao @ 2012-10-15 9:56 UTC (permalink / raw) To: Jan Stancek; +Cc: ltp-list On 10/15/2012 03:54 PM, Jan Stancek wrote: > errno testcase for readahead(2). > > Signed-off-by: Jan Stancek <jstancek@redhat.com> Reviewed-by: Wanlong Gao <gaowanlong@cn.fujitsu.com> > --- > runtest/syscalls | 2 + > testcases/kernel/syscalls/readahead/Makefile | 22 +++ > testcases/kernel/syscalls/readahead/readahead01.c | 172 +++++++++++++++++++++ > 3 files changed, 196 insertions(+), 0 deletions(-) > create mode 100644 testcases/kernel/syscalls/readahead/Makefile > create mode 100644 testcases/kernel/syscalls/readahead/readahead01.c > > diff --git a/runtest/syscalls b/runtest/syscalls > index edf6c1e..e754c60 100644 > --- a/runtest/syscalls > +++ b/runtest/syscalls > @@ -767,6 +767,8 @@ read02 read02 > read03 read03 > read04 read04 > > +readahead01 readahead01 > + > readdir01 readdir01 > readdir02 readdir02 > > diff --git a/testcases/kernel/syscalls/readahead/Makefile b/testcases/kernel/syscalls/readahead/Makefile > new file mode 100644 > index 0000000..45a3bbc > --- /dev/null > +++ b/testcases/kernel/syscalls/readahead/Makefile > @@ -0,0 +1,22 @@ > +# > +# Copyright (C) 2012 Linux Test Project, Inc. > +# > +# This program is free software; you can redistribute it and/or modify > +# it under the terms of the GNU General Public License as published by > +# the Free Software Foundation; either version 2 of the License, or > +# (at your option) any later version. > +# > +# This program is distributed in the hope that it will be useful, > +# but WITHOUT ANY WARRANTY; without even the implied warranty of > +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See > +# the GNU General Public License for more details. > +# > +# You should have received a copy of the GNU General Public License > +# along with this program; if not, write to the Free Software > +# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA > +# > + > +top_srcdir ?= ../../../.. > + > +include $(top_srcdir)/include/mk/testcases.mk > +include $(top_srcdir)/include/mk/generic_leaf_target.mk > diff --git a/testcases/kernel/syscalls/readahead/readahead01.c b/testcases/kernel/syscalls/readahead/readahead01.c > new file mode 100644 > index 0000000..c9b5202 > --- /dev/null > +++ b/testcases/kernel/syscalls/readahead/readahead01.c > @@ -0,0 +1,172 @@ > +/* > + * Copyright (C) 2012 Linux Test Project, Inc. > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of version 2 of the GNU General Public > + * License as published by the Free Software Foundation. > + * > + * This program is distributed in the hope that it would be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. > + * > + * Further, this software is distributed without any warranty that it > + * is free of the rightful claim of any third person regarding > + * infringement or the like. Any license provided herein, whether > + * implied or otherwise, applies only to this software file. Patent > + * licenses, if any, provided herein do not apply to combinations of > + * this program with other software, or any other product whatsoever. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA > + * 02110-1301, USA. > + */ > + > +/* > + * errno tests for readahead() syscall > + */ > +#include <sys/types.h> > +#include <sys/stat.h> > +#include <sys/syscall.h> > +#include <sys/socket.h> > +#include <errno.h> > +#include <stdio.h> > +#include <stdlib.h> > +#include <unistd.h> > +#include "config.h" > +#include "test.h" > +#include "usctest.h" > +#include "safe_macros.h" > +#include "linux_syscall_numbers.h" > + > +char *TCID = "readahead01"; > +int TST_TOTAL = 1; > + > +option_t options[] = { > + { NULL, NULL, NULL } > +}; > + > +#if defined(__NR_readahead) > +static void setup(void); > +static void cleanup(void); > + > +static int check_ret(long expected_ret) > +{ > + if (expected_ret == TEST_RETURN) { > + tst_resm(TPASS, "expected ret success - " > + "returned value = %ld", TEST_RETURN); > + return 0; > + } > + tst_resm(TFAIL, "unexpected failure - " > + "returned value = %ld, expected: %ld", > + TEST_RETURN, expected_ret); > + return 1; > +} > + > +static int check_errno(long expected_errno) > +{ > + if (TEST_ERRNO == expected_errno) { > + tst_resm(TPASS|TTERRNO, "expected failure"); > + return 0; > + } > + > + if (TEST_ERRNO == 0) > + tst_resm(TFAIL, "call succeeded unexpectedly"); > + else > + tst_resm(TFAIL|TTERRNO, "unexpected failure - " > + "expected = %ld : %s, actual", > + expected_errno, strerror(expected_errno)); > + return 1; > +} > + > +static void test_bad_fd(void) > +{ > + char tempname[PATH_MAX] = "readahead01_XXXXXX"; > + int fd; > + > + tst_resm(TINFO, "test_bad_fd -1"); > + TEST(syscall(__NR_readahead, -1, 0, getpagesize())); > + check_ret(-1); > + check_errno(EBADF); > + > + tst_resm(TINFO, "test_bad_fd O_WRONLY"); > + fd = mkstemp(tempname); > + if (fd == -1) > + tst_resm(TBROK|TERRNO, "mkstemp failed"); > + close(fd); > + fd = open(tempname, O_WRONLY); > + if (fd == -1) > + tst_resm(TBROK|TERRNO, "Failed to open testfile"); > + TEST(syscall(__NR_readahead, fd, 0, getpagesize())); > + check_ret(-1); > + check_errno(EBADF); > + close(fd); > + unlink(tempname); > +} > + > +static void test_invalid_fd(void) > +{ > + int fd[2]; > + > + tst_resm(TINFO, "test_invalid_fd pipe"); > + if (pipe(fd) < 0) > + tst_resm(TBROK|TERRNO, "Failed to create pipe"); > + TEST(syscall(__NR_readahead, fd[0], 0, getpagesize())); > + check_ret(-1); > + check_errno(EINVAL); > + close(fd[0]); > + close(fd[1]); > + > + tst_resm(TINFO, "test_invalid_fd socket"); > + fd[0] = socket(AF_INET, SOCK_STREAM, 0); > + if (fd[0] < 0) > + tst_resm(TBROK|TERRNO, "Failed to create socket"); > + TEST(syscall(__NR_readahead, fd[0], 0, getpagesize())); > + check_ret(-1); > + check_errno(EINVAL); > + close(fd[0]); > +} > + > +int main(int argc, char *argv[]) > +{ > + char *msg; > + int lc; > + > + msg = parse_opts(argc, argv, options, NULL); > + if (msg != NULL) > + tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); > + > + setup(); > + for (lc = 0; TEST_LOOPING(lc); lc++) { > + Tst_count = 0; > + test_bad_fd(); > + test_invalid_fd(); > + } > + cleanup(); > + tst_exit(); > +} > + > +static void setup(void) > +{ > + tst_require_root(NULL); > + tst_tmpdir(); > + > + /* check if readahead syscall is supported */ > + syscall(__NR_readahead, 0, 0, 0); > + > + TEST_PAUSE; > +} > + > +static void cleanup(void) > +{ > + TEST_CLEANUP; > + tst_rmdir(); > +} > + > +#else /* __NR_readahead */ > +int main(void) > +{ > + tst_brkm(TCONF, NULL, "System doesn't support __NR_readahead"); > +} > +#endif > + > ------------------------------------------------------------------------------ Don't let slow site performance ruin your business. Deploy New Relic APM Deploy New Relic app performance management and know exactly what is happening inside your Ruby, Python, PHP, Java, and .NET app Try New Relic at no cost today and get our sweet Data Nerd shirt too! http://p.sf.net/sfu/newrelic-dev2dev _______________________________________________ Ltp-list mailing list Ltp-list@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/ltp-list ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [LTP] [PATCH v3 1/2] new syscall test: readahead01 2012-10-15 7:54 ` [LTP] [PATCH v3 1/2] new syscall test: readahead01 Jan Stancek 2012-10-15 9:56 ` Wanlong Gao @ 2012-10-15 15:50 ` chrubis 1 sibling, 0 replies; 6+ messages in thread From: chrubis @ 2012-10-15 15:50 UTC (permalink / raw) To: Jan Stancek; +Cc: ltp-list Hi! Both commited, thanks. -- Cyril Hrubis chrubis@suse.cz ------------------------------------------------------------------------------ Don't let slow site performance ruin your business. Deploy New Relic APM Deploy New Relic app performance management and know exactly what is happening inside your Ruby, Python, PHP, Java, and .NET app Try New Relic at no cost today and get our sweet Data Nerd shirt too! http://p.sf.net/sfu/newrelic-dev2dev _______________________________________________ Ltp-list mailing list Ltp-list@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/ltp-list ^ permalink raw reply [flat|nested] 6+ messages in thread
* [LTP] [PATCH v3 2/2] new syscall test: readahead02 2012-10-15 7:54 [LTP] [PATCH v3 0/2] new restcases: readahead01/02 Jan Stancek 2012-10-15 7:54 ` [LTP] [PATCH v3 1/2] new syscall test: readahead01 Jan Stancek @ 2012-10-15 7:54 ` Jan Stancek 2012-10-15 9:57 ` Wanlong Gao 1 sibling, 1 reply; 6+ messages in thread From: Jan Stancek @ 2012-10-15 7:54 UTC (permalink / raw) To: ltp-list Use readahead() syscall and check if subsequent read saves some I/O and if cache size increased. Signed-off-by: Jan Stancek <jstancek@redhat.com> --- runtest/syscalls | 1 + testcases/kernel/syscalls/readahead/readahead02.c | 378 +++++++++++++++++++++ 2 files changed, 379 insertions(+), 0 deletions(-) create mode 100644 testcases/kernel/syscalls/readahead/readahead02.c diff --git a/runtest/syscalls b/runtest/syscalls index e754c60..6973aaa 100644 --- a/runtest/syscalls +++ b/runtest/syscalls @@ -768,6 +768,7 @@ read03 read03 read04 read04 readahead01 readahead01 +readahead02 readahead02 readdir01 readdir01 readdir02 readdir02 diff --git a/testcases/kernel/syscalls/readahead/readahead02.c b/testcases/kernel/syscalls/readahead/readahead02.c new file mode 100644 index 0000000..48064d5 --- /dev/null +++ b/testcases/kernel/syscalls/readahead/readahead02.c @@ -0,0 +1,378 @@ +/* + * Copyright (C) 2012 Linux Test Project, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it + * is free of the rightful claim of any third person regarding + * infringement or the like. Any license provided herein, whether + * implied or otherwise, applies only to this software file. Patent + * licenses, if any, provided herein do not apply to combinations of + * this program with other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +/* + * functional test for readahead() syscall + * + * This test is measuring effects of readahead syscall. + * It mmaps/reads a test file with and without prior call to readahead. + * + */ +#define _GNU_SOURCE +#include <sys/types.h> +#include <sys/syscall.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/time.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <unistd.h> +#include <fcntl.h> +#include "config.h" +#include "test.h" +#include "usctest.h" +#include "safe_macros.h" +#include "linux_syscall_numbers.h" + +char *TCID = "readahead02"; +int TST_TOTAL = 1; + +#if defined(__NR_readahead) +static const char testfile[] = "testfile"; +static const char drop_caches_fname[] = "/proc/sys/vm/drop_caches"; +static const char meminfo_fname[] = "/proc/meminfo"; +static size_t testfile_size = 64*1024*1024; +static int opt_fsize; +static char *opt_fsizestr; +static int pagesize; + +option_t options[] = { + { "s:", &opt_fsize, &opt_fsizestr}, + { NULL, NULL, NULL } +}; + +static void setup(void); +static void cleanup(void); + +static void help(void) +{ + printf(" -s x testfile size (default 64MB)\n"); +} + +static int check_ret(long expected_ret) +{ + if (expected_ret == TEST_RETURN) { + tst_resm(TPASS, "expected ret success - " + "returned value = %ld", TEST_RETURN); + return 0; + } + tst_resm(TFAIL, "unexpected failure - " + "returned value = %ld, expected: %ld", + TEST_RETURN, expected_ret); + return 1; +} + +static int has_file(const char *fname, int required) +{ + int ret; + struct stat buf; + ret = stat(fname, &buf); + if (ret == -1) { + if (errno == ENOENT) + if (required) + tst_brkm(TCONF, cleanup, "%s not available", + fname); + else + return 0; + else + tst_brkm(TBROK|TERRNO, cleanup, "stat %s", fname); + } + return 1; +} + +static void drop_caches(void) +{ + int ret; + FILE *f; + + f = fopen(drop_caches_fname, "w"); + if (f) { + ret = fprintf(f, "1"); + fclose(f); + if (ret < 1) + tst_brkm(TBROK, cleanup, "Failed to drop caches"); + } else { + tst_brkm(TBROK, cleanup, "Failed to open drop_caches"); + } +} + +static long parse_entry(const char *fname, const char *entry) +{ + FILE *f; + long value = -1; + int ret; + char *line = NULL; + size_t linelen; + + f = fopen(fname, "r"); + if (f) { + do { + ret = getline(&line, &linelen, f); + if (sscanf(line, entry, &value) == 1) + break; + } while (ret != -1); + fclose(f); + } + return value; +} + +static long get_bytes_read(void) +{ + char fname[128]; + char entry[] = "read_bytes: %ld"; + sprintf(fname, "/proc/%u/io", getpid()); + return parse_entry(fname, entry); +} + +static long get_cached_size(void) +{ + char entry[] = "Cached: %ld"; + return parse_entry(meminfo_fname, entry); +} + +static void create_testfile(void) +{ + FILE *f; + char *tmp; + int i; + + tst_resm(TINFO, "creating test file of size: %ld", testfile_size); + tmp = SAFE_MALLOC(cleanup, pagesize); + + /* round to page size */ + testfile_size = testfile_size & ~((long)pagesize - 1); + + f = fopen(testfile, "w"); + if (!f) { + free(tmp); + tst_brkm(TBROK|TERRNO, cleanup, "Failed to create %s", + testfile); + } + + for (i = 0; i < testfile_size; i += pagesize) + if (fwrite(tmp, pagesize, 1, f) < 1) { + free(tmp); + tst_brkm(TBROK, cleanup, "Failed to create %s", + testfile); + } + fflush(f); + fsync(fileno(f)); + fclose(f); + free(tmp); +} + +/* read_testfile - mmap testfile and read every page. + * This functions measures how many I/O and time it takes to fully + * read contents of test file. + * + * @do_readahead: call readahead prior to reading file content? + * @fname: name of file to test + * @fsize: how many bytes to read/mmap + * @read_bytes: returns difference of bytes read, parsed from /proc/<pid>/io + * @usec: returns how many microsecond it took to go over fsize bytes + * @cached: returns cached kB from /proc/meminfo + */ +static void read_testfile(int do_readahead, const char *fname, size_t fsize, + long *read_bytes, long *usec, long *cached) +{ + int fd, i; + long read_bytes_start; + unsigned char *p, tmp; + unsigned long time_start_usec, time_end_usec; + off_t offset; + struct timeval now; + + fd = open(fname, O_RDONLY); + if (fd < 0) + tst_brkm(TBROK|TERRNO, cleanup, "Failed to open %s", + fname); + + if (do_readahead) { + TEST(syscall(__NR_readahead, fd, (off64_t)0, (size_t)fsize)); + check_ret(0); + *cached = get_cached_size(); + + /* offset of file shouldn't change after readahead */ + offset = lseek(fd, 0, SEEK_CUR); + if (offset == (off_t) -1) + tst_brkm(TBROK|TERRNO, cleanup, "lseek failed"); + if (offset == 0) + tst_resm(TPASS, "offset is still at 0 as expected"); + else + tst_resm(TFAIL, "offset has changed to: %lu", offset); + } + + if (gettimeofday(&now, NULL) == -1) + tst_brkm(TBROK|TERRNO, cleanup, "gettimeofday failed"); + time_start_usec = now.tv_sec * 1000000 + now.tv_usec; + read_bytes_start = get_bytes_read(); + + p = mmap(NULL, fsize, PROT_READ, MAP_SHARED|MAP_POPULATE, fd, 0); + if (p == MAP_FAILED) + tst_brkm(TBROK|TERRNO, cleanup, "mmap failed"); + + /* for old kernels, where MAP_POPULATE doesn't work, touch each page */ + tmp = 0; + for (i = 0; i < fsize; i += pagesize) + tmp = tmp ^ p[i]; + /* prevent gcc from optimizing out loop above */ + if (tmp != 0) + tst_brkm(TBROK, NULL, "This line should not be reached"); + + if (!do_readahead) + *cached = get_cached_size(); + + if (munmap(p, fsize) == -1) + tst_brkm(TBROK|TERRNO, cleanup, "munmap failed"); + + *read_bytes = get_bytes_read() - read_bytes_start; + if (gettimeofday(&now, NULL) == -1) + tst_brkm(TBROK|TERRNO, cleanup, "gettimeofday failed"); + time_end_usec = now.tv_sec * 1000000 + now.tv_usec; + *usec = time_end_usec - time_start_usec; + + if (close(fd) == -1) + tst_brkm(TBROK|TERRNO, cleanup, "close failed"); +} + +static void test_readahead(void) +{ + long read_bytes, read_bytes_ra; + long usec, usec_ra; + long cached_max, cached_low, cached, cached_ra; + char proc_io_fname[128]; + sprintf(proc_io_fname, "/proc/%u/io", getpid()); + + /* find out how much can cache hold if we read whole file */ + read_testfile(0, testfile, testfile_size, &read_bytes, + &usec, &cached); + cached_max = get_cached_size(); + sync(); + drop_caches(); + cached_low = get_cached_size(); + cached_max = cached_max - cached_low; + + tst_resm(TINFO, "read_testfile(0)"); + read_testfile(0, testfile, testfile_size, &read_bytes, + &usec, &cached); + cached = cached - cached_low; + + sync(); + drop_caches(); + cached_low = get_cached_size(); + tst_resm(TINFO, "read_testfile(1)"); + read_testfile(1, testfile, testfile_size, &read_bytes_ra, + &usec_ra, &cached_ra); + cached_ra = cached_ra - cached_low; + + tst_resm(TINFO, "read_testfile(0) took: %ld usec", usec); + tst_resm(TINFO, "read_testfile(1) took: %ld usec", usec_ra); + if (has_file(proc_io_fname, 0)) { + tst_resm(TINFO, "read_testfile(0) read: %ld bytes", + read_bytes); + tst_resm(TINFO, "read_testfile(1) read: %ld bytes", + read_bytes_ra); + /* actual number of read bytes depends on total RAM */ + if (read_bytes_ra < read_bytes) + tst_resm(TPASS, "readahead saved some I/O"); + else + tst_resm(TFAIL, "readahead failed to save any I/O"); + } else { + tst_resm(TCONF, "Your system doesn't have /proc/pid/io," + " unable to determine read bytes during test"); + } + + tst_resm(TINFO, "cache can hold at least: %ld kB", cached_max); + tst_resm(TINFO, "read_testfile(0) used cache: %ld kB", cached); + tst_resm(TINFO, "read_testfile(1) used cache: %ld kB", cached_ra); + + if (cached_max*1024 >= testfile_size) { + /* + * if cache can hold ~testfile_size then cache increase + * for readahead should be at least testfile_size/2 + */ + if (cached_ra*1024 > testfile_size/2) + tst_resm(TPASS, "using cache as expected"); + else + tst_resm(TWARN, "using less cache than expected"); + } else { + tst_resm(TCONF, "Page cache on your system is too small " + "to hold whole testfile."); + } +} + +int main(int argc, char *argv[]) +{ + char *msg; + int lc; + + msg = parse_opts(argc, argv, options, help); + if (msg != NULL) + tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); + + if (opt_fsize) + testfile_size = atoi(opt_fsizestr); + + setup(); + for (lc = 0; TEST_LOOPING(lc); lc++) { + Tst_count = 0; + test_readahead(); + } + cleanup(); + tst_exit(); +} + +static void setup(void) +{ + tst_require_root(NULL); + tst_tmpdir(); + TEST_PAUSE; + + has_file(drop_caches_fname, 1); + has_file(meminfo_fname, 1); + + /* check if readahead is supported */ + syscall(__NR_readahead, 0, 0, 0); + + pagesize = getpagesize(); + create_testfile(); +} + +static void cleanup(void) +{ + TEST_CLEANUP; + unlink(testfile); + tst_rmdir(); +} + +#else /* __NR_readahead */ +int main(void) +{ + tst_brkm(TCONF, NULL, "System doesn't support __NR_readahead"); +} +#endif + -- 1.7.1 ------------------------------------------------------------------------------ Don't let slow site performance ruin your business. Deploy New Relic APM Deploy New Relic app performance management and know exactly what is happening inside your Ruby, Python, PHP, Java, and .NET app Try New Relic at no cost today and get our sweet Data Nerd shirt too! http://p.sf.net/sfu/newrelic-dev2dev _______________________________________________ Ltp-list mailing list Ltp-list@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/ltp-list ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [LTP] [PATCH v3 2/2] new syscall test: readahead02 2012-10-15 7:54 ` [LTP] [PATCH v3 2/2] new syscall test: readahead02 Jan Stancek @ 2012-10-15 9:57 ` Wanlong Gao 0 siblings, 0 replies; 6+ messages in thread From: Wanlong Gao @ 2012-10-15 9:57 UTC (permalink / raw) To: Jan Stancek; +Cc: ltp-list On 10/15/2012 03:54 PM, Jan Stancek wrote: > Use readahead() syscall and check if subsequent > read saves some I/O and if cache size increased. > > Signed-off-by: Jan Stancek <jstancek@redhat.com> Reviewed-by: Wanlong Gao <gaowanlong@cn.fujitsu.com> > --- > runtest/syscalls | 1 + > testcases/kernel/syscalls/readahead/readahead02.c | 378 +++++++++++++++++++++ > 2 files changed, 379 insertions(+), 0 deletions(-) > create mode 100644 testcases/kernel/syscalls/readahead/readahead02.c > > diff --git a/runtest/syscalls b/runtest/syscalls > index e754c60..6973aaa 100644 > --- a/runtest/syscalls > +++ b/runtest/syscalls > @@ -768,6 +768,7 @@ read03 read03 > read04 read04 > > readahead01 readahead01 > +readahead02 readahead02 > > readdir01 readdir01 > readdir02 readdir02 > diff --git a/testcases/kernel/syscalls/readahead/readahead02.c b/testcases/kernel/syscalls/readahead/readahead02.c > new file mode 100644 > index 0000000..48064d5 > --- /dev/null > +++ b/testcases/kernel/syscalls/readahead/readahead02.c > @@ -0,0 +1,378 @@ > +/* > + * Copyright (C) 2012 Linux Test Project, Inc. > + * > + * This program is free software; you can redistribute it and/or > + * modify it under the terms of version 2 of the GNU General Public > + * License as published by the Free Software Foundation. > + * > + * This program is distributed in the hope that it would be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. > + * > + * Further, this software is distributed without any warranty that it > + * is free of the rightful claim of any third person regarding > + * infringement or the like. Any license provided herein, whether > + * implied or otherwise, applies only to this software file. Patent > + * licenses, if any, provided herein do not apply to combinations of > + * this program with other software, or any other product whatsoever. > + * > + * You should have received a copy of the GNU General Public License > + * along with this program; if not, write the Free Software > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA > + * 02110-1301, USA. > + */ > + > +/* > + * functional test for readahead() syscall > + * > + * This test is measuring effects of readahead syscall. > + * It mmaps/reads a test file with and without prior call to readahead. > + * > + */ > +#define _GNU_SOURCE > +#include <sys/types.h> > +#include <sys/syscall.h> > +#include <sys/mman.h> > +#include <sys/stat.h> > +#include <sys/types.h> > +#include <sys/time.h> > +#include <errno.h> > +#include <stdio.h> > +#include <stdlib.h> > +#include <stdint.h> > +#include <unistd.h> > +#include <fcntl.h> > +#include "config.h" > +#include "test.h" > +#include "usctest.h" > +#include "safe_macros.h" > +#include "linux_syscall_numbers.h" > + > +char *TCID = "readahead02"; > +int TST_TOTAL = 1; > + > +#if defined(__NR_readahead) > +static const char testfile[] = "testfile"; > +static const char drop_caches_fname[] = "/proc/sys/vm/drop_caches"; > +static const char meminfo_fname[] = "/proc/meminfo"; > +static size_t testfile_size = 64*1024*1024; > +static int opt_fsize; > +static char *opt_fsizestr; > +static int pagesize; > + > +option_t options[] = { > + { "s:", &opt_fsize, &opt_fsizestr}, > + { NULL, NULL, NULL } > +}; > + > +static void setup(void); > +static void cleanup(void); > + > +static void help(void) > +{ > + printf(" -s x testfile size (default 64MB)\n"); > +} > + > +static int check_ret(long expected_ret) > +{ > + if (expected_ret == TEST_RETURN) { > + tst_resm(TPASS, "expected ret success - " > + "returned value = %ld", TEST_RETURN); > + return 0; > + } > + tst_resm(TFAIL, "unexpected failure - " > + "returned value = %ld, expected: %ld", > + TEST_RETURN, expected_ret); > + return 1; > +} > + > +static int has_file(const char *fname, int required) > +{ > + int ret; > + struct stat buf; > + ret = stat(fname, &buf); > + if (ret == -1) { > + if (errno == ENOENT) > + if (required) > + tst_brkm(TCONF, cleanup, "%s not available", > + fname); > + else > + return 0; > + else > + tst_brkm(TBROK|TERRNO, cleanup, "stat %s", fname); > + } > + return 1; > +} > + > +static void drop_caches(void) > +{ > + int ret; > + FILE *f; > + > + f = fopen(drop_caches_fname, "w"); > + if (f) { > + ret = fprintf(f, "1"); > + fclose(f); > + if (ret < 1) > + tst_brkm(TBROK, cleanup, "Failed to drop caches"); > + } else { > + tst_brkm(TBROK, cleanup, "Failed to open drop_caches"); > + } > +} > + > +static long parse_entry(const char *fname, const char *entry) > +{ > + FILE *f; > + long value = -1; > + int ret; > + char *line = NULL; > + size_t linelen; > + > + f = fopen(fname, "r"); > + if (f) { > + do { > + ret = getline(&line, &linelen, f); > + if (sscanf(line, entry, &value) == 1) > + break; > + } while (ret != -1); > + fclose(f); > + } > + return value; > +} > + > +static long get_bytes_read(void) > +{ > + char fname[128]; > + char entry[] = "read_bytes: %ld"; > + sprintf(fname, "/proc/%u/io", getpid()); > + return parse_entry(fname, entry); > +} > + > +static long get_cached_size(void) > +{ > + char entry[] = "Cached: %ld"; > + return parse_entry(meminfo_fname, entry); > +} > + > +static void create_testfile(void) > +{ > + FILE *f; > + char *tmp; > + int i; > + > + tst_resm(TINFO, "creating test file of size: %ld", testfile_size); > + tmp = SAFE_MALLOC(cleanup, pagesize); > + > + /* round to page size */ > + testfile_size = testfile_size & ~((long)pagesize - 1); > + > + f = fopen(testfile, "w"); > + if (!f) { > + free(tmp); > + tst_brkm(TBROK|TERRNO, cleanup, "Failed to create %s", > + testfile); > + } > + > + for (i = 0; i < testfile_size; i += pagesize) > + if (fwrite(tmp, pagesize, 1, f) < 1) { > + free(tmp); > + tst_brkm(TBROK, cleanup, "Failed to create %s", > + testfile); > + } > + fflush(f); > + fsync(fileno(f)); > + fclose(f); > + free(tmp); > +} > + > +/* read_testfile - mmap testfile and read every page. > + * This functions measures how many I/O and time it takes to fully > + * read contents of test file. > + * > + * @do_readahead: call readahead prior to reading file content? > + * @fname: name of file to test > + * @fsize: how many bytes to read/mmap > + * @read_bytes: returns difference of bytes read, parsed from /proc/<pid>/io > + * @usec: returns how many microsecond it took to go over fsize bytes > + * @cached: returns cached kB from /proc/meminfo > + */ > +static void read_testfile(int do_readahead, const char *fname, size_t fsize, > + long *read_bytes, long *usec, long *cached) > +{ > + int fd, i; > + long read_bytes_start; > + unsigned char *p, tmp; > + unsigned long time_start_usec, time_end_usec; > + off_t offset; > + struct timeval now; > + > + fd = open(fname, O_RDONLY); > + if (fd < 0) > + tst_brkm(TBROK|TERRNO, cleanup, "Failed to open %s", > + fname); > + > + if (do_readahead) { > + TEST(syscall(__NR_readahead, fd, (off64_t)0, (size_t)fsize)); > + check_ret(0); > + *cached = get_cached_size(); > + > + /* offset of file shouldn't change after readahead */ > + offset = lseek(fd, 0, SEEK_CUR); > + if (offset == (off_t) -1) > + tst_brkm(TBROK|TERRNO, cleanup, "lseek failed"); > + if (offset == 0) > + tst_resm(TPASS, "offset is still at 0 as expected"); > + else > + tst_resm(TFAIL, "offset has changed to: %lu", offset); > + } > + > + if (gettimeofday(&now, NULL) == -1) > + tst_brkm(TBROK|TERRNO, cleanup, "gettimeofday failed"); > + time_start_usec = now.tv_sec * 1000000 + now.tv_usec; > + read_bytes_start = get_bytes_read(); > + > + p = mmap(NULL, fsize, PROT_READ, MAP_SHARED|MAP_POPULATE, fd, 0); > + if (p == MAP_FAILED) > + tst_brkm(TBROK|TERRNO, cleanup, "mmap failed"); > + > + /* for old kernels, where MAP_POPULATE doesn't work, touch each page */ > + tmp = 0; > + for (i = 0; i < fsize; i += pagesize) > + tmp = tmp ^ p[i]; > + /* prevent gcc from optimizing out loop above */ > + if (tmp != 0) > + tst_brkm(TBROK, NULL, "This line should not be reached"); > + > + if (!do_readahead) > + *cached = get_cached_size(); > + > + if (munmap(p, fsize) == -1) > + tst_brkm(TBROK|TERRNO, cleanup, "munmap failed"); > + > + *read_bytes = get_bytes_read() - read_bytes_start; > + if (gettimeofday(&now, NULL) == -1) > + tst_brkm(TBROK|TERRNO, cleanup, "gettimeofday failed"); > + time_end_usec = now.tv_sec * 1000000 + now.tv_usec; > + *usec = time_end_usec - time_start_usec; > + > + if (close(fd) == -1) > + tst_brkm(TBROK|TERRNO, cleanup, "close failed"); > +} > + > +static void test_readahead(void) > +{ > + long read_bytes, read_bytes_ra; > + long usec, usec_ra; > + long cached_max, cached_low, cached, cached_ra; > + char proc_io_fname[128]; > + sprintf(proc_io_fname, "/proc/%u/io", getpid()); > + > + /* find out how much can cache hold if we read whole file */ > + read_testfile(0, testfile, testfile_size, &read_bytes, > + &usec, &cached); > + cached_max = get_cached_size(); > + sync(); > + drop_caches(); > + cached_low = get_cached_size(); > + cached_max = cached_max - cached_low; > + > + tst_resm(TINFO, "read_testfile(0)"); > + read_testfile(0, testfile, testfile_size, &read_bytes, > + &usec, &cached); > + cached = cached - cached_low; > + > + sync(); > + drop_caches(); > + cached_low = get_cached_size(); > + tst_resm(TINFO, "read_testfile(1)"); > + read_testfile(1, testfile, testfile_size, &read_bytes_ra, > + &usec_ra, &cached_ra); > + cached_ra = cached_ra - cached_low; > + > + tst_resm(TINFO, "read_testfile(0) took: %ld usec", usec); > + tst_resm(TINFO, "read_testfile(1) took: %ld usec", usec_ra); > + if (has_file(proc_io_fname, 0)) { > + tst_resm(TINFO, "read_testfile(0) read: %ld bytes", > + read_bytes); > + tst_resm(TINFO, "read_testfile(1) read: %ld bytes", > + read_bytes_ra); > + /* actual number of read bytes depends on total RAM */ > + if (read_bytes_ra < read_bytes) > + tst_resm(TPASS, "readahead saved some I/O"); > + else > + tst_resm(TFAIL, "readahead failed to save any I/O"); > + } else { > + tst_resm(TCONF, "Your system doesn't have /proc/pid/io," > + " unable to determine read bytes during test"); > + } > + > + tst_resm(TINFO, "cache can hold at least: %ld kB", cached_max); > + tst_resm(TINFO, "read_testfile(0) used cache: %ld kB", cached); > + tst_resm(TINFO, "read_testfile(1) used cache: %ld kB", cached_ra); > + > + if (cached_max*1024 >= testfile_size) { > + /* > + * if cache can hold ~testfile_size then cache increase > + * for readahead should be at least testfile_size/2 > + */ > + if (cached_ra*1024 > testfile_size/2) > + tst_resm(TPASS, "using cache as expected"); > + else > + tst_resm(TWARN, "using less cache than expected"); > + } else { > + tst_resm(TCONF, "Page cache on your system is too small " > + "to hold whole testfile."); > + } > +} > + > +int main(int argc, char *argv[]) > +{ > + char *msg; > + int lc; > + > + msg = parse_opts(argc, argv, options, help); > + if (msg != NULL) > + tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); > + > + if (opt_fsize) > + testfile_size = atoi(opt_fsizestr); > + > + setup(); > + for (lc = 0; TEST_LOOPING(lc); lc++) { > + Tst_count = 0; > + test_readahead(); > + } > + cleanup(); > + tst_exit(); > +} > + > +static void setup(void) > +{ > + tst_require_root(NULL); > + tst_tmpdir(); > + TEST_PAUSE; > + > + has_file(drop_caches_fname, 1); > + has_file(meminfo_fname, 1); > + > + /* check if readahead is supported */ > + syscall(__NR_readahead, 0, 0, 0); > + > + pagesize = getpagesize(); > + create_testfile(); > +} > + > +static void cleanup(void) > +{ > + TEST_CLEANUP; > + unlink(testfile); > + tst_rmdir(); > +} > + > +#else /* __NR_readahead */ > +int main(void) > +{ > + tst_brkm(TCONF, NULL, "System doesn't support __NR_readahead"); > +} > +#endif > + > ------------------------------------------------------------------------------ Don't let slow site performance ruin your business. Deploy New Relic APM Deploy New Relic app performance management and know exactly what is happening inside your Ruby, Python, PHP, Java, and .NET app Try New Relic at no cost today and get our sweet Data Nerd shirt too! http://p.sf.net/sfu/newrelic-dev2dev _______________________________________________ Ltp-list mailing list Ltp-list@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/ltp-list ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2012-10-15 15:52 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2012-10-15 7:54 [LTP] [PATCH v3 0/2] new restcases: readahead01/02 Jan Stancek 2012-10-15 7:54 ` [LTP] [PATCH v3 1/2] new syscall test: readahead01 Jan Stancek 2012-10-15 9:56 ` Wanlong Gao 2012-10-15 15:50 ` chrubis 2012-10-15 7:54 ` [LTP] [PATCH v3 2/2] new syscall test: readahead02 Jan Stancek 2012-10-15 9:57 ` Wanlong Gao
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox