diff --git a/drivers/net/loopback.c b/drivers/net/loopback.c index f2a6e71..656e29c 100644 --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c @@ -126,6 +126,17 @@ static void emulate_large_send_offload(struct sk_buff *skb) } #endif /* LOOPBACK_TSO */ +static int enough_stack_space(void) +{ +#ifdef CONFIG_STACK_GROWSUP + return 0; +#else + unsigned long free = (unsigned long)&free - + (unsigned long)end_of_stack(current); + return free >= THREAD_SIZE/3 ; +#endif +} + /* * The higher levels take care of making this non-reentrant (it's * called with bh's disabled). @@ -158,7 +169,14 @@ static int loopback_xmit(struct sk_buff *skb, struct net_device *dev) lb_stats->bytes += skb->len; lb_stats->packets++; - netif_rx(skb); + /* + * We can call netif_receive_skb() instead of netif_rx() + * to speedup processing, but only if we have enough stack space. + */ + if (enough_stack_space()) + netif_receive_skb(skb); + else + netif_rx(skb); return 0; }