From patchwork Wed Sep 30 18:18:25 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Oliver Hartkopp X-Patchwork-Id: 34610 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by ozlabs.org (Postfix) with ESMTP id E8167B7BD6 for ; Thu, 1 Oct 2009 04:18:36 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755068AbZI3SSZ (ORCPT ); Wed, 30 Sep 2009 14:18:25 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1755060AbZI3SSY (ORCPT ); Wed, 30 Sep 2009 14:18:24 -0400 Received: from mo-p00-ob.rzone.de ([81.169.146.161]:28677 "EHLO mo-p00-ob.rzone.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755051AbZI3SSX (ORCPT ); Wed, 30 Sep 2009 14:18:23 -0400 DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; t=1254334706; l=4954; s=domk; d=hartkopp.net; h=Content-Type:In-Reply-To:References:Subject:CC:To:MIME-Version:From: Date:X-RZG-CLASS-ID:X-RZG-AUTH; bh=ynq9NgLIP+U/29PjOSaYEMC/Nw0=; b=njSENV2qtfASkLf2AQkIKTieO2ya4ZTuETxMlJaAKq/c+7iPiRNsDGwSW3gk3qhWuBf q48FJRyhSBiM0Jjw6zPcC8BOrAJJNsNNE3x4au0Rx9H3hmzj+JTqP6dZ5vn1S/QJyrqMO C2Yt0WEy7fOA/MoP9hsJyOXhXEmPxoRcKSY= X-RZG-AUTH: :I2ANY0W6W/eA95XfH/xfO6gOxLxTty/udEMngcJ/VAKW226lDNJVyuUIJDI/ObAx X-RZG-CLASS-ID: mo00 Received: from [192.168.11.10] (p5B22F077.dip.t-dialin.net [91.34.240.119]) by post.strato.de (klopstock mo64) (RZmta 22.1) with ESMTP id t037e4l8UHZIwu ; Wed, 30 Sep 2009 20:18:25 +0200 (MEST) Message-ID: <4AC3A0F1.3060306@hartkopp.net> Date: Wed, 30 Sep 2009 20:18:25 +0200 From: Oliver Hartkopp User-Agent: Mozilla-Thunderbird 2.0.0.22 (X11/20090706) MIME-Version: 1.0 To: David Miller CC: Johannes Berg , Michael Buesch , Kalle Valo , "John W. Linville" , linux-wireless@vger.kernel.org, netdev@vger.kernel.org Subject: [PATCH] net: fix NOHZ: local_softirq_pending 08 References: <200909111648.50902.mb@bu3sch.de> <87ocosqykb.fsf@purkki.valot.fi> <1254322466.3959.5.camel@johannes.local> <200909301710.31082.mb@bu3sch.de> <1254324077.3959.7.camel@johannes.local> <4AC39A90.6060602@hartkopp.net> In-Reply-To: <4AC39A90.6060602@hartkopp.net> X-Enigmail-Version: 0.96.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Socket buffers that are generated and received inside softirqs or from process context must not use netif_rx() that's intended to be used from irq context only. This patch introduces a new helper function netif_rx_ti(skb) that tests for in_interrupt() before invoking netif_rx() or netif_rx_ni(). It fixes the ratelimited kernel warning NOHZ: local_softirq_pending 08 in the mac80211 and can subsystems. Signed-off-by: Oliver Hartkopp Acked-by: John W. Linville diff --git a/drivers/net/can/vcan.c b/drivers/net/can/vcan.c index 80ac563..899f3d3 100644 --- a/drivers/net/can/vcan.c +++ b/drivers/net/can/vcan.c @@ -80,7 +80,7 @@ static void vcan_rx(struct sk_buff *skb, struct net_device *dev) skb->dev = dev; skb->ip_summed = CHECKSUM_UNNECESSARY; - netif_rx_ni(skb); + netif_rx_ti(skb); } static netdev_tx_t vcan_tx(struct sk_buff *skb, struct net_device *dev) diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 94958c1..dc8dfb2 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -1509,6 +1509,19 @@ extern int netdev_budget; extern void netdev_run_todo(void); /** + * netif_rx_ti - test for irq context and post buffer to the network code + * @skb: buffer to post + * + */ +static inline int netif_rx_ti(struct sk_buff *skb) +{ + if (in_interrupt()) + return netif_rx(skb); + else + return netif_rx_ni(skb); +} + +/** * dev_put - release reference to device * @dev: network device * diff --git a/net/can/af_can.c b/net/can/af_can.c index 6068321..c21e7f4 100644 --- a/net/can/af_can.c +++ b/net/can/af_can.c @@ -199,8 +199,6 @@ static int can_create(struct net *net, struct socket *sock, int protocol) * @skb: pointer to socket buffer with CAN frame in data section * @loop: loopback for listeners on local CAN sockets (recommended default!) * - * Due to the loopback this routine must not be called from hardirq context. - * * Return: * 0 on success * -ENETDOWN when the selected interface is down @@ -280,7 +278,7 @@ int can_send(struct sk_buff *skb, int loop) } if (newskb) - netif_rx_ni(newskb); + netif_rx_ti(newskb); /* update statistics */ can_stats.tx_frames++; diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 5608f6c..bbcb4cb 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -606,7 +606,7 @@ static void ieee80211_send_layer2_update(struct sta_info *sta) skb->dev = sta->sdata->dev; skb->protocol = eth_type_trans(skb, sta->sdata->dev); memset(skb->cb, 0, sizeof(skb->cb)); - netif_rx(skb); + netif_rx_ti(skb); } static void sta_apply_parameters(struct ieee80211_local *local, diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 797f539..1109f99 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -591,7 +591,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) skb2 = skb_clone(skb, GFP_ATOMIC); if (skb2) { skb2->dev = prev_dev; - netif_rx(skb2); + netif_rx_ti(skb2); } } @@ -600,7 +600,7 @@ void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb) } if (prev_dev) { skb->dev = prev_dev; - netif_rx(skb); + netif_rx_ti(skb); skb = NULL; } rcu_read_unlock(); diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index c01588f..5bb7c04 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -309,7 +309,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, skb2 = skb_clone(skb, GFP_ATOMIC); if (skb2) { skb2->dev = prev_dev; - netif_rx(skb2); + netif_rx_ti(skb2); } } @@ -320,7 +320,7 @@ ieee80211_rx_monitor(struct ieee80211_local *local, struct sk_buff *origskb, if (prev_dev) { skb->dev = prev_dev; - netif_rx(skb); + netif_rx_ti(skb); } else dev_kfree_skb(skb); @@ -1349,7 +1349,7 @@ ieee80211_deliver_skb(struct ieee80211_rx_data *rx) /* deliver to local stack */ skb->protocol = eth_type_trans(skb, dev); memset(skb->cb, 0, sizeof(skb->cb)); - netif_rx(skb); + netif_rx_ti(skb); } } @@ -1943,7 +1943,7 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx) skb2 = skb_clone(skb, GFP_ATOMIC); if (skb2) { skb2->dev = prev_dev; - netif_rx(skb2); + netif_rx_ti(skb2); } } @@ -1954,7 +1954,7 @@ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx) if (prev_dev) { skb->dev = prev_dev; - netif_rx(skb); + netif_rx_ti(skb); skb = NULL; } else goto out_free_skb;