All of lore.kernel.org
 help / color / mirror / Atom feed
* [LTP] [PATCH] msgctl11: process message queues by portions
@ 2013-12-16 13:39 Stanislav Kholmanskikh
  2014-02-06 13:29 ` chrubis
  0 siblings, 1 reply; 11+ messages in thread
From: Stanislav Kholmanskikh @ 2013-12-16 13:39 UTC (permalink / raw)
  To: ltp-list; +Cc: vasily.isaenko

As /proc/sys/kernel/msgmni value scales with an amount of host memory,
on systems with several tens gigabytes of ram this testcase fails
with "Not enough free pids" error.

Now if the amount of free pids is not enough to use all the queues at once
we process the queues by portions (with the size based on amount of free pids).

Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
---
 testcases/kernel/syscalls/ipc/msgctl/msgctl11.c |   98 +++++++++++++----------
 1 files changed, 57 insertions(+), 41 deletions(-)

diff --git a/testcases/kernel/syscalls/ipc/msgctl/msgctl11.c b/testcases/kernel/syscalls/ipc/msgctl/msgctl11.c
index 57f4ae0..8bbb922 100644
--- a/testcases/kernel/syscalls/ipc/msgctl/msgctl11.c
+++ b/testcases/kernel/syscalls/ipc/msgctl/msgctl11.c
@@ -60,6 +60,7 @@ static int rkidarray[MAXNKIDS];
 static int wkidarray[MAXNKIDS];
 static int tid;
 static int nprocs, nreps, nkids, MSGMNI;
+static int maxnprocs;
 static int procstat;
 
 void setup(void);
@@ -67,6 +68,7 @@ void cleanup(void);
 
 static void term(int);
 static int dotest(key_t, int);
+static void dotest_iteration(int, int);
 static void cleanup_msgqueue(int i, int tid);
 
 #ifdef UCLINUX
@@ -84,8 +86,7 @@ static void do_child_3_uclinux();
 
 int main(int argc, char **argv)
 {
-	int i, j, ok, pid;
-	int count, status;
+	int i, j, ok;
 
 #ifdef UCLINUX
 	char *msg;
@@ -109,7 +110,6 @@ int main(int argc, char **argv)
 	if (argc == 1) {
 		/* Set default parameters */
 		nreps = MAXNREPS;
-		nprocs = MSGMNI;
 		nkids = maxnkids;
 	} else if (argc == 4) {
 		if (atoi(argv[1]) > MAXNREPS) {
@@ -120,13 +120,12 @@ int main(int argc, char **argv)
 		} else {
 			nreps = atoi(argv[1]);
 		}
-		if (atoi(argv[2]) > MSGMNI) {
+		if (atoi(argv[2]) > maxnprocs) {
 			tst_resm(TCONF,
 				 "Requested number of processes too large, setting to Max. of %d",
-				 MSGMNI);
-			nprocs = MSGMNI;
+				 maxnprocs);
 		} else {
-			nprocs = atoi(argv[2]);
+			maxnprocs = atoi(argv[2]);
 		}
 		if (atoi(argv[3]) > maxnkids) {
 			tst_resm(TCONF,
@@ -147,15 +146,14 @@ int main(int argc, char **argv)
 	srand48((unsigned)getpid() + (unsigned)(getppid() << 16));
 	tid = -1;
 
-	/* Setup signal handleing routine */
-	if (sigset(SIGTERM, term) == SIG_ERR) {
-		tst_resm(TFAIL, "Sigset SIGTERM failed");
-		tst_exit();
-	}
+	/* Setup signal handling routine */
+	if (sigset(SIGTERM, term) == SIG_ERR)
+		tst_brkm(TFAIL, cleanup, "Sigset SIGTERM failed");
+
 	/* Set up array of unique keys for use in allocating message
 	 * queues
 	 */
-	for (i = 0; i < nprocs; i++) {
+	for (i = 0; i < MSGMNI; i++) {
 		ok = 1;
 		do {
 			/* Get random key */
@@ -174,13 +172,45 @@ int main(int argc, char **argv)
 			}
 		} while (ok == 0);
 	}
-	/* Fork a number of processes (nprocs), each of which will
+	/* Fork a number of processes, each of which will
 	 * create a message queue with several (nkids) reader/writer
 	 * pairs which will read and write a number (iterations)
 	 * of random length messages with specific values (keys).
+	 *
+	 * We do not fork more than maxnprocs at a time and
+	 * we fork until all the message queues get used.
 	 */
 
+	if (MSGMNI < maxnprocs) {
+		dotest_iteration(0, MSGMNI);
+	} else {
+		for (i = 0; i < (MSGMNI / maxnprocs); i++)
+			dotest_iteration(i*(MSGMNI / maxnprocs),
+					maxnprocs);
+
+		dotest_iteration(i*(MSGMNI / maxnprocs),
+				MSGMNI % maxnprocs);
+	}
+
+	tst_resm(TPASS, "msgctl11 ran successfully!");
+
+	cleanup();
+	tst_exit();
+}
+
+static void dotest_iteration(int idx, int no_of_processes)
+{
+	key_t key;
+	int i, count, status;
+	pid_t pid;
+
+	nprocs = no_of_processes;
+
+	memset(pidarray, 0, MAXNPROCS * sizeof(*pidarray));
+
 	for (i = 0; i < nprocs; i++) {
+		key = keyarray[idx + i];
+
 		fflush(stdout);
 		if ((pid = FORK_OR_VFORK()) < 0) {
 			tst_resm(TFAIL,
@@ -190,13 +220,13 @@ int main(int argc, char **argv)
 		/* Child does this */
 		if (pid == 0) {
 #ifdef UCLINUX
-			if (self_exec(argv[0], "ndd", 1, keyarray[i], i) < 0) {
+			if (self_exec(argv0, "ndd", 1, key, i) < 0) {
 				tst_resm(TFAIL, "\tself_exec failed");
 				tst_exit();
 			}
 #else
 			procstat = 1;
-			exit(dotest(keyarray[i], i));
+			exit(dotest(key, i));
 #endif
 		}
 		pidarray[i] = pid;
@@ -227,13 +257,6 @@ int main(int argc, char **argv)
 			 count, nprocs);
 		tst_exit();
 	}
-
-	tst_resm(TPASS, "msgctl11 ran successfully!");
-
-	cleanup();
-
-	return (0);
-
 }
 
 #ifdef UCLINUX
@@ -453,33 +476,26 @@ void setup(void)
 
 	nr_msgqs = get_max_msgqueues();
 	if (nr_msgqs < 0)
-		cleanup();
+		tst_brkm(TBROK, cleanup, "get_max_msgqueues() failed");
 
 	MSGMNI = nr_msgqs - get_used_msgqueues();
-	if (MSGMNI <= 0) {
-		tst_resm(TBROK,
+	if (MSGMNI <= 0)
+		tst_brkm(TBROK, cleanup,
 			 "Max number of message queues already used, cannot create more.");
-		cleanup();
-	}
+
+	tst_resm(TINFO, "Found %d available message queues", MSGMNI);
 
 	free_pids = get_free_pids();
 	if (free_pids < 0) {
-		tst_resm(TBROK, "Can't obtain free_pid count");
-		tst_exit();
+		tst_brkm(TBROK, cleanup, "Can't obtain free_pid count");
+	} else if (!free_pids) {
+		tst_brkm(TBROK, cleanup, "No free pids");
 	}
 
-	else if (!free_pids) {
-		tst_resm(TBROK, "No free pids");
-		tst_exit();
-	}
+	maxnprocs = (free_pids / 2) / (1 + 2*maxnkids);
 
-	if ((MSGMNI * MAXNKIDS * 2) > (free_pids / 2)) {
-		maxnkids = ((free_pids / 4) / MSGMNI);
-		if (!maxnkids) {
-			tst_resm(TBROK, "Not enough free pids");
-			tst_exit();
-		}
-	}
+	if (!maxnprocs)
+		tst_brkm(TBROK, cleanup, "Not enough free pids");
 
 	tst_resm(TINFO, "Using upto %d pids", free_pids / 2);
 }
-- 
1.7.1


------------------------------------------------------------------------------
Rapidly troubleshoot problems before they affect your business. Most IT 
organizations don't have a clear picture of how application performance 
affects their revenue. With AppDynamics, you get 100% visibility into your 
Java,.NET, & PHP application. Start your 15-day FREE TRIAL of AppDynamics Pro!
http://pubads.g.doubleclick.net/gampad/clk?id=84349831&iu=/4140/ostg.clktrk
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [LTP] [PATCH] msgctl11: process message queues by portions
  2013-12-16 13:39 [LTP] [PATCH] msgctl11: process message queues by portions Stanislav Kholmanskikh
@ 2014-02-06 13:29 ` chrubis
       [not found]   ` <52F9EE70.9040700@oracle.com>
  0 siblings, 1 reply; 11+ messages in thread
From: chrubis @ 2014-02-06 13:29 UTC (permalink / raw)
  To: Stanislav Kholmanskikh; +Cc: vasily.isaenko, ltp-list

Hi!
> As /proc/sys/kernel/msgmni value scales with an amount of host memory,
> on systems with several tens gigabytes of ram this testcase fails
> with "Not enough free pids" error.
> 
> Now if the amount of free pids is not enough to use all the queues at once
> we process the queues by portions (with the size based on amount of free pids).

The general idea is fine, comments below.

> Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
> ---
>  testcases/kernel/syscalls/ipc/msgctl/msgctl11.c |   98 +++++++++++++----------
>  1 files changed, 57 insertions(+), 41 deletions(-)
> 
> diff --git a/testcases/kernel/syscalls/ipc/msgctl/msgctl11.c b/testcases/kernel/syscalls/ipc/msgctl/msgctl11.c
> index 57f4ae0..8bbb922 100644
> --- a/testcases/kernel/syscalls/ipc/msgctl/msgctl11.c
> +++ b/testcases/kernel/syscalls/ipc/msgctl/msgctl11.c
> @@ -60,6 +60,7 @@ static int rkidarray[MAXNKIDS];
>  static int wkidarray[MAXNKIDS];
>  static int tid;
>  static int nprocs, nreps, nkids, MSGMNI;
> +static int maxnprocs;
>  static int procstat;
>  
>  void setup(void);
> @@ -67,6 +68,7 @@ void cleanup(void);
>  
>  static void term(int);
>  static int dotest(key_t, int);
> +static void dotest_iteration(int, int);
>  static void cleanup_msgqueue(int i, int tid);
>  
>  #ifdef UCLINUX
> @@ -84,8 +86,7 @@ static void do_child_3_uclinux();
>  
>  int main(int argc, char **argv)
>  {
> -	int i, j, ok, pid;
> -	int count, status;
> +	int i, j, ok;
>  
>  #ifdef UCLINUX
>  	char *msg;
> @@ -109,7 +110,6 @@ int main(int argc, char **argv)
>  	if (argc == 1) {
>  		/* Set default parameters */
>  		nreps = MAXNREPS;
> -		nprocs = MSGMNI;
>  		nkids = maxnkids;
>  	} else if (argc == 4) {
>  		if (atoi(argv[1]) > MAXNREPS) {
> @@ -120,13 +120,12 @@ int main(int argc, char **argv)
>  		} else {
>  			nreps = atoi(argv[1]);
>  		}
> -		if (atoi(argv[2]) > MSGMNI) {
> +		if (atoi(argv[2]) > maxnprocs) {
>  			tst_resm(TCONF,
>  				 "Requested number of processes too large, setting to Max. of %d",
> -				 MSGMNI);
> -			nprocs = MSGMNI;
> +				 maxnprocs);
>  		} else {
> -			nprocs = atoi(argv[2]);
> +			maxnprocs = atoi(argv[2]);
>  		}
>  		if (atoi(argv[3]) > maxnkids) {
>  			tst_resm(TCONF,
> @@ -147,15 +146,14 @@ int main(int argc, char **argv)
>  	srand48((unsigned)getpid() + (unsigned)(getppid() << 16));
>  	tid = -1;
>  
> -	/* Setup signal handleing routine */
> -	if (sigset(SIGTERM, term) == SIG_ERR) {
> -		tst_resm(TFAIL, "Sigset SIGTERM failed");
> -		tst_exit();
> -	}
> +	/* Setup signal handling routine */
> +	if (sigset(SIGTERM, term) == SIG_ERR)
> +		tst_brkm(TFAIL, cleanup, "Sigset SIGTERM failed");

Please keep cleanup changes separate from functional changes.

Also the original testcase is quite messy and deserves to be cleaned
up...

>  	/* Set up array of unique keys for use in allocating message
>  	 * queues
>  	 */
> -	for (i = 0; i < nprocs; i++) {
> +	for (i = 0; i < MSGMNI; i++) {
>  		ok = 1;
>  		do {
>  			/* Get random key */
> @@ -174,13 +172,45 @@ int main(int argc, char **argv)
>  			}
>  		} while (ok == 0);
>  	}
> -	/* Fork a number of processes (nprocs), each of which will
> +	/* Fork a number of processes, each of which will
>  	 * create a message queue with several (nkids) reader/writer
>  	 * pairs which will read and write a number (iterations)
>  	 * of random length messages with specific values (keys).
> +	 *
> +	 * We do not fork more than maxnprocs at a time and
> +	 * we fork until all the message queues get used.
>  	 */
>  
> +	if (MSGMNI < maxnprocs) {

That should be <= otherwise you would unnecessarily call
dotest_iteration() with zero as the number of processes in the else
branch. It looks like it will work, but I would rather see this changed.

> +		dotest_iteration(0, MSGMNI);
> +	} else {
> +		for (i = 0; i < (MSGMNI / maxnprocs); i++)
> +			dotest_iteration(i*(MSGMNI / maxnprocs),
> +					maxnprocs);
> +
> +		dotest_iteration(i*(MSGMNI / maxnprocs),
> +				MSGMNI % maxnprocs);
> +	}
> +
> +	tst_resm(TPASS, "msgctl11 ran successfully!");
> +
> +	cleanup();
> +	tst_exit();
> +}
> +
> +static void dotest_iteration(int idx, int no_of_processes)
> +{

Technically the idx should be named offset or off.

> +	key_t key;
> +	int i, count, status;
> +	pid_t pid;
> +
> +	nprocs = no_of_processes;

This is hacky, you should either pass the number as a function parameter
or in global variable but doing both is messy.

> +	memset(pidarray, 0, MAXNPROCS * sizeof(*pidarray));

In this case MAXNPROCS * sizeof(*pidarray) is just a complicated way to
write sizeof(pidarray).

>  	for (i = 0; i < nprocs; i++) {
> +		key = keyarray[idx + i];
> +
>  		fflush(stdout);
>  		if ((pid = FORK_OR_VFORK()) < 0) {

I've just pushed a change that flushes the test output on
FORK_OR_VFORK() automatically. So we can remove all the fflush(stdout)
from the testcase.

>  			tst_resm(TFAIL,
> @@ -190,13 +220,13 @@ int main(int argc, char **argv)
>  		/* Child does this */
>  		if (pid == 0) {
>  #ifdef UCLINUX
> -			if (self_exec(argv[0], "ndd", 1, keyarray[i], i) < 0) {
> +			if (self_exec(argv0, "ndd", 1, key, i) < 0) {
>  				tst_resm(TFAIL, "\tself_exec failed");
>  				tst_exit();
>  			}
>  #else
>  			procstat = 1;
> -			exit(dotest(keyarray[i], i));
> +			exit(dotest(key, i));
>  #endif
>  		}
>  		pidarray[i] = pid;
> @@ -227,13 +257,6 @@ int main(int argc, char **argv)
>  			 count, nprocs);
>  		tst_exit();
>  	}
> -
> -	tst_resm(TPASS, "msgctl11 ran successfully!");
> -
> -	cleanup();
> -
> -	return (0);
> -
>  }
>  
>  #ifdef UCLINUX
> @@ -453,33 +476,26 @@ void setup(void)
>  
>  	nr_msgqs = get_max_msgqueues();
>  	if (nr_msgqs < 0)
> -		cleanup();
> +		tst_brkm(TBROK, cleanup, "get_max_msgqueues() failed");
>  
>  	MSGMNI = nr_msgqs - get_used_msgqueues();
> -	if (MSGMNI <= 0) {
> -		tst_resm(TBROK,
> +	if (MSGMNI <= 0)
> +		tst_brkm(TBROK, cleanup,
>  			 "Max number of message queues already used, cannot create more.");
> -		cleanup();
> -	}
> +
> +	tst_resm(TINFO, "Found %d available message queues", MSGMNI);
>  
>  	free_pids = get_free_pids();
>  	if (free_pids < 0) {
> -		tst_resm(TBROK, "Can't obtain free_pid count");
> -		tst_exit();
> +		tst_brkm(TBROK, cleanup, "Can't obtain free_pid count");
> +	} else if (!free_pids) {
> +		tst_brkm(TBROK, cleanup, "No free pids");
>  	}
>  
> -	else if (!free_pids) {
> -		tst_resm(TBROK, "No free pids");
> -		tst_exit();
> -	}
> +	maxnprocs = (free_pids / 2) / (1 + 2*maxnkids);

Perpahs this computation is complicated enough to deserve a comment.

> -	if ((MSGMNI * MAXNKIDS * 2) > (free_pids / 2)) {
> -		maxnkids = ((free_pids / 4) / MSGMNI);
> -		if (!maxnkids) {
> -			tst_resm(TBROK, "Not enough free pids");
> -			tst_exit();
> -		}
> -	}
> +	if (!maxnprocs)
> +		tst_brkm(TBROK, cleanup, "Not enough free pids");
>  
>  	tst_resm(TINFO, "Using upto %d pids", free_pids / 2);
>  }

-- 
Cyril Hrubis
chrubis@suse.cz

------------------------------------------------------------------------------
Managing the Performance of Cloud-Based Applications
Take advantage of what the Cloud has to offer - Avoid Common Pitfalls.
Read the Whitepaper.
http://pubads.g.doubleclick.net/gampad/clk?id=121051231&iu=/4140/ostg.clktrk
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [LTP] [PATCH] msgctl11: process message queues by portions
       [not found]   ` <52F9EE70.9040700@oracle.com>
