diff options
Diffstat (limited to 'kernel/bpf/syscall.c')
-rw-r--r-- | kernel/bpf/syscall.c | 39 |
1 files changed, 37 insertions, 2 deletions
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 797a99c7493e..bc34cf9fe9ee 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c | |||
@@ -1283,24 +1283,54 @@ static int bpf_prog_release(struct inode *inode, struct file *filp) | |||
1283 | return 0; | 1283 | return 0; |
1284 | } | 1284 | } |
1285 | 1285 | ||
1286 | static void bpf_prog_get_stats(const struct bpf_prog *prog, | ||
1287 | struct bpf_prog_stats *stats) | ||
1288 | { | ||
1289 | u64 nsecs = 0, cnt = 0; | ||
1290 | int cpu; | ||
1291 | |||
1292 | for_each_possible_cpu(cpu) { | ||
1293 | const struct bpf_prog_stats *st; | ||
1294 | unsigned int start; | ||
1295 | u64 tnsecs, tcnt; | ||
1296 | |||
1297 | st = per_cpu_ptr(prog->aux->stats, cpu); | ||
1298 | do { | ||
1299 | start = u64_stats_fetch_begin_irq(&st->syncp); | ||
1300 | tnsecs = st->nsecs; | ||
1301 | tcnt = st->cnt; | ||
1302 | } while (u64_stats_fetch_retry_irq(&st->syncp, start)); | ||
1303 | nsecs += tnsecs; | ||
1304 | cnt += tcnt; | ||
1305 | } | ||
1306 | stats->nsecs = nsecs; | ||
1307 | stats->cnt = cnt; | ||
1308 | } | ||
1309 | |||
1286 | #ifdef CONFIG_PROC_FS | 1310 | #ifdef CONFIG_PROC_FS |
1287 | static void bpf_prog_show_fdinfo(struct seq_file *m, struct file *filp) | 1311 | static void bpf_prog_show_fdinfo(struct seq_file *m, struct file *filp) |
1288 | { | 1312 | { |
1289 | const struct bpf_prog *prog = filp->private_data; | 1313 | const struct bpf_prog *prog = filp->private_data; |
1290 | char prog_tag[sizeof(prog->tag) * 2 + 1] = { }; | 1314 | char prog_tag[sizeof(prog->tag) * 2 + 1] = { }; |
1315 | struct bpf_prog_stats stats; | ||
1291 | 1316 | ||
1317 | bpf_prog_get_stats(prog, &stats); | ||
1292 | bin2hex(prog_tag, prog->tag, sizeof(prog->tag)); | 1318 | bin2hex(prog_tag, prog->tag, sizeof(prog->tag)); |
1293 | seq_printf(m, | 1319 | seq_printf(m, |
1294 | "prog_type:\t%u\n" | 1320 | "prog_type:\t%u\n" |
1295 | "prog_jited:\t%u\n" | 1321 | "prog_jited:\t%u\n" |
1296 | "prog_tag:\t%s\n" | 1322 | "prog_tag:\t%s\n" |
1297 | "memlock:\t%llu\n" | 1323 | "memlock:\t%llu\n" |
1298 | "prog_id:\t%u\n", | 1324 | "prog_id:\t%u\n" |
1325 | "run_time_ns:\t%llu\n" | ||
1326 | "run_cnt:\t%llu\n", | ||
1299 | prog->type, | 1327 | prog->type, |
1300 | prog->jited, | 1328 | prog->jited, |
1301 | prog_tag, | 1329 | prog_tag, |
1302 | prog->pages * 1ULL << PAGE_SHIFT, | 1330 | prog->pages * 1ULL << PAGE_SHIFT, |
1303 | prog->aux->id); | 1331 | prog->aux->id, |
1332 | stats.nsecs, | ||
1333 | stats.cnt); | ||
1304 | } | 1334 | } |
1305 | #endif | 1335 | #endif |
1306 | 1336 | ||
@@ -2122,6 +2152,7 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog, | |||
2122 | struct bpf_prog_info __user *uinfo = u64_to_user_ptr(attr->info.info); | 2152 | struct bpf_prog_info __user *uinfo = u64_to_user_ptr(attr->info.info); |
2123 | struct bpf_prog_info info = {}; | 2153 | struct bpf_prog_info info = {}; |
2124 | u32 info_len = attr->info.info_len; | 2154 | u32 info_len = attr->info.info_len; |
2155 | struct bpf_prog_stats stats; | ||
2125 | char __user *uinsns; | 2156 | char __user *uinsns; |
2126 | u32 ulen; | 2157 | u32 ulen; |
2127 | int err; | 2158 | int err; |
@@ -2161,6 +2192,10 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog, | |||
2161 | if (err) | 2192 | if (err) |
2162 | return err; | 2193 | return err; |
2163 | 2194 | ||
2195 | bpf_prog_get_stats(prog, &stats); | ||
2196 | info.run_time_ns = stats.nsecs; | ||
2197 | info.run_cnt = stats.cnt; | ||
2198 | |||
2164 | if (!capable(CAP_SYS_ADMIN)) { | 2199 | if (!capable(CAP_SYS_ADMIN)) { |
2165 | info.jited_prog_len = 0; | 2200 | info.jited_prog_len = 0; |
2166 | info.xlated_prog_len = 0; | 2201 | info.xlated_prog_len = 0; |