History

bpf: Use mutex lock pool for bpf trampolines

Adding mutex lock pool that replaces bpf trampolines mutex. For tracing_multi link coming in following changes we need to lock all the involved trampolines during the attachment. This could mean thousands of mutex locks, which is not convenient. As suggested by Andrii we can replace bpf trampolines mutex with mutex pool, where each trampoline is hash-ed to one of the locks from the pool. It's better to lock all the pool mutexes (32 at the moment) than thousands of them. There is 48 (MAX_LOCK_DEPTH) lock limit allowed to be simultaneously held by task, so we need to keep 32 mutexes (5 bits) in the pool, so when we lock them all in following changes the lockdep won't scream. Removing the mutex_is_locked in bpf_trampoline_put, because we removed the mutex from bpf_trampoline.

Jiri Olsa committed 5 months ago

Commit e6abd4c1 parent 2cd298c2 files · +53 −26Browse files

Showing the changes to kernel (1 of 2 files). Show all

Unified · Split

kernel/bpf/trampoline.c+53−24
@@ -30,6 +30,35 @@ static struct hlist_head trampoline_ip_table[TRAMPOLINE_TABLE_SIZE]; · 29 unmodified lines
3030 /* serializes access to trampoline tables */
3131 static DEFINE_MUTEX(trampoline_mutex);
3232
33+/*
34+ * Keep 32 trampoline locks (5 bits) in the pool so trampoline_lock_all()
35+ * stays below MAX_LOCK_DEPTH. Each pool slot has a distinct lockdep
36+ * class because trampoline_lock_all() takes all pool mutexes at once;
37+ * otherwise lockdep would report recursive locking on same-class mutexes.
38+ */
39+#define TRAMPOLINE_LOCKS_BITS 5
40+#define TRAMPOLINE_LOCKS_TABLE_SIZE (1 << TRAMPOLINE_LOCKS_BITS)
41+
42+static struct {
43+ struct mutex mutex;
44+ struct lock_class_key key;
45+} trampoline_locks[TRAMPOLINE_LOCKS_TABLE_SIZE];
46+
47+static struct mutex *select_trampoline_lock(struct bpf_trampoline *tr)
48+{
49+ return &trampoline_locks[hash_ptr(tr, TRAMPOLINE_LOCKS_BITS)].mutex;
50+}
51+
52+static void trampoline_lock(struct bpf_trampoline *tr)
53+{
54+ mutex_lock(select_trampoline_lock(tr));
55+}
56+
57+static void trampoline_unlock(struct bpf_trampoline *tr)
58+{
59+ mutex_unlock(select_trampoline_lock(tr));
60+}
61+
3362 #ifdef CONFIG_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
3463 static int bpf_trampoline_update(struct bpf_trampoline *tr, bool lock_direct_mutex);
3564
@@ -69,9 +98,9 @@ static int bpf_tramp_ftrace_ops_func(struct ftrace_ops *ops, unsigned long ip, · 33 unmodified lines
6998
7099 if (cmd == FTRACE_OPS_CMD_ENABLE_SHARE_IPMODIFY_SELF) {
71100 /* This is called inside register_ftrace_direct_multi(), so
72− * tr->mutex is already locked.
101+ * trampoline's mutex is already locked.
73102 */
74− lockdep_assert_held_once(&tr->mutex);
103+ lockdep_assert_held_once(select_trampoline_lock(tr));
75104
76105 /* Instead of updating the trampoline here, we propagate
77106 * -EAGAIN to register_ftrace_direct(). Then we can
@@ -91,7 +120,7 @@ static int bpf_tramp_ftrace_ops_func(struct ftrace_ops *ops, unsigned long ip, · 13 unmodified lines
91120 }
92121
93122 /* The normal locking order is
94− * tr->mutex => direct_mutex (ftrace.c) => ftrace_lock (ftrace.c)
123+ * select_trampoline_lock(tr) => direct_mutex (ftrace.c) => ftrace_lock (ftrace.c)
95124 *
96125 * The following two commands are called from
97126 *
@@ -99,12 +128,12 @@ static int bpf_tramp_ftrace_ops_func(struct ftrace_ops *ops, unsigned long ip, · 1 unmodified line
99128 * cleanup_direct_functions_after_ipmodify
100129 *
101130 * In both cases, direct_mutex is already locked. Use
102− * mutex_trylock(&tr->mutex) to avoid deadlock in race condition
103− * (something else is making changes to this same trampoline).
131+ * mutex_trylock(select_trampoline_lock(tr)) to avoid deadlock in race condition
132+ * (something else holds the same pool lock).
104133 */
105− if (!mutex_trylock(&tr->mutex)) {
106− /* sleep 1 ms to make sure whatever holding tr->mutex makes
107− * some progress.
134+ if (!mutex_trylock(select_trampoline_lock(tr))) {
135+ /* sleep 1 ms to make sure whatever holding select_trampoline_lock(tr)
136+ * makes some progress.
108137 */
109138 msleep(1);
110139 return -EAGAIN;
@@ -129,7 +158,7 @@ static int bpf_tramp_ftrace_ops_func(struct ftrace_ops *ops, unsigned long ip, · 18 unmodified lines
129158 break;
130159 }
131160
132− mutex_unlock(&tr->mutex);
161+ trampoline_unlock(tr);
133162 return ret;
134163 }
135164 #endif
@@ -359,7 +388,6 @@ static struct bpf_trampoline *bpf_trampoline_lookup(u64 key, unsigned long ip) · 223 unmodified lines
359388 head = &trampoline_ip_table[hash_64(tr->ip, TRAMPOLINE_HASH_BITS)];
360389 hlist_add_head(&tr->hlist_ip, head);
361390 refcount_set(&tr->refcnt, 1);
362− mutex_init(&tr->mutex);
363391 for (i = 0; i < BPF_TRAMP_MAX; i++)
364392 INIT_HLIST_HEAD(&tr->progs_hlist[i]);
365393 out:
@@ -843,9 +871,9 @@ int bpf_trampoline_link_prog(struct bpf_tramp_link *link, · 477 unmodified lines
843871 {
844872 int err;
845873
846− mutex_lock(&tr->mutex);
874+ trampoline_lock(tr);
847875 err = __bpf_trampoline_link_prog(link, tr, tgt_prog);
848− mutex_unlock(&tr->mutex);
876+ trampoline_unlock(tr);
849877 return err;
850878 }
851879
@@ -886,9 +914,9 @@ int bpf_trampoline_unlink_prog(struct bpf_tramp_link *link, · 34 unmodified lines
886914 {
887915 int err;
888916
889− mutex_lock(&tr->mutex);
917+ trampoline_lock(tr);
890918 err = __bpf_trampoline_unlink_prog(link, tr, tgt_prog);
891− mutex_unlock(&tr->mutex);
919+ trampoline_unlock(tr);
892920 return err;
893921 }
894922
@@ -998,12 +1026,12 @@ int bpf_trampoline_link_cgroup_shim(struct bpf_prog *prog, · 103 unmodified lines
9981026 if (!tr)
9991027 return -ENOMEM;
10001028
1001− mutex_lock(&tr->mutex);
1029+ trampoline_lock(tr);
10021030
10031031 shim_link = cgroup_shim_find(tr, bpf_func);
10041032 if (shim_link && !IS_ERR(bpf_link_inc_not_zero(&shim_link->link.link))) {
10051033 /* Reusing existing shim attached by the other program. */
1006− mutex_unlock(&tr->mutex);
1034+ trampoline_unlock(tr);
10071035 bpf_trampoline_put(tr); /* bpf_trampoline_get above */
10081036 return 0;
10091037 }
@@ -1023,16 +1051,16 @@ int bpf_trampoline_link_cgroup_shim(struct bpf_prog *prog, · 13 unmodified lines
10231051 shim_link->trampoline = tr;
10241052 /* note, we're still holding tr refcnt from above */
10251053
1026− mutex_unlock(&tr->mutex);
1054+ trampoline_unlock(tr);
10271055
10281056 return 0;
10291057 err:
1030− mutex_unlock(&tr->mutex);
1058+ trampoline_unlock(tr);
10311059
10321060 if (shim_link)
10331061 bpf_link_put(&shim_link->link.link);
10341062
1035− /* have to release tr while _not_ holding its mutex */
1063+ /* have to release tr while _not_ holding pool mutex for trampoline */
10361064 bpf_trampoline_put(tr); /* bpf_trampoline_get above */
10371065
10381066 return err;
@@ -1053,9 +1081,9 @@ void bpf_trampoline_unlink_cgroup_shim(struct bpf_prog *prog) · 14 unmodified lines
10531081 if (WARN_ON_ONCE(!tr))
10541082 return;
10551083
1056− mutex_lock(&tr->mutex);
1084+ trampoline_lock(tr);
10571085 shim_link = cgroup_shim_find(tr, bpf_func);
1058− mutex_unlock(&tr->mutex);
1086+ trampoline_unlock(tr);
10591087
10601088 if (shim_link)
10611089 bpf_link_put(&shim_link->link.link);
@@ -1073,14 +1101,14 @@ struct bpf_trampoline *bpf_trampoline_get(u64 key, · 11 unmodified lines
10731101 if (!tr)
10741102 return NULL;
10751103
1076− mutex_lock(&tr->mutex);
1104+ trampoline_lock(tr);
10771105 if (tr->func.addr)
10781106 goto out;
10791107
10801108 memcpy(&tr->func.model, &tgt_info->fmodel, sizeof(tgt_info->fmodel));
10811109 tr->func.addr = (void *)tgt_info->tgt_addr;
10821110 out:
1083− mutex_unlock(&tr->mutex);
1111+ trampoline_unlock(tr);
10841112 return tr;
10851113 }
10861114
@@ -1093,7 +1121,6 @@ void bpf_trampoline_put(struct bpf_trampoline *tr) · 6 unmodified lines
10931121 mutex_lock(&trampoline_mutex);
10941122 if (!refcount_dec_and_test(&tr->refcnt))
10951123 goto out;
1096− WARN_ON_ONCE(mutex_is_locked(&tr->mutex));
10971124
10981125 for (i = 0; i < BPF_TRAMP_MAX; i++)
10991126 if (WARN_ON_ONCE(!hlist_empty(&tr->progs_hlist[i])))
@@ -1379,6 +1406,8 @@ static int __init init_trampolines(void) · 279 unmodified lines
13791406 INIT_HLIST_HEAD(&trampoline_key_table[i]);
13801407 for (i = 0; i < TRAMPOLINE_TABLE_SIZE; i++)
13811408 INIT_HLIST_HEAD(&trampoline_ip_table[i]);
1409+ for (i = 0; i < TRAMPOLINE_LOCKS_TABLE_SIZE; i++)
1410+ __mutex_init(&trampoline_locks[i].mutex, "trampoline_lock", &trampoline_locks[i].key);
13821411 return 0;
13831412 }
13841413 late_initcall(init_trampolines);