@ 2014-02-11 14:23     ` chrubis
  2014-02-11 15:19       ` [LTP] [PATCH V2 1/2] msgctl11: cleanup and fflush removed Stanislav Kholmanskikh
  0 siblings, 1 reply; 11+ messages in thread
From: chrubis @ 2014-02-11 14:23 UTC (permalink / raw)
  To: Stanislav Kholmanskikh; +Cc: vasily.isaenko, ltp-list

Hi!
> > Technically the idx should be named offset or off.
> >
> >> +	key_t key;
> >> +	int i, count, status;
> >> +	pid_t pid;
> >> +
> >> +	nprocs = no_of_processes;
> >
> > This is hacky, you should either pass the number as a function parameter
> > or in global variable but doing both is messy.
> >
> 
> Yes, it's.... But I need to keep nprocs global, because it's used in the 
> signal handler.

I know, there is a cleanup that depends on it.

> So I either can update nprocs before calling dotest_iteration() (right 
> in main()) or do this inside dotest_iteration().
> 
> I think that doing so inside dotest_iteration() is not an excellent 
> solution but it's compact and this choice should be pretty clear for 
> further maintenance.
> 
> What do you think?

I would prefer setting nprocs right before you call dotest_iteration(),
IMHO that way the code follows the rule of least surprise.

