[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [RFC PATCH 2/3] Xen: rework NR_EVENT_CHANNELS related stuffs.
Signed-off-by: Wei Liu <wei.liu2@xxxxxxxxxx> --- drivers/xen/events.c | 44 +++++++++++++++++++++++++++++-------------- drivers/xen/evtchn.c | 16 +++++++++------- include/xen/events.h | 3 +++ include/xen/interface/xen.h | 17 ++++++++++++++++- 4 files changed, 58 insertions(+), 22 deletions(-) diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 835101f..f60ba76 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -52,7 +52,8 @@ #include <xen/interface/hvm/params.h> /* N-level event channel, starting from 2 */ -static unsigned int evtchn_level = 2; +unsigned int evtchn_level = 2; +EXPORT_SYMBOL_GPL(evtchn_level); struct evtchn_ops { unsigned long (*active_evtchns)(unsigned int, @@ -130,8 +131,7 @@ static int *evtchn_to_irq; static unsigned long *pirq_eoi_map; static bool (*pirq_needs_eoi)(unsigned irq); -static DEFINE_PER_CPU(unsigned long [NR_EVENT_CHANNELS/BITS_PER_LONG], - cpu_evtchn_mask); +static DEFINE_PER_CPU(unsigned long *, cpu_evtchn_mask); /* Xen will never allocate port zero for any purpose. */ #define VALID_EVTCHN(chn) ((chn) != 0) @@ -913,7 +913,7 @@ static int find_virq(unsigned int virq, unsigned int cpu) int port, rc = -ENOENT; memset(&status, 0, sizeof(status)); - for (port = 0; port <= NR_EVENT_CHANNELS; port++) { + for (port = 0; port <= NR_EVENT_CHANNELS(evtchn_level); port++) { status.dom = DOMID_SELF; status.port = port; rc = HYPERVISOR_event_channel_op(EVTCHNOP_status, &status); @@ -1138,7 +1138,7 @@ int evtchn_get(unsigned int evtchn) struct irq_info *info; int err = -ENOENT; - if (evtchn >= NR_EVENT_CHANNELS) + if (evtchn >= NR_EVENT_CHANNELS(evtchn_level)) return -EINVAL; mutex_lock(&irq_mapping_update_lock); @@ -1227,7 +1227,7 @@ static irqreturn_t __xen_debug_interrupt_l2(int irq, void *dev_id) i % 8 == 0 ? "\n " : " "); printk("\nlocal cpu%d mask:\n ", cpu); - for (i = (NR_EVENT_CHANNELS/BITS_PER_LONG)-1; i >= 0; i--) + for (i = (NR_EVENT_CHANNELS(evtchn_level)/BITS_PER_LONG)-1; i >= 0; i--) printk("%0*lx%s", (int)(sizeof(cpu_evtchn[0])*2), cpu_evtchn[i], i % 8 == 0 ? "\n " : " "); @@ -1242,7 +1242,7 @@ static irqreturn_t __xen_debug_interrupt_l2(int irq, void *dev_id) } printk("\npending list:\n"); - for (i = 0; i < NR_EVENT_CHANNELS; i++) { + for (i = 0; i < NR_EVENT_CHANNELS(evtchn_level); i++) { if (sync_test_bit(i, sh->evtchn_pending)) { int word_idx = i / BITS_PER_LONG; printk(" %d: event %d -> irq %d%s%s%s\n", @@ -1709,14 +1709,14 @@ void xen_irq_resume(void) init_evtchn_cpu_bindings(); /* New event-channel space is not 'live' yet. */ - for (evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++) + for (evtchn = 0; evtchn < NR_EVENT_CHANNELS(evtchn_level); evtchn++) eops->mask_evtchn(evtchn); /* No IRQ <-> event-channel mappings. */ list_for_each_entry(info, &xen_irq_list_head, list) info->evtchn = 0; /* zap event-channel binding */ - for (evtchn = 0; evtchn < NR_EVENT_CHANNELS; evtchn++) + for (evtchn = 0; evtchn < NR_EVENT_CHANNELS(evtchn_level); evtchn++) evtchn_to_irq[evtchn] = -1; for_each_possible_cpu(cpu) { @@ -1824,21 +1824,37 @@ static struct evtchn_ops evtchn_ops_l2 __read_mostly = { void __init xen_init_IRQ(void) { int i, rc; + int cpu; - evtchn_level = 2; + /* Setup 2-level event channel */ eops = &evtchn_ops_l2; + evtchn_level = 2; - /* Setup 2-level event channel */ - evtchn_to_irq = kcalloc(NR_EVENT_CHANNELS, sizeof(*evtchn_to_irq), + evtchn_to_irq = kcalloc(NR_EVENT_CHANNELS(evtchn_level), + sizeof(*evtchn_to_irq), GFP_KERNEL); BUG_ON(!evtchn_to_irq); - for (i = 0; i < NR_EVENT_CHANNELS; i++) + + for_each_possible_cpu(cpu) { + void *p; + unsigned int nr = NR_EVENT_CHANNELS(evtchn_level)/BITS_PER_LONG; + p = kzalloc_node(sizeof(unsigned long) * nr, + GFP_KERNEL, + cpu_to_node(cpu)); + if (!p) + p = kzalloc(sizeof(unsigned long) * nr, + GFP_KERNEL); + BUG_ON(!p); + per_cpu(cpu_evtchn_mask, cpu) = p; + } + + for (i = 0; i < NR_EVENT_CHANNELS(evtchn_level); i++) evtchn_to_irq[i] = -1; init_evtchn_cpu_bindings(); /* No event channels are 'live' right now. */ - for (i = 0; i < NR_EVENT_CHANNELS; i++) + for (i = 0; i < NR_EVENT_CHANNELS(evtchn_level); i++) eops->mask_evtchn(i); pirq_needs_eoi = pirq_needs_eoi_flag; diff --git a/drivers/xen/evtchn.c b/drivers/xen/evtchn.c index b1f60a0..cb45ecf 100644 --- a/drivers/xen/evtchn.c +++ b/drivers/xen/evtchn.c @@ -232,7 +232,7 @@ static ssize_t evtchn_write(struct file *file, const char __user *buf, for (i = 0; i < (count/sizeof(evtchn_port_t)); i++) { unsigned port = kbuf[i]; - if (port < NR_EVENT_CHANNELS && + if (port < NR_EVENT_CHANNELS(evtchn_level) && get_port_user(port) == u && !get_port_enabled(port)) { set_port_enabled(port, true); @@ -364,7 +364,7 @@ static long evtchn_ioctl(struct file *file, break; rc = -EINVAL; - if (unbind.port >= NR_EVENT_CHANNELS) + if (unbind.port >= NR_EVENT_CHANNELS(evtchn_level)) break; spin_lock_irq(&port_user_lock); @@ -392,7 +392,7 @@ static long evtchn_ioctl(struct file *file, if (copy_from_user(¬ify, uarg, sizeof(notify))) break; - if (notify.port >= NR_EVENT_CHANNELS) { + if (notify.port >= NR_EVENT_CHANNELS(evtchn_level)) { rc = -EINVAL; } else if (get_port_user(notify.port) != u) { rc = -ENOTCONN; @@ -482,7 +482,7 @@ static int evtchn_release(struct inode *inode, struct file *filp) free_page((unsigned long)u->ring); - for (i = 0; i < NR_EVENT_CHANNELS; i++) { + for (i = 0; i < NR_EVENT_CHANNELS(evtchn_level); i++) { if (get_port_user(i) != u) continue; @@ -491,7 +491,7 @@ static int evtchn_release(struct inode *inode, struct file *filp) spin_unlock_irq(&port_user_lock); - for (i = 0; i < NR_EVENT_CHANNELS; i++) { + for (i = 0; i < NR_EVENT_CHANNELS(evtchn_level); i++) { if (get_port_user(i) != u) continue; @@ -528,7 +528,8 @@ static int __init evtchn_init(void) if (!xen_domain()) return -ENODEV; - port_user = kcalloc(NR_EVENT_CHANNELS, sizeof(*port_user), GFP_KERNEL); + port_user = kcalloc(NR_EVENT_CHANNELS(evtchn_level), + sizeof(*port_user), GFP_KERNEL); if (port_user == NULL) return -ENOMEM; @@ -541,7 +542,8 @@ static int __init evtchn_init(void) return err; } - printk(KERN_INFO "Event-channel device installed.\n"); + printk(KERN_INFO "Event-channel device installed." + " Event-channel level: %d\n", evtchn_level); return 0; } diff --git a/include/xen/events.h b/include/xen/events.h index 04399b2..bc10f22 100644 --- a/include/xen/events.h +++ b/include/xen/events.h @@ -109,4 +109,7 @@ int xen_irq_from_gsi(unsigned gsi); /* Determine whether to ignore this IRQ if it is passed to a guest. */ int xen_test_irq_shared(int irq); +/* N-level event channels */ +extern unsigned int evtchn_level; + #endif /* _XEN_EVENTS_H */ diff --git a/include/xen/interface/xen.h b/include/xen/interface/xen.h index a890804..c66e1ff 100644 --- a/include/xen/interface/xen.h +++ b/include/xen/interface/xen.h @@ -283,9 +283,24 @@ DEFINE_GUEST_HANDLE_STRUCT(multicall_entry); /* * Event channel endpoints per domain: + * 2-level: * 1024 if a long is 32 bits; 4096 if a long is 64 bits. + * 3-level: + * 32k if a long is 32 bits; 256k if a long is 64 bits. */ -#define NR_EVENT_CHANNELS (sizeof(unsigned long) * sizeof(unsigned long) * 64) +#define NR_EVENT_CHANNELS_L2 (sizeof(unsigned long) * sizeof(unsigned long) * 64) +#define NR_EVENT_CHANNELS_L3 (NR_EVENT_CHANNELS_L2 * sizeof(unsigned long)) +#define NR_EVENT_CHANNELS(x) ({ unsigned int __v = 0; \ + switch (x) { \ + case 2: \ + __v = NR_EVENT_CHANNELS_L2; break; \ + case 3: \ + __v = NR_EVENT_CHANNELS_L3; break; \ + default: \ + BUG(); \ + } \ + __v; }) + struct vcpu_time_info { /* -- 1.7.10.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |