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

[Xen-devel] [PATCH] evtchn_do_upcall: search a snapshot of level 2 bits for pending upcalls


  • To: xen-devel@xxxxxxxxxxxxxxxxxxx
  • From: Kaushik Kumar Ram <kaushik@xxxxxxxx>
  • Date: Fri, 29 Jan 2010 00:02:51 -0600
  • Delivery-date: Thu, 28 Jan 2010 22:03:13 -0800
  • List-id: Xen developer discussion <xen-devel.lists.xensource.com>

# HG changeset patch
# User kaushik
# Date 1264744731 21600
# Node ID 12c3dcae53baf45665266614d4b589875c819355
# Parent  91224343eeee460c9aafdaadc1bdedab54e92256
Search a snapshot of level 2 bits for pending upcalls.

Using only a snapshot of level 1 bits can lead to unfairness
in some cases. Consider the case where two upcalls are marked
pending after a snapshot of level 1 bits is taken. One of these
two upcalls can still be processed if the corresponding level 1
bit was already set.

This is not a perfect solution since its still possible for a level 2
bit to be set before a level 2 snapshot is taken (unless both
snapshots are taken atomically).

Signed-off-by: Kaushik Kumar Ram <kaushik@xxxxxxxx>

diff -r 91224343eeee -r 12c3dcae53ba drivers/xen/core/evtchn.c
--- a/drivers/xen/core/evtchn.c Thu Jan 21 15:05:02 2010 +0000
+++ b/drivers/xen/core/evtchn.c Thu Jan 28 23:58:51 2010 -0600
@@ -243,6 +243,8 @@ asmlinkage void evtchn_do_upcall(struct 
        unsigned int        cpu = smp_processor_id();
        shared_info_t      *s = HYPERVISOR_shared_info;
        vcpu_info_t        *vcpu_info = &s->vcpu_info[cpu];
+       int i;
+       unsigned long local_l2[sizeof(unsigned long) * 8];

        exit_idle();
        irq_enter();
@@ -260,6 +262,10 @@ asmlinkage void evtchn_do_upcall(struct 
                wmb();
 #endif
                l1 = xchg(&vcpu_info->evtchn_pending_sel, 0);
+                
+               for(i = 0; i < BITS_PER_LONG; i++) {
+                       local_l2[i] = active_evtchns(cpu, s, i);
+               }

                l1i = per_cpu(last_processed_l1i, cpu);
                l2i = per_cpu(last_processed_l2i, cpu);
@@ -277,7 +283,7 @@ asmlinkage void evtchn_do_upcall(struct 
                        l1i = __ffs(masked_l1);

                        do {
-                               l2 = active_evtchns(cpu, s, l1i);
+                              l2 = local_l2[l1i];

                                l2i = (l2i + 1) % BITS_PER_LONG;
                                masked_l2 = l2 & ((~0UL) << l2i);
@@ -296,13 +302,15 @@ asmlinkage void evtchn_do_upcall(struct 
                                else
                                        evtchn_device_upcall(port);

+                             clear_bit(l2i, &local_l2[l1i]);
+
                                /* if this is the final port processed, we'll 
pick up here+1 next time */
                                per_cpu(last_processed_l1i, cpu) = l1i;
                                per_cpu(last_processed_l2i, cpu) = l2i;

                        } while (l2i != BITS_PER_LONG - 1);

-                       l2 = active_evtchns(cpu, s, l1i);
+                      l2 = local_l2[l1i];
                        if (l2 == 0) /* we handled all ports, so we can clear 
the selector bit */
                                l1 &= ~(1UL << l1i);


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


 


Rackspace

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