-- 
Cyril Hrubis
chrubis@suse.cz

------------------------------------------------------------------------------
Android apps run on BlackBerry 10
Introducing the new BlackBerry 10.2.1 Runtime for Android apps.
Now with support for Jelly Bean, Bluetooth, Mapview and more.
Get your Android app in front of a whole new audience.  Start now.
http://pubads.g.doubleclick.net/gampad/clk?id=124407151&iu=/4140/ostg.clktrk
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [LTP] [PATCH V2 1/2] msgctl11: cleanup and fflush removed
  2014-02-11 14:23     ` chrubis
@ 2014-02-11 15:19       ` Stanislav Kholmanskikh
  2014-02-11 15:19         ` [LTP] [PATCH V2 2/2] msgctl11: process message queues by portions Stanislav Kholmanskikh
  0 siblings, 1 reply; 11+ messages in thread
From: Stanislav Kholmanskikh @ 2014-02-11 15:19 UTC (permalink / raw)
  To: ltp-list; +Cc: vasily.isaenko

Performed some cleanup and removed fflush() from the
testcase.

fflush() before FORK_OR_VFORK() is not needed because of
commit 3f0510cb2d18720e294e89fbdb4ce38e0ede47d6

fflush() before exit() is redundant.

Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
---
 testcases/kernel/syscalls/ipc/msgctl/msgctl11.c |   83 ++++++++--------------
 1 files changed, 30 insertions(+), 53 deletions(-)

diff --git a/testcases/kernel/syscalls/ipc/msgctl/msgctl11.c b/testcases/kernel/syscalls/ipc/msgctl/msgctl11.c
index 57f4ae0..63ff88f 100644
--- a/testcases/kernel/syscalls/ipc/msgctl/msgctl11.c
+++ b/testcases/kernel/syscalls/ipc/msgctl/msgctl11.c
@@ -77,9 +77,9 @@ static int pid_uclinux;
 static int child_process_uclinux;
 static int rkid_uclinux;
 
-static void do_child_1_uclinux();
-static void do_child_2_uclinux();
-static void do_child_3_uclinux();
+static void do_child_1_uclinux(void);
+static void do_child_2_uclinux(void);
+static void do_child_3_uclinux(void);
 #endif
 
 int main(int argc, char **argv)
@@ -137,21 +137,19 @@ int main(int argc, char **argv)
 			nkids = atoi(argv[3]);
 		}
 	} else {
-		tst_resm(TCONF,
+		tst_brkm(TCONF, cleanup,
 			 " Usage: %s [ number of iterations  number of processes number of read/write pairs ]",
 			 argv[0]);
-		tst_exit();
 	}
 
 	procstat = 0;
 	srand48((unsigned)getpid() + (unsigned)(getppid() << 16));
 	tid = -1;
 
-	/* Setup signal handleing routine */
-	if (sigset(SIGTERM, term) == SIG_ERR) {
-		tst_resm(TFAIL, "Sigset SIGTERM failed");
-		tst_exit();
-	}
+	/* Setup signal handling routine */
+	if (sigset(SIGTERM, term) == SIG_ERR)
+		tst_brkm(TFAIL, cleanup, "Sigset SIGTERM failed");
+
 	/* Set up array of unique keys for use in allocating message
 	 * queues
 	 */
@@ -181,18 +179,16 @@ int main(int argc, char **argv)
 	 */
 
 	for (i = 0; i < nprocs; i++) {
-		fflush(stdout);
-		if ((pid = FORK_OR_VFORK()) < 0) {
-			tst_resm(TFAIL,
-				 "\tFork failed (may be OK if under stress)");
-			tst_exit();
-		}
+		if ((pid = FORK_OR_VFORK()) < 0)
+			tst_brkm(TFAIL, cleanup,
+				 "Fork failed (may be OK if under stress)");
+
 		/* Child does this */
 		if (pid == 0) {
 #ifdef UCLINUX
 			if (self_exec(argv[0], "ndd", 1, keyarray[i], i) < 0) {
-				tst_resm(TFAIL, "\tself_exec failed");
-				tst_exit();
+				printf("\tself_exec failed\n");
+				exit(FAIL);
 			}
 #else
 			procstat = 1;
@@ -205,11 +201,9 @@ int main(int argc, char **argv)
 	count = 0;
 	while (1) {
 		if ((wait(&status)) > 0) {
-			if (status >> 8 != PASS) {
-				tst_resm(TFAIL, "Child exit status = %d",
-					 status >> 8);
-				tst_exit();
-			}
+			if (status >> 8 != PASS)
+				tst_brkm(TFAIL, cleanup,
+					"Child exit status = %d", status >> 8);
 			count++;
 		} else {
 			if (errno != EINTR) {
@@ -221,19 +215,15 @@ int main(int argc, char **argv)
 		}
 	}
 	/* Make sure proper number of children exited */
-	if (count != nprocs) {
-		tst_resm(TFAIL,
+	if (count != nprocs)
+		tst_brkm(TFAIL, cleanup,
 			 "Wrong number of children exited, Saw %d, Expected %d",
 			 count, nprocs);
-		tst_exit();
-	}
 
 	tst_resm(TPASS, "msgctl11 ran successfully!");
 
 	cleanup();
-
-	return (0);
-
+	tst_exit();
 }
 
 #ifdef UCLINUX
@@ -276,8 +266,8 @@ static void cleanup_msgqueue(int i, int tid)
 	}
 
 	if (msgctl(tid, IPC_RMID, 0) < 0) {
-		tst_resm(TFAIL | TERRNO, "Msgctl error in cleanup");
-		tst_exit();
+		printf("Msgctl error in cleanup_msgqueue %d\n", errno);
+		exit(FAIL);
 	}
 }
 
@@ -298,7 +288,6 @@ static int dotest(key_t key, int child_process)
 	exit_status = PASS;
 
 	for (i = 0; i < nkids; i++) {
-		fflush(stdout);
 		if ((pid = FORK_OR_VFORK()) < 0) {
 			printf("Fork failure in the first child of child group %d\n",
 				child_process);
@@ -321,7 +310,6 @@ static int dotest(key_t key, int child_process)
 #endif
 		}
 		rkidarray[i] = pid;
-		fflush(stdout);
 		if ((pid = FORK_OR_VFORK()) < 0) {
 			printf("Fork failure in the second child of child group %d\n",
 				child_process);
@@ -420,7 +408,6 @@ static void term(int sig)
 	}
 
 	if (procstat == 2) {
-		fflush(stdout);
 		exit(PASS);
 	}
 
@@ -453,32 +440,24 @@ void setup(void)
 
 	nr_msgqs = get_max_msgqueues();
 	if (nr_msgqs < 0)
-		cleanup();
+		tst_brkm(TBROK, cleanup, "get_max_msgqueues() failed");
 
 	MSGMNI = nr_msgqs - get_used_msgqueues();
-	if (MSGMNI <= 0) {
-		tst_resm(TBROK,
+	if (MSGMNI <= 0)
+		tst_brkm(TBROK, cleanup,
 			 "Max number of message queues already used, cannot create more.");
-		cleanup();
-	}
 
 	free_pids = get_free_pids();
 	if (free_pids < 0) {
-		tst_resm(TBROK, "Can't obtain free_pid count");
-		tst_exit();
-	}
-
-	else if (!free_pids) {
-		tst_resm(TBROK, "No free pids");
-		tst_exit();
+		tst_brkm(TBROK, cleanup, "Can't obtain free_pid count");
+	} else if (!free_pids) {
+		tst_brkm(TBROK, cleanup, "No free pids");
 	}
 
 	if ((MSGMNI * MAXNKIDS * 2) > (free_pids / 2)) {
 		maxnkids = ((free_pids / 4) / MSGMNI);
-		if (!maxnkids) {
-			tst_resm(TBROK, "Not enough free pids");
-			tst_exit();
-		}
+		if (!maxnkids)
+			tst_brkm(TBROK, cleanup, "Not enough free pids");
 	}
 
 	tst_resm(TINFO, "Using upto %d pids", free_pids / 2);
@@ -496,7 +475,6 @@ void cleanup(void)
 #ifdef DEBUG
 	tst_resm(TINFO, "Removing the message queue");
 #endif
-	fflush(stdout);
 	(void)msgctl(tid, IPC_RMID, NULL);
 	if ((status = msgctl(tid, IPC_STAT, NULL)) != -1) {
 		(void)msgctl(tid, IPC_RMID, NULL);
@@ -504,6 +482,5 @@ void cleanup(void)
 
 	}
 
-	fflush(stdout);
 	tst_rmdir();
 }
-- 
1.7.1


------------------------------------------------------------------------------
Android apps run on BlackBerry 10
Introducing the new BlackBerry 10.2.1 Runtime for Android apps.
Now with support for Jelly Bean, Bluetooth, Mapview and more.
Get your Android app in front of a whole new audience.  Start now.
http://pubads.g.doubleclick.net/gampad/clk?id=124407151&iu=/4140/ostg.clktrk
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [LTP] [PATCH V2 2/2] msgctl11: process message queues by portions
  2014-02-11 15:19       ` [LTP] [PATCH V2 1/2] msgctl11: cleanup and fflush removed Stanislav Kholmanskikh
