qubes-linux-kernel/patches.xen/xen-netback-notify-multi

86 lines
2.7 KiB
Plaintext
Raw Normal View History

From: jbeulich@novell.com
Subject: netback: use multicall for send multiple notifications
Patch-mainline: obsolete
This also does a small fairness improvement since now notifications
get sent in the order requests came in rather than in the inverse one.
--- head-2010-04-15.orig/drivers/xen/core/evtchn.c 2010-04-23 15:20:36.000000000 +0200
+++ head-2010-04-15/drivers/xen/core/evtchn.c 2010-04-23 15:20:52.000000000 +0200
@@ -1336,6 +1336,21 @@ void notify_remote_via_irq(int irq)
}
EXPORT_SYMBOL_GPL(notify_remote_via_irq);
+int multi_notify_remote_via_irq(multicall_entry_t *mcl, int irq)
+{
+ int evtchn = evtchn_from_irq(irq);
+
+ BUG_ON(type_from_irq(irq) == IRQT_VIRQ);
+ BUG_IF_IPI(irq);
+
+ if (!VALID_EVTCHN(evtchn))
+ return -EINVAL;
+
+ multi_notify_remote_via_evtchn(mcl, evtchn);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(multi_notify_remote_via_irq);
+
int irq_to_evtchn_port(int irq)
{
BUG_IF_VIRQ_PER_CPU(irq);
--- head-2010-04-15.orig/drivers/xen/netback/netback.c 2010-01-04 13:31:44.000000000 +0100
+++ head-2010-04-15/drivers/xen/netback/netback.c 2010-01-04 13:31:57.000000000 +0100
@@ -778,10 +778,20 @@ static void net_rx_action(unsigned long
npo.meta_cons += nr_frags + 1;
}
- while (notify_nr != 0) {
- irq = notify_list[--notify_nr];
+ if (notify_nr == 1) {
+ irq = *notify_list;
__clear_bit(irq, rx_notify);
notify_remote_via_irq(irq + DYNIRQ_BASE);
+ } else {
+ for (count = ret = 0; ret < notify_nr; ++ret) {
+ irq = notify_list[ret];
+ __clear_bit(irq, rx_notify);
+ if (!multi_notify_remote_via_irq(rx_mcl + count,
+ irq + DYNIRQ_BASE))
+ ++count;
+ }
+ if (HYPERVISOR_multicall(rx_mcl, count))
+ BUG();
}
/* More work to do? */
--- head-2010-04-15.orig/include/xen/evtchn.h 2010-03-31 14:11:09.000000000 +0200
+++ head-2010-04-15/include/xen/evtchn.h 2010-03-31 14:42:45.000000000 +0200
@@ -192,6 +192,18 @@ static inline void notify_remote_via_evt
VOID(HYPERVISOR_event_channel_op(EVTCHNOP_send, &send));
}
+static inline void
+multi_notify_remote_via_evtchn(multicall_entry_t *mcl, int port)
+{
+ struct evtchn_send *send = (void *)(mcl->args + 2);
+
+ BUILD_BUG_ON(sizeof(*send) > sizeof(mcl->args) - 2 * sizeof(*mcl->args));
+ send->port = port;
+ mcl->op = __HYPERVISOR_event_channel_op;
+ mcl->args[0] = EVTCHNOP_send;
+ mcl->args[1] = (unsigned long)send;
+}
+
/* Clear an irq's pending state, in preparation for polling on it. */
void xen_clear_irq_pending(int irq);
@@ -210,6 +222,7 @@ void xen_poll_irq(int irq);
* by bind_*_to_irqhandler().
*/
void notify_remote_via_irq(int irq);
+int multi_notify_remote_via_irq(multicall_entry_t *, int irq);
int irq_to_evtchn_port(int irq);
#if defined(CONFIG_SMP) && !defined(MODULE) && defined(CONFIG_X86)