There is a psi module that exists under kernel/sched/psi.
Add a basic test to test the psi.
This test just add the basic support to check cpu/memory/io interface.
Further test will be added on top of this.

Signed-off-by: Pintu Kumar <[email protected]>
---
 MAINTAINERS                              |  2 +
 tools/testing/selftests/sched/.gitignore |  1 +
 tools/testing/selftests/sched/Makefile   |  4 +-
 tools/testing/selftests/sched/config     |  1 +
 tools/testing/selftests/sched/psi_test.c | 85 ++++++++++++++++++++++++
 tools/testing/selftests/sched/run_psi.sh | 36 ++++++++++
 6 files changed, 127 insertions(+), 2 deletions(-)
 create mode 100644 tools/testing/selftests/sched/psi_test.c
 create mode 100755 tools/testing/selftests/sched/run_psi.sh

diff --git a/MAINTAINERS b/MAINTAINERS
index 84a73e90cfe8..d84ff9ca36a9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -18548,10 +18548,12 @@ F:    include/uapi/linux/pps.h
 PRESSURE STALL INFORMATION (PSI)
 M:     Johannes Weiner <[email protected]>
 M:     Suren Baghdasaryan <[email protected]>
+M:     Pintu Kumar <[email protected]>
 R:     Peter Ziljstra <[email protected]>
 S:     Maintained
 F:     include/linux/psi*
 F:     kernel/sched/psi.c
+F:     tools/testing/selftests/sched/psi_test.c
 
 PRINTK
 M:     Petr Mladek <[email protected]>
diff --git a/tools/testing/selftests/sched/.gitignore 
b/tools/testing/selftests/sched/.gitignore
index 6996d4654d92..2b15c11b93e6 100644
--- a/tools/testing/selftests/sched/.gitignore
+++ b/tools/testing/selftests/sched/.gitignore
@@ -1 +1,2 @@
 cs_prctl_test
+psi_test
diff --git a/tools/testing/selftests/sched/Makefile 
b/tools/testing/selftests/sched/Makefile
index 099ee9213557..795f6613eb2c 100644
--- a/tools/testing/selftests/sched/Makefile
+++ b/tools/testing/selftests/sched/Makefile
@@ -8,7 +8,7 @@ CFLAGS += -O2 -Wall -g -I./ $(KHDR_INCLUDES) -Wl,-rpath=./ \
          $(CLANG_FLAGS)
 LDLIBS += -lpthread
 
-TEST_GEN_FILES := cs_prctl_test
-TEST_PROGS := cs_prctl_test
+TEST_GEN_FILES := cs_prctl_test psi_test
+TEST_PROGS := cs_prctl_test run_psi.sh
 
 include ../lib.mk
diff --git a/tools/testing/selftests/sched/config 
b/tools/testing/selftests/sched/config
index e8b09aa7c0c4..287cccd434fd 100644
--- a/tools/testing/selftests/sched/config
+++ b/tools/testing/selftests/sched/config
@@ -1 +1,2 @@
 CONFIG_SCHED_DEBUG=y
+CONFIG_PSI=y
diff --git a/tools/testing/selftests/sched/psi_test.c 
b/tools/testing/selftests/sched/psi_test.c
new file mode 100644
index 000000000000..eeba138d2b39
--- /dev/null
+++ b/tools/testing/selftests/sched/psi_test.c
@@ -0,0 +1,85 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+
+
+struct load_avg {
+       float avg10;
+       float avg60;
+       float avg300;
+       unsigned long long total;
+};
+
+struct pressure {
+       struct load_avg some;
+       struct load_avg full;
+};
+
+
+int psi_get_data_from_proc_pressure(const char *path, struct pressure *p)
+{
+       FILE *fp;
+       int rc = -1;
+       int ret = 0;
+
+       if (path == NULL || p == NULL)
+               return -1;
+
+       fp = fopen(path, "r");
+       if (fp == NULL)
+               return -1;
+
+       while (!feof(fp)) {
+               rc = fscanf(fp, "some avg10=%f avg60=%f avg300=%f total=%llu\n",
+                       &p->some.avg10, &p->some.avg60, &p->some.avg300, 
&p->some.total);
+               if (rc < 1) {
+                       ret = -1;
+                       break;
+               }
+
+               /* Note: In some cases (cpu) full may not exists */
+               rc = fscanf(fp, "full avg10=%f avg60=%f avg300=%f total=%llu\n",
+                       &p->full.avg10, &p->full.avg60, &p->full.avg300, 
&p->full.total);
+               /* We don't care about full case. This is needed to avoid 
warnings */
+               rc = 0;
+       }
+
+       fclose(fp);
+
+       return ret;
+}
+
+int main(int argc, char *argv[])
+{
+       int ret;
+       struct pressure rs = {0,};
+       char path[32];
+
+       if (argc < 2) {
+               fprintf(stderr, "usage: %s <path>\n", argv[0]);
+               return -1;
+       }
+
+       memset(&rs, 0, sizeof(rs));
+       printf("Pressure data: %s\n", argv[1]);
+       snprintf(path, sizeof(path)-1, "/proc/pressure/%s", argv[1]);
+
+       ret = psi_get_data_from_proc_pressure(path, &rs);
+       if (ret < 0) {
+               printf("PSI <%s>: FAIL\n", argv[1]);
+               return -1;
+       }
+       printf("Some Avg10   = %5.2f\n", rs.some.avg10);
+       printf("Some Avg60   = %5.2f\n", rs.some.avg60);
+       printf("Some Avg300  = %5.2f\n", rs.some.avg300);
+       printf("Some Total  = %llu\n", rs.some.total);
+       printf("Full Avg10  = %5.2f\n", rs.full.avg10);
+       printf("Full Avg60  = %5.2f\n", rs.full.avg60);
+       printf("Full Avg300 = %5.2f\n", rs.full.avg300);
+       printf("Full Total  = %llu\n", rs.full.total);
+
+
+       return 0;
+}
diff --git a/tools/testing/selftests/sched/run_psi.sh 
b/tools/testing/selftests/sched/run_psi.sh
new file mode 100755
index 000000000000..d0b1c7ae3736
--- /dev/null
+++ b/tools/testing/selftests/sched/run_psi.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+
+
+# Kselftest framework requirement - SKIP code is 4.
+ksft_skip=4
+
+# Just one node check is enough to detect psi
+if [ ! -e /proc/pressure/cpu ]; then
+       echo "PSI not present..."
+       exit $ksft_skip
+fi
+
+echo ""
+./psi_test cpu
+if [ $? -ne 0 ]; then
+       echo "CPU - [FAIL]"
+else
+       echo "CPU - [PASS]"
+fi
+
+echo ""
+./psi_test memory
+if [ $? -ne 0 ]; then
+       echo "MEMORY - [FAIL]"
+else
+       echo "MEMORY - [PASS]"
+fi
+
+echo ""
+./psi_test io
+if [ $? -ne 0 ]; then
+       echo "IO - [FAIL]"
+else
+       echo "IO - [PASS]"
+fi
-- 
2.17.1


Reply via email to