perf_event: Provide vmalloc() based mmap() backing
[safe/jmp/linux-2.6] / kernel / irq / handle.c
index a6368db..a81cf80 100644 (file)
  */
 
 #include <linux/irq.h>
+#include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/random.h>
 #include <linux/interrupt.h>
 #include <linux/kernel_stat.h>
 #include <linux/rculist.h>
 #include <linux/hash.h>
-#include <trace/irq.h>
 #include <linux/bootmem.h>
+#include <trace/events/irq.h>
 
 #include "internals.h"
 
@@ -44,7 +45,7 @@ void handle_bad_irq(unsigned int irq, struct irq_desc *desc)
 #if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_HARDIRQS)
 static void __init init_irq_default_affinity(void)
 {
-       alloc_bootmem_cpumask_var(&irq_default_affinity);
+       alloc_cpumask_var(&irq_default_affinity, GFP_NOWAIT);
        cpumask_setall(irq_default_affinity);
 }
 #else
@@ -81,11 +82,16 @@ static struct irq_desc irq_desc_init = {
        .lock       = __SPIN_LOCK_UNLOCKED(irq_desc_init.lock),
 };
 
-void init_kstat_irqs(struct irq_desc *desc, int node, int nr)
+void __ref init_kstat_irqs(struct irq_desc *desc, int node, int nr)
 {
        void *ptr;
 
-       ptr = kzalloc_node(nr * sizeof(*desc->kstat_irqs), GFP_ATOMIC, node);
+       if (slab_is_available())
+               ptr = kzalloc_node(nr * sizeof(*desc->kstat_irqs),
+                                  GFP_ATOMIC, node);
+       else
+               ptr = alloc_bootmem_node(NODE_DATA(node),
+                               nr * sizeof(*desc->kstat_irqs));
 
        /*
         * don't overwite if can not get new one
@@ -144,6 +150,7 @@ int __init early_irq_init(void)
 {
        struct irq_desc *desc;
        int legacy_count;
+       int node;
        int i;
 
        init_irq_default_affinity();
@@ -154,20 +161,23 @@ int __init early_irq_init(void)
 
        desc = irq_desc_legacy;
        legacy_count = ARRAY_SIZE(irq_desc_legacy);
+       node = first_online_node;
 
        /* allocate irq_desc_ptrs array based on nr_irqs */
-       irq_desc_ptrs = alloc_bootmem(nr_irqs * sizeof(void *));
+       irq_desc_ptrs = kcalloc(nr_irqs, sizeof(void *), GFP_NOWAIT);
 
        /* allocate based on nr_cpu_ids */
-       /* FIXME: invert kstat_irgs, and it'd be a per_cpu_alloc'd thing */
-       kstat_irqs_legacy = alloc_bootmem(NR_IRQS_LEGACY * nr_cpu_ids *
-                                         sizeof(int));
+       kstat_irqs_legacy = kzalloc_node(NR_IRQS_LEGACY * nr_cpu_ids *
+                                         sizeof(int), GFP_NOWAIT, node);
 
        for (i = 0; i < legacy_count; i++) {
                desc[i].irq = i;
+#ifdef CONFIG_SMP
+               desc[i].node = node;
+#endif
                desc[i].kstat_irqs = kstat_irqs_legacy + i * nr_cpu_ids;
                lockdep_set_class(&desc[i].lock, &irq_desc_lock_class);
-               alloc_desc_masks(&desc[i], 0, true);
+               alloc_desc_masks(&desc[i], node, true);
                init_desc_masks(&desc[i]);
                irq_desc_ptrs[i] = desc + i;
        }
@@ -186,7 +196,7 @@ struct irq_desc *irq_to_desc(unsigned int irq)
        return NULL;
 }
 
-struct irq_desc *irq_to_desc_alloc_node(unsigned int irq, int node)
+struct irq_desc * __ref irq_to_desc_alloc_node(unsigned int irq, int node)
 {
        struct irq_desc *desc;
        unsigned long flags;
@@ -208,7 +218,11 @@ struct irq_desc *irq_to_desc_alloc_node(unsigned int irq, int node)
        if (desc)
                goto out_unlock;
 
-       desc = kzalloc_node(sizeof(*desc), GFP_ATOMIC, node);
+       if (slab_is_available())
+               desc = kzalloc_node(sizeof(*desc), GFP_ATOMIC, node);
+       else
+               desc = alloc_bootmem_node(NODE_DATA(node), sizeof(*desc));
+
        printk(KERN_DEBUG "  alloc irq_desc for %d on node %d\n", irq, node);
        if (!desc) {
                printk(KERN_ERR "can not alloc irq_desc\n");
@@ -345,9 +359,6 @@ static void warn_no_thread(unsigned int irq, struct irqaction *action)
               "but no thread function available.", irq, action->name);
 }
 
-DEFINE_TRACE(irq_handler_entry);
-DEFINE_TRACE(irq_handler_exit);
-
 /**
  * handle_IRQ_event - irq action chain handler
  * @irq:       the interrupt number
@@ -360,8 +371,6 @@ irqreturn_t handle_IRQ_event(unsigned int irq, struct irqaction *action)
        irqreturn_t ret, retval = IRQ_NONE;
        unsigned int status = 0;
 
-       WARN_ONCE(!in_irq(), "BUG: IRQ handler called from non-hardirq context!");
-
        if (!(action->flags & IRQF_DISABLED))
                local_irq_enable_in_hardirq();