History

bpf: add a test case for helper bpf_perf_prog_read_value

The bpf sample program trace_event is enhanced to use the new helper to print out enabled/running time.

Yonghong Song committed 9 years ago

Commit 81b9cf81 parent 4bebdc74 files · +23 −6Browse files

Unified · Split

4 files
  1. samples/bpf/trace_event_kern.c +10 −0
  2. samples/bpf/trace_event_user.c +8 −5
  3. tools/include/uapi/linux/bpf.h +2 −1
  4. tools/testing/selftests/bpf/bpf_helpers.h +3 −0
samples/bpf/trace_event_kern.c+10−0
@@ -37,10 +37,14 @@ struct bpf_map_def SEC("maps") stackmap = { · 36 unmodified lines
37SEC("perf_event")37SEC("perf_event")
38int bpf_prog1(struct bpf_perf_event_data *ctx)38int bpf_prog1(struct bpf_perf_event_data *ctx)
39{39{
40 char time_fmt1[] = "Time Enabled: %llu, Time Running: %llu";
41 char time_fmt2[] = "Get Time Failed, ErrCode: %d";
40 char fmt[] = "CPU-%d period %lld ip %llx";42 char fmt[] = "CPU-%d period %lld ip %llx";
41 u32 cpu = bpf_get_smp_processor_id();43 u32 cpu = bpf_get_smp_processor_id();
44 struct bpf_perf_event_value value_buf;
42 struct key_t key;45 struct key_t key;
43 u64 *val, one = 1;46 u64 *val, one = 1;
47 int ret;
44 48
45 if (ctx->sample_period < 10000)49 if (ctx->sample_period < 10000)
46 /* ignore warmup */50 /* ignore warmup */
@@ -54,6 +58,12 @@ int bpf_prog1(struct bpf_perf_event_data *ctx) · 7 unmodified lines
54 return 0;58 return 0;
55 }59 }
56 60
61 ret = bpf_perf_prog_read_value(ctx, (void *)&value_buf, sizeof(struct bpf_perf_event_value));
62 if (!ret)
63 bpf_trace_printk(time_fmt1, sizeof(time_fmt1), value_buf.enabled, value_buf.running);
64 else
65 bpf_trace_printk(time_fmt2, sizeof(time_fmt2), ret);
66
57 val = bpf_map_lookup_elem(&counts, &key);67 val = bpf_map_lookup_elem(&counts, &key);
58 if (val)68 if (val)
59 (*val)++;69 (*val)++;
samples/bpf/trace_event_user.c+8−5
@@ -127,6 +127,9 @@ static void test_perf_event_all_cpu(struct perf_event_attr *attr) · 126 unmodified lines
127 int *pmu_fd = malloc(nr_cpus * sizeof(int));127 int *pmu_fd = malloc(nr_cpus * sizeof(int));
128 int i, error = 0;128 int i, error = 0;
129 129
130 /* system wide perf event, no need to inherit */
131 attr->inherit = 0;
132
130 /* open perf_event on all cpus */133 /* open perf_event on all cpus */
131 for (i = 0; i < nr_cpus; i++) {134 for (i = 0; i < nr_cpus; i++) {
132 pmu_fd[i] = sys_perf_event_open(attr, -1, i, -1, 0);135 pmu_fd[i] = sys_perf_event_open(attr, -1, i, -1, 0);
@@ -154,6 +157,11 @@ static void test_perf_event_task(struct perf_event_attr *attr) · 21 unmodified lines
154{157{
155 int pmu_fd;158 int pmu_fd;
156 159
160 /* per task perf event, enable inherit so the "dd ..." command can be traced properly.
161 * Enabling inherit will cause bpf_perf_prog_read_time helper failure.
162 */
163 attr->inherit = 1;
164
157 /* open task bound event */165 /* open task bound event */
158 pmu_fd = sys_perf_event_open(attr, 0, -1, -1, 0);166 pmu_fd = sys_perf_event_open(attr, 0, -1, -1, 0);
159 if (pmu_fd < 0) {167 if (pmu_fd < 0) {
@@ -175,14 +183,12 @@ static void test_bpf_perf_event(void) · 15 unmodified lines
175 .freq = 1,183 .freq = 1,
176 .type = PERF_TYPE_HARDWARE,184 .type = PERF_TYPE_HARDWARE,
177 .config = PERF_COUNT_HW_CPU_CYCLES,185 .config = PERF_COUNT_HW_CPU_CYCLES,
178 .inherit = 1,
179 };186 };
180 struct perf_event_attr attr_type_sw = {187 struct perf_event_attr attr_type_sw = {
181 .sample_freq = SAMPLE_FREQ,188 .sample_freq = SAMPLE_FREQ,
182 .freq = 1,189 .freq = 1,
183 .type = PERF_TYPE_SOFTWARE,190 .type = PERF_TYPE_SOFTWARE,
184 .config = PERF_COUNT_SW_CPU_CLOCK,191 .config = PERF_COUNT_SW_CPU_CLOCK,
185 .inherit = 1,
186 };192 };
187 struct perf_event_attr attr_hw_cache_l1d = {193 struct perf_event_attr attr_hw_cache_l1d = {
188 .sample_freq = SAMPLE_FREQ,194 .sample_freq = SAMPLE_FREQ,
@@ -192,7 +198,6 @@ static void test_bpf_perf_event(void) · 3 unmodified lines
192 PERF_COUNT_HW_CACHE_L1D |198 PERF_COUNT_HW_CACHE_L1D |
193 (PERF_COUNT_HW_CACHE_OP_READ << 8) |199 (PERF_COUNT_HW_CACHE_OP_READ << 8) |
194 (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16),200 (PERF_COUNT_HW_CACHE_RESULT_ACCESS << 16),
195 .inherit = 1,
196 };201 };
197 struct perf_event_attr attr_hw_cache_branch_miss = {202 struct perf_event_attr attr_hw_cache_branch_miss = {
198 .sample_freq = SAMPLE_FREQ,203 .sample_freq = SAMPLE_FREQ,
@@ -202,7 +207,6 @@ static void test_bpf_perf_event(void) · 3 unmodified lines
202 PERF_COUNT_HW_CACHE_BPU |207 PERF_COUNT_HW_CACHE_BPU |
203 (PERF_COUNT_HW_CACHE_OP_READ << 8) |208 (PERF_COUNT_HW_CACHE_OP_READ << 8) |
204 (PERF_COUNT_HW_CACHE_RESULT_MISS << 16),209 (PERF_COUNT_HW_CACHE_RESULT_MISS << 16),
205 .inherit = 1,
206 };210 };
207 struct perf_event_attr attr_type_raw = {211 struct perf_event_attr attr_type_raw = {
208 .sample_freq = SAMPLE_FREQ,212 .sample_freq = SAMPLE_FREQ,
@@ -210,7 +214,6 @@ static void test_bpf_perf_event(void) · 1 unmodified line
210 .type = PERF_TYPE_RAW,214 .type = PERF_TYPE_RAW,
211 /* Intel Instruction Retired */215 /* Intel Instruction Retired */
212 .config = 0xc0,216 .config = 0xc0,
213 .inherit = 1,
214 };217 };
215 218
216 printf("Test HW_CPU_CYCLES\n");219 printf("Test HW_CPU_CYCLES\n");
tools/include/uapi/linux/bpf.h+2−1
@@ -698,7 +698,8 @@ union bpf_attr { · 697 unmodified lines
698 FN(sk_redirect_map), \698 FN(sk_redirect_map), \
699 FN(sock_map_update), \699 FN(sock_map_update), \
700 FN(xdp_adjust_meta), \700 FN(xdp_adjust_meta), \
701 FN(perf_event_read_value),701 FN(perf_event_read_value), \
702 FN(perf_prog_read_value),
702 703
703/* integer value in 'imm' field of BPF_CALL instruction selects which helper704/* integer value in 'imm' field of BPF_CALL instruction selects which helper
704 * function eBPF program intends to call705 * function eBPF program intends to call
tools/testing/selftests/bpf/bpf_helpers.h+3−0
@@ -75,6 +75,9 @@ static int (*bpf_sock_map_update)(void *map, void *key, void *value, · 74 unmodified lines
75static int (*bpf_perf_event_read_value)(void *map, unsigned long long flags,75static int (*bpf_perf_event_read_value)(void *map, unsigned long long flags,
76 void *buf, unsigned int buf_size) =76 void *buf, unsigned int buf_size) =
77 (void *) BPF_FUNC_perf_event_read_value;77 (void *) BPF_FUNC_perf_event_read_value;
78static int (*bpf_perf_prog_read_value)(void *ctx, void *buf,
79 unsigned int buf_size) =
80 (void *) BPF_FUNC_perf_prog_read_value;
78 81
79 82
80/* llvm builtin functions that eBPF C program may use to83/* llvm builtin functions that eBPF C program may use to