[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] [IA64] Fix network issue on VTI domain



# HG changeset patch
# User awilliam@xxxxxxxxxxx
# Node ID 0fff4c07af186f6772060a4b3b40a05329c598fb
# Parent  f662f98d594b65e1698c5da241312f1ae136b975
[IA64] Fix network issue on VTI domain

Clean up event wait sequence in io emulation path, as a critical
fix to a severe issue where VTI domain may fall into block state
when doing bulk network transfer.

Signed-off-by Kevin Tian <kevin.tian@xxxxxxxxx>
---
 xen/arch/ia64/vmx/vmx_support.c |   64 +++++++++++++---------------------------
 1 files changed, 22 insertions(+), 42 deletions(-)

diff -r f662f98d594b -r 0fff4c07af18 xen/arch/ia64/vmx/vmx_support.c
--- a/xen/arch/ia64/vmx/vmx_support.c   Mon Jun 05 14:28:39 2006 -0600
+++ b/xen/arch/ia64/vmx/vmx_support.c   Tue Jun 06 09:01:38 2006 -0600
@@ -32,7 +32,8 @@
  * when emulation code is waiting for I/O completion by blocking,
  * other events like DM interrupt, VBD, etc. may come and unblock
  * current exection flow. So we have to prepare for re-block if unblocked
- * by non I/O completion event.
+ * by non I/O completion event. After io emulation is done, re-enable
+ * pending indicaion if other ports are pending
  */
 void vmx_wait_io(void)
 {
@@ -40,39 +41,25 @@ void vmx_wait_io(void)
     struct domain *d = v->domain;
     int port = iopacket_port(v);
 
-    do {
-       if (!test_bit(port,
-               &d->shared_info->evtchn_pending[0]))
-            do_sched_op_compat(SCHEDOP_block, 0);
+    for (;;) {
+        if (test_and_clear_bit(0, &v->vcpu_info->evtchn_upcall_pending) &&
+            test_and_clear_bit(port / BITS_PER_LONG,
+                                     &v->vcpu_info->evtchn_pending_sel) &&
+            test_and_clear_bit(port, &d->shared_info->evtchn_pending[0]))
+            vmx_io_assist(v);
 
-       /* Unblocked when some event is coming. Clear pending indication
-        * immediately if deciding to go for io assist
-         */
-       if (test_and_clear_bit(port,
-               &d->shared_info->evtchn_pending[0])) {
-           clear_bit(port/BITS_PER_LONG, &v->vcpu_info->evtchn_pending_sel);
-           clear_bit(0, &v->vcpu_info->evtchn_upcall_pending);
-           vmx_io_assist(v);
-       }
+        if (!test_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags))
+            break;
 
+        do_sched_op_compat(SCHEDOP_block, 0);
+    }
 
-       if (test_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags)) {
-           /*
-            * Latest event is not I/O completion, so clear corresponding
-            * selector and pending indication, to allow real event coming
-            */
-           clear_bit(0, &v->vcpu_info->evtchn_upcall_pending);
+    /* re-enable indication if other pending events */
+    if (d->shared_info->evtchn_pending[port / BITS_PER_LONG])
+        set_bit(port / BITS_PER_LONG, &v->vcpu_info->evtchn_pending_sel);
 
-           /* Here atually one window is leaved before selector is cleared.
-            * However this window only delay the indication to coming event,
-            * nothing losed. Next loop will check I/O channel to fix this
-            * window.
-            */
-           clear_bit(port/BITS_PER_LONG, &v->vcpu_info->evtchn_pending_sel);
-       }
-       else
-           break;
-    } while (test_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags));
+    if (&v->vcpu_info->evtchn_pending_sel)
+        set_bit(0, &v->vcpu_info->evtchn_upcall_pending);
 }
 
 /*
@@ -110,8 +97,7 @@ void vmx_io_assist(struct vcpu *v)
            p->state = STATE_INVALID;
 
        clear_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags);
-    } else
-       return; /* Spurous event? */
+    }
 }
 
 /*
@@ -131,21 +117,15 @@ void vmx_intr_assist(struct vcpu *v)
                                        unsigned long *pend_irr);
     int port = iopacket_port(v);
 
+    if (test_bit(port, &d->shared_info->evtchn_pending[0]) ||
+       test_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags))
+       vmx_wait_io();
+
     /* I/O emulation is atomic, so it's impossible to see execution flow
      * out of vmx_wait_io, when guest is still waiting for response.
      */
     if (test_bit(ARCH_VMX_IO_WAIT, &v->arch.arch_vmx.flags))
        panic_domain(vcpu_regs(v),"!!!Bad resume to guest before I/O emulation 
is done.\n");
-
-    /* Clear indicator specific to interrupt delivered from DM */
-    if (test_and_clear_bit(port,
-               &d->shared_info->evtchn_pending[0])) {
-       if (!d->shared_info->evtchn_pending[port/BITS_PER_LONG])
-           clear_bit(port/BITS_PER_LONG, &v->vcpu_info->evtchn_pending_sel);
-
-       if (!v->vcpu_info->evtchn_pending_sel)
-           clear_bit(0, &v->vcpu_info->evtchn_upcall_pending);
-    }
 
     /* Even without event pending, we still need to sync pending bits
      * between DM and vlsapic. The reason is that interrupt delivery

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.