OSDN Git Service

x86/apic: Provide apic_ack_irq()
[tomoyo/tomoyo-test1.git] / arch / x86 / kernel / apic / vector.c
index bb6f7a2..b708f59 100644 (file)
@@ -235,6 +235,15 @@ static int allocate_vector(struct irq_data *irqd, const struct cpumask *dest)
        if (vector && cpu_online(cpu) && cpumask_test_cpu(cpu, dest))
                return 0;
 
+       /*
+        * Careful here. @apicd might either have move_in_progress set or
+        * be enqueued for cleanup. Assigning a new vector would either
+        * leave a stale vector on some CPU around or in case of a pending
+        * cleanup corrupt the hlist.
+        */
+       if (apicd->move_in_progress || !hlist_unhashed(&apicd->clist))
+               return -EBUSY;
+
        vector = irq_matrix_alloc(vector_matrix, dest, resvd, &cpu);
        if (vector > 0)
                apic_update_vector(irqd, vector, cpu);
@@ -800,13 +809,18 @@ static int apic_retrigger_irq(struct irq_data *irqd)
        return 1;
 }
 
-void apic_ack_edge(struct irq_data *irqd)
+void apic_ack_irq(struct irq_data *irqd)
 {
-       irq_complete_move(irqd_cfg(irqd));
        irq_move_irq(irqd);
        ack_APIC_irq();
 }
 
+void apic_ack_edge(struct irq_data *irqd)
+{
+       irq_complete_move(irqd_cfg(irqd));
+       apic_ack_irq(irqd);
+}
+
 static struct irq_chip lapic_controller = {
        .name                   = "APIC",
        .irq_ack                = apic_ack_edge,