From 218cae5a714342b5d82a5b004d58f0a9ebbbfe5e Mon Sep 17 00:00:00 2001 From: Richard Braun Date: Wed, 6 Nov 2013 01:44:09 +0100 Subject: pfinet: fix emission on the loopback device Unlike other devices, sending packets on the loopback device causes the netif_rx() function to be called from the net_bh worker thread. Since the thread is already running, it can't wake itself up when calling mark_bh(). Use a new variable to indicate when net_bh work is pending. * glue-include/linux/interrupt.h (net_bh_raised): Declare new global variable. (mark_bh): Set net_bh_raised to 1 before waking up net_bh worker thread. * loopback.c (loopback_xmit): Add comment giving details about locking. * sched.c (net_bh_raised): Define new global variable. (net_bh_worker): Wait for net_bh_raised to become true and reset it before processing net_bh work. --- pfinet/loopback.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'pfinet/loopback.c') diff --git a/pfinet/loopback.c b/pfinet/loopback.c index 068cf3c8..e15e4265 100644 --- a/pfinet/loopback.c +++ b/pfinet/loopback.c @@ -71,6 +71,13 @@ static int loopback_xmit(struct sk_buff *skb, struct device *dev) #ifndef LOOPBACK_MUST_CHECKSUM skb->ip_summed = CHECKSUM_UNNECESSARY; #endif + + /* + * Calling netif_rx() requires locking net_bh_lock, which + * has already been done since this function is called by + * the net_bh worker thread. + */ + netif_rx(skb); stats->rx_bytes+=skb->len; -- cgit v1.2.3