From 711531939f77c1a014ab75671b1aa03288c73d65 Mon Sep 17 00:00:00 2001 From: t_jeang Date: Tue, 6 Jan 2009 12:06:02 +0000 Subject: [PATCH] imported patch netback-thread --- drivers/xen/netback/netback.c | 69 ++++++++++++++++++++++++++++------- 1 file changed, 55 insertions(+), 14 deletions(-) diff --git a/drivers/xen/netback/netback.c b/drivers/xen/netback/netback.c index c91849d9..11518632 100644 --- a/drivers/xen/netback/netback.c +++ b/drivers/xen/netback/netback.c @@ -37,6 +37,7 @@ #include "common.h" #include #include +#include /*define NETBE_DEBUG_INTERRUPT*/ @@ -65,11 +66,9 @@ static netif_rx_response_t *make_rx_response(netif_t *netif, u16 size, u16 flags); -static void net_tx_action(unsigned long unused); -static DECLARE_TASKLET(net_tx_tasklet, net_tx_action, 0); - -static void net_rx_action(unsigned long unused); -static DECLARE_TASKLET(net_rx_tasklet, net_rx_action, 0); +static void net_rx_action(void); +static void net_tx_action(void); +static DECLARE_WAIT_QUEUE_HEAD(netbk_action_wq); static struct timer_list net_timer; static struct timer_list netbk_tx_pending_timer; @@ -194,7 +193,7 @@ static inline void maybe_schedule_tx_action(void) smp_mb(); if ((NR_PENDING_REQS < (MAX_PENDING_REQS/2)) && !list_empty(&net_schedule_list)) - tasklet_schedule(&net_tx_tasklet); + wake_up(&netbk_action_wq); } static struct sk_buff *netbk_copy_skb(struct sk_buff *skb) @@ -378,7 +377,7 @@ int netif_be_start_xmit(struct sk_buff *skb, struct net_device *dev) } skb_queue_tail(&rx_queue, skb); - tasklet_schedule(&net_rx_tasklet); + wake_up(&netbk_action_wq); return 0; @@ -676,7 +675,12 @@ struct skb_cb_overlay { int meta_slots_used; }; -static void net_rx_action(unsigned long unused) +static inline int net_rx_action_work_to_do(void) +{ + return !skb_queue_empty(&rx_queue); +} + +static void net_rx_action(void) { netif_t *netif = NULL; s8 status; @@ -880,9 +884,11 @@ static void net_rx_action(unsigned long unused) notify_remote_via_irq(irq); } +#if 0 /* More work to do? */ if (!skb_queue_empty(&rx_queue) && !timer_pending(&net_timer)) - tasklet_schedule(&net_rx_tasklet); + wake_up(&netbk_action_wq); +#endif #if 0 else xen_network_done_notify(); @@ -891,12 +897,12 @@ static void net_rx_action(unsigned long unused) static void net_alarm(unsigned long unused) { - tasklet_schedule(&net_rx_tasklet); + wake_up(&netbk_action_wq); } static void netbk_tx_pending_timeout(unsigned long unused) { - tasklet_schedule(&net_tx_tasklet); + wake_up(&netbk_action_wq); } struct net_device_stats *netif_be_get_stats(struct net_device *dev) @@ -1326,8 +1332,20 @@ static int netbk_set_skb_gso(struct sk_buff *skb, struct netif_extra_info *gso) return 0; } +static inline int net_tx_action_work_to_do(void) +{ + if (dealloc_cons != dealloc_prod) + return 1; + + if (((NR_PENDING_REQS + MAX_SKB_FRAGS) < MAX_PENDING_REQS) && + !list_empty(&net_schedule_list)) + return 1; + + return 0; +} + /* Called after netfront has transmitted */ -static void net_tx_action(unsigned long unused) +static void net_tx_action(void) { struct list_head *ent; struct sk_buff *skb; @@ -1559,7 +1577,7 @@ static void net_tx_action(unsigned long unused) continue; } - netif_rx(skb); + netif_rx_ni(skb); netif->dev->last_rx = jiffies; } @@ -1585,7 +1603,7 @@ static void netif_idx_release(u16 pending_idx) dealloc_prod++; spin_unlock_irqrestore(&_lock, flags); - tasklet_schedule(&net_tx_tasklet); + wake_up(&netbk_action_wq); } static void netif_page_release(struct page *page) @@ -1661,6 +1679,24 @@ static netif_rx_response_t *make_rx_response(netif_t *netif, return resp; } +static int netbk_action_thread(void *unused) +{ + while (1) { + wait_event_interruptible(netbk_action_wq, + net_rx_action_work_to_do() || net_tx_action_work_to_do()); + cond_resched(); + + if (net_rx_action_work_to_do()) + net_rx_action(); + + if (net_tx_action_work_to_do()) + net_tx_action(); + } + + return 0; +} + + #ifdef NETBE_DEBUG_INTERRUPT static irqreturn_t netif_be_dbg(int irq, void *dev_id, struct pt_regs *regs) { @@ -1699,6 +1735,7 @@ static int __init netback_init(void) { int i; struct page *page; + struct task_struct *task; if (!is_running_on_xen()) return -ENODEV; @@ -1752,6 +1789,10 @@ static int __init netback_init(void) netif_xenbus_init(); + task = kthread_run(netbk_action_thread, NULL, "netback"); + if (IS_ERR(task)) + return PTR_ERR(task); + #ifdef NETBE_DEBUG_INTERRUPT (void)bind_virq_to_irqhandler(VIRQ_DEBUG, 0, -- 2.39.5