Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at master 108 lines 2.3 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2/* Copyright (c) 2024 Google */ 3#include <vmlinux.h> 4#include <bpf/bpf_helpers.h> 5#include <bpf/bpf_tracing.h> 6#include "bpf_experimental.h" 7 8char _license[] SEC("license") = "GPL"; 9 10#define SLAB_NAME_MAX 32 11 12struct kmem_cache_result { 13 char name[SLAB_NAME_MAX]; 14 long obj_size; 15}; 16 17struct { 18 __uint(type, BPF_MAP_TYPE_HASH); 19 __uint(key_size, sizeof(void *)); 20 __uint(value_size, SLAB_NAME_MAX); 21 __uint(max_entries, 1); 22} slab_hash SEC(".maps"); 23 24struct { 25 __uint(type, BPF_MAP_TYPE_ARRAY); 26 __uint(key_size, sizeof(int)); 27 __uint(value_size, sizeof(struct kmem_cache_result)); 28 __uint(max_entries, 1024); 29} slab_result SEC(".maps"); 30 31extern struct kmem_cache *bpf_get_kmem_cache(u64 addr) __ksym; 32 33/* Result, will be checked by userspace */ 34int task_struct_found; 35int kmem_cache_seen; 36int open_coded_seen; 37 38SEC("iter/kmem_cache") 39int slab_info_collector(struct bpf_iter__kmem_cache *ctx) 40{ 41 struct seq_file *seq = ctx->meta->seq; 42 struct kmem_cache *s = ctx->s; 43 struct kmem_cache_result *r; 44 int idx; 45 46 if (s) { 47 /* To make sure if the slab_iter implements the seq interface 48 * properly and it's also useful for debugging. 49 */ 50 BPF_SEQ_PRINTF(seq, "%s: %u\n", s->name, s->size); 51 52 idx = kmem_cache_seen; 53 r = bpf_map_lookup_elem(&slab_result, &idx); 54 if (r == NULL) 55 return 0; 56 57 kmem_cache_seen++; 58 59 /* Save name and size to match /proc/slabinfo */ 60 bpf_probe_read_kernel_str(r->name, sizeof(r->name), s->name); 61 r->obj_size = s->size; 62 63 if (!bpf_strncmp(r->name, 11, "task_struct")) 64 bpf_map_update_elem(&slab_hash, &s, r->name, BPF_NOEXIST); 65 } 66 67 return 0; 68} 69 70SEC("raw_tp/bpf_test_finish") 71int BPF_PROG(check_task_struct) 72{ 73 u64 curr = bpf_get_current_task(); 74 struct kmem_cache *s; 75 char *name; 76 77 s = bpf_get_kmem_cache(curr); 78 if (s == NULL) { 79 task_struct_found = -1; 80 return 0; 81 } 82 name = bpf_map_lookup_elem(&slab_hash, &s); 83 if (name && !bpf_strncmp(name, 11, "task_struct")) 84 task_struct_found = 1; 85 else 86 task_struct_found = -2; 87 return 0; 88} 89 90SEC("syscall") 91int open_coded_iter(const void *ctx) 92{ 93 struct kmem_cache *s; 94 95 bpf_for_each(kmem_cache, s) { 96 struct kmem_cache_result *r; 97 98 r = bpf_map_lookup_elem(&slab_result, &open_coded_seen); 99 if (!r) 100 break; 101 102 if (r->obj_size != s->size) 103 break; 104 105 open_coded_seen++; 106 } 107 return 0; 108}