Skip to content

Commit

Permalink
bpf: fix rcu lockdep warning for lpm_trie map_free callback
Browse files Browse the repository at this point in the history
Commit 9a3efb6 ("bpf: fix memory leak in lpm_trie map_free callback function")
fixed a memory leak and removed unnecessary locks in map_free callback function.
Unfortrunately, it introduced a lockdep warning. When lockdep checking is turned on,
running tools/testing/selftests/bpf/test_lpm_map will have:

  [   98.294321] =============================
  [   98.294807] WARNING: suspicious RCU usage
  [   98.295359] 4.16.0-rc2+ torvalds#193 Not tainted
  [   98.295907] -----------------------------
  [   98.296486] /home/yhs/work/bpf/kernel/bpf/lpm_trie.c:572 suspicious rcu_dereference_check() usage!
  [   98.297657]
  [   98.297657] other info that might help us debug this:
  [   98.297657]
  [   98.298663]
  [   98.298663] rcu_scheduler_active = 2, debug_locks = 1
  [   98.299536] 2 locks held by kworker/2:1/54:
  [   98.300152]  #0:  ((wq_completion)"events"){+.+.}, at: [<00000000196bc1f0>] process_one_work+0x157/0x5c0
  [   98.301381]  #1:  ((work_completion)(&map->work)){+.+.}, at: [<00000000196bc1f0>] process_one_work+0x157/0x5c0

Since actual trie tree removal happens only after no other
accesses to the tree are possible, this patch simply converted all
rcu protected pointer access to normal access, which removed the
above warning.

Fixes: 9a3efb6 ("bpf: fix memory leak in lpm_trie map_free callback function")
Reported-by: Eric Dumazet <[email protected]>
Signed-off-by: Yonghong Song <[email protected]>
  • Loading branch information
yonghong-song authored and 0day robot committed Feb 22, 2018
1 parent 31a8260 commit ca07351
Showing 1 changed file with 5 additions and 6 deletions.
11 changes: 5 additions & 6 deletions kernel/bpf/lpm_trie.c
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,7 @@ static struct bpf_map *trie_alloc(union bpf_attr *attr)
static void trie_free(struct bpf_map *map)
{
struct lpm_trie *trie = container_of(map, struct lpm_trie, map);
struct lpm_trie_node __rcu **slot;
struct lpm_trie_node **slot;
struct lpm_trie_node *node;

/* Wait for outstanding programs to complete
Expand All @@ -569,23 +569,22 @@ static void trie_free(struct bpf_map *map)
slot = &trie->root;

for (;;) {
node = rcu_dereference_protected(*slot,
lockdep_is_held(&trie->lock));
node = *slot;
if (!node)
goto out;

if (rcu_access_pointer(node->child[0])) {
if (node->child[0]) {
slot = &node->child[0];
continue;
}

if (rcu_access_pointer(node->child[1])) {
if (node->child[1]) {
slot = &node->child[1];
continue;
}

kfree(node);
RCU_INIT_POINTER(*slot, NULL);
*slot = NULL;
break;
}
}
Expand Down

0 comments on commit ca07351

Please sign in to comment.