From: Eric Dumazet <eduma...@google.com> I had crashes in a DEBUG_PAGEALLOC kernels in fib_table_flush() or fib_table_lookup() that I back tracked to a refcounting issue happening when we clone struct fib_alias in fib_trie_unmerge()
While fixing this issue, I also noticed a mem leak happening if fib_insert_alias() fails. Fixes: 0ddcf43d5d4a0 ("ipv4: FIB Local/MAIN table collapse") Signed-off-by: Eric Dumazet <eduma...@google.com> Cc: Alexander Duyck <alexander.h.du...@intel.com> --- net/ipv4/fib_trie.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 4cff74d4133f..ebf49ab889e8 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -1737,14 +1737,19 @@ struct fib_table *fib_trie_unmerge(struct fib_table *oldtb) goto out; memcpy(new_fa, fa, sizeof(*fa)); + if (fa->fa_info) + fa->fa_info->fib_treeref++; /* insert clone into table */ if (!local_l) local_l = fib_find_node(lt, &local_tp, l->key); if (fib_insert_alias(lt, local_tp, local_l, new_fa, - NULL, l->key)) + NULL, l->key)) { + kmem_cache_free(fn_alias_kmem, new_fa); + fib_release_info(fa->fa_info); goto out; + } } /* stop loop if key wrapped back to 0 */