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