Skip to content

Commit

Permalink
evl/net: ipv4: use atomic allocation when learning routes
Browse files Browse the repository at this point in the history
evl_net_learn_ipv4_route() may be called from a softirq context. Make
sure we don't enter fs reclaim, use atomic allocation instead.

Fixes this lockdep splat:

[  393.641581] ================================
[  393.641584] WARNING: inconsistent lock state
[  393.641588] 6.1.111-00840-g87ef751da8a7-dirty torvalds#30 Not tainted
[  393.641594] --------------------------------
[  393.641597] inconsistent {SOFTIRQ-ON-W} -> {IN-SOFTIRQ-W} usage.
[  393.641601] swapper/0/0 [HC0[0]:SC1[3]:HE1:SE0] takes:
[  393.641611] c190530c (fs_reclaim){+.?.}-{0:0}, at: __kmem_cache_alloc_node+0x2c/0x204
[  393.641647] {SOFTIRQ-ON-W} state was registered at:
[  393.641651]   fs_reclaim_acquire+0x70/0xa8
[  393.641664]   __kmem_cache_alloc_node+0x2c/0x204
[  393.641673]   kmalloc_node_trace+0x24/0x4c
[  393.641682]   init_rescuer+0x3c/0xe8
[  393.641696]   workqueue_init+0xa0/0x1e4
[  393.641716]   kernel_init_freeable+0x88/0x240
[  393.641733]   kernel_init+0x14/0x140
[  393.641751]   ret_from_fork+0x14/0x1c
[  393.641760] irq event stamp: 280800
[  393.641764] hardirqs last  enabled at (280800): [<c012ff8c>] handle_softirqs+0xa0/0x480
[  393.641784] hardirqs last disabled at (280798): [<c01ab6f4>] sync_current_irq_stage+0x214/0x268
[  393.641799] softirqs last  enabled at (280780): [<c01301c0>] handle_softirqs+0x2d4/0x480
[  393.641813] softirqs last disabled at (280799): [<c013050c>] __irq_exit_rcu+0x144/0x188
[  393.641827]
[  393.641827] other info that might help us debug this:
[  393.641831]  Possible unsafe locking scenario:
[  393.641831]
[  393.641833]        CPU0
[  393.641835]        ----
[  393.641837]   lock(fs_reclaim);
[  393.641843]   <Interrupt>
[  393.641845]     lock(fs_reclaim);
[  393.641852]
[  393.641852]  *** DEADLOCK ***
[  393.641852]
[  393.641853] 2 locks held by swapper/0/0:
[  393.641859]  #0: c18e21c0 (rcu_read_lock){....}-{1:2}, at: netif_receive_skb_list_internal+0xc8/0x3d4
[  393.641891]  #1: c18e21c0 (rcu_read_lock){....}-{1:2}, at: ip_local_deliver_finish+0x64/0x1c8
[  393.641920]
[  393.641920] stack backtrace:
[  393.641924] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 6.1.111-00840-g87ef751da8a7-dirty torvalds#30
[  393.641933] Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
[  393.641937] IRQ stage: Linux
[  393.641944]  unwind_backtrace from show_stack+0x10/0x14
[  393.641967]  show_stack from dump_stack_lvl+0x94/0xcc
[  393.641986]  dump_stack_lvl from mark_lock.part.0+0x730/0x940
[  393.642004]  mark_lock.part.0 from __lock_acquire+0x978/0x2924
[  393.642016]  __lock_acquire from lock_acquire+0xf8/0x368
[  393.642029]  lock_acquire from fs_reclaim_acquire+0x70/0xa8
[  393.642042]  fs_reclaim_acquire from __kmem_cache_alloc_node+0x2c/0x204
[  393.642058]  __kmem_cache_alloc_node from kmalloc_trace+0x28/0x58
[  393.642072]  kmalloc_trace from evl_net_learn_ipv4_route+0x6c/0x12c
[  393.642095]  evl_net_learn_ipv4_route from ip_route_output_flow+0x5c/0x64
[  393.642113]  ip_route_output_flow from ip_send_unicast_reply+0x144/0x50c
[  393.642132]  ip_send_unicast_reply from tcp_v4_send_reset+0x25c/0x514
[  393.642151]  tcp_v4_send_reset from tcp_v4_rcv+0x98c/0xcdc
[  393.642164]  tcp_v4_rcv from ip_protocol_deliver_rcu+0x3c/0x248
[  393.642178]  ip_protocol_deliver_rcu from ip_local_deliver_finish+0xd0/0x1c8
[  393.642194]  ip_local_deliver_finish from ip_sublist_rcv_finish+0x38/0xa0
[  393.642210]  ip_sublist_rcv_finish from ip_sublist_rcv+0x1e8/0x340
[  393.642225]  ip_sublist_rcv from ip_list_rcv+0xe4/0x2f8
[  393.642240]  ip_list_rcv from __netif_receive_skb_list_core+0x18c/0x1fc
[  393.642258]  __netif_receive_skb_list_core from netif_receive_skb_list_internal+0x1f8/0x3d4
[  393.642275]  netif_receive_skb_list_internal from net_rx_action+0xe0/0x3cc
[  393.642291]  net_rx_action from handle_softirqs+0xdc/0x480
[  393.642312]  handle_softirqs from __irq_exit_rcu+0x144/0x188
[  393.642332]  __irq_exit_rcu from irq_exit+0x8/0x28
[  393.642352]  irq_exit from arch_do_IRQ_pipelined+0x30/0x64
[  393.642372]  arch_do_IRQ_pipelined from sync_current_irq_stage+0x160/0x268
[  393.642386]  sync_current_irq_stage from __inband_irq_enable+0x48/0x54
[  393.642400]  __inband_irq_enable from cpuidle_enter_state+0x198/0x3e8
[  393.642421]  cpuidle_enter_state from cpuidle_enter+0x30/0x40
[  393.642436]  cpuidle_enter from do_idle+0x1e0/0x2ac
[  393.642460]  do_idle from cpu_startup_entry+0x28/0x2c
[  393.642481]  cpu_startup_entry from rest_init+0xd4/0x188
[  393.642504]  rest_init from arch_post_acpi_subsys_init+0x0/0x8

Signed-off-by: Philippe Gerum <rpm@xenomai.org>
  • Loading branch information
pgerum committed Oct 18, 2024
1 parent e986731 commit 02ebff8
Showing 1 changed file with 3 additions and 2 deletions.
5 changes: 3 additions & 2 deletions kernel/evl/net/ipv4/route.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,8 @@ void evl_net_cleanup_ipv4_routing(struct net *net)
/*
* Update the out-of-band front-cache on the fly with the routing
* information we received for the outgoing IPv4 traffic on an
* oob-enabled device.
* oob-enabled device. We may be running in softirq context, don't
* wait.
*/
void evl_net_learn_ipv4_route(struct net *net,
struct flowi4 *fl4, struct rtable *rt) /* in-band */
Expand All @@ -108,7 +109,7 @@ void evl_net_learn_ipv4_route(struct net *net,
return;
}

e = kzalloc(sizeof(*e) + sizeof(fl4->daddr), GFP_KERNEL);
e = kzalloc(sizeof(*e) + sizeof(fl4->daddr), GFP_ATOMIC);
if (!e)
goto warn;

Expand Down

0 comments on commit 02ebff8

Please sign in to comment.