[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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |