Performance_counter01 and performance_counter02 in kernel/performance_counters
actually have tests on perf_event_open system call, so we move these two tests
to syscalls/perf_event_open.

Signed-off-by: Xiaoguang Wang <[email protected]>
---
 testcases/kernel/Makefile                          |   1 -
 testcases/kernel/performance_counters/.gitignore   |   2 -
 testcases/kernel/performance_counters/Makefile     |  27 ---
 .../performance_counters/performance_counter01.c   | 108 ---------
 .../performance_counters/performance_counter02.c   | 242 ---------------------
 testcases/kernel/syscalls/.gitignore               |   2 +
 testcases/kernel/syscalls/perf_event_open/Makefile |  25 +++
 .../syscalls/perf_event_open/perf_event_open01.c   | 108 +++++++++
 .../syscalls/perf_event_open/perf_event_open02.c   | 242 +++++++++++++++++++++
 9 files changed, 377 insertions(+), 380 deletions(-)
 delete mode 100644 testcases/kernel/performance_counters/.gitignore
 delete mode 100644 testcases/kernel/performance_counters/Makefile
 delete mode 100644 
testcases/kernel/performance_counters/performance_counter01.c
 delete mode 100644 
testcases/kernel/performance_counters/performance_counter02.c
 create mode 100644 testcases/kernel/syscalls/perf_event_open/Makefile
 create mode 100644 
testcases/kernel/syscalls/perf_event_open/perf_event_open01.c
 create mode 100644 
testcases/kernel/syscalls/perf_event_open/perf_event_open02.c

diff --git a/testcases/kernel/Makefile b/testcases/kernel/Makefile
index 6bffe79..50a12fa 100644
--- a/testcases/kernel/Makefile
+++ b/testcases/kernel/Makefile
@@ -47,7 +47,6 @@ SUBDIRS                       += connectors \
                           logging \
                           mem \
                           numa \
-                          performance_counters \
                           pty \
                           sched \
                           security \