@ 2014-02-11 15:19         ` Stanislav Kholmanskikh
  2014-02-21 18:11           ` chrubis
  0 siblings, 1 reply; 11+ messages in thread
From: Stanislav Kholmanskikh @ 2014-02-11 15:19 UTC (permalink / raw)
  To: ltp-list; +Cc: vasily.isaenko

As /proc/sys/kernel/msgmni value scales with an amount of host memory,
on systems with several tens gigabytes of ram this testcase fails
with "Not enough free pids" error.

Now if the amount of free pids is not enough to use all the queues at once
we process the queues by portions (with the size based on an amount of free pids).

Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
---
 testcases/kernel/syscalls/ipc/msgctl/msgctl11.c |   71 ++++++++++++++++-------
 1 files changed, 50 insertions(+), 21 deletions(-)

diff --git a/testcases/kernel/syscalls/ipc/msgctl/msgctl11.c b/testcases/kernel/syscalls/ipc/msgctl/msgctl11.c
index 63ff88f..9ef18da 100644
--- a/testcases/kernel/syscalls/ipc/msgctl/msgctl11.c
+++ b/testcases/kernel/syscalls/ipc/msgctl/msgctl11.c
@@ -60,6 +60,7 @@ static int rkidarray[MAXNKIDS];
 static int wkidarray[MAXNKIDS];
 static int tid;
 static int nprocs, nreps, nkids, MSGMNI;
+static int maxnprocs;
 static int procstat;
 
 void setup(void);
@@ -67,6 +68,7 @@ void cleanup(void);
 
 static void term(int);
 static int dotest(key_t, int);
+static void dotest_iteration(int off);
 static void cleanup_msgqueue(int i, int tid);
 
 #ifdef UCLINUX
