All of lore.kernel.org
 help / color / mirror / Atom feed
* [LTP] [PATCH] mem/min_free_kbytes: Fix incorrect pass/fail accounting
@ 2026-07-08 12:42 Sachin Sant
  2026-07-08 15:25 ` [LTP] " linuxtestproject.agent
  0 siblings, 1 reply; 3+ messages in thread
From: Sachin Sant @ 2026-07-08 12:42 UTC (permalink / raw)
  To: ltp

When check_monitor() detected a violation (MemFree < min_free_kbytes) it
called tst_res(TFAIL, ...) from the child process, which atomically
incremented the shared results->failed counter, and then the child exited
with status 0. Back in the parent, min_free_kbytes_test() checked the
child exit status, found it was 0, and fell through to the unconditional
tst_res(TPASS, ...) at the end of the function.

This produced a misleading summary of 'passed 1 / failed 1' on violation:
the TFAIL from the monitor child was correctly counted, but the
unconditional TPASS that followed also added to the pass count regardless
of the violation.

Fix this by:
- Removing the tst_res(TFAIL, ...) from check_monitor() and replacing it
  with a local 'violated' flag; the TINFO diagnostic is kept so the exact
  MemFree and tune values are still logged.
- Returning 'violated' from check_monitor() and passing it directly to
  exit(), so the child exits non-zero when a violation was detected.
- Restructuring the parent's wait-result check so that TPASS is only
  emitted when the monitor child exited normally with status 0; any other
  termination (signal death, unexpected non-zero exit) maps to TFAIL.
  A violation exit (status == 1) emits a semantically accurate message;
  all other abnormal exits fall back to tst_strstatus() for diagnostics.

After the fix the summary correctly reflects the outcome:
  - No violation:  passed 1 / failed 0
  - Violation:     passed 0 / failed 1

Signed-off-by: Sachin Sant <sachinp@linux.ibm.com>
---
 .../kernel/mem/tunable/min_free_kbytes.c      | 28 +++++++++++--------
 1 file changed, 17 insertions(+), 11 deletions(-)

diff --git a/testcases/kernel/mem/tunable/min_free_kbytes.c b/testcases/kernel/mem/tunable/min_free_kbytes.c
index bdc9126c2..5bed61db5 100644
--- a/testcases/kernel/mem/tunable/min_free_kbytes.c
+++ b/testcases/kernel/mem/tunable/min_free_kbytes.c
@@ -41,7 +41,7 @@ static unsigned long total_mem;
 
 static void test_tune(unsigned long overcommit_policy);
 static int eatup_mem(unsigned long overcommit_policy);
-static void check_monitor(void);
+static int check_monitor(void);
 static void sighandler(int signo LTP_ATTRIBUTE_UNUSED);
 
 static void min_free_kbytes_test(void)
@@ -57,8 +57,7 @@ static void min_free_kbytes_test(void)
 	pid = SAFE_FORK();
 	if (pid == 0) {
 		/* startup the check monitor */
-		check_monitor();
-		exit(0);
+		exit(check_monitor());
 	}
 
 	test_tune(2);
@@ -68,11 +67,15 @@ static void min_free_kbytes_test(void)
 	SAFE_KILL(pid, SIGUSR1);
 	SAFE_WAITPID(pid, &status, WUNTRACED | WCONTINUED);
 
-	if (WIFEXITED(status) && WEXITSTATUS(status) != 0)
-		tst_res(TFAIL, "check_monitor child exit with status: %s",
-			tst_strstatus(status));
-
-	tst_res(TPASS, "min_free_kbytes test pass");
+	if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
+		if (WIFEXITED(status) && WEXITSTATUS(status) == 1)
+			tst_res(TFAIL, "MemFree dropped below min_free_kbytes");
+		else
+			tst_res(TFAIL, "check_monitor child failed: %s",
+				tst_strstatus(status));
+	} else {
+		tst_res(TPASS, "min_free_kbytes test pass");
+	}
 }
 
 static void test_tune(unsigned long overcommit_policy)
@@ -171,8 +174,9 @@ static int eatup_mem(unsigned long overcommit_policy)
 	return ret;
 }
 
-static void check_monitor(void)
+static int check_monitor(void)
 {
+	int violated = 0;
 	unsigned long tune;
 	unsigned long memfree;
 
@@ -182,12 +186,14 @@ static void check_monitor(void)
 
 		if (memfree < tune) {
 			tst_res(TINFO, "MemFree is %lu kB, "
-				 "min_free_kbytes is %lu kB", memfree, tune);
-			tst_res(TFAIL, "MemFree < min_free_kbytes");
+				"min_free_kbytes is %lu kB", memfree, tune);
+			violated = 1;
 		}
 
 		sleep(2);
 	}
+
+	return violated;
 }
 
 static void sighandler(int signo LTP_ATTRIBUTE_UNUSED)
-- 
2.39.1


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply related	[flat|nested] 3+ messages in thread
* [LTP] [PATCH v2] mem/min_free_kbytes: Fix incorrect pass/fail accounting
@ 2026-07-09  4:13 Sachin Sant
  2026-07-09  6:52 ` [LTP] " linuxtestproject.agent
  0 siblings, 1 reply; 3+ messages in thread
