From mboxrd@z Thu Jan 1 00:00:00 1970 From: Ian Campbell Subject: [PATCH 4/5] xen: events: Make round-robin scan fairer by snapshotting each l2 word Date: Thu, 3 Mar 2011 17:10:14 +0000 Message-ID: <1299172215-29470-4-git-send-email-ian.campbell@citrix.com> References: <1299172198.6552.14.camel@zakaz.uk.xensource.com> Return-path: In-Reply-To: <1299172198.6552.14.camel@zakaz.uk.xensource.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xensource.com Errors-To: xen-devel-bounces@lists.xensource.com To: xen-devel@lists.xensource.com Cc: Jeremy Fitzhardinge , James Harper , Ian Campbell , Konrad Rzeszutek Wilk , Keir Fraser , Keir Fraser List-Id: xen-devel@lists.xenproject.org From: Keir Fraser Signed-off-by: Keir Fraser Signed-off-by: Ian Campbell [ijc: forward ported from linux-2.6.18-xen.hg 990:427276ac595d] --- drivers/xen/events.c | 30 +++++++++++++++++++++--------- 1 files changed, 21 insertions(+), 9 deletions(-) diff --git a/drivers/xen/events.c b/drivers/xen/events.c index c49cb6d..0c3f17b 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -1045,7 +1045,9 @@ static DEFINE_PER_CPU(unsigned int, current_bit_idx); */ static void __xen_evtchn_do_upcall(void) { + int start_word_idx, start_bit_idx; int word_idx, bit_idx; + int i; int cpu = get_cpu(); struct shared_info *s = HYPERVISOR_shared_info; struct vcpu_info *vcpu_info = __this_cpu_read(xen_vcpu); @@ -1065,10 +1067,12 @@ static void __xen_evtchn_do_upcall(void) #endif pending_words = xchg(&vcpu_info->evtchn_pending_sel, 0); - word_idx = __this_cpu_read(current_word_idx); - bit_idx = __this_cpu_read(current_bit_idx); + start_word_idx = __this_cpu_read(current_word_idx); + start_bit_idx = __this_cpu_read(current_bit_idx); + + word_idx = start_word_idx; - while (pending_words != 0) { + for (i = 0; pending_words != 0; i++) { unsigned long pending_bits; unsigned long words; @@ -1084,13 +1088,23 @@ static void __xen_evtchn_do_upcall(void) } word_idx = __ffs(words); + pending_bits = active_evtchns(cpu, s, word_idx); + bit_idx = 0; /* usually scan entire word from start */ + if (word_idx == start_word_idx) { + /* We scan the starting word in two parts */ + if (i == 0) + /* 1st time: start in the middle */ + bit_idx = start_bit_idx; + else + /* 2nd time: mask bits done already */ + bit_idx &= (1UL << start_bit_idx) - 1; + } + do { unsigned long bits; int port, irq; struct irq_desc *desc; - pending_bits = active_evtchns(cpu, s, word_idx); - bits = MASK_LSBS(pending_bits, bit_idx); /* If we masked out all events, move on. */ @@ -1121,10 +1135,8 @@ static void __xen_evtchn_do_upcall(void) __this_cpu_write(current_bit_idx, bit_idx); } while (bit_idx != 0); - pending_bits = active_evtchns(cpu, s, word_idx); - - /* If we handled all ports, clear the selector bit. */ - if (pending_bits == 0) + /* Scan start_l1i twice; all others once. */ + if ((word_idx != start_word_idx) || (i != 0)) pending_words &= ~(1UL << word_idx); word_idx = (word_idx + 1) % BITS_PER_LONG; -- 1.5.6.5