@@ -84,8 +86,7 @@ static void do_child_3_uclinux(void);
 
 int main(int argc, char **argv)
 {
-	int i, j, ok, pid;
-	int count, status;
+	int i, j, ok;
 
 #ifdef UCLINUX
 	char *msg;
@@ -109,7 +110,6 @@ int main(int argc, char **argv)
 	if (argc == 1) {
 		/* Set default parameters */
 		nreps = MAXNREPS;
-		nprocs = MSGMNI;
 		nkids = maxnkids;
 	} else if (argc == 4) {
 		if (atoi(argv[1]) > MAXNREPS) {
@@ -120,13 +120,12 @@ int main(int argc, char **argv)
 		} else {
 			nreps = atoi(argv[1]);
 		}
-		if (atoi(argv[2]) > MSGMNI) {
+		if (atoi(argv[2]) > maxnprocs) {
 			tst_resm(TCONF,
 				 "Requested number of processes too large, setting to Max. of %d",
-				 MSGMNI);
-			nprocs = MSGMNI;
+				 maxnprocs);
 		} else {
-			nprocs = atoi(argv[2]);
+			maxnprocs = atoi(argv[2]);
 		}
 		if (atoi(argv[3]) > maxnkids) {
 			tst_resm(TCONF,
@@ -153,7 +152,7 @@ int main(int argc, char **argv)
 	/* Set up array of unique keys for use in allocating message
 	 * queues
 	 */
-	for (i = 0; i < nprocs; i++) {
+	for (i = 0; i < MSGMNI; i++) {
 		ok = 1;
 		do {
 			/* Get random key */
@@ -172,13 +171,45 @@ int main(int argc, char **argv)
 			}
 		} while (ok == 0);
 	}
-	/* Fork a number of processes (nprocs), each of which will
+	/* Fork a number of processes, each of which will
 	 * create a message queue with several (nkids) reader/writer
 	 * pairs which will read and write a number (iterations)
 	 * of random length messages with specific values (keys).
+	 *
+	 * We do not fork more than maxnprocs at a time and
+	 * we fork until all the message queues get used.
 	 */
 
+	if (MSGMNI <= maxnprocs) {
+		nprocs = MSGMNI;
+		dotest_iteration(0);
+	} else {
+		for (i = 0; i < (MSGMNI / maxnprocs); i++) {
+			nprocs = maxnprocs;
+			dotest_iteration(i*(MSGMNI / maxnprocs));
+		}
+
+		nprocs = MSGMNI % maxnprocs;
+		dotest_iteration(i*(MSGMNI / maxnprocs));
+	}
+
+	tst_resm(TPASS, "msgctl11 ran successfully!");
+
+	cleanup();
+	tst_exit();
+}
+
+static void dotest_iteration(int off)
+{
+	key_t key;
+	int i, count, status;
+	pid_t pid;
+
+	memset(pidarray, 0, sizeof(pidarray));
+
 	for (i = 0; i < nprocs; i++) {
+		key = keyarray[off + i];
+
 		if ((pid = FORK_OR_VFORK()) < 0)
 			tst_brkm(TFAIL, cleanup,
 				 "Fork failed (may be OK if under stress)");
@@ -186,13 +217,13 @@ int main(int argc, char **argv)
 		/* Child does this */
 		if (pid == 0) {
 #ifdef UCLINUX
-			if (self_exec(argv[0], "ndd", 1, keyarray[i], i) < 0) {
+			if (self_exec(argv0, "ndd", 1, key, i) < 0) {
 				printf("\tself_exec failed\n");
 				exit(FAIL);
 			}
 #else
 			procstat = 1;
-			exit(dotest(keyarray[i], i));
+			exit(dotest(key, i));
 #endif
 		}
 		pidarray[i] = pid;
@@ -219,11 +250,6 @@ int main(int argc, char **argv)
 		tst_brkm(TFAIL, cleanup,
 			 "Wrong number of children exited, Saw %d, Expected %d",
 			 count, nprocs);
-
-	tst_resm(TPASS, "msgctl11 ran successfully!");
-
-	cleanup();
-	tst_exit();
 }
 
 #ifdef UCLINUX
@@ -447,6 +473,8 @@ void setup(void)
 		tst_brkm(TBROK, cleanup,
 			 "Max number of message queues already used, cannot create more.");
 
+	tst_resm(TINFO, "Found %d available message queues", MSGMNI);
+
 	free_pids = get_free_pids();
 	if (free_pids < 0) {
 		tst_brkm(TBROK, cleanup, "Can't obtain free_pid count");
@@ -454,11 +482,12 @@ void setup(void)
 		tst_brkm(TBROK, cleanup, "No free pids");
 	}
 
-	if ((MSGMNI * MAXNKIDS * 2) > (free_pids / 2)) {
-		maxnkids = ((free_pids / 4) / MSGMNI);
-		if (!maxnkids)
-			tst_brkm(TBROK, cleanup, "Not enough free pids");
-	}
+	/* We don't use more than a half of available pids.
+	 * For each child we fork up to 2*maxnkids grandchildren. */
+	maxnprocs = (free_pids / 2) / (1 + 2 * maxnkids);
+
+	if (!maxnprocs)
+		tst_brkm(TBROK, cleanup, "Not enough free pids");
 
 	tst_resm(TINFO, "Using upto %d pids", free_pids / 2);
 }
-- 
1.7.1


------------------------------------------------------------------------------
Android apps run on BlackBerry 10
Introducing the new BlackBerry 10.2.1 Runtime for Android apps.
Now with support for Jelly Bean, Bluetooth, Mapview and more.
Get your Android app in front of a whole new audience.  Start now.
http://pubads.g.doubleclick.net/gampad/clk?id=124407151&iu=/4140/ostg.clktrk
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [LTP] [PATCH V2 2/2] msgctl11: process message queues by portions
  2014-02-11 15:19         ` [LTP] [PATCH V2 2/2] msgctl11: process message queues by portions Stanislav Kholmanskikh
@ 2014-02-21 18:11           ` chrubis
       [not found]             ` <530C5E99.6050809@oracle.com>
  0 siblings, 1 reply; 11+ messages in thread
From: chrubis @ 2014-02-21 18:11 UTC (permalink / raw)
  To: Stanislav Kholmanskikh; +Cc: vasily.isaenko, ltp-list

Hi!
> As /proc/sys/kernel/msgmni value scales with an amount of host memory,
> on systems with several tens gigabytes of ram this testcase fails
> with "Not enough free pids" error.
> 
> Now if the amount of free pids is not enough to use all the queues at once
> we process the queues by portions (with the size based on an amount of free pids).
> 
> Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
> ---
>  testcases/kernel/syscalls/ipc/msgctl/msgctl11.c |   71 ++++++++++++++++-------
>  1 files changed, 50 insertions(+), 21 deletions(-)
> 
> diff --git a/testcases/kernel/syscalls/ipc/msgctl/msgctl11.c b/testcases/kernel/syscalls/ipc/msgctl/msgctl11.c
> index 63ff88f..9ef18da 100644
> --- a/testcases/kernel/syscalls/ipc/msgctl/msgctl11.c
> +++ b/testcases/kernel/syscalls/ipc/msgctl/msgctl11.c
> @@ -60,6 +60,7 @@ static int rkidarray[MAXNKIDS];
>  static int wkidarray[MAXNKIDS];
>  static int tid;
>  static int nprocs, nreps, nkids, MSGMNI;
> +static int maxnprocs;
>  static int procstat;
>  
>  void setup(void);
> @@ -67,6 +68,7 @@ void cleanup(void);
>  
>  static void term(int);
>  static int dotest(key_t, int);
> +static void dotest_iteration(int off);
>  static void cleanup_msgqueue(int i, int tid);
>  
>  #ifdef UCLINUX
> @@ -84,8 +86,7 @@ static void do_child_3_uclinux(void);
>  
>  int main(int argc, char **argv)
>  {
> -	int i, j, ok, pid;
> -	int count, status;
> +	int i, j, ok;
>  
>  #ifdef UCLINUX
>  	char *msg;
> @@ -109,7 +110,6 @@ int main(int argc, char **argv)
>  	if (argc == 1) {
>  		/* Set default parameters */
>  		nreps = MAXNREPS;
> -		nprocs = MSGMNI;
>  		nkids = maxnkids;
>  	} else if (argc == 4) {
>  		if (atoi(argv[1]) > MAXNREPS) {
> @@ -120,13 +120,12 @@ int main(int argc, char **argv)
>  		} else {
>  			nreps = atoi(argv[1]);
>  		}
> -		if (atoi(argv[2]) > MSGMNI) {
> +		if (atoi(argv[2]) > maxnprocs) {
>  			tst_resm(TCONF,
>  				 "Requested number of processes too large, setting to Max. of %d",

                                 This should be TINFO

> -				 MSGMNI);
> -			nprocs = MSGMNI;
> +				 maxnprocs);
>  		} else {
> -			nprocs = atoi(argv[2]);
> +			maxnprocs = atoi(argv[2]);
>  		}
>  		if (atoi(argv[3]) > maxnkids) {
>  			tst_resm(TCONF,
> @@ -153,7 +152,7 @@ int main(int argc, char **argv)
>  	/* Set up array of unique keys for use in allocating message
>  	 * queues
>  	 */
> -	for (i = 0; i < nprocs; i++) {
> +	for (i = 0; i < MSGMNI; i++) {
>  		ok = 1;
>  		do {
>  			/* Get random key */
> @@ -172,13 +171,45 @@ int main(int argc, char **argv)
>  			}
>  		} while (ok == 0);
>  	}
> -	/* Fork a number of processes (nprocs), each of which will
> +	/* Fork a number of processes, each of which will
>  	 * create a message queue with several (nkids) reader/writer
>  	 * pairs which will read and write a number (iterations)
>  	 * of random length messages with specific values (keys).
> +	 *
> +	 * We do not fork more than maxnprocs at a time and
> +	 * we fork until all the message queues get used.
>  	 */
>  
> +	if (MSGMNI <= maxnprocs) {
> +		nprocs = MSGMNI;
> +		dotest_iteration(0);
> +	} else {
> +		for (i = 0; i < (MSGMNI / maxnprocs); i++) {
> +			nprocs = maxnprocs;
> +			dotest_iteration(i*(MSGMNI / maxnprocs));
> +		}
> +
> +		nprocs = MSGMNI % maxnprocs;
> +		dotest_iteration(i*(MSGMNI / maxnprocs));
> +	}
> +
> +	tst_resm(TPASS, "msgctl11 ran successfully!");
> +
> +	cleanup();
> +	tst_exit();
> +}
> +
> +static void dotest_iteration(int off)
> +{
> +	key_t key;
> +	int i, count, status;
> +	pid_t pid;
> +
> +	memset(pidarray, 0, sizeof(pidarray));
> +
>  	for (i = 0; i < nprocs; i++) {
> +		key = keyarray[off + i];
> +
>  		if ((pid = FORK_OR_VFORK()) < 0)
>  			tst_brkm(TFAIL, cleanup,
>  				 "Fork failed (may be OK if under stress)");
> @@ -186,13 +217,13 @@ int main(int argc, char **argv)
>  		/* Child does this */
>  		if (pid == 0) {
>  #ifdef UCLINUX
> -			if (self_exec(argv[0], "ndd", 1, keyarray[i], i) < 0) {
> +			if (self_exec(argv0, "ndd", 1, key, i) < 0) {
>  				printf("\tself_exec failed\n");
>  				exit(FAIL);
>  			}
>  #else
>  			procstat = 1;
> -			exit(dotest(keyarray[i], i));
> +			exit(dotest(key, i));
>  #endif
>  		}
>  		pidarray[i] = pid;
> @@ -219,11 +250,6 @@ int main(int argc, char **argv)
>  		tst_brkm(TFAIL, cleanup,
>  			 "Wrong number of children exited, Saw %d, Expected %d",
>  			 count, nprocs);
> -
> -	tst_resm(TPASS, "msgctl11 ran successfully!");
> -
> -	cleanup();
> -	tst_exit();
>  }
>  
>  #ifdef UCLINUX
> @@ -447,6 +473,8 @@ void setup(void)
>  		tst_brkm(TBROK, cleanup,
>  			 "Max number of message queues already used, cannot create more.");
>  
> +	tst_resm(TINFO, "Found %d available message queues", MSGMNI);
> +
>  	free_pids = get_free_pids();
>  	if (free_pids < 0) {
>  		tst_brkm(TBROK, cleanup, "Can't obtain free_pid count");
> @@ -454,11 +482,12 @@ void setup(void)
>  		tst_brkm(TBROK, cleanup, "No free pids");
>  	}
>  
> -	if ((MSGMNI * MAXNKIDS * 2) > (free_pids / 2)) {
> -		maxnkids = ((free_pids / 4) / MSGMNI);
> -		if (!maxnkids)
> -			tst_brkm(TBROK, cleanup, "Not enough free pids");
> -	}

Removing this part of the code makes the test run more than ten times
longer because now the maximal number of reader/writer pairs is set to
default value (10) and not to 1 which is what the code did previously. I
guess that this was intentional but it took me some time to figure that
out.

Now what I would like to do is to set maxkids default to 1 to preserve
the test behavior without any parameters and we can eventually add a few
more runtest entires with more interesting options too.

> +	/* We don't use more than a half of available pids.
> +	 * For each child we fork up to 2*maxnkids grandchildren. */
> +	maxnprocs = (free_pids / 2) / (1 + 2 * maxnkids);
> +
> +	if (!maxnprocs)
> +		tst_brkm(TBROK, cleanup, "Not enough free pids");
>  
>  	tst_resm(TINFO, "Using upto %d pids", free_pids / 2);
>  }

-- 
Cyril Hrubis
chrubis@suse.cz

------------------------------------------------------------------------------
Managing the Performance of Cloud-Based Applications
Take advantage of what the Cloud has to offer - Avoid Common Pitfalls.
Read the Whitepaper.
http://pubads.g.doubleclick.net/gampad/clk?id=121054471&iu=/4140/ostg.clktrk
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [LTP] [PATCH V2 2/2] msgctl11: process message queues by portions
       [not found]             ` <530C5E99.6050809@oracle.com>
@ 2014-02-25 12:25               ` chrubis
       [not found]                 ` <530CA0A3.403@oracle.com>
  0 siblings, 1 reply; 11+ messages in thread
From: chrubis @ 2014-02-25 12:25 UTC (permalink / raw)
  To: Stanislav Kholmanskikh; +Cc: vasily.isaenko, ltp-list

Hi!
> >> -	if ((MSGMNI * MAXNKIDS * 2) > (free_pids / 2)) {
> >> -		maxnkids = ((free_pids / 4) / MSGMNI);
> >> -		if (!maxnkids)
> >> -			tst_brkm(TBROK, cleanup, "Not enough free pids");
> >> -	}
> >
> > Removing this part of the code makes the test run more than ten times
> > longer because now the maximal number of reader/writer pairs is set to
> > default value (10) and not to 1 which is what the code did previously. I
> > guess that this was intentional but it took me some time to figure that
> > out.
> 
> Hmmm. Could you elaborate on that? About '1' value.
> 
> For example, given that:
>   free_pids = 32333
>   MSGMNI = 4000
>   MAXNKIDS = 10
> maxnkids will evaluate to 2. But if MSGMNI is 9000, the initial version 
> of msgctl11 will fail with "Not enough free pids".
> 
> In some situations this expression:
>    (MSGMNI * MAXNKIDS * 2) > (free_pids / 2)
> may evaluate to false, and maxnkids will be MAXNKIDS (10).
> 
> So the original version may execute faster under __some__ circumstances 
> where the maxnkids value is evaluated to be < 10.

On my systems /proc/sys/kernel/pid_max is set to 32768 and MSGMNI is
from 2000 to 7000 on most of the machines I've seen. So the value of
maxnkids was between 1 and 4 previously but it defaults to 10 after this
patch which increases the test runtime by minute or two.

Thinking of this again the most behavior preserving change would be:

	if ((MSGMNI * MAXNKIDS * 2) > (free_pids / 2))
	        maxnkids = MAX(1, ((free_pids / 4) / MSGMNI));

Which would scale the number of kids to the free pids but will not abort
the test if there is not enough free pids. The drawback is that the code
is complicated enough even without this change...

-- 
Cyril Hrubis
chrubis@suse.cz

------------------------------------------------------------------------------
Flow-based real-time traffic analytics software. Cisco certified tool.
Monitor traffic, SLAs, QoS, Medianet, WAAS etc. with NetFlow Analyzer
Customize your own dashboards, set traffic alerts and generate reports.
Network behavioral analysis & security monitoring. All-in-one tool.
http://pubads.g.doubleclick.net/gampad/clk?id=126839071&iu=/4140/ostg.clktrk
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [LTP] [PATCH V2 2/2] msgctl11: process message queues by portions
       [not found]                 ` <530CA0A3.403@oracle.com>
@ 2014-02-25 14:00                   ` chrubis
  2014-02-25 14:40                     ` [LTP] [PATCH V3 1/2] msgctl11: cleanup and fflush removed Stanislav Kholmanskikh
  2014-02-25 14:40                     ` [LTP] [PATCH V3 2/2] msgctl11: process message queues by portions Stanislav Kholmanskikh
  0 siblings, 2 replies; 11+ messages in thread
From: chrubis @ 2014-02-25 14:00 UTC (permalink / raw)
  To: Stanislav Kholmanskikh; +Cc: vasily.isaenko, ltp-list

Hi!
> > On my systems /proc/sys/kernel/pid_max is set to 32768 and MSGMNI is
> > from 2000 to 7000 on most of the machines I've seen. So the value of
> > maxnkids was between 1 and 4 previously but it defaults to 10 after this
> > patch which increases the test runtime by minute or two.
> >
> > Thinking of this again the most behavior preserving change would be:
> >
> > 	if ((MSGMNI * MAXNKIDS * 2) > (free_pids / 2))
> > 	        maxnkids = MAX(1, ((free_pids / 4) / MSGMNI));
> >
> > Which would scale the number of kids to the free pids but will not abort
> > the test if there is not enough free pids. The drawback is that the code
> > is complicated enough even without this change...
> >
> 
> According to the definition of recompute_msgmni() function (ipc/msg.c) 
> the limit by which the kernel may increase msgmni automatically is 
> IPCMNI. And IPCMNI is defined to be 32768 (include/linux/ipc.h).
> 
> So yes, the above approach (using MAX) should work on most systems 
> (maybe even all. I'm not sure about embedded stuff) where neither 
> pid_max nor msgmni values were modified manually. Manually changing 
> pid_max and/or msgmni values we can break the test.
> 
> Actually, I don't like the MAX-variant, because of the drawback you 
> mentioned. But the MAX-variant is sufficient for my needs.
> 
> So which patch set to prepare? :)

I would be inclined to set the default maxnkids value to something more
reasonable than 10, perhaps 2 or 3 would be a good compromise between
the test runtime and the amount of system stress the test does.

-- 
Cyril Hrubis
chrubis@suse.cz

------------------------------------------------------------------------------
Flow-based real-time traffic analytics software. Cisco certified tool.
Monitor traffic, SLAs, QoS, Medianet, WAAS etc. with NetFlow Analyzer
Customize your own dashboards, set traffic alerts and generate reports.
Network behavioral analysis & security monitoring. All-in-one tool.
http://pubads.g.doubleclick.net/gampad/clk?id=126839071&iu=/4140/ostg.clktrk
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [LTP] [PATCH V3 1/2] msgctl11: cleanup and fflush removed
  2014-02-25 14:00                   ` chrubis
@ 2014-02-25 14:40                     ` Stanislav Kholmanskikh
  2014-02-25 14:40                     ` [LTP] [PATCH V3 2/2] msgctl11: process message queues by portions Stanislav Kholmanskikh
  1 sibling, 0 replies; 11+ messages in thread
From: Stanislav Kholmanskikh @ 2014-02-25 14:40 UTC (permalink / raw)
  To: ltp-list; +Cc: vasily.isaenko

Performed some cleanup and removed fflush() from the
testcase.

fflush() before FORK_OR_VFORK() is not needed because of
commit 3f0510cb2d18720e294e89fbdb4ce38e0ede47d6

fflush() before exit() is redundant.

Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
---
 testcases/kernel/syscalls/ipc/msgctl/msgctl11.c |   83 ++++++++--------------
 1 files changed, 30 insertions(+), 53 deletions(-)

diff --git a/testcases/kernel/syscalls/ipc/msgctl/msgctl11.c b/testcases/kernel/syscalls/ipc/msgctl/msgctl11.c
index 57f4ae0..63ff88f 100644
--- a/testcases/kernel/syscalls/ipc/msgctl/msgctl11.c
+++ b/testcases/kernel/syscalls/ipc/msgctl/msgctl11.c
@@ -77,9 +77,9 @@ static int pid_uclinux;
 static int child_process_uclinux;
 static int rkid_uclinux;
 
-static void do_child_1_uclinux();
-static void do_child_2_uclinux();
-static void do_child_3_uclinux();
+static void do_child_1_uclinux(void);
+static void do_child_2_uclinux(void);
+static void do_child_3_uclinux(void);
 #endif
 
 int main(int argc, char **argv)
@@ -137,21 +137,19 @@ int main(int argc, char **argv)
 			nkids = atoi(argv[3]);
 		}
 	} else {
-		tst_resm(TCONF,
+		tst_brkm(TCONF, cleanup,
 			 " Usage: %s [ number of iterations  number of processes number of read/write pairs ]",
 			 argv[0]);
-		tst_exit();
 	}
 
 	procstat = 0;
 	srand48((unsigned)getpid() + (unsigned)(getppid() << 16));
 	tid = -1;
 
-	/* Setup signal handleing routine */
-	if (sigset(SIGTERM, term) == SIG_ERR) {
-		tst_resm(TFAIL, "Sigset SIGTERM failed");
-		tst_exit();
-	}
+	/* Setup signal handling routine */
+	if (sigset(SIGTERM, term) == SIG_ERR)
+		tst_brkm(TFAIL, cleanup, "Sigset SIGTERM failed");
+
 	/* Set up array of unique keys for use in allocating message
 	 * queues
 	 */
@@ -181,18 +179,16 @@ int main(int argc, char **argv)
 	 */
 
 	for (i = 0; i < nprocs; i++) {
-		fflush(stdout);
-		if ((pid = FORK_OR_VFORK()) < 0) {
-			tst_resm(TFAIL,
-				 "\tFork failed (may be OK if under stress)");
-			tst_exit();
-		}
+		if ((pid = FORK_OR_VFORK()) < 0)
+			tst_brkm(TFAIL, cleanup,
+				 "Fork failed (may be OK if under stress)");
+
 		/* Child does this */
 		if (pid == 0) {
 #ifdef UCLINUX
 			if (self_exec(argv[0], "ndd", 1, keyarray[i], i) < 0) {
-				tst_resm(TFAIL, "\tself_exec failed");
-				tst_exit();
+				printf("\tself_exec failed\n");
+				exit(FAIL);
 			}
 #else
 			procstat = 1;
@@ -205,11 +201,9 @@ int main(int argc, char **argv)
 	count = 0;
 	while (1) {
 		if ((wait(&status)) > 0) {
-			if (status >> 8 != PASS) {
-				tst_resm(TFAIL, "Child exit status = %d",
-					 status >> 8);
-				tst_exit();
-			}
+			if (status >> 8 != PASS)
+				tst_brkm(TFAIL, cleanup,
+					"Child exit status = %d", status >> 8);
 			count++;
 		} else {
 			if (errno != EINTR) {
@@ -221,19 +215,15 @@ int main(int argc, char **argv)
 		}
 	}
 	/* Make sure proper number of children exited */
-	if (count != nprocs) {
-		tst_resm(TFAIL,
+	if (count != nprocs)
+		tst_brkm(TFAIL, cleanup,
 			 "Wrong number of children exited, Saw %d, Expected %d",
 			 count, nprocs);
-		tst_exit();
-	}
 
 	tst_resm(TPASS, "msgctl11 ran successfully!");
 
 	cleanup();
-
-	return (0);
-
+	tst_exit();
 }
 
 #ifdef UCLINUX
@@ -276,8 +266,8 @@ static void cleanup_msgqueue(int i, int tid)
 	}
 
 	if (msgctl(tid, IPC_RMID, 0) < 0) {
-		tst_resm(TFAIL | TERRNO, "Msgctl error in cleanup");
-		tst_exit();
+		printf("Msgctl error in cleanup_msgqueue %d\n", errno);
+		exit(FAIL);
 	}
 }
 
@@ -298,7 +288,6 @@ static int dotest(key_t key, int child_process)
 	exit_status = PASS;
 
 	for (i = 0; i < nkids; i++) {
-		fflush(stdout);
 		if ((pid = FORK_OR_VFORK()) < 0) {
 			printf("Fork failure in the first child of child group %d\n",
 				child_process);
@@ -321,7 +310,6 @@ static int dotest(key_t key, int child_process)
 #endif
 		}
 		rkidarray[i] = pid;
-		fflush(stdout);
 		if ((pid = FORK_OR_VFORK()) < 0) {
 			printf("Fork failure in the second child of child group %d\n",
 				child_process);
@@ -420,7 +408,6 @@ static void term(int sig)
 	}
 
 	if (procstat == 2) {
-		fflush(stdout);
 		exit(PASS);
 	}
 
@@ -453,32 +440,24 @@ void setup(void)
 
 	nr_msgqs = get_max_msgqueues();
 	if (nr_msgqs < 0)
-		cleanup();
+		tst_brkm(TBROK, cleanup, "get_max_msgqueues() failed");
 
 	MSGMNI = nr_msgqs - get_used_msgqueues();
-	if (MSGMNI <= 0) {
-		tst_resm(TBROK,
+	if (MSGMNI <= 0)
+		tst_brkm(TBROK, cleanup,
 			 "Max number of message queues already used, cannot create more.");
-		cleanup();
-	}
 
 	free_pids = get_free_pids();
 	if (free_pids < 0) {
-		tst_resm(TBROK, "Can't obtain free_pid count");
-		tst_exit();
-	}
-
-	else if (!free_pids) {
-		tst_resm(TBROK, "No free pids");
-		tst_exit();
+		tst_brkm(TBROK, cleanup, "Can't obtain free_pid count");
+	} else if (!free_pids) {
+		tst_brkm(TBROK, cleanup, "No free pids");
 	}
 
 	if ((MSGMNI * MAXNKIDS * 2) > (free_pids / 2)) {
 		maxnkids = ((free_pids / 4) / MSGMNI);
-		if (!maxnkids) {
-			tst_resm(TBROK, "Not enough free pids");
-			tst_exit();
-		}
+		if (!maxnkids)
+			tst_brkm(TBROK, cleanup, "Not enough free pids");
 	}
 
 	tst_resm(TINFO, "Using upto %d pids", free_pids / 2);
@@ -496,7 +475,6 @@ void cleanup(void)
 #ifdef DEBUG
 	tst_resm(TINFO, "Removing the message queue");
 #endif
-	fflush(stdout);
 	(void)msgctl(tid, IPC_RMID, NULL);
 	if ((status = msgctl(tid, IPC_STAT, NULL)) != -1) {
 		(void)msgctl(tid, IPC_RMID, NULL);
@@ -504,6 +482,5 @@ void cleanup(void)
 
 	}
 
-	fflush(stdout);
 	tst_rmdir();
 }
-- 
1.7.1


------------------------------------------------------------------------------
Flow-based real-time traffic analytics software. Cisco certified tool.
Monitor traffic, SLAs, QoS, Medianet, WAAS etc. with NetFlow Analyzer
Customize your own dashboards, set traffic alerts and generate reports.
Network behavioral analysis & security monitoring. All-in-one tool.
http://pubads.g.doubleclick.net/gampad/clk?id=126839071&iu=/4140/ostg.clktrk
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [LTP] [PATCH V3 2/2] msgctl11: process message queues by portions
  2014-02-25 14:00                   ` chrubis
  2014-02-25 14:40                     ` [LTP] [PATCH V3 1/2] msgctl11: cleanup and fflush removed Stanislav Kholmanskikh
@ 2014-02-25 14:40                     ` Stanislav Kholmanskikh
  2014-03-05 10:45                       ` chrubis
  1 sibling, 1 reply; 11+ messages in thread
From: Stanislav Kholmanskikh @ 2014-02-25 14:40 UTC (permalink / raw)
  To: ltp-list; +Cc: vasily.isaenko

/proc/sys/kernel/msgmni value scales with the amount of the host memory.

On systems with several tens gigabytes of ram this value is rather big (and
even may reach its limit - IPCMI (32768), defined in include/linux/ipc.h) and
therefore the test case fails with "Not enough free pids" error.

Now we process all avaliable message queues by portions (with the size based
on the amount of free pids).

Signed-off-by: Stanislav Kholmanskikh <stanislav.kholmanskikh@oracle.com>
---
 testcases/kernel/syscalls/ipc/msgctl/msgctl11.c |   80 ++++++++++++++++-------
 1 files changed, 55 insertions(+), 25 deletions(-)

diff --git a/testcases/kernel/syscalls/ipc/msgctl/msgctl11.c b/testcases/kernel/syscalls/ipc/msgctl/msgctl11.c
index 63ff88f..2be34b8 100644
--- a/testcases/kernel/syscalls/ipc/msgctl/msgctl11.c
+++ b/testcases/kernel/syscalls/ipc/msgctl/msgctl11.c
@@ -52,6 +52,7 @@ int TST_TOTAL = 1;
 #define MAXNPROCS	 100000	/* Coldfire can't deal with 1000000 */
 #endif
 #define MAXNKIDS	10
+#define DEFNKIDS	2
 
 static int maxnkids = MAXNKIDS;	/* Used if pid_max is exceeded */
 static key_t keyarray[MAXNPROCS];
@@ -60,6 +61,7 @@ static int rkidarray[MAXNKIDS];
 static int wkidarray[MAXNKIDS];
 static int tid;
 static int nprocs, nreps, nkids, MSGMNI;
+static int maxnprocs;
 static int procstat;
 
 void setup(void);
@@ -67,6 +69,7 @@ void cleanup(void);
 
 static void term(int);
 static int dotest(key_t, int);
+static void dotest_iteration(int off);
 static void cleanup_msgqueue(int i, int tid);
 
 #ifdef UCLINUX
@@ -84,8 +87,7 @@ static void do_child_3_uclinux(void);
 
 int main(int argc, char **argv)
 {
-	int i, j, ok, pid;
-	int count, status;
+	int i, j, ok;
 
 #ifdef UCLINUX
 	char *msg;
@@ -109,27 +111,25 @@ int main(int argc, char **argv)
 	if (argc == 1) {
 		/* Set default parameters */
 		nreps = MAXNREPS;
-		nprocs = MSGMNI;
-		nkids = maxnkids;
+		nkids = DEFNKIDS;
 	} else if (argc == 4) {
 		if (atoi(argv[1]) > MAXNREPS) {
-			tst_resm(TCONF,
+			tst_resm(TINFO,
 				 "Requested number of iterations too large, setting to Max. of %d",
 				 MAXNREPS);
 			nreps = MAXNREPS;
 		} else {
 			nreps = atoi(argv[1]);
 		}
-		if (atoi(argv[2]) > MSGMNI) {
-			tst_resm(TCONF,
+		if (atoi(argv[2]) > maxnprocs) {
+			tst_resm(TINFO,
 				 "Requested number of processes too large, setting to Max. of %d",
-				 MSGMNI);
-			nprocs = MSGMNI;
+				 maxnprocs);
 		} else {
-			nprocs = atoi(argv[2]);
+			maxnprocs = atoi(argv[2]);
 		}
 		if (atoi(argv[3]) > maxnkids) {
-			tst_resm(TCONF,
+			tst_resm(TINFO,
 				 "Requested number of read/write pairs too large; setting to Max. of %d",
 				 maxnkids);
 			nkids = maxnkids;
@@ -153,7 +153,7 @@ int main(int argc, char **argv)
 	/* Set up array of unique keys for use in allocating message
 	 * queues
 	 */
-	for (i = 0; i < nprocs; i++) {
+	for (i = 0; i < MSGMNI; i++) {
 		ok = 1;
 		do {
 			/* Get random key */
@@ -172,13 +172,45 @@ int main(int argc, char **argv)
 			}
 		} while (ok == 0);
 	}
-	/* Fork a number of processes (nprocs), each of which will
+	/* Fork a number of processes, each of which will
 	 * create a message queue with several (nkids) reader/writer
 	 * pairs which will read and write a number (iterations)
 	 * of random length messages with specific values (keys).
+	 *
+	 * We do not fork more than maxnprocs at a time and
+	 * we fork until all the message queues get used.
 	 */
 
+	if (MSGMNI <= maxnprocs) {
+		nprocs = MSGMNI;
+		dotest_iteration(0);
+	} else {
+		for (i = 0; i < (MSGMNI / maxnprocs); i++) {
+			nprocs = maxnprocs;
+			dotest_iteration(i*(MSGMNI / maxnprocs));
+		}
+
+		nprocs = MSGMNI % maxnprocs;
+		dotest_iteration(i*(MSGMNI / maxnprocs));
+	}
+
+	tst_resm(TPASS, "msgctl11 ran successfully!");
+
+	cleanup();
+	tst_exit();
+}
+
+static void dotest_iteration(int off)
+{
+	key_t key;
+	int i, count, status;
+	pid_t pid;
+
+	memset(pidarray, 0, sizeof(pidarray));
+
 	for (i = 0; i < nprocs; i++) {
+		key = keyarray[off + i];
+
 		if ((pid = FORK_OR_VFORK()) < 0)
 			tst_brkm(TFAIL, cleanup,
 				 "Fork failed (may be OK if under stress)");
@@ -186,13 +218,13 @@ int main(int argc, char **argv)
 		/* Child does this */
 		if (pid == 0) {
 #ifdef UCLINUX
-			if (self_exec(argv[0], "ndd", 1, keyarray[i], i) < 0) {
+			if (self_exec(argv0, "ndd", 1, key, i) < 0) {
 				printf("\tself_exec failed\n");
 				exit(FAIL);
 			}
 #else
 			procstat = 1;
-			exit(dotest(keyarray[i], i));
+			exit(dotest(key, i));
 #endif
 		}
 		pidarray[i] = pid;
@@ -219,11 +251,6 @@ int main(int argc, char **argv)
 		tst_brkm(TFAIL, cleanup,
 			 "Wrong number of children exited, Saw %d, Expected %d",
 			 count, nprocs);
-
-	tst_resm(TPASS, "msgctl11 ran successfully!");
-
-	cleanup();
-	tst_exit();
 }
 
 #ifdef UCLINUX
@@ -447,6 +474,8 @@ void setup(void)
 		tst_brkm(TBROK, cleanup,
 			 "Max number of message queues already used, cannot create more.");
 
+	tst_resm(TINFO, "Found %d available message queues", MSGMNI);
+
 	free_pids = get_free_pids();
 	if (free_pids < 0) {
 		tst_brkm(TBROK, cleanup, "Can't obtain free_pid count");
@@ -454,11 +483,12 @@ void setup(void)
 		tst_brkm(TBROK, cleanup, "No free pids");
 	}
 
-	if ((MSGMNI * MAXNKIDS * 2) > (free_pids / 2)) {
-		maxnkids = ((free_pids / 4) / MSGMNI);
-		if (!maxnkids)
-			tst_brkm(TBROK, cleanup, "Not enough free pids");
-	}
+	/* We don't use more than a half of available pids.
+	 * For each child we fork up to 2*maxnkids grandchildren. */
+	maxnprocs = (free_pids / 2) / (1 + 2 * maxnkids);
+
+	if (!maxnprocs)
+		tst_brkm(TBROK, cleanup, "Not enough free pids");
 
 	tst_resm(TINFO, "Using upto %d pids", free_pids / 2);
 }
-- 
1.7.1


------------------------------------------------------------------------------
Flow-based real-time traffic analytics software. Cisco certified tool.
Monitor traffic, SLAs, QoS, Medianet, WAAS etc. with NetFlow Analyzer
Customize your own dashboards, set traffic alerts and generate reports.
Network behavioral analysis & security monitoring. All-in-one tool.
http://pubads.g.doubleclick.net/gampad/clk?id=126839071&iu=/4140/ostg.clktrk
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [LTP] [PATCH V3 2/2] msgctl11: process message queues by portions
  2014-02-25 14:40                     ` [LTP] [PATCH V3 2/2] msgctl11: process message queues by portions Stanislav Kholmanskikh
@ 2014-03-05 10:45                       ` chrubis
  0 siblings, 0 replies; 11+ messages in thread
From: chrubis @ 2014-03-05 10:45 UTC (permalink / raw)
  To: Stanislav Kholmanskikh; +Cc: vasily.isaenko, ltp-list

Hi!
> /proc/sys/kernel/msgmni value scales with the amount of the host memory.
> 
> On systems with several tens gigabytes of ram this value is rather big (and
> even may reach its limit - IPCMI (32768), defined in include/linux/ipc.h) and
> therefore the test case fails with "Not enough free pids" error.
> 
> Now we process all avaliable message queues by portions (with the size based
> on the amount of free pids).

Pushed, thanks.

-- 
Cyril Hrubis
chrubis@suse.cz

------------------------------------------------------------------------------
Subversion Kills Productivity. Get off Subversion & Make the Move to Perforce.
With Perforce, you get hassle-free workflows. Merge that actually works. 
Faster operations. Version large binaries.  Built-in WAN optimization and the
freedom to use Git, Perforce or both. Make the move to Perforce.
http://pubads.g.doubleclick.net/gampad/clk?id=122218951&iu=/4140/ostg.clktrk
_______________________________________________
Ltp-list mailing list
Ltp-list@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ltp-list

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2014-03-05 10:45 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-12-16 13:39 [LTP] [PATCH] msgctl11: process message queues by portions Stanislav Kholmanskikh
2014-02-06 13:29 ` chrubis
     [not found]   ` <52F9EE70.9040700@oracle.com>
2014-02-11 14:23     ` chrubis
2014-02-11 15:19       ` [LTP] [PATCH V2 1/2] msgctl11: cleanup and fflush removed Stanislav Kholmanskikh
2014-02-11 15:19         ` [LTP] [PATCH V2 2/2] msgctl11: process message queues by portions Stanislav Kholmanskikh
2014-02-21 18:11           ` chrubis
     [not found]             ` <530C5E99.6050809@oracle.com>
2014-02-25 12:25               ` chrubis
     [not found]                 ` <530CA0A3.403@oracle.com>
2014-02-25 14:00                   ` chrubis
2014-02-25 14:40                     ` [LTP] [PATCH V3 1/2] msgctl11: cleanup and fflush removed Stanislav Kholmanskikh
2014-02-25 14:40                     ` [LTP] [PATCH V3 2/2] msgctl11: process message queues by portions Stanislav Kholmanskikh
2014-03-05 10:45                       ` chrubis

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.