Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright 2014, Michael Ellerman, IBM Corp.
0004  */
0005 
0006 #include <signal.h>
0007 #include <stdio.h>
0008 #include <stdlib.h>
0009 #include <stdbool.h>
0010 #include <sys/types.h>
0011 #include <sys/wait.h>
0012 #include <unistd.h>
0013 
0014 #include "ebb.h"
0015 
0016 
0017 /*
0018  * Tests we can setup an EBB on our child. Nothing interesting happens, because
0019  * even though the event is enabled and running the child hasn't enabled the
0020  * actual delivery of the EBBs.
0021  */
0022 
0023 static int victim_child(union pipe read_pipe, union pipe write_pipe)
0024 {
0025     int i;
0026 
0027     FAIL_IF(wait_for_parent(read_pipe));
0028     FAIL_IF(notify_parent(write_pipe));
0029 
0030     /* Parent creates EBB event */
0031 
0032     FAIL_IF(wait_for_parent(read_pipe));
0033     FAIL_IF(notify_parent(write_pipe));
0034 
0035     /* Check the EBB is enabled by writing PMC1 */
0036     write_pmc1();
0037 
0038     /* EBB event is enabled here */
0039     for (i = 0; i < 1000000; i++) ;
0040 
0041     return 0;
0042 }
0043 
0044 int ebb_on_child(void)
0045 {
0046     union pipe read_pipe, write_pipe;
0047     struct event event;
0048     pid_t pid;
0049 
0050     SKIP_IF(!ebb_is_supported());
0051 
0052     FAIL_IF(pipe(read_pipe.fds) == -1);
0053     FAIL_IF(pipe(write_pipe.fds) == -1);
0054 
0055     pid = fork();
0056     if (pid == 0) {
0057         /* NB order of pipes looks reversed */
0058         exit(victim_child(write_pipe, read_pipe));
0059     }
0060 
0061     FAIL_IF(sync_with_child(read_pipe, write_pipe));
0062 
0063     /* Child is running now */
0064 
0065     event_init_named(&event, 0x1001e, "cycles");
0066     event_leader_ebb_init(&event);
0067 
0068     event.attr.exclude_kernel = 1;
0069     event.attr.exclude_hv = 1;
0070     event.attr.exclude_idle = 1;
0071 
0072     FAIL_IF(event_open_with_pid(&event, pid));
0073     FAIL_IF(ebb_event_enable(&event));
0074 
0075     FAIL_IF(sync_with_child(read_pipe, write_pipe));
0076 
0077     /* Child should just exit happily */
0078     FAIL_IF(wait_for_child(pid));
0079 
0080     event_close(&event);
0081 
0082     return 0;
0083 }
0084 
0085 int main(void)
0086 {
0087     return test_harness(ebb_on_child, "ebb_on_child");
0088 }