Re: mac80211: NOHZ: local_softirq_pending 08

Oliver Hartkopp
2009-09-12T16:41:29Z

[-- Attachment #1: Type: text/plain, Size: 932 bytes --]

Michael Buesch wrote:

>> As there are several users in the kernel do exact this test and call the
>> appropriate netif_rx() function, i would suggest to create a static inline
>> function:
>>
>> static inline int netif_rx_ti(struct sk_buff *skb)
>> {
>> if (in_interrupt())
>> return netif_rx(skb);
>> return netif_rx_ni(skb);
>> }
>>
>> ('ti' for test in_interrupt())
>>
>> in include/linux/netdevice.h
>>
>> What do you think about that?
>
> Yeah, I'm fine with that.
>

Hi Michael,

i cooked a patch that introduces netif_rx_ti() and fixes up the problems in
mac80211 and the CAN subsystem.

Currently i'm pondering whether netif_rx_ti() is needed in all cases or if
there are code sections that'll never be executed from irq-context.

In theses cases netif_rx_ni() should be prefered to netif_rx_ti() to prevent
the obsolete check ...

Is there any of your changes that should better use netif_rx_ni() ?

Regards,
Oliver

[-- Attachment #2: net-NOHZ-local_softirq_pending-08.patch --]
[-- Type: text/x-patch, Size: 3612 bytes --]

diff --git a/drivers/net/can/vcan.c b/drivers/net/can/vcan.c
index 6971f6c..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(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 a44118b..b34c05d 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1503,6 +1503,18 @@ 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);
+ 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 ef1c43a..c21e7f4 100644
--- a/net/can/af_can.c
+++ b/net/can/af_can.c
@@ -278,7 +278,7 @@ int can_send(struct sk_buff *skb, int loop)
}

if (newskb)
- netif_rx(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;