1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright (c) 2024 Google */ 3 4 #include "bpf_iter.h" 5 #include <bpf/bpf_helpers.h> 6 #include <bpf/bpf_tracing.h> 7 8 char _license[] SEC("license") = "GPL"; 9 10 #define SLAB_NAME_MAX 32 11 12 struct kmem_cache_result { 13 char name[SLAB_NAME_MAX]; 14 long obj_size; 15 }; 16 17 struct { 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 24 struct { 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 31 extern struct kmem_cache *bpf_get_kmem_cache(u64 addr) __ksym; 32 33 /* Result, will be checked by userspace */ 34 int task_struct_found; 35 int kmem_cache_seen; 36 37 SEC("iter/kmem_cache") 38 int slab_info_collector(struct bpf_iter__kmem_cache *ctx) 39 { 40 struct seq_file *seq = ctx->meta->seq; 41 struct kmem_cache *s = ctx->s; 42 struct kmem_cache_result *r; 43 int idx; 44 45 if (s) { 46 /* To make sure if the slab_iter implements the seq interface 47 * properly and it's also useful for debugging. 48 */ 49 BPF_SEQ_PRINTF(seq, "%s: %u\n", s->name, s->size); 50 51 idx = kmem_cache_seen; 52 r = bpf_map_lookup_elem(&slab_result, &idx); 53 if (r == NULL) 54 return 0; 55 56 kmem_cache_seen++; 57 58 /* Save name and size to match /proc/slabinfo */ 59 bpf_probe_read_kernel_str(r->name, sizeof(r->name), s->name); 60 r->obj_size = s->size; 61 62 if (!bpf_strncmp(r->name, 11, "task_struct")) 63 bpf_map_update_elem(&slab_hash, &s, r->name, BPF_NOEXIST); 64 } 65 66 return 0; 67 } 68 69 SEC("raw_tp/bpf_test_finish") 70 int BPF_PROG(check_task_struct) 71 { 72 u64 curr = bpf_get_current_task(); 73 struct kmem_cache *s; 74 char *name; 75 76 s = bpf_get_kmem_cache(curr); 77 if (s == NULL) { 78 task_struct_found = -1; 79 return 0; 80 } 81 name = bpf_map_lookup_elem(&slab_hash, &s); 82 if (name && !bpf_strncmp(name, 11, "task_struct")) 83 task_struct_found = 1; 84 else 85 task_struct_found = -2; 86 return 0; 87 } 88