[PATCH] xics_disable_irq() irq server bug

John Rose johnrose at austin.ibm.com
Fri Jan 9 04:02:10 EST 2004


The xics_disable_irq() function can use an incorrect irq server when
setting an irq to the lowest priority.  This happens in the case of
CONFIG_IRQ_ALL_CPUS=y, which is the default case.

This bug prevents DLPAR removal for slots that contain adapters that
have been activated since boot.  Will push tomorrow if there are no
objections.

Thanks-
John

diff -Nru a/arch/ppc64/kernel/xics.c b/arch/ppc64/kernel/xics.c
--- a/arch/ppc64/kernel/xics.c	Thu Jan  8 10:58:28 2004
+++ b/arch/ppc64/kernel/xics.c	Thu Jan  8 10:58:28 2004
@@ -213,21 +213,17 @@
 	pSeriesLP_qirr_info
 };

+
 /* XXX Fix this when we clean up large irq support */
 extern cpumask_t get_irq_affinity(unsigned int irq);

-void xics_enable_irq(unsigned int irq)
+static int get_irq_server(unsigned int irq)
 {
-	long call_status;
-	unsigned int server;
 	cpumask_t cpumask = get_irq_affinity(irq);
 	cpumask_t allcpus = CPU_MASK_ALL;
 	cpumask_t tmp = CPU_MASK_NONE;
-
-	irq = irq_offset_down(irq);
-	if (irq == XICS_IPI)
-		return;
-
+	unsigned int server;
+
 #ifdef CONFIG_IRQ_ALL_CPUS
 	/* For the moment only implement delivery to all cpus or one cpu */
 	if (smp_threads_ready) {
@@ -247,7 +243,20 @@
 #else
 	server = default_server;
 #endif
+	return server;
+
+}
+
+void xics_enable_irq(unsigned int irq)
+{
+	long call_status;
+	unsigned int server;

+	irq = irq_offset_down(irq);
+	if (irq == XICS_IPI)
+		return;
+
+	server = get_irq_server(irq);
 	call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, server,
 				DEFAULT_PRIORITY);
 	if (call_status != 0) {
@@ -268,6 +277,7 @@
 void xics_disable_irq(unsigned int irq)
 {
 	long call_status;
+	unsigned int server;

 	irq = irq_offset_down(irq);
 	if (irq == XICS_IPI)
@@ -280,9 +290,9 @@
 		return;
 	}

+	server = get_irq_server(irq);
 	/* Have to set XIVE to 0xff to be able to remove a slot */
-	call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, default_server,
-				0xff);
+	call_status = rtas_call(ibm_set_xive, 3, 1, NULL, irq, server, 0xff);
 	if (call_status != 0) {
 	printk("xics_disable_irq: irq=%x: ibm_set_xive(0xff) returned %lx\n",
 	       irq, call_status);

** Sent via the linuxppc64-dev mail list. See http://lists.linuxppc.org/





More information about the Linuxppc64-dev mailing list