From: Sachin Sant @ 2026-07-09  4:13 UTC (permalink / raw)
  To: ltp

When check_monitor() detected a violation (MemFree < min_free_kbytes) it
called tst_res(TFAIL, ...) from the child process, which atomically
incremented the shared results->failed counter, and then the child exited
with status 0. Back in the parent, min_free_kbytes_test() checked the
child exit status, found it was 0, and fell through to the unconditional
tst_res(TPASS, ...) at the end of the function.

This produced a misleading summary of 'passed 1 / failed 1' on violation:
the TFAIL from the monitor child was correctly counted, but the
unconditional TPASS that followed also added to the pass count regardless
of the violation.

Fix this by moving TPASS/TFAIL reporting into check_monitor() in the child
process. Emit tst_res(TFAIL, ...) immediately on each individual violation
so that the TINFO diagnostic and its corresponding TFAIL are always paired;
the 'violated' flag is kept to suppress the final TPASS when any breach was
seen. Emit tst_res(TPASS, ...) only when no violation was observed across
the entire monitoring run.
The parent's wait-result block is changed to guard against unexpected
termination (signal death or non-zero exit) only; it emits no result for
the monitor outcome since that is already reported by the child. The
original condition WIFEXITED && WEXITSTATUS != 0 missed signal death;
the corrected condition is !WIFEXITED || WEXITSTATUS != 0.

After the fix the summary correctly reflects the outcome:
- No violation:  passed 1 / failed 0
- Violation:     passed 0 / failed N  (one TFAIL per breached sample)

Signed-off-by: Sachin Sant <sachinp@linux.ibm.com>
---
v1 -> v2:
- Addressed review comments by moving TPASS/TFAIL reporting
  into check_monitor() in the child process.

---
 testcases/kernel/mem/tunable/min_free_kbytes.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/testcases/kernel/mem/tunable/min_free_kbytes.c b/testcases/kernel/mem/tunable/min_free_kbytes.c
index bdc9126c2..132c8fe70 100644
--- a/testcases/kernel/mem/tunable/min_free_kbytes.c
+++ b/testcases/kernel/mem/tunable/min_free_kbytes.c
@@ -68,11 +68,9 @@ static void min_free_kbytes_test(void)
 	SAFE_KILL(pid, SIGUSR1);
 	SAFE_WAITPID(pid, &status, WUNTRACED | WCONTINUED);
 
-	if (WIFEXITED(status) && WEXITSTATUS(status) != 0)
-		tst_res(TFAIL, "check_monitor child exit with status: %s",
+	if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
+		tst_res(TFAIL, "check_monitor child failed: %s",
 			tst_strstatus(status));
-
-	tst_res(TPASS, "min_free_kbytes test pass");
 }
 
 static void test_tune(unsigned long overcommit_policy)
@@ -173,6 +171,7 @@ static int eatup_mem(unsigned long overcommit_policy)
 
 static void check_monitor(void)
 {
+	int violated = 0;
 	unsigned long tune;
 	unsigned long memfree;
 
@@ -182,12 +181,16 @@ static void check_monitor(void)
 
 		if (memfree < tune) {
 			tst_res(TINFO, "MemFree is %lu kB, "
-				 "min_free_kbytes is %lu kB", memfree, tune);
+				"min_free_kbytes is %lu kB", memfree, tune);
 			tst_res(TFAIL, "MemFree < min_free_kbytes");
+			violated = 1;
 		}
 
 		sleep(2);
 	}
+
+	if (!violated)
+		tst_res(TPASS, "min_free_kbytes test pass");
 }
 
 static void sighandler(int signo LTP_ATTRIBUTE_UNUSED)
-- 
2.39.1


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

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

end of thread, other threads:[~2026-07-09  6:53 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-08 12:42 [LTP] [PATCH] mem/min_free_kbytes: Fix incorrect pass/fail accounting Sachin Sant
2026-07-08 15:25 ` [LTP] " linuxtestproject.agent
  -- strict thread matches above, loose matches on Subject: below --
2026-07-09  4:13 [LTP] [PATCH v2] " Sachin Sant
2026-07-09  6:52 ` [LTP] " linuxtestproject.agent

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.