Commit d0b075ff authored by David Vrabel's avatar David Vrabel Committed by Konrad Rzeszutek Wilk

xen/events: Refactor evtchn_to_irq array to be dynamically allocated

Refactor static array evtchn_to_irq array to be dynamically allocated by
implementing get and set functions for accesses to the array.

Two new port ops are added: max_channels (maximum supported number of
event channels) and nr_channels (number of currently usable event
channels).  For the 2-level ABI, these numbers are both the same as
the shared data structure is a fixed size. For the FIFO ABI, these
will be different as the event array is expanded dynamically.

This allows more than 65000 event channels so an unsigned short is no
longer sufficient for an event channel port number and unsigned int is
used instead.
Signed-off-by: default avatarMalcolm Crossley <malcolm.crossley@citrix.com>
Signed-off-by: default avatarDavid Vrabel <david.vrabel@citrix.com>
Reviewed-by: default avatarKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Reviewed-by: default avatarBoris Ostrovsky <boris.ostrovsky@oracle.com>
parent 08385875
...@@ -41,6 +41,11 @@ ...@@ -41,6 +41,11 @@
static DEFINE_PER_CPU(xen_ulong_t [NR_EVENT_CHANNELS/BITS_PER_EVTCHN_WORD], static DEFINE_PER_CPU(xen_ulong_t [NR_EVENT_CHANNELS/BITS_PER_EVTCHN_WORD],
cpu_evtchn_mask); cpu_evtchn_mask);
static unsigned evtchn_2l_max_channels(void)
{
return NR_EVENT_CHANNELS;
}
static void evtchn_2l_bind_to_cpu(struct irq_info *info, unsigned cpu) static void evtchn_2l_bind_to_cpu(struct irq_info *info, unsigned cpu)
{ {
clear_bit(info->evtchn, BM(per_cpu(cpu_evtchn_mask, info->cpu))); clear_bit(info->evtchn, BM(per_cpu(cpu_evtchn_mask, info->cpu)));
...@@ -238,7 +243,7 @@ static void evtchn_2l_handle_events(unsigned cpu) ...@@ -238,7 +243,7 @@ static void evtchn_2l_handle_events(unsigned cpu)
/* Process port. */ /* Process port. */
port = (word_idx * BITS_PER_EVTCHN_WORD) + bit_idx; port = (word_idx * BITS_PER_EVTCHN_WORD) + bit_idx;
irq = evtchn_to_irq[port]; irq = get_evtchn_to_irq(port);
if (irq != -1) { if (irq != -1) {
desc = irq_to_desc(irq); desc = irq_to_desc(irq);
...@@ -332,7 +337,7 @@ irqreturn_t xen_debug_interrupt(int irq, void *dev_id) ...@@ -332,7 +337,7 @@ irqreturn_t xen_debug_interrupt(int irq, void *dev_id)
int word_idx = i / BITS_PER_EVTCHN_WORD; int word_idx = i / BITS_PER_EVTCHN_WORD;
printk(" %d: event %d -> irq %d%s%s%s\n", printk(" %d: event %d -> irq %d%s%s%s\n",
cpu_from_evtchn(i), i, cpu_from_evtchn(i), i,
evtchn_to_irq[i], get_evtchn_to_irq(i),
sync_test_bit(word_idx, BM(&v->evtchn_pending_sel)) sync_test_bit(word_idx, BM(&v->evtchn_pending_sel))
? "" : " l2-clear", ? "" : " l2-clear",
!sync_test_bit(i, BM(sh->evtchn_mask)) !sync_test_bit(i, BM(sh->evtchn_mask))
...@@ -348,6 +353,8 @@ irqreturn_t xen_debug_interrupt(int irq, void *dev_id) ...@@ -348,6 +353,8 @@ irqreturn_t xen_debug_interrupt(int irq, void *dev_id)
} }
static const struct evtchn_ops evtchn_ops_2l = { static const struct evtchn_ops evtchn_ops_2l = {
.max_channels = evtchn_2l_max_channels,
.nr_channels = evtchn_2l_max_channels,
.bind_to_cpu = evtchn_2l_bind_to_cpu, .bind_to_cpu = evtchn_2l_bind_to_cpu,
.clear_pending = evtchn_2l_clear_pending, .clear_pending = evtchn_2l_clear_pending,
.set_pending = evtchn_2l_set_pending, .set_pending = evtchn_2l_set_pending,
......
This diff is collapsed.
...@@ -35,7 +35,7 @@ struct irq_info { ...@@ -35,7 +35,7 @@ struct irq_info {
int refcnt; int refcnt;
enum xen_irq_type type; /* type */ enum xen_irq_type type; /* type */
unsigned irq; unsigned irq;
unsigned short evtchn; /* event channel */ unsigned int evtchn; /* event channel */
unsigned short cpu; /* cpu bound */ unsigned short cpu; /* cpu bound */
union { union {
...@@ -55,6 +55,9 @@ struct irq_info { ...@@ -55,6 +55,9 @@ struct irq_info {
#define PIRQ_SHAREABLE (1 << 1) #define PIRQ_SHAREABLE (1 << 1)
struct evtchn_ops { struct evtchn_ops {
unsigned (*max_channels)(void);
unsigned (*nr_channels)(void);
int (*setup)(struct irq_info *info); int (*setup)(struct irq_info *info);
void (*bind_to_cpu)(struct irq_info *info, unsigned cpu); void (*bind_to_cpu)(struct irq_info *info, unsigned cpu);
...@@ -70,12 +73,23 @@ struct evtchn_ops { ...@@ -70,12 +73,23 @@ struct evtchn_ops {
extern const struct evtchn_ops *evtchn_ops; extern const struct evtchn_ops *evtchn_ops;
extern int *evtchn_to_irq; extern int **evtchn_to_irq;
int get_evtchn_to_irq(unsigned int evtchn);
struct irq_info *info_for_irq(unsigned irq); struct irq_info *info_for_irq(unsigned irq);
unsigned cpu_from_irq(unsigned irq); unsigned cpu_from_irq(unsigned irq);
unsigned cpu_from_evtchn(unsigned int evtchn); unsigned cpu_from_evtchn(unsigned int evtchn);
static inline unsigned xen_evtchn_max_channels(void)
{
return evtchn_ops->max_channels();
}
static inline unsigned xen_evtchn_nr_channels(void)
{
return evtchn_ops->nr_channels();
}
/* /*
* Do any ABI specific setup for a bound event channel before it can * Do any ABI specific setup for a bound event channel before it can
* be unmasked and used. * be unmasked and used.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment