[Devel] [PATCH 01/14] netpoll: don't free skb from completion_queue in interrupt context

Kirill Tkhai ktkhai at odin.com
Mon Jun 8 07:20:11 PDT 2015


Porting patch diff-netpoll-dont-free-skb-from-completion_queue-in-interrupt-context
from 2.6.32:

skb is queued to completion_queue from dev_kfree_skb_irq,
because skb can't be freed in irq context.

This patch fixes the warning:
[ 6253.592727] WARNING: at kernel/softirq.c:161 local_bh_enable_ip+0x7d/0xb0()
[ 6253.592727] Call Trace:
[ 6253.592727]  <IRQ>  [<ffffffff81071927>] ? warn_slowpath_common+0x87/0xc0
[ 6253.592727]  [<ffffffff8107197a>] ? warn_slowpath_null+0x1a/0x20
[ 6253.592727]  [<ffffffff8107a72d>] ? local_bh_enable_ip+0x7d/0xb0
[ 6253.592727]  [<ffffffff8151997b>] ? _spin_unlock_bh+0x1b/0x20
[ 6253.592727]  [<ffffffffa041c928>] ? destroy_conntrack+0xd8/0x190 [nf_conntrack]
[ 6253.592727]  [<ffffffff81484247>] ? nf_conntrack_destroy+0x17/0x30
[ 6253.592727]  [<ffffffff8144b205>] ? skb_release_head_state+0xf5/0x120
[ 6253.592727]  [<ffffffff8144af76>] ? __kfree_skb+0x16/0xa0
[ 6253.592727]  [<ffffffff8146da54>] ? zap_completion_queue+0x84/0xa0
[ 6253.592727]  [<ffffffff8146db95>] ? netpoll_poll_dev+0x125/0x490
[ 6253.592727]  [<ffffffff8146e101>] ? netpoll_send_skb_on_dev+0x151/0x230
[ 6253.592727]  [<ffffffff8146e3f3>] ? netpoll_send_udp+0x213/0x230
[ 6253.592727]  [<ffffffffa001c31b>] ? write_msg+0xbb/0x110 [netconsole]

write_msg calls spin_lock_irqsave, which disables interrupts.
Then destroy_conntrack calls spin_lock_bh and we get this warning.

https://jira.sw.ru/browse/PSBM-23346
https://bugzilla.openvz.org/show_bug.cgi?id=2526

Signed-off-by: Andrey Vagin <avagin at openvz.org>
Signed-off-by: Kirill Tkhai <ktkhai at odin.com>
---
 net/core/netpoll.c |    6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index 99091a2..18eeb81 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -291,8 +291,12 @@ static void refill_skbs(void)
 static void zap_completion_queue(void)
 {
 	unsigned long flags;
-	struct softnet_data *sd = &get_cpu_var(softnet_data);
+	struct softnet_data *sd;
 
+	if (in_irq() || irqs_disabled())
+		return;
+
+	sd = &get_cpu_var(softnet_data);
 	if (sd->completion_queue) {
 		struct sk_buff *clist;
 




More information about the Devel mailing list