Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 #include <test_progs.h>
0003 
0004 void serial_test_tp_attach_query(void)
0005 {
0006     const int num_progs = 3;
0007     int i, j, bytes, efd, err, prog_fd[num_progs], pmu_fd[num_progs];
0008     __u32 duration = 0, info_len, saved_prog_ids[num_progs];
0009     const char *file = "./test_tracepoint.o";
0010     struct perf_event_query_bpf *query;
0011     struct perf_event_attr attr = {};
0012     struct bpf_object *obj[num_progs];
0013     struct bpf_prog_info prog_info;
0014     char buf[256];
0015 
0016     for (i = 0; i < num_progs; i++)
0017         obj[i] = NULL;
0018 
0019     snprintf(buf, sizeof(buf),
0020          "/sys/kernel/debug/tracing/events/sched/sched_switch/id");
0021     efd = open(buf, O_RDONLY, 0);
0022     if (CHECK(efd < 0, "open", "err %d errno %d\n", efd, errno))
0023         return;
0024     bytes = read(efd, buf, sizeof(buf));
0025     close(efd);
0026     if (CHECK(bytes <= 0 || bytes >= sizeof(buf),
0027           "read", "bytes %d errno %d\n", bytes, errno))
0028         return;
0029 
0030     attr.config = strtol(buf, NULL, 0);
0031     attr.type = PERF_TYPE_TRACEPOINT;
0032     attr.sample_type = PERF_SAMPLE_RAW | PERF_SAMPLE_CALLCHAIN;
0033     attr.sample_period = 1;
0034     attr.wakeup_events = 1;
0035 
0036     query = malloc(sizeof(*query) + sizeof(__u32) * num_progs);
0037     for (i = 0; i < num_progs; i++) {
0038         err = bpf_prog_test_load(file, BPF_PROG_TYPE_TRACEPOINT, &obj[i],
0039                     &prog_fd[i]);
0040         if (CHECK(err, "prog_load", "err %d errno %d\n", err, errno))
0041             goto cleanup1;
0042 
0043         bzero(&prog_info, sizeof(prog_info));
0044         prog_info.jited_prog_len = 0;
0045         prog_info.xlated_prog_len = 0;
0046         prog_info.nr_map_ids = 0;
0047         info_len = sizeof(prog_info);
0048         err = bpf_obj_get_info_by_fd(prog_fd[i], &prog_info, &info_len);
0049         if (CHECK(err, "bpf_obj_get_info_by_fd", "err %d errno %d\n",
0050               err, errno))
0051             goto cleanup1;
0052         saved_prog_ids[i] = prog_info.id;
0053 
0054         pmu_fd[i] = syscall(__NR_perf_event_open, &attr, -1 /* pid */,
0055                     0 /* cpu 0 */, -1 /* group id */,
0056                     0 /* flags */);
0057         if (CHECK(pmu_fd[i] < 0, "perf_event_open", "err %d errno %d\n",
0058               pmu_fd[i], errno))
0059             goto cleanup2;
0060         err = ioctl(pmu_fd[i], PERF_EVENT_IOC_ENABLE, 0);
0061         if (CHECK(err, "perf_event_ioc_enable", "err %d errno %d\n",
0062               err, errno))
0063             goto cleanup3;
0064 
0065         if (i == 0) {
0066             /* check NULL prog array query */
0067             query->ids_len = num_progs;
0068             err = ioctl(pmu_fd[i], PERF_EVENT_IOC_QUERY_BPF, query);
0069             if (CHECK(err || query->prog_cnt != 0,
0070                   "perf_event_ioc_query_bpf",
0071                   "err %d errno %d query->prog_cnt %u\n",
0072                   err, errno, query->prog_cnt))
0073                 goto cleanup3;
0074         }
0075 
0076         err = ioctl(pmu_fd[i], PERF_EVENT_IOC_SET_BPF, prog_fd[i]);
0077         if (CHECK(err, "perf_event_ioc_set_bpf", "err %d errno %d\n",
0078               err, errno))
0079             goto cleanup3;
0080 
0081         if (i == 1) {
0082             /* try to get # of programs only */
0083             query->ids_len = 0;
0084             err = ioctl(pmu_fd[i], PERF_EVENT_IOC_QUERY_BPF, query);
0085             if (CHECK(err || query->prog_cnt != 2,
0086                   "perf_event_ioc_query_bpf",
0087                   "err %d errno %d query->prog_cnt %u\n",
0088                   err, errno, query->prog_cnt))
0089                 goto cleanup3;
0090 
0091             /* try a few negative tests */
0092             /* invalid query pointer */
0093             err = ioctl(pmu_fd[i], PERF_EVENT_IOC_QUERY_BPF,
0094                     (struct perf_event_query_bpf *)0x1);
0095             if (CHECK(!err || errno != EFAULT,
0096                   "perf_event_ioc_query_bpf",
0097                   "err %d errno %d\n", err, errno))
0098                 goto cleanup3;
0099 
0100             /* no enough space */
0101             query->ids_len = 1;
0102             err = ioctl(pmu_fd[i], PERF_EVENT_IOC_QUERY_BPF, query);
0103             if (CHECK(!err || errno != ENOSPC || query->prog_cnt != 2,
0104                   "perf_event_ioc_query_bpf",
0105                   "err %d errno %d query->prog_cnt %u\n",
0106                   err, errno, query->prog_cnt))
0107                 goto cleanup3;
0108         }
0109 
0110         query->ids_len = num_progs;
0111         err = ioctl(pmu_fd[i], PERF_EVENT_IOC_QUERY_BPF, query);
0112         if (CHECK(err || query->prog_cnt != (i + 1),
0113               "perf_event_ioc_query_bpf",
0114               "err %d errno %d query->prog_cnt %u\n",
0115               err, errno, query->prog_cnt))
0116             goto cleanup3;
0117         for (j = 0; j < i + 1; j++)
0118             if (CHECK(saved_prog_ids[j] != query->ids[j],
0119                   "perf_event_ioc_query_bpf",
0120                   "#%d saved_prog_id %x query prog_id %x\n",
0121                   j, saved_prog_ids[j], query->ids[j]))
0122                 goto cleanup3;
0123     }
0124 
0125     i = num_progs - 1;
0126     for (; i >= 0; i--) {
0127  cleanup3:
0128         ioctl(pmu_fd[i], PERF_EVENT_IOC_DISABLE);
0129  cleanup2:
0130         close(pmu_fd[i]);
0131  cleanup1:
0132         bpf_object__close(obj[i]);
0133     }
0134     free(query);
0135 }