From: jbeulich@novell.com
Subject: netback: reduce overhead of IRQ recording
Patch-mainline: obsolete

Since both NR_PIRQS and NR_DYNIRQS are no longer hardcoded, the
(memory) overhead of tracking which ones to send notifications to can
be pretty unbounded. Also, store the dynirq rather than the raw irq
to push up the limit where the type of notify_list needs to become
'int' rather than 'u16'.

--- head-2010-01-19.orig/drivers/xen/netback/interface.c	2010-01-26 08:58:19.000000000 +0100
+++ head-2010-01-19/drivers/xen/netback/interface.c	2010-01-26 09:03:24.000000000 +0100
@@ -343,6 +343,7 @@ int netif_map(netif_t *netif, unsigned l
 		netif->dev->name, netif);
 	if (err < 0)
 		goto err_hypervisor;
+	BUG_ON(err < DYNIRQ_BASE || err >= DYNIRQ_BASE + NR_DYNIRQS);
 	netif->irq = err;
 	disable_irq(netif->irq);
 
--- head-2010-01-19.orig/drivers/xen/netback/netback.c	2010-01-04 13:31:38.000000000 +0100
+++ head-2010-01-19/drivers/xen/netback/netback.c	2010-01-04 13:31:44.000000000 +0100
@@ -590,8 +590,12 @@ static void net_rx_action(unsigned long 
 	static mmu_update_t rx_mmu[NET_RX_RING_SIZE];
 	static gnttab_transfer_t grant_trans_op[NET_RX_RING_SIZE];
 	static gnttab_copy_t grant_copy_op[NET_RX_RING_SIZE];
-	static unsigned char rx_notify[NR_IRQS];
+	static DECLARE_BITMAP(rx_notify, NR_DYNIRQS);
+#if NR_DYNIRQS <= 0x10000
 	static u16 notify_list[NET_RX_RING_SIZE];
+#else
+	static int notify_list[NET_RX_RING_SIZE];
+#endif
 	static struct netbk_rx_meta meta[NET_RX_RING_SIZE];
 
 	struct netrx_pending_operations npo = {
@@ -749,11 +753,9 @@ static void net_rx_action(unsigned long 
 					 nr_frags);
 
 		RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&netif->rx, ret);
-		irq = netif->irq;
-		if (ret && !rx_notify[irq]) {
-			rx_notify[irq] = 1;
+		irq = netif->irq - DYNIRQ_BASE;
+		if (ret && !__test_and_set_bit(irq, rx_notify))
 			notify_list[notify_nr++] = irq;
-		}
 
 		if (netif_queue_stopped(netif->dev) &&
 		    netif_schedulable(netif) &&
@@ -778,8 +780,8 @@ static void net_rx_action(unsigned long 
 
 	while (notify_nr != 0) {
 		irq = notify_list[--notify_nr];
-		rx_notify[irq] = 0;
-		notify_remote_via_irq(irq);
+		__clear_bit(irq, rx_notify);
+		notify_remote_via_irq(irq + DYNIRQ_BASE);
 	}
 
 	/* More work to do? */
