brintos

brintos / linux-shallow public Read only

0
0
Text · 2.0 KiB · f1853c3 Raw
91 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Copyright (c) 2021 Facebook */3 4#include "vmlinux.h"5#include <bpf/bpf_helpers.h>6#include <bpf/bpf_tracing.h>7 8#ifndef EBUSY9#define EBUSY 1610#endif11 12char _license[] SEC("license") = "GPL";13int nr_del_errs = 0;14int test_pid = 0;15 16struct {17	__uint(type, BPF_MAP_TYPE_TASK_STORAGE);18	__uint(map_flags, BPF_F_NO_PREALLOC);19	__type(key, int);20	__type(value, long);21} map_a SEC(".maps");22 23struct {24	__uint(type, BPF_MAP_TYPE_TASK_STORAGE);25	__uint(map_flags, BPF_F_NO_PREALLOC);26	__type(key, int);27	__type(value, long);28} map_b SEC(".maps");29 30SEC("fentry/bpf_local_storage_update")31int BPF_PROG(on_update)32{33	struct task_struct *task = bpf_get_current_task_btf();34	long *ptr;35 36	if (!test_pid || task->pid != test_pid)37		return 0;38 39	ptr = bpf_task_storage_get(&map_a, task, 0,40				   BPF_LOCAL_STORAGE_GET_F_CREATE);41	/* ptr will not be NULL when it is called from42	 * the bpf_task_storage_get(&map_b,...F_CREATE) in43	 * the BPF_PROG(on_enter) below.  It is because44	 * the value can be found in map_a and the kernel45	 * does not need to acquire any spin_lock.46	 */47	if (ptr) {48		int err;49 50		*ptr += 1;51		err = bpf_task_storage_delete(&map_a, task);52		if (err == -EBUSY)53			nr_del_errs++;54	}55 56	/* This will still fail because map_b is empty and57	 * this BPF_PROG(on_update) has failed to acquire58	 * the percpu busy lock => meaning potential59	 * deadlock is detected and it will fail to create60	 * new storage.61	 */62	ptr = bpf_task_storage_get(&map_b, task, 0,63				   BPF_LOCAL_STORAGE_GET_F_CREATE);64	if (ptr)65		*ptr += 1;66 67	return 0;68}69 70SEC("tp_btf/sys_enter")71int BPF_PROG(on_enter, struct pt_regs *regs, long id)72{73	struct task_struct *task;74	long *ptr;75 76	task = bpf_get_current_task_btf();77	if (!test_pid || task->pid != test_pid)78		return 0;79 80	ptr = bpf_task_storage_get(&map_a, task, 0,81				   BPF_LOCAL_STORAGE_GET_F_CREATE);82	if (ptr && !*ptr)83		*ptr = 200;84 85	ptr = bpf_task_storage_get(&map_b, task, 0,86				   BPF_LOCAL_STORAGE_GET_F_CREATE);87	if (ptr && !*ptr)88		*ptr = 100;89	return 0;90}91