Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.8.
  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}