diff --git a/testcases/kernel/performance_counters/.gitignore 
b/testcases/kernel/performance_counters/.gitignore
deleted file mode 100644
index 1b69fd0..0000000
--- a/testcases/kernel/performance_counters/.gitignore
+++ /dev/null
@@ -1,2 +0,0 @@
-/performance_counter01
-/performance_counter02
diff --git a/testcases/kernel/performance_counters/Makefile 
b/testcases/kernel/performance_counters/Makefile
deleted file mode 100644
index 9c72fa3..0000000
--- a/testcases/kernel/performance_counters/Makefile
+++ /dev/null
@@ -1,27 +0,0 @@
-#
-#    kernel/performance_counters testcases Makefile.
-#
-#    Copyright (C) 2009, Cisco Systems Inc.
-#
-#    This program is free software; you can redistribute it and/or modify
-#    it under the terms of the GNU General Public License as published by
-#    the Free Software Foundation; either version 2 of the License, or
-#    (at your option) any later version.
-#
-#    This program is distributed in the hope that it will be useful,
-#    but WITHOUT ANY WARRANTY; without even the implied warranty of
-#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-#    GNU General Public License for more details.
-#
-#    You should have received a copy of the GNU General Public License along
-#    with this program; if not, write to the Free Software Foundation, Inc.,
-#    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Garrett Cooper, July 2009
-#
-
-top_srcdir     ?= ../../..
-
-include $(top_srcdir)/include/mk/testcases.mk
-
-include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/performance_counters/performance_counter01.c 
b/testcases/kernel/performance_counters/performance_counter01.c
deleted file mode 100644
index 6d7cbc9..0000000
--- a/testcases/kernel/performance_counters/performance_counter01.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/******************************************************************************/
-/*                                                                            
*/
-/* Ingo Molnar <[email protected]>, 2009                                         */
-/*                                                                            
*/
-/* This program is free software;  you can redistribute it and/or modify      
*/
-/* it under the terms of the GNU General Public License as published by       
*/
-/* the Free Software Foundation; either version 2 of the License, or          
*/
-/* (at your option) any later version.                                        
*/
-/*                                                                            
*/
-/* This program is distributed in the hope that it will be useful,            
*/
-/* but WITHOUT ANY WARRANTY;  without even the implied warranty of            
*/
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See                  
*/
-/* the GNU General Public License for more details.                           
*/
-/*                                                                            
*/
-/* You should have received a copy of the GNU General Public License          
*/
-/* along with this program;  if not, write to the Free Software               
*/
-/* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 
USA    */
-/*                                                                            
*/
-/******************************************************************************/
-
-/*
- * Very simple performance counter testcase.
- * Picked up from: http://lkml.org/lkml/2008/12/5/17
- */
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <sys/stat.h>
-#include <sys/time.h>
-#include <sys/uio.h>
-#include <linux/unistd.h>
-
-#include <assert.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdio.h>
-#include <fcntl.h>
-
-/* Harness Specific Include Files. */
-#include "test.h"
-#include "usctest.h"
-#include "linux_syscall_numbers.h"
-
-/* Extern Global Variables */
-extern int tst_count;
-extern char *TESTDIR;          /* temporary dir created by tst_tmpdir() */
-/* Global Variables */
-char *TCID = "performance_counter01";  /* test program identifier.          */
-int TST_TOTAL = 1;
-
-enum hw_event_types {
-       PERF_COUNT_CYCLES,
-       PERF_COUNT_INSTRUCTIONS,
-       PERF_COUNT_CACHE_REFERENCES,
-       PERF_COUNT_CACHE_MISSES,
-       PERF_COUNT_BRANCH_INSTRUCTIONS,
-       PERF_COUNT_BRANCH_MISSES,
-};
-
-void cleanup(void)
-{                              /* Stub function. */
-}
-
-int main(void)
-{
-
-       unsigned long long count1, count2;
-       int fd1, fd2, ret;
-
-       fd1 = ltp_syscall(__NR_perf_event_open,
-                     PERF_COUNT_INSTRUCTIONS, 0, 0, 0, -1);
-       if (fd1 < 0) {
-               tst_brkm(TBROK | TERRNO, cleanup,
-                        "Failed to create PERF_COUNT_INSTRUCTIONS fd");
-       }
-       fd2 = ltp_syscall(__NR_perf_event_open,
-                     PERF_COUNT_CACHE_MISSES, 0, 0, 0, -1);
-       if (fd2 < 0) {
-               tst_brkm(TBROK | TERRNO, cleanup,
-                        "Failed to create PERF_COUNT_CACHE_MISSES fd");
-       }
-
-       do {
-
-               ret = read(fd1, &count1, sizeof(count1));
-
-               if (ret == sizeof(count1)) {
-
-                       ret = read(fd2, &count2, sizeof(count2));
-
-                       if (ret == sizeof(count2)) {
-                               tst_resm(TINFO,
-                                        "counter1 value: %Ld instructions",
-                                        count1);
-                               tst_resm(TINFO,
-                                        "counter2 value: %Ld cachemisses",
-                                        count2);
-                               sleep(1);
-                       }
-
-               }
-
-       } while (ret == sizeof(unsigned long long));
-
-       tst_exit();
-
-}
diff --git a/testcases/kernel/performance_counters/performance_counter02.c 
b/testcases/kernel/performance_counters/performance_counter02.c
deleted file mode 100644
index 5402b81..0000000
--- a/testcases/kernel/performance_counters/performance_counter02.c
+++ /dev/null
@@ -1,242 +0,0 @@
-/******************************************************************************/
-/*                                                                            
*/
-/* Paul Mackerras <[email protected]>, 2009                                    
*/
-/*                                                                            
*/
-/* This program is free software;  you can redistribute it and/or modify      
*/
-/* it under the terms of the GNU General Public License as published by       
*/
-/* the Free Software Foundation; either version 2 of the License, or          
*/
-/* (at your option) any later version.                                        
*/
-/*                                                                            
*/
-/* This program is distributed in the hope that it will be useful,            
*/
-/* but WITHOUT ANY WARRANTY;  without even the implied warranty of            
*/
-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See                  
*/
-/* the GNU General Public License for more details.                           
*/
-/*                                                                            
*/
-/* You should have received a copy of the GNU General Public License          
*/
-/* along with this program;  if not, write to the Free Software               
*/
-/* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 
USA    */
-/*                                                                            
*/
-/******************************************************************************/
-/*
-Here's a little test program that checks whether software counters
-(specifically, the task clock counter) work correctly when they're in
-a group with hardware counters.
-
-What it does is to create several groups, each with one hardware
-counter, counting instructions, plus a task clock counter.  It needs
-to know an upper bound N on the number of hardware counters you have
-(N defaults to 8), and it creates N+4 groups to force them to be
-multiplexed.  It also creates an overall task clock counter.
-
-Then it spins for a while, and then stops all the counters and reads
-them.  It takes the total of the task clock counters in the groups and
-computes the ratio of that total to the overall execution time from
-the overall task clock counter.
-
-That ratio should be equal to the number of actual hardware counters
-that can count instructions.  If the task clock counters in the groups
-don't stop when their group gets taken off the PMU, the ratio will
-instead be close to N+4.  The program will declare that the test fails
-if the ratio is greater than N (actually, N + 0.0001 to allow for FP
-rounding errors).
-
-Could someone run this on x86 on the latest PCL tree and let me know
-what happens?  I don't have an x86 crash box easily to hand.  On
-powerpc, it passes, but I think that is because I am missing setting
-counter->prev_count in arch/powerpc/kernel/perf_counter.c, and I think
-that means that enabling/disabling a group with a task clock counter
-in it won't work correctly (I'll do a test program for that next).
-
-Usage is: ./performance_counter02 [-c num-hw-counters] [-v]
-
-Use -c N if you have more than 8 hardware counters.  The -v flag makes
-it print out the values of each counter.
-*/
-
-#include <stdio.h>
-#include <stddef.h>
-#include <stdlib.h>
-#include <string.h>
-#include <fcntl.h>
-#include <poll.h>
-#include <unistd.h>
-#include <errno.h>
-#include "config.h"
-#include <sys/prctl.h>
-#include <sys/types.h>
-#include <linux/types.h>
-
-/* Harness Specific Include Files. */
-#include "test.h"
-#include "usctest.h"
-#include "linux_syscall_numbers.h"
-
-#define PR_TASK_PERF_COUNTERS_DISABLE           31
-#define PR_TASK_PERF_COUNTERS_ENABLE            32
-
-/* Global Variables */
-char *TCID = "performance_counter02";  /* test program identifier.          */
-int TST_TOTAL = 1;             /* total number of tests in this file.   */
-
-typedef unsigned int u32;
-typedef unsigned long long u64;
-typedef long long s64;
-
-struct perf_counter_hw_event {
-       s64 type;
-       u64 irq_period;
-       u32 record_type;
-
-       u32 disabled:1,         /* off by default */
-        nmi:1,                 /* NMI sampling   */
-        raw:1,                 /* raw event type */
-        __reserved_1:29;
-       u64 __reserved_2;
-};
-
-enum hw_event_types {
-       PERF_COUNT_CYCLES = 0,
-       PERF_COUNT_INSTRUCTIONS = 1,
-       PERF_COUNT_CACHE_REFERENCES = 2,
-       PERF_COUNT_CACHE_MISSES = 3,
-       PERF_COUNT_BRANCH_INSTRUCTIONS = 4,
-       PERF_COUNT_BRANCH_MISSES = 5,
-
-       /*
-        * Special "software" counters provided by the kernel, even if
-        * the hardware does not support performance counters. These
-        * counters measure various physical and sw events of the
-        * kernel (and allow the profiling of them as well):
-        */
-       PERF_COUNT_CPU_CLOCK = -1,
-       PERF_COUNT_TASK_CLOCK = -2,
-       /*
-        * Future software events:
-        */
-       /* PERF_COUNT_PAGE_FAULTS       = -3,
-          PERF_COUNT_CONTEXT_SWITCHES  = -4, */
-};
-
-int sys_perf_counter_open(struct perf_counter_hw_event *hw_event,
-                         pid_t pid, int cpu, int group_fd, unsigned long flags)
-{
-       return ltp_syscall(__NR_perf_event_open, hw_event, pid, cpu, group_fd,
-                      flags);
-}
-
-#define MAX_CTRS       50
-#define LOOPS  1000000000
-
-void do_work(void)
-{
-       int i;
-
-       for (i = 0; i < LOOPS; ++i)
-               asm volatile (""::"g" (i));
-}
-
-void cleanup(void)
-{                              /* Stub function. */
-}
-
-int main(int ac, char **av)
-{
-       int tsk0;
-       int hwfd[MAX_CTRS], tskfd[MAX_CTRS];
-       struct perf_counter_hw_event tsk_event;
-       struct perf_counter_hw_event hw_event;
-       unsigned long long vt0, vt[MAX_CTRS], vh[MAX_CTRS], vtsum, vhsum;
-       int i, n, nhw;
-       int verbose = 0;
-       double ratio;
-
-       nhw = 8;
-       while ((i = getopt(ac, av, "c:v")) != -1) {
-               switch (i) {
-               case 'c':
-                       n = atoi(optarg);
-                       break;
-               case 'v':
-                       verbose = 1;
-                       break;
-               case '?':
-                       fprintf(stderr, "Usage: %s [-c #hwctrs] [-v]\n", av[0]);
-                       exit(1);
-               }
-       }
-
-       if (nhw < 0 || nhw > MAX_CTRS - 4) {
-               fprintf(stderr, "invalid number of hw counters specified: %d\n",
-                       nhw);
-               exit(1);
-       }
-
-       n = nhw + 4;
-
-       memset(&tsk_event, 0, sizeof(tsk_event));
-       tsk_event.type = PERF_COUNT_TASK_CLOCK;
-       tsk_event.disabled = 1;
-
-       memset(&hw_event, 0, sizeof(hw_event));
-       hw_event.disabled = 1;
-       hw_event.type = PERF_COUNT_INSTRUCTIONS;
-
-       tsk0 = sys_perf_counter_open(&tsk_event, 0, -1, -1, 0);
-       if (tsk0 == -1) {
-               tst_brkm(TBROK | TERRNO, cleanup,
-                        "perf_counter_open failed (1)");
-       } else {
-
-               tsk_event.disabled = 0;
-               for (i = 0; i < n; ++i) {
-                       hwfd[i] = sys_perf_counter_open(&hw_event, 0, -1,
-                                                       -1, 0);
-                       tskfd[i] = sys_perf_counter_open(&tsk_event, 0, -1,
-                                                        hwfd[i], 0);
-                       if (tskfd[i] == -1 || hwfd[i] == -1) {
-                               tst_brkm(TBROK | TERRNO, cleanup,
-                                        "perf_counter_open failed (2)");
-                       }
-               }
-       }
-
-       prctl(PR_TASK_PERF_COUNTERS_ENABLE);
-       do_work();
-       prctl(PR_TASK_PERF_COUNTERS_DISABLE);
-
-       if (read(tsk0, &vt0, sizeof(vt0)) != sizeof(vt0)) {
-               tst_brkm(TBROK | TERRNO, cleanup,
-                        "error reading task clock counter");
-       }
-
-       vtsum = vhsum = 0;
-       for (i = 0; i < n; ++i) {
-               if (read(tskfd[i], &vt[i], sizeof(vt[i])) != sizeof(vt[i]) ||
-                   read(hwfd[i], &vh[i], sizeof(vh[i])) != sizeof(vh[i])) {
-                       tst_brkm(TBROK | TERRNO, cleanup,
-                                "error reading counter(s)");
-               }
-               vtsum += vt[i];
-               vhsum += vh[i];
-       }
-
-       tst_resm(TINFO, "overall task clock: %lld", vt0);
-       tst_resm(TINFO, "hw sum: %lld, task clock sum: %lld", vhsum, vtsum);
-       if (verbose) {
-               printf("hw counters:");
-               for (i = 0; i < n; ++i)
-                       printf(" %lld", vh[i]);
-               printf("\ntask clock counters:");
-               for (i = 0; i < n; ++i)
-                       printf(" %lld", vt[i]);
-               printf("\n");
-       }
-       ratio = (double)vtsum / vt0;
-       tst_resm(TINFO, "ratio: %.2f", ratio);
-       if (ratio > nhw + 0.0001) {
-               tst_resm(TFAIL, "test failed (ratio was greater than )");
-       } else {
-               tst_resm(TINFO, "test passed");
-       }
-       tst_exit();
-}
diff --git a/testcases/kernel/syscalls/.gitignore 
b/testcases/kernel/syscalls/.gitignore
index d5c7bac..3afabd7 100644
--- a/testcases/kernel/syscalls/.gitignore
+++ b/testcases/kernel/syscalls/.gitignore
@@ -1029,3 +1029,5 @@
 /fanotify/fanotify03
 /fanotify/fanotify04
 /fanotify/fanotify05
+/perf_event_open/perf_event_open01
+/perf_event_open/perf_event_open02
diff --git a/testcases/kernel/syscalls/perf_event_open/Makefile 
b/testcases/kernel/syscalls/perf_event_open/Makefile
new file mode 100644
index 0000000..65276cf
--- /dev/null
+++ b/testcases/kernel/syscalls/perf_event_open/Makefile
@@ -0,0 +1,25 @@
+#
+#    Copyright (C) 2009, Cisco Systems Inc.
+#
+#    This program is free software; you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation; either version 2 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License along
+#    with this program; if not, write to the Free Software Foundation, Inc.,
+#    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Garrett Cooper, July 2009
+#
+
+top_srcdir     ?= ../../../..
+
+include $(top_srcdir)/include/mk/testcases.mk
+
+include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/testcases/kernel/syscalls/perf_event_open/perf_event_open01.c 
b/testcases/kernel/syscalls/perf_event_open/perf_event_open01.c
new file mode 100644
index 0000000..6d7cbc9
--- /dev/null
+++ b/testcases/kernel/syscalls/perf_event_open/perf_event_open01.c
@@ -0,0 +1,108 @@
+/******************************************************************************/
+/*                                                                            
*/
+/* Ingo Molnar <[email protected]>, 2009                                         */
+/*                                                                            
*/
+/* This program is free software;  you can redistribute it and/or modify      
*/
+/* it under the terms of the GNU General Public License as published by       
*/
+/* the Free Software Foundation; either version 2 of the License, or          
*/
+/* (at your option) any later version.                                        
*/
+/*                                                                            
*/
+/* This program is distributed in the hope that it will be useful,            
*/
+/* but WITHOUT ANY WARRANTY;  without even the implied warranty of            
*/
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See                  
*/
+/* the GNU General Public License for more details.                           
*/
+/*                                                                            
*/
+/* You should have received a copy of the GNU General Public License          
*/
+/* along with this program;  if not, write to the Free Software               
*/
+/* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 
USA    */
+/*                                                                            
*/
+/******************************************************************************/
+
+/*
+ * Very simple performance counter testcase.
+ * Picked up from: http://lkml.org/lkml/2008/12/5/17
+ */
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/uio.h>
+#include <linux/unistd.h>
+
+#include <assert.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+#include <fcntl.h>
+
+/* Harness Specific Include Files. */
+#include "test.h"
+#include "usctest.h"
+#include "linux_syscall_numbers.h"
+
+/* Extern Global Variables */
+extern int tst_count;
+extern char *TESTDIR;          /* temporary dir created by tst_tmpdir() */
+/* Global Variables */
+char *TCID = "performance_counter01";  /* test program identifier.          */
+int TST_TOTAL = 1;
+
+enum hw_event_types {
+       PERF_COUNT_CYCLES,
+       PERF_COUNT_INSTRUCTIONS,
+       PERF_COUNT_CACHE_REFERENCES,
+       PERF_COUNT_CACHE_MISSES,
+       PERF_COUNT_BRANCH_INSTRUCTIONS,
+       PERF_COUNT_BRANCH_MISSES,
+};
+
+void cleanup(void)
+{                              /* Stub function. */
+}
+
+int main(void)
+{
+
+       unsigned long long count1, count2;
+       int fd1, fd2, ret;
+
+       fd1 = ltp_syscall(__NR_perf_event_open,
+                     PERF_COUNT_INSTRUCTIONS, 0, 0, 0, -1);
+       if (fd1 < 0) {
+               tst_brkm(TBROK | TERRNO, cleanup,
+                        "Failed to create PERF_COUNT_INSTRUCTIONS fd");
+       }
+       fd2 = ltp_syscall(__NR_perf_event_open,
+                     PERF_COUNT_CACHE_MISSES, 0, 0, 0, -1);
+       if (fd2 < 0) {
+               tst_brkm(TBROK | TERRNO, cleanup,
+                        "Failed to create PERF_COUNT_CACHE_MISSES fd");
+       }
+
+       do {
+
+               ret = read(fd1, &count1, sizeof(count1));
+
+               if (ret == sizeof(count1)) {
+
+                       ret = read(fd2, &count2, sizeof(count2));
+
+                       if (ret == sizeof(count2)) {
+                               tst_resm(TINFO,
+                                        "counter1 value: %Ld instructions",
+                                        count1);
+                               tst_resm(TINFO,
+                                        "counter2 value: %Ld cachemisses",
+                                        count2);
+                               sleep(1);
+                       }
+
+               }
+
+       } while (ret == sizeof(unsigned long long));
+
+       tst_exit();
+
+}
diff --git a/testcases/kernel/syscalls/perf_event_open/perf_event_open02.c 
b/testcases/kernel/syscalls/perf_event_open/perf_event_open02.c
new file mode 100644
index 0000000..5402b81
--- /dev/null
+++ b/testcases/kernel/syscalls/perf_event_open/perf_event_open02.c
@@ -0,0 +1,242 @@
+/******************************************************************************/
+/*                                                                            
*/
+/* Paul Mackerras <[email protected]>, 2009                                    
*/
+/*                                                                            
*/
+/* This program is free software;  you can redistribute it and/or modify      
*/
+/* it under the terms of the GNU General Public License as published by       
*/
+/* the Free Software Foundation; either version 2 of the License, or          
*/
+/* (at your option) any later version.                                        
*/
+/*                                                                            
*/
+/* This program is distributed in the hope that it will be useful,            
*/
+/* but WITHOUT ANY WARRANTY;  without even the implied warranty of            
*/
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See                  
*/
+/* the GNU General Public License for more details.                           
*/
+/*                                                                            
*/
+/* You should have received a copy of the GNU General Public License          
*/
+/* along with this program;  if not, write to the Free Software               
*/
+/* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 
USA    */
+/*                                                                            
*/
+/******************************************************************************/
+/*
+Here's a little test program that checks whether software counters
+(specifically, the task clock counter) work correctly when they're in
+a group with hardware counters.
+
+What it does is to create several groups, each with one hardware
+counter, counting instructions, plus a task clock counter.  It needs
+to know an upper bound N on the number of hardware counters you have
+(N defaults to 8), and it creates N+4 groups to force them to be
+multiplexed.  It also creates an overall task clock counter.
+
+Then it spins for a while, and then stops all the counters and reads
+them.  It takes the total of the task clock counters in the groups and
+computes the ratio of that total to the overall execution time from
+the overall task clock counter.
+
+That ratio should be equal to the number of actual hardware counters
+that can count instructions.  If the task clock counters in the groups
+don't stop when their group gets taken off the PMU, the ratio will
+instead be close to N+4.  The program will declare that the test fails
+if the ratio is greater than N (actually, N + 0.0001 to allow for FP
+rounding errors).
+
+Could someone run this on x86 on the latest PCL tree and let me know
+what happens?  I don't have an x86 crash box easily to hand.  On
+powerpc, it passes, but I think that is because I am missing setting
+counter->prev_count in arch/powerpc/kernel/perf_counter.c, and I think
+that means that enabling/disabling a group with a task clock counter
+in it won't work correctly (I'll do a test program for that next).
+
+Usage is: ./performance_counter02 [-c num-hw-counters] [-v]
+
+Use -c N if you have more than 8 hardware counters.  The -v flag makes
+it print out the values of each counter.
+*/
+
+#include <stdio.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <unistd.h>
+#include <errno.h>
+#include "config.h"
+#include <sys/prctl.h>
+#include <sys/types.h>
+#include <linux/types.h>
+
+/* Harness Specific Include Files. */
+#include "test.h"
+#include "usctest.h"
+#include "linux_syscall_numbers.h"
+
+#define PR_TASK_PERF_COUNTERS_DISABLE           31
+#define PR_TASK_PERF_COUNTERS_ENABLE            32
+
+/* Global Variables */
+char *TCID = "performance_counter02";  /* test program identifier.          */
+int TST_TOTAL = 1;             /* total number of tests in this file.   */
+
+typedef unsigned int u32;
+typedef unsigned long long u64;
+typedef long long s64;
+
+struct perf_counter_hw_event {
+       s64 type;
+       u64 irq_period;
+       u32 record_type;
+
+       u32 disabled:1,         /* off by default */
+        nmi:1,                 /* NMI sampling   */
+        raw:1,                 /* raw event type */
+        __reserved_1:29;
+       u64 __reserved_2;
+};
+
+enum hw_event_types {
+       PERF_COUNT_CYCLES = 0,
+       PERF_COUNT_INSTRUCTIONS = 1,
+       PERF_COUNT_CACHE_REFERENCES = 2,
+       PERF_COUNT_CACHE_MISSES = 3,
+       PERF_COUNT_BRANCH_INSTRUCTIONS = 4,
+       PERF_COUNT_BRANCH_MISSES = 5,
+
+       /*
+        * Special "software" counters provided by the kernel, even if
+        * the hardware does not support performance counters. These
+        * counters measure various physical and sw events of the
+        * kernel (and allow the profiling of them as well):
+        */
+       PERF_COUNT_CPU_CLOCK = -1,
+       PERF_COUNT_TASK_CLOCK = -2,
+       /*
+        * Future software events:
+        */
+       /* PERF_COUNT_PAGE_FAULTS       = -3,
+          PERF_COUNT_CONTEXT_SWITCHES  = -4, */
+};
+
+int sys_perf_counter_open(struct perf_counter_hw_event *hw_event,
+                         pid_t pid, int cpu, int group_fd, unsigned long flags)
+{
+       return ltp_syscall(__NR_perf_event_open, hw_event, pid, cpu, group_fd,
+                      flags);
+}
+
+#define MAX_CTRS       50
+#define LOOPS  1000000000
+
+void do_work(void)
+{
+       int i;
+
+       for (i = 0; i < LOOPS; ++i)
+               asm volatile (""::"g" (i));
+}
+
+void cleanup(void)
+{                              /* Stub function. */
+}
+
+int main(int ac, char **av)
+{
+       int tsk0;
+       int hwfd[MAX_CTRS], tskfd[MAX_CTRS];
+       struct perf_counter_hw_event tsk_event;
+       struct perf_counter_hw_event hw_event;
+       unsigned long long vt0, vt[MAX_CTRS], vh[MAX_CTRS], vtsum, vhsum;
+       int i, n, nhw;
+       int verbose = 0;
+       double ratio;
+
+       nhw = 8;
+       while ((i = getopt(ac, av, "c:v")) != -1) {
+               switch (i) {
+               case 'c':
+                       n = atoi(optarg);
+                       break;
+               case 'v':
+                       verbose = 1;
+                       break;
+               case '?':
+                       fprintf(stderr, "Usage: %s [-c #hwctrs] [-v]\n", av[0]);
+                       exit(1);
+               }
+       }
+
+       if (nhw < 0 || nhw > MAX_CTRS - 4) {
+               fprintf(stderr, "invalid number of hw counters specified: %d\n",
+                       nhw);
+               exit(1);
+       }
+
+       n = nhw + 4;
+
+       memset(&tsk_event, 0, sizeof(tsk_event));
+       tsk_event.type = PERF_COUNT_TASK_CLOCK;
+       tsk_event.disabled = 1;
+
+       memset(&hw_event, 0, sizeof(hw_event));
+       hw_event.disabled = 1;
+       hw_event.type = PERF_COUNT_INSTRUCTIONS;
+
+       tsk0 = sys_perf_counter_open(&tsk_event, 0, -1, -1, 0);
+       if (tsk0 == -1) {
+               tst_brkm(TBROK | TERRNO, cleanup,
+                        "perf_counter_open failed (1)");
+       } else {
+
+               tsk_event.disabled = 0;
+               for (i = 0; i < n; ++i) {
+                       hwfd[i] = sys_perf_counter_open(&hw_event, 0, -1,
+                                                       -1, 0);
+                       tskfd[i] = sys_perf_counter_open(&tsk_event, 0, -1,
+                                                        hwfd[i], 0);
+                       if (tskfd[i] == -1 || hwfd[i] == -1) {
+                               tst_brkm(TBROK | TERRNO, cleanup,
+                                        "perf_counter_open failed (2)");
+                       }
+               }
+       }
+
+       prctl(PR_TASK_PERF_COUNTERS_ENABLE);
+       do_work();
+       prctl(PR_TASK_PERF_COUNTERS_DISABLE);
+
+       if (read(tsk0, &vt0, sizeof(vt0)) != sizeof(vt0)) {
+               tst_brkm(TBROK | TERRNO, cleanup,
+                        "error reading task clock counter");
+       }
+
+       vtsum = vhsum = 0;
+       for (i = 0; i < n; ++i) {
+               if (read(tskfd[i], &vt[i], sizeof(vt[i])) != sizeof(vt[i]) ||
+                   read(hwfd[i], &vh[i], sizeof(vh[i])) != sizeof(vh[i])) {
+                       tst_brkm(TBROK | TERRNO, cleanup,
+                                "error reading counter(s)");
+               }
+               vtsum += vt[i];
+               vhsum += vh[i];
+       }
+
+       tst_resm(TINFO, "overall task clock: %lld", vt0);
+       tst_resm(TINFO, "hw sum: %lld, task clock sum: %lld", vhsum, vtsum);
+       if (verbose) {
+               printf("hw counters:");
+               for (i = 0; i < n; ++i)
+                       printf(" %lld", vh[i]);
+               printf("\ntask clock counters:");
+               for (i = 0; i < n; ++i)
+                       printf(" %lld", vt[i]);
+               printf("\n");
+       }
+       ratio = (double)vtsum / vt0;
+       tst_resm(TINFO, "ratio: %.2f", ratio);
+       if (ratio > nhw + 0.0001) {
+               tst_resm(TFAIL, "test failed (ratio was greater than )");
+       } else {
+               tst_resm(TINFO, "test passed");
+       }
+       tst_exit();
+}
-- 
1.8.2.1


------------------------------------------------------------------------------
Put Bad Developers to Shame
Dominate Development with Jenkins Continuous Integration
Continuously Automate Build, Test & Deployment 
Start a new project now. Try Jenkins in the cloud.
http://p.sf.net/sfu/13600_Cloudbees
_______________________________________________
Ltp-list mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ltp-list

Reply via email to