direct-io.hg
changeset 13560:914304b3a3da
linux: Fix enable_irq() crash by removing a BUG_ON() assumption in our
event-channel retrigger() function. Also clean up bitmap usages.
Signed-off-by: Keir Fraser <keir@xensource.com>
event-channel retrigger() function. Also clean up bitmap usages.
Signed-off-by: Keir Fraser <keir@xensource.com>
author | kfraser@localhost.localdomain |
---|---|
date | Tue Jan 23 13:39:20 2007 +0000 (2007-01-23) |
parents | ee7c422c5f7b |
children | ffe52263b430 |
files | linux-2.6-xen-sparse/drivers/xen/core/evtchn.c linux-2.6-xen-sparse/include/xen/evtchn.h |
line diff
1.1 --- a/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c Tue Jan 23 11:39:32 2007 +0000 1.2 +++ b/linux-2.6-xen-sparse/drivers/xen/core/evtchn.c Tue Jan 23 13:39:20 2007 +0000 1.3 @@ -60,8 +60,6 @@ static int evtchn_to_irq[NR_EVENT_CHANNE 1.4 /* Packed IRQ information: binding type, sub-type index, and event channel. */ 1.5 static u32 irq_info[NR_IRQS]; 1.6 1.7 -static int resend_irq_on_evtchn(unsigned int); 1.8 - 1.9 /* Binding types. */ 1.10 enum { 1.11 IRQT_UNBOUND, 1.12 @@ -113,7 +111,7 @@ DEFINE_PER_CPU(int, ipi_to_irq[NR_IPIS]) 1.13 static int irq_bindcount[NR_IRQS]; 1.14 1.15 /* Bitmap indicating which PIRQs require Xen to be notified on unmask. */ 1.16 -static unsigned long pirq_needs_eoi[NR_PIRQS/sizeof(unsigned long)]; 1.17 +static DECLARE_BITMAP(pirq_needs_eoi, NR_PIRQS); 1.18 1.19 #ifdef CONFIG_SMP 1.20 1.21 @@ -614,6 +612,22 @@ static void set_affinity_irq(unsigned ir 1.22 } 1.23 #endif 1.24 1.25 +static int resend_irq_on_evtchn(unsigned int i) 1.26 +{ 1.27 + int masked, evtchn = evtchn_from_irq(i); 1.28 + shared_info_t *s = HYPERVISOR_shared_info; 1.29 + 1.30 + if (!VALID_EVTCHN(evtchn)) 1.31 + return 1; 1.32 + 1.33 + masked = synch_test_and_set_bit(evtchn, s->evtchn_mask); 1.34 + synch_set_bit(evtchn, s->evtchn_pending); 1.35 + if (!masked) 1.36 + unmask_evtchn(evtchn); 1.37 + 1.38 + return 1; 1.39 +} 1.40 + 1.41 /* 1.42 * Interface to generic handling in irq.c 1.43 */ 1.44 @@ -688,7 +702,7 @@ static struct hw_interrupt_type dynirq_t 1.45 static inline void pirq_unmask_notify(int pirq) 1.46 { 1.47 struct physdev_eoi eoi = { .irq = pirq }; 1.48 - if (unlikely(test_bit(pirq, &pirq_needs_eoi[0]))) 1.49 + if (unlikely(test_bit(pirq, pirq_needs_eoi))) 1.50 (void)HYPERVISOR_physdev_op(PHYSDEVOP_eoi, &eoi); 1.51 } 1.52 1.53 @@ -697,9 +711,9 @@ static inline void pirq_query_unmask(int 1.54 struct physdev_irq_status_query irq_status; 1.55 irq_status.irq = pirq; 1.56 (void)HYPERVISOR_physdev_op(PHYSDEVOP_irq_status_query, &irq_status); 1.57 - clear_bit(pirq, &pirq_needs_eoi[0]); 1.58 + clear_bit(pirq, pirq_needs_eoi); 1.59 if (irq_status.flags & XENIRQSTAT_needs_eoi) 1.60 - set_bit(pirq, &pirq_needs_eoi[0]); 1.61 + set_bit(pirq, pirq_needs_eoi); 1.62 } 1.63 1.64 /* 1.65 @@ -824,18 +838,6 @@ int irq_ignore_unhandled(unsigned int ir 1.66 return !!(irq_status.flags & XENIRQSTAT_shared); 1.67 } 1.68 1.69 -static int resend_irq_on_evtchn(unsigned int i) 1.70 -{ 1.71 - int evtchn = evtchn_from_irq(i); 1.72 - shared_info_t *s = HYPERVISOR_shared_info; 1.73 - if (!VALID_EVTCHN(evtchn)) 1.74 - return 0; 1.75 - BUG_ON(!synch_test_bit(evtchn, &s->evtchn_mask[0])); 1.76 - synch_set_bit(evtchn, &s->evtchn_pending[0]); 1.77 - 1.78 - return 1; 1.79 -} 1.80 - 1.81 void notify_remote_via_irq(int irq) 1.82 { 1.83 int evtchn = evtchn_from_irq(irq); 1.84 @@ -854,7 +856,7 @@ EXPORT_SYMBOL_GPL(irq_to_evtchn_port); 1.85 void mask_evtchn(int port) 1.86 { 1.87 shared_info_t *s = HYPERVISOR_shared_info; 1.88 - synch_set_bit(port, &s->evtchn_mask[0]); 1.89 + synch_set_bit(port, s->evtchn_mask); 1.90 } 1.91 EXPORT_SYMBOL_GPL(mask_evtchn); 1.92 1.93 @@ -873,14 +875,10 @@ void unmask_evtchn(int port) 1.94 return; 1.95 } 1.96 1.97 - synch_clear_bit(port, &s->evtchn_mask[0]); 1.98 + synch_clear_bit(port, s->evtchn_mask); 1.99 1.100 - /* 1.101 - * The following is basically the equivalent of 'hw_resend_irq'. Just 1.102 - * like a real IO-APIC we 'lose the interrupt edge' if the channel is 1.103 - * masked. 1.104 - */ 1.105 - if (synch_test_bit(port, &s->evtchn_pending[0]) && 1.106 + /* Did we miss an interrupt 'edge'? Re-fire if so. */ 1.107 + if (synch_test_bit(port, s->evtchn_pending) && 1.108 !synch_test_and_set_bit(port / BITS_PER_LONG, 1.109 &vcpu_info->evtchn_pending_sel)) 1.110 vcpu_info->evtchn_upcall_pending = 1;
2.1 --- a/linux-2.6-xen-sparse/include/xen/evtchn.h Tue Jan 23 11:39:32 2007 +0000 2.2 +++ b/linux-2.6-xen-sparse/include/xen/evtchn.h Tue Jan 23 13:39:20 2007 +0000 2.3 @@ -108,7 +108,7 @@ void unmask_evtchn(int port); 2.4 static inline void clear_evtchn(int port) 2.5 { 2.6 shared_info_t *s = HYPERVISOR_shared_info; 2.7 - synch_clear_bit(port, &s->evtchn_pending[0]); 2.8 + synch_clear_bit(port, s->evtchn_pending); 2.9 } 2.10 2.11 static inline void notify_remote_via_evtchn(int port)