* [LTP] [PATCH] thp01: Find largest arguments size
@ 2017-08-31 8:34 Richard Palethorpe
2017-09-01 7:05 ` Li Wang
2017-09-01 10:03 ` Cyril Hrubis
0 siblings, 2 replies; 8+ messages in thread
From: Richard Palethorpe @ 2017-08-31 8:34 UTC (permalink / raw)
To: ltp
Because of kernel commit da029c11e6b1 the arguments size for exec has been
reduced considerably. This causes exec to fail with E2BIG, so we call it
repeatedly with a decreasing number of arguments until it is successful.
As far as I know, there is no other reliable and easy way to determine the
maximum argument length.
Signed-off-by: Richard Palethorpe <rpalethorpe@suse.com>
---
testcases/kernel/mem/thp/thp01.c | 83 ++++++++++++++++++++++++----------------
1 file changed, 50 insertions(+), 33 deletions(-)
diff --git a/testcases/kernel/mem/thp/thp01.c b/testcases/kernel/mem/thp/thp01.c
index 101a9b5c8..b90b9b637 100644
--- a/testcases/kernel/mem/thp/thp01.c
+++ b/testcases/kernel/mem/thp/thp01.c
@@ -30,6 +30,7 @@
* ....
*/
+#include <errno.h>
#include <sys/types.h>
#include <sys/resource.h>
#include <sys/wait.h>
@@ -38,56 +39,72 @@
#include <stdlib.h>
#include <unistd.h>
#include "mem.h"
+#include "tst_minmax.h"
+#include "tst_safe_sysv_ipc.h"
-#define ARRAY_SZ 256
+#define ARGS_SZ 256
-static int ps;
-static long length;
-static char *array[ARRAY_SZ];
+static int shm_id;
+static char *args[ARGS_SZ];
static char *arg;
-static struct rlimit rl = {
- .rlim_cur = RLIM_INFINITY,
- .rlim_max = RLIM_INFINITY,
-};
+static long *arg_count;
static void thp_test(void)
{
- int i;
- pid_t pid;
-
- switch (pid = SAFE_FORK()) {
- case 0:
- memset(arg, 'c', length - 1);
- arg[length - 1] = '\0';
- array[0] = "true";
- for (i = 1; i < ARRAY_SZ - 1; i++)
- array[i] = arg;
- array[ARRAY_SZ - 1] = NULL;
- if (setrlimit(RLIMIT_STACK, &rl) == -1) {
- perror("setrlimit");
- exit(1);
- }
- if (execvp("true", array) == -1) {
- perror("execvp");
- exit(1);
- }
- default:
- tst_reap_children();
+ pid_t pid = SAFE_FORK();
+
+ if (!arg_count)
+ tst_brk(TBROK, "No shared memory");
+
+ if (!pid) {
+ args[*arg_count] = NULL;
+
+ do {
+ TEST(execvp("true", args));
+ args[--(*arg_count)] = NULL;
+ } while (*arg_count > 0 && TEST_ERRNO == E2BIG);
+
+ tst_brk(TBROK | TTERRNO, "execvp(\"true\", ...)");
}
+ tst_reap_children();
tst_res(TPASS, "system didn't crash, pass.");
}
static void setup(void)
{
- ps = sysconf(_SC_PAGESIZE);
- length = 32 * ps;
- arg = SAFE_MALLOC(length);
+ struct rlimit rl = {
+ .rlim_cur = RLIM_INFINITY,
+ .rlim_max = RLIM_INFINITY,
+ };
+ int i;
+ long arg_len;
+
+ shm_id = SAFE_SHMGET(IPC_PRIVATE, sizeof(long),
+ IPC_CREAT | IPC_EXCL);
+ arg_count = SAFE_SHMAT(shm_id, NULL, 0);
+
+ arg_len = 32 * sysconf(_SC_PAGESIZE);
+ arg = SAFE_MALLOC(arg_len);
+ memset(arg, 'c', arg_len - 1);
+ arg[arg_len - 1] = '\0';
+
+ args[0] = "true";
+ *arg_count = ARGS_SZ - 1;
+ for (i = 1; i < *arg_count; i++)
+ args[i] = arg;
+
+ SAFE_SETRLIMIT(RLIMIT_STACK, &rl);
}
static void cleanup(void)
{
- free(arg);
+ if (arg)
+ free(arg);
+ if (arg_count)
+ SAFE_SHMDT(arg_count);
+ if (shm_id)
+ SAFE_SHMCTL(shm_id, IPC_RMID, NULL);
}
static struct tst_test test = {
--
2.14.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [LTP] [PATCH] thp01: Find largest arguments size
2017-08-31 8:34 [LTP] [PATCH] thp01: Find largest arguments size Richard Palethorpe
@ 2017-09-01 7:05 ` Li Wang
2017-09-01 9:34 ` Richard Palethorpe
2017-09-01 10:03 ` Cyril Hrubis
1 sibling, 1 reply; 8+ messages in thread
From: Li Wang @ 2017-09-01 7:05 UTC (permalink / raw)
To: ltp
On Thu, Aug 31, 2017 at 4:34 PM, Richard Palethorpe
<rpalethorpe@suse.com> wrote:
> Because of kernel commit da029c11e6b1 the arguments size for exec has been
> reduced considerably. This causes exec to fail with E2BIG, so we call it
> repeatedly with a decreasing number of arguments until it is successful.
>
> As far as I know, there is no other reliable and easy way to determine the
> maximum argument length.
>
> Signed-off-by: Richard Palethorpe <rpalethorpe@suse.com>
> ---
> testcases/kernel/mem/thp/thp01.c | 83 ++++++++++++++++++++++++----------------
> 1 file changed, 50 insertions(+), 33 deletions(-)
>
> diff --git a/testcases/kernel/mem/thp/thp01.c b/testcases/kernel/mem/thp/thp01.c
> index 101a9b5c8..b90b9b637 100644
> --- a/testcases/kernel/mem/thp/thp01.c
> +++ b/testcases/kernel/mem/thp/thp01.c
> @@ -30,6 +30,7 @@
> * ....
> */
>
> +#include <errno.h>
> #include <sys/types.h>
> #include <sys/resource.h>
> #include <sys/wait.h>
> @@ -38,56 +39,72 @@
> #include <stdlib.h>
> #include <unistd.h>
> #include "mem.h"
> +#include "tst_minmax.h"
> +#include "tst_safe_sysv_ipc.h"
>
> -#define ARRAY_SZ 256
> +#define ARGS_SZ 256
>
> -static int ps;
> -static long length;
> -static char *array[ARRAY_SZ];
> +static int shm_id;
> +static char *args[ARGS_SZ];
> static char *arg;
> -static struct rlimit rl = {
> - .rlim_cur = RLIM_INFINITY,
> - .rlim_max = RLIM_INFINITY,
> -};
> +static long *arg_count;
Two queries:
1. Can't we declare the arg_count just as a global variable? why
should we take use of share memory, only for the loop counting?
2. The kernel patch limit all arg stack usage to at most 75% of _STK_LIM (6MB),
and here the size of arg_len is 32*PAGE_SIZE. So it means that there
almost only have 6MB/(PAGE_SIZE*32) numbers can be accepted in
args[(*arg_count)], if it is a ppc64 machine(*arg_count == 3) that's
OK, but if a system PAGE_SIZE > 192KB, then the test will be break and
your loop is absolutely useless. About that, if we shrink the arg_len
size, things would be better I guess.
--
Li Wang
liwang@redhat.com
^ permalink raw reply [flat|nested] 8+ messages in thread
* [LTP] [PATCH] thp01: Find largest arguments size
2017-09-01 7:05 ` Li Wang
@ 2017-09-01 9:34 ` Richard Palethorpe
2017-09-01 10:44 ` Li Wang
0 siblings, 1 reply; 8+ messages in thread
From: Richard Palethorpe @ 2017-09-01 9:34 UTC (permalink / raw)
To: ltp
Hello,
Thanks for the review,
Li Wang writes:
> On Thu, Aug 31, 2017 at 4:34 PM, Richard Palethorpe
> <rpalethorpe@suse.com> wrote:
>> Because of kernel commit da029c11e6b1 the arguments size for exec has been
>> reduced considerably. This causes exec to fail with E2BIG, so we call it
>> repeatedly with a decreasing number of arguments until it is successful.
>>
>> As far as I know, there is no other reliable and easy way to determine the
>> maximum argument length.
>>
>> Signed-off-by: Richard Palethorpe <rpalethorpe@suse.com>
>> ---
>> testcases/kernel/mem/thp/thp01.c | 83 ++++++++++++++++++++++++----------------
>> 1 file changed, 50 insertions(+), 33 deletions(-)
>>
>> diff --git a/testcases/kernel/mem/thp/thp01.c b/testcases/kernel/mem/thp/thp01.c
>> index 101a9b5c8..b90b9b637 100644
>> --- a/testcases/kernel/mem/thp/thp01.c
>> +++ b/testcases/kernel/mem/thp/thp01.c
>> @@ -30,6 +30,7 @@
>> * ....
>> */
>>
>> +#include <errno.h>
>> #include <sys/types.h>
>> #include <sys/resource.h>
>> #include <sys/wait.h>
>> @@ -38,56 +39,72 @@
>> #include <stdlib.h>
>> #include <unistd.h>
>> #include "mem.h"
>> +#include "tst_minmax.h"
>> +#include "tst_safe_sysv_ipc.h"
>>
>> -#define ARRAY_SZ 256
>> +#define ARGS_SZ 256
>>
>> -static int ps;
>> -static long length;
>> -static char *array[ARRAY_SZ];
>> +static int shm_id;
>> +static char *args[ARGS_SZ];
>> static char *arg;
>> -static struct rlimit rl = {
>> - .rlim_cur = RLIM_INFINITY,
>> - .rlim_max = RLIM_INFINITY,
>> -};
>> +static long *arg_count;
>
>
> Two queries:
>
> 1. Can't we declare the arg_count just as a global variable? why
> should we take use of share memory, only for the loop counting?
It forks so that it can call exec without overwriting the test process
image. Global variables are copy-on-write for a child process (unless we
use clone()), so the parent's memory would not be updated by the
child. We need the parent to be updated so that, when the next child is
run, it already has the correct argument count saving a lot of calls to
exec.
>
>
> 2. The kernel patch limit all arg stack usage to at most 75% of _STK_LIM (6MB),
> and here the size of arg_len is 32*PAGE_SIZE. So it means that there
> almost only have 6MB/(PAGE_SIZE*32) numbers can be accepted in
> args[(*arg_count)], if it is a ppc64 machine(*arg_count == 3) that's
> OK, but if a system PAGE_SIZE > 192KB, then the test will be break and
> your loop is absolutely useless. About that, if we shrink the arg_len
> size, things would be better I guess.
That is true, but even on PPC64 with a default page size of 64Kb, the
default huge page size is 15MB (I think). So, on PPC64, we are only
doing a very basic test of exec on current kernels. Systems with page
sizes over 192KB seem even less likely to have huge pages smaller than
6MB.
However I don't see any harm in reducing the PAGE_SIZE coefficient to 1
and multiplying the ARGS_SZ by 32, this will make the test slower, but
more accurate at finding the maximum argument size while maintaining the
allocation size of the original reproducer.
--
Thank you,
Richard.
^ permalink raw reply [flat|nested] 8+ messages in thread
* [LTP] [PATCH] thp01: Find largest arguments size
2017-08-31 8:34 [LTP] [PATCH] thp01: Find largest arguments size Richard Palethorpe
2017-09-01 7:05 ` Li Wang
@ 2017-09-01 10:03 ` Cyril Hrubis
2017-09-01 14:13 ` [LTP] [PATCH v2] " Richard Palethorpe
1 sibling, 1 reply; 8+ messages in thread
From: Cyril Hrubis @ 2017-09-01 10:03 UTC (permalink / raw)
To: ltp
Hi!
> +#include <errno.h>
> #include <sys/types.h>
> #include <sys/resource.h>
> #include <sys/wait.h>
> @@ -38,56 +39,72 @@
> #include <stdlib.h>
> #include <unistd.h>
> #include "mem.h"
> +#include "tst_minmax.h"
> +#include "tst_safe_sysv_ipc.h"
>
> -#define ARRAY_SZ 256
> +#define ARGS_SZ 256
>
> -static int ps;
> -static long length;
> -static char *array[ARRAY_SZ];
> +static int shm_id;
> +static char *args[ARGS_SZ];
> static char *arg;
> -static struct rlimit rl = {
> - .rlim_cur = RLIM_INFINITY,
> - .rlim_max = RLIM_INFINITY,
> -};
> +static long *arg_count;
>
> static void thp_test(void)
> {
> - int i;
> - pid_t pid;
> -
> - switch (pid = SAFE_FORK()) {
> - case 0:
> - memset(arg, 'c', length - 1);
> - arg[length - 1] = '\0';
> - array[0] = "true";
> - for (i = 1; i < ARRAY_SZ - 1; i++)
> - array[i] = arg;
> - array[ARRAY_SZ - 1] = NULL;
> - if (setrlimit(RLIMIT_STACK, &rl) == -1) {
> - perror("setrlimit");
> - exit(1);
> - }
> - if (execvp("true", array) == -1) {
> - perror("execvp");
> - exit(1);
> - }
> - default:
> - tst_reap_children();
> + pid_t pid = SAFE_FORK();
> +
> + if (!arg_count)
> + tst_brk(TBROK, "No shared memory");
> +
> + if (!pid) {
> + args[*arg_count] = NULL;
> +
> + do {
> + TEST(execvp("true", args));
> + args[--(*arg_count)] = NULL;
> + } while (*arg_count > 0 && TEST_ERRNO == E2BIG);
Hmm, for how long does this loop runs? If it's more than
half of a second or so we should consider using binary
search to reach the maximal size of arguments...
> + tst_brk(TBROK | TTERRNO, "execvp(\"true\", ...)");
> }
>
> + tst_reap_children();
> tst_res(TPASS, "system didn't crash, pass.");
> }
>
> static void setup(void)
> {
> - ps = sysconf(_SC_PAGESIZE);
> - length = 32 * ps;
> - arg = SAFE_MALLOC(length);
> + struct rlimit rl = {
> + .rlim_cur = RLIM_INFINITY,
> + .rlim_max = RLIM_INFINITY,
> + };
> + int i;
> + long arg_len;
> +
> + shm_id = SAFE_SHMGET(IPC_PRIVATE, sizeof(long),
> + IPC_CREAT | IPC_EXCL);
> + arg_count = SAFE_SHMAT(shm_id, NULL, 0);
Can we, pretty please, use mmap() to map a page of shared memory instead
of using the System V shared memory that has ugly API and system
persistence?
> + arg_len = 32 * sysconf(_SC_PAGESIZE);
> + arg = SAFE_MALLOC(arg_len);
> + memset(arg, 'c', arg_len - 1);
> + arg[arg_len - 1] = '\0';
> +
> + args[0] = "true";
> + *arg_count = ARGS_SZ - 1;
> + for (i = 1; i < *arg_count; i++)
> + args[i] = arg;
> +
> + SAFE_SETRLIMIT(RLIMIT_STACK, &rl);
> }
>
> static void cleanup(void)
> {
> - free(arg);
> + if (arg)
> + free(arg);
> + if (arg_count)
> + SAFE_SHMDT(arg_count);
> + if (shm_id)
> + SAFE_SHMCTL(shm_id, IPC_RMID, NULL);
> }
>
> static struct tst_test test = {
> --
> 2.14.1
>
>
> --
> Mailing list info: https://lists.linux.it/listinfo/ltp
--
Cyril Hrubis
chrubis@suse.cz
^ permalink raw reply [flat|nested] 8+ messages in thread
* [LTP] [PATCH] thp01: Find largest arguments size
2017-09-01 9:34 ` Richard Palethorpe
@ 2017-09-01 10:44 ` Li Wang
0 siblings, 0 replies; 8+ messages in thread
From: Li Wang @ 2017-09-01 10:44 UTC (permalink / raw)
To: ltp
On Fri, Sep 1, 2017 at 5:34 PM, Richard Palethorpe <rpalethorpe@suse.de> wrote:
> Hello,
>
> Thanks for the review,
>>
>> 1. Can't we declare the arg_count just as a global variable? why
>> should we take use of share memory, only for the loop counting?
>
> It forks so that it can call exec without overwriting the test process
> image. Global variables are copy-on-write for a child process (unless we
> use clone()), so the parent's memory would not be updated by the
> child. We need the parent to be updated so that, when the next child is
> run, it already has the correct argument count saving a lot of calls to
> exec.
Yep! But for this test, it does not need to update 'arg_count' in the
parent process, and after fork a child, it call execvp() to create a
new process image. So I think here is OK to take use of global
variable.
Did I miss anything?
I do change the 'arg_count' to a global variable and get pass:
(see attachment)
static void thp_test(void)
{
pid_t pid = SAFE_FORK();
if (!pid) {
args[arg_count] = NULL;
do {
TEST(execvp("true", args));
args[--arg_count] = NULL;
printf("debuginfo: arg_count = %d\n", arg_count);
} while (arg_count > 0 && TEST_ERRNO == E2BIG);
tst_brk(TBROK | TTERRNO, "execvp(\"true\", ...)");
}
tst_reap_children();
tst_res(TPASS, "system didn't crash, pass.");
}
==========
# ./thp01
tst_test.c:908: INFO: Timeout per run is 0h 05m 00s
debuginfo: arg_count = 254
...
debuginfo: arg_count = 49
debuginfo: arg_count = 48
thp01.c:69: PASS: system didn't crash, pass.
Summary:
passed 1
failed 0
skipped 0
warnings 0
>>
>>
>> 2. The kernel patch limit all arg stack usage to at most 75% of _STK_LIM (6MB),
>> and here the size of arg_len is 32*PAGE_SIZE. So it means that there
>> almost only have 6MB/(PAGE_SIZE*32) numbers can be accepted in
>> args[(*arg_count)], if it is a ppc64 machine(*arg_count == 3) that's
>> OK, but if a system PAGE_SIZE > 192KB, then the test will be break and
>> your loop is absolutely useless. About that, if we shrink the arg_len
>> size, things would be better I guess.
>
> That is true, but even on PPC64 with a default page size of 64Kb, the
> default huge page size is 15MB (I think). So, on PPC64, we are only
> doing a very basic test of exec on current kernels. Systems with page
> sizes over 192KB seem even less likely to have huge pages smaller than
> 6MB.
>
> However I don't see any harm in reducing the PAGE_SIZE coefficient to 1
> and multiplying the ARGS_SZ by 32, this will make the test slower, but
> more accurate at finding the maximum argument size while maintaining the
> allocation size of the original reproducer.
>
> --
> Thank you,
> Richard.
--
Li Wang
liwang@redhat.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: thp01.c
Type: text/x-csrc
Size: 2434 bytes
Desc: not available
URL: <http://lists.linux.it/pipermail/ltp/attachments/20170901/27ea9726/attachment.c>
^ permalink raw reply [flat|nested] 8+ messages in thread
* [LTP] [PATCH v2] thp01: Find largest arguments size
2017-09-01 10:03 ` Cyril Hrubis
@ 2017-09-01 14:13 ` Richard Palethorpe
2017-09-04 11:29 ` Li Wang
0 siblings, 1 reply; 8+ messages in thread
From: Richard Palethorpe @ 2017-09-01 14:13 UTC (permalink / raw)
To: ltp
Because of kernel commit da029c11e6b1 the arguments size for exec has been
reduced considerably. This causes exec to fail with E2BIG, so we call it
repeatedly with a decreasing number of arguments until it is successful.
As far as I know, there is no other reliable and easy way to determine the
maximum argument length.
Signed-off-by: Richard Palethorpe <rpalethorpe@suse.com>
---
V2 - Reduced the argument length, but increased the argument array and
switched to a binary search
testcases/kernel/mem/thp/thp01.c | 96 ++++++++++++++++++++++++++++------------
1 file changed, 67 insertions(+), 29 deletions(-)
diff --git a/testcases/kernel/mem/thp/thp01.c b/testcases/kernel/mem/thp/thp01.c
index 101a9b5c8..cd14bec14 100644
--- a/testcases/kernel/mem/thp/thp01.c
+++ b/testcases/kernel/mem/thp/thp01.c
@@ -30,6 +30,7 @@
* ....
*/
+#include <errno.h>
#include <sys/types.h>
#include <sys/resource.h>
#include <sys/wait.h>
@@ -38,56 +39,92 @@
#include <stdlib.h>
#include <unistd.h>
#include "mem.h"
+#include "tst_minmax.h"
+#include "tst_safe_sysv_ipc.h"
-#define ARRAY_SZ 256
+#define ARGS_SZ 256 * 32
-static int ps;
-static long length;
-static char *array[ARRAY_SZ];
+static char *args[ARGS_SZ];
static char *arg;
-static struct rlimit rl = {
- .rlim_cur = RLIM_INFINITY,
- .rlim_max = RLIM_INFINITY,
-};
+static long *arg_count, *change, *arg_count_next;
static void thp_test(void)
{
- int i;
pid_t pid;
- switch (pid = SAFE_FORK()) {
- case 0:
- memset(arg, 'c', length - 1);
- arg[length - 1] = '\0';
- array[0] = "true";
- for (i = 1; i < ARRAY_SZ - 1; i++)
- array[i] = arg;
- array[ARRAY_SZ - 1] = NULL;
- if (setrlimit(RLIMIT_STACK, &rl) == -1) {
- perror("setrlimit");
- exit(1);
- }
- if (execvp("true", array) == -1) {
- perror("execvp");
- exit(1);
+ while (*change > 1) {
+ *arg_count = *arg_count_next;
+ *change /= 2;
+ *arg_count_next = *arg_count + *change;
+
+ pid = SAFE_FORK();
+ if (!pid) {
+ args[*arg_count] = NULL;
+
+ TEST(execvp("true", args));
+ if (TEST_ERRNO != E2BIG)
+ tst_brk(TBROK | TTERRNO, "execvp(\"true\", ...)");
+
+ *arg_count_next = *arg_count - *change;
+ exit(0);
}
- default:
+ tst_res(TINFO, "count: %ld, change: %ld, next: %ld",
+ *arg_count, *change, *arg_count_next);
tst_reap_children();
}
+ pid = SAFE_FORK();
+ if (!pid) {
+ args[*arg_count] = NULL;
+ do {
+ TEST(execvp("true", args));
+ if (TEST_ERRNO != E2BIG)
+ tst_brk(TBROK | TTERRNO, "execvp(\"true\", ...)");
+ tst_res(TINFO, "Binary search finished on 2BIG value: %ld",
+ *arg_count);
+ args[--(*arg_count)] = NULL;
+ } while (*arg_count > 0);
+ exit(0);
+ }
+
tst_res(TPASS, "system didn't crash, pass.");
}
static void setup(void)
{
- ps = sysconf(_SC_PAGESIZE);
- length = 32 * ps;
- arg = SAFE_MALLOC(length);
+ struct rlimit rl = {
+ .rlim_cur = RLIM_INFINITY,
+ .rlim_max = RLIM_INFINITY,
+ };
+ int i;
+ long arg_len;
+
+ arg_count = SAFE_MMAP(NULL, sizeof(*arg_count) * 3,
+ PROT_READ | PROT_WRITE,
+ MAP_ANONYMOUS | MAP_SHARED, -1, 0);
+ arg_count_next = arg_count + 1;
+ change = arg_count + 2;
+
+ arg_len = sysconf(_SC_PAGESIZE);
+ arg = SAFE_MALLOC(arg_len);
+ memset(arg, 'c', arg_len - 1);
+ arg[arg_len - 1] = '\0';
+
+ args[0] = "true";
+ *change = (ARGS_SZ - 1) / 2;
+ for (i = 1; i < ARGS_SZ - 1; i++)
+ args[i] = arg;
+ *arg_count_next += *change;
+
+ SAFE_SETRLIMIT(RLIMIT_STACK, &rl);
}
static void cleanup(void)
{
- free(arg);
+ if (arg)
+ free(arg);
+ if (arg_count)
+ SAFE_MUNMAP(arg_count, sizeof(*arg_count));
}
static struct tst_test test = {
@@ -96,4 +133,5 @@ static struct tst_test test = {
.setup = setup,
.cleanup = cleanup,
.test_all = thp_test,
+ .min_kver = "2.4",
};
--
2.14.1
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [LTP] [PATCH v2] thp01: Find largest arguments size
2017-09-01 14:13 ` [LTP] [PATCH v2] " Richard Palethorpe
@ 2017-09-04 11:29 ` Li Wang
2017-09-11 9:26 ` Richard Palethorpe
0 siblings, 1 reply; 8+ messages in thread
From: Li Wang @ 2017-09-04 11:29 UTC (permalink / raw)
To: ltp
On Fri, Sep 1, 2017 at 10:13 PM, Richard Palethorpe
<rpalethorpe@suse.com> wrote:
>
> static void thp_test(void)
> {
> - int i;
> pid_t pid;
>
> - switch (pid = SAFE_FORK()) {
> - case 0:
> - memset(arg, 'c', length - 1);
> - arg[length - 1] = '\0';
> - array[0] = "true";
> - for (i = 1; i < ARRAY_SZ - 1; i++)
> - array[i] = arg;
> - array[ARRAY_SZ - 1] = NULL;
> - if (setrlimit(RLIMIT_STACK, &rl) == -1) {
> - perror("setrlimit");
> - exit(1);
> - }
> - if (execvp("true", array) == -1) {
> - perror("execvp");
> - exit(1);
> + while (*change > 1) {
> + *arg_count = *arg_count_next;
> + *change /= 2;
> + *arg_count_next = *arg_count + *change;
> +
> + pid = SAFE_FORK();
> + if (!pid) {
> + args[*arg_count] = NULL;
> +
> + TEST(execvp("true", args));
Do binary search in shared memory is really good to performance.
But here maybe we could NOT find the largest arguments size rightly.
Cut from manual page:
"Traditionally, the functions execlp() and execvp() ignored all
errors except for the ones described above and ENOMEM and E2BIG, upon
which they returned. They now return if any error other than the ones
described above occurs."
Let me give an example, if we just add one line in your thp01.c as:
--- a/testcases/kernel/mem/thp/thp01.c
+++ b/testcases/kernel/mem/thp/thp01.c
@@ -65,6 +65,7 @@ static void thp_test(void)
if (TEST_ERRNO != E2BIG)
tst_brk(TBROK | TTERRNO,
"execvp(\"true\", ...)");
+ printf("debuginfo: *arg_count = %ld\n", *arg_count);
*arg_count_next = *arg_count - *change;
exit(0);
}
Compile and run thp01 as below:
# ./thp01
tst_test.c:908: INFO: Timeout per run is 0h 05m 00s
thp01.c:76: INFO: count: 4095, change: 2047, next: 6142
debuginfo: *arg_count = 4095
thp01.c:76: INFO: count: 2048, change: 1023, next: 3071
debuginfo: *arg_count = 2048
thp01.c:76: INFO: count: 1025, change: 511, next: 1536
thp01.c:76: INFO: count: 1536, change: 255, next: 1791
debuginfo: *arg_count = 1536
thp01.c:76: INFO: count: 1281, change: 127, next: 1408
thp01.c:76: INFO: count: 1408, change: 63, next: 1471
thp01.c:76: INFO: count: 1471, change: 31, next: 1502
thp01.c:76: INFO: count: 1502, change: 15, next: 1517
thp01.c:76: INFO: count: 1517, change: 7, next: 1524
thp01.c:76: INFO: count: 1524, change: 3, next: 1527
thp01.c:76: INFO: count: 1527, change: 1, next: 1528
thp01.c:95: PASS: system didn't crash, pass.
Summary:
passed 1
failed 0
skipped 0
warnings 0
Do you notice that some debuginfo sentence have not been printed?
because it will be never return if the children process run
successfully. Though the while loop finished and *chage == 1, the
*arg_count == 1527 is still not the largest value as we expected.
I'm not sure if that is on purpose, if yes, maybe you should not say
find largest arguments size in the subject. :)
>
> + pid = SAFE_FORK();
> + if (!pid) {
> + args[*arg_count] = NULL;
> + do {
> + TEST(execvp("true", args));
> + if (TEST_ERRNO != E2BIG)
> + tst_brk(TBROK | TTERRNO, "execvp(\"true\", ...)");
> + tst_res(TINFO, "Binary search finished on 2BIG value: %ld",
> + *arg_count);
> + args[--(*arg_count)] = NULL;
> + } while (*arg_count > 0);
> + exit(0);
> + }
> +
here also need: tst_reap_children();
> tst_res(TPASS, "system didn't crash, pass.");
> }
--
Li Wang
liwang@redhat.com
^ permalink raw reply [flat|nested] 8+ messages in thread
* [LTP] [PATCH v2] thp01: Find largest arguments size
2017-09-04 11:29 ` Li Wang
@ 2017-09-11 9:26 ` Richard Palethorpe
0 siblings, 0 replies; 8+ messages in thread
From: Richard Palethorpe @ 2017-09-11 9:26 UTC (permalink / raw)
To: ltp
Hello Li,
Li Wang writes:
> Cut from manual page:
> "Traditionally, the functions execlp() and execvp() ignored all
> errors except for the ones described above and ENOMEM and E2BIG, upon
> which they returned. They now return if any error other than the ones
> described above occurs."
>
> Let me give an example, if we just add one line in your thp01.c as:
>
> --- a/testcases/kernel/mem/thp/thp01.c
> +++ b/testcases/kernel/mem/thp/thp01.c
> @@ -65,6 +65,7 @@ static void thp_test(void)
> if (TEST_ERRNO != E2BIG)
> tst_brk(TBROK | TTERRNO,
> "execvp(\"true\", ...)");
>
> + printf("debuginfo: *arg_count = %ld\n", *arg_count);
> *arg_count_next = *arg_count - *change;
> exit(0);
> }
>
>
>
> Compile and run thp01 as below:
>
> # ./thp01
> tst_test.c:908: INFO: Timeout per run is 0h 05m 00s
> thp01.c:76: INFO: count: 4095, change: 2047, next: 6142
> debuginfo: *arg_count = 4095
> thp01.c:76: INFO: count: 2048, change: 1023, next: 3071
> debuginfo: *arg_count = 2048
> thp01.c:76: INFO: count: 1025, change: 511, next: 1536
> thp01.c:76: INFO: count: 1536, change: 255, next: 1791
> debuginfo: *arg_count = 1536
> thp01.c:76: INFO: count: 1281, change: 127, next: 1408
> thp01.c:76: INFO: count: 1408, change: 63, next: 1471
> thp01.c:76: INFO: count: 1471, change: 31, next: 1502
> thp01.c:76: INFO: count: 1502, change: 15, next: 1517
> thp01.c:76: INFO: count: 1517, change: 7, next: 1524
> thp01.c:76: INFO: count: 1524, change: 3, next: 1527
> thp01.c:76: INFO: count: 1527, change: 1, next: 1528
> thp01.c:95: PASS: system didn't crash, pass.
>
> Summary:
> passed 1
> failed 0
> skipped 0
> warnings 0
>
>
> Do you notice that some debuginfo sentence have not been printed?
> because it will be never return if the children process run
> successfully. Though the while loop finished and *chage == 1, the
> *arg_count == 1527 is still not the largest value as we expected.
>
> I'm not sure if that is on purpose, if yes, maybe you should not say
> find largest arguments size in the subject. :)
>
I set the initial value of change incorrectly, so it wasn't finding the
highest arg count value. It should now finish on either the correct
value or the correct value plus one (which is then corrected by the
linear search afterwards).
Note that I am setting *arg_count_next before and after
execvp(). Overwriting the first value if execvp fails. So I am
deliberately using the fact it does not return on success.
>
>>
>> + pid = SAFE_FORK();
>> + if (!pid) {
>> + args[*arg_count] = NULL;
>> + do {
>> + TEST(execvp("true", args));
>> + if (TEST_ERRNO != E2BIG)
>> + tst_brk(TBROK | TTERRNO, "execvp(\"true\", ...)");
>> + tst_res(TINFO, "Binary search finished on 2BIG value: %ld",
>> + *arg_count);
>> + args[--(*arg_count)] = NULL;
>> + } while (*arg_count > 0);
>> + exit(0);
>> + }
>> +
>
> here also need: tst_reap_children();
Thanks, added.
--
Thank you,
Richard.
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2017-09-11 9:26 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-08-31 8:34 [LTP] [PATCH] thp01: Find largest arguments size Richard Palethorpe
2017-09-01 7:05 ` Li Wang
2017-09-01 9:34 ` Richard Palethorpe
2017-09-01 10:44 ` Li Wang
2017-09-01 10:03 ` Cyril Hrubis
2017-09-01 14:13 ` [LTP] [PATCH v2] " Richard Palethorpe
2017-09-04 11:29 ` Li Wang
2017-09-11 9:26 ` Richard Palethorpe
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox