2010-07-07 11:12:45 +00:00
|
|
|
From: jbeulich@novell.com
|
|
|
|
Subject: netback: use multicall for send multiple notifications
|
|
|
|
Patch-mainline: obsolete
|
|
|
|
|
2011-04-19 20:09:59 +00:00
|
|
|
This also yields a small fairness improvement since now notifications
|
2010-07-07 11:12:45 +00:00
|
|
|
get sent in the order requests came in rather than in the inverse one.
|
|
|
|
|
2011-04-19 20:09:59 +00:00
|
|
|
--- head-2011-02-08.orig/drivers/xen/core/evtchn.c 2011-02-16 08:29:29.000000000 +0100
|
|
|
|
+++ head-2011-02-08/drivers/xen/core/evtchn.c 2011-02-16 08:29:50.000000000 +0100
|
|
|
|
@@ -1473,6 +1473,27 @@ void notify_remote_via_irq(int irq)
|
2010-07-07 11:12:45 +00:00
|
|
|
}
|
|
|
|
EXPORT_SYMBOL_GPL(notify_remote_via_irq);
|
|
|
|
|
2011-04-19 20:09:59 +00:00
|
|
|
+#if defined(CONFIG_XEN_BACKEND) || defined(CONFIG_XEN_BACKEND_MODULE)
|
2010-07-07 11:12:45 +00:00
|
|
|
+int multi_notify_remote_via_irq(multicall_entry_t *mcl, int irq)
|
|
|
|
+{
|
2011-04-19 20:09:59 +00:00
|
|
|
+ const struct irq_cfg *cfg = irq_cfg(irq);
|
|
|
|
+ int evtchn;
|
2010-07-07 11:12:45 +00:00
|
|
|
+
|
2011-04-19 20:09:59 +00:00
|
|
|
+ if (WARN_ON_ONCE(!cfg))
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ BUG_ON(type_from_irq_cfg(cfg) == IRQT_VIRQ);
|
|
|
|
+ BUG_IF_IPI(cfg);
|
2010-07-07 11:12:45 +00:00
|
|
|
+
|
2011-04-19 20:09:59 +00:00
|
|
|
+ evtchn = evtchn_from_irq_cfg(cfg);
|
2010-07-07 11:12:45 +00:00
|
|
|
+ if (!VALID_EVTCHN(evtchn))
|
|
|
|
+ return -EINVAL;
|
|
|
|
+
|
|
|
|
+ multi_notify_remote_via_evtchn(mcl, evtchn);
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+EXPORT_SYMBOL_GPL(multi_notify_remote_via_irq);
|
2011-04-19 20:09:59 +00:00
|
|
|
+#endif
|
2010-07-07 11:12:45 +00:00
|
|
|
+
|
|
|
|
int irq_to_evtchn_port(int irq)
|
|
|
|
{
|
2011-04-19 20:09:59 +00:00
|
|
|
const struct irq_cfg *cfg = irq_cfg(irq);
|
|
|
|
--- head-2011-02-08.orig/drivers/xen/netback/netback.c 2011-01-03 13:30:08.000000000 +0100
|
|
|
|
+++ head-2011-02-08/drivers/xen/netback/netback.c 2011-01-03 13:30:15.000000000 +0100
|
|
|
|
@@ -767,10 +767,20 @@ static void net_rx_action(unsigned long
|
2010-07-07 11:12:45 +00:00
|
|
|
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? */
|
2011-04-19 20:09:59 +00:00
|
|
|
--- head-2011-02-08.orig/include/xen/evtchn.h 2010-11-23 16:18:23.000000000 +0100
|
|
|
|
+++ head-2011-02-08/include/xen/evtchn.h 2010-11-23 16:20:08.000000000 +0100
|
|
|
|
@@ -193,6 +193,18 @@ static inline void notify_remote_via_evt
|
2010-07-07 11:12:45 +00:00
|
|
|
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;
|
|
|
|
+}
|
|
|
|
+
|
2011-04-19 20:09:59 +00:00
|
|
|
static inline int close_evtchn(int port)
|
|
|
|
{
|
|
|
|
struct evtchn_close close = { .port = port };
|
|
|
|
@@ -207,6 +219,7 @@ int xen_test_irq_pending(int irq);
|
2010-07-07 11:12:45 +00:00
|
|
|
* 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)
|