linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [patch] Real-Time Preemption, -RT-2.6.12-rc6-V0.7.48-00
@ 2005-06-08 11:28 Ingo Molnar
  2005-06-08 14:18 ` Michal Schmidt
                   ` (9 more replies)
  0 siblings, 10 replies; 179+ messages in thread
From: Ingo Molnar @ 2005-06-08 11:28 UTC (permalink / raw)
  To: linux-kernel; +Cc: Eugeny S. Mints, Daniel Walker


i have released the -V0.7.48-00 Real-Time Preemption patch, which can be 
downloaded from the usual place:

    http://redhat.com/~mingo/realtime-preempt/

this release includes an improved version of Daniel Walker's soft 
irq-flag (hardirq-disable removal) feature. It is an unconditional part
of the PREEMPT_RT preemption model - other preemption models should not
be affected that much (besides possible build issues). Non-x86 arches
wont build. Some regressions might happen, so take care..

Changes since -47-29:

 - soft IRQ flag support (Daniel Walker)

 - fix race in usbnet.c (Eugeny S. Mints)

 - further improvements to the soft IRQ flag code

to build a -V0.7.48-00 tree, the following patches should to be applied:

   http://kernel.org/pub/linux/kernel/v2.6/linux-2.6.11.tar.bz2
   http://kernel.org/pub/linux/kernel/v2.6/testing/patch-2.6.12-rc6.bz2
   http://redhat.com/~mingo/realtime-preempt/realtime-preempt-2.6.12-rc6-V0.7.48-00

	Ingo

^ permalink raw reply	[flat|nested] 179+ messages in thread
* Re: Real-Time Preemption, -RT-2.6.12-final-V0.7.50-24
@ 2005-06-28 17:27 Karsten Wiese
  2005-06-28 20:21 ` Ingo Molnar
  0 siblings, 1 reply; 179+ messages in thread
From: Karsten Wiese @ 2005-06-28 17:27 UTC (permalink / raw)
  To: linux-kernel; +Cc: mingo

Hi Ingo,

suffering (not really ;-) double-rated IO-APIC level-interrupts I found the following patch as a solution:

--- arch/i386/kernel/io_apic.c~	2005-06-28 19:07:49.000000000 +0200
+++ arch/i386/kernel/io_apic.c	2005-06-28 19:07:49.000000000 +0200
@@ -1959,6 +1959,7 @@
 static void mask_and_ack_level_ioapic_irq(unsigned int irq)
 {
 	move_irq(irq);
+	mask_IO_APIC_irq(irq);
 	ack_APIC_irq();
 }
 
--- kernel/irq/handle.c~	2005-06-28 19:19:32.000000000 +0200
+++ kernel/irq/handle.c	2005-06-28 19:19:32.000000000 +0200
@@ -214,7 +214,6 @@
 	 * hardirq redirection to the irqd process context:
 	 */
 	if (redirect_hardirq(desc)) {
-		desc->handler->disable(irq);
 		goto out_no_end;
 	}

it works here on a PREEMPT_RT 2.6.12-RT-V0.7.50-29 base.
Level-interrupts are sanely rated again.
Didn't check, if the patch breaks XT-PIC mode, which works ok without the patch.
Mainline shows the same effect here (VIA K8T800 UP), didn't dig there yet.

thanks,
Karsten

	

	
		
___________________________________________________________ 
Gesendet von Yahoo! Mail - Jetzt mit 1GB Speicher kostenlos - Hier anmelden: http://mail.yahoo.de

^ permalink raw reply	[flat|nested] 179+ messages in thread
* Re: Real-Time Preemption, -RT-2.6.12-final-V0.7.50-24
@ 2005-07-12 10:23 Karsten Wiese
  2005-07-12 14:02 ` Ingo Molnar
  0 siblings, 1 reply; 179+ messages in thread
From: Karsten Wiese @ 2005-07-12 10:23 UTC (permalink / raw)
  To: Ingo Molnar; +Cc: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1006 bytes --]

Hi Ingo

I've refined io_apic.c a little more:
- merged all ioapic data into a struct ioapic_data_struct
- Allocate the ioapic cache memory from bootmem. Allocate only,
  what is needed ((nr of registers + 5)*sizeod(u64)).
- Removed "cache overrun by reg out of bounds" check.
  this should never happen, as reg is calculated out of irq_2_pin[irq].pin.
- Do the index lookup 
	struct ioapic_data_struct *ioapic = ioapic_data[apic];
  as early and as rarely as possible.
  In the consequence many functions parameter changed from
	io_apic_*(unsigned int apic,....
  to
	io_apic_*(struct ioapic_data_struct *ioapic,.... 
- New function setup_IO_APIC_early(int _ioapic).
  It does the setup of the ioapic's struct ioapic_data_struct.
  if IOAPIC_CACHE is defined, it calls the also new function
  ioapic_cache_init().
  ioapic_cache_init() initializes the cache completely.
  Thereby we may safely omit to query a caches elements validity before
  reading it.

Works fine here applied against -51-27

Karsten

[-- Attachment #2: io_apic-RT-51-23 --]
[-- Type: text/x-diff, Size: 22712 bytes --]

diff -ur ../linux-2.6.12-RT-51-23/arch/i386/kernel/io_apic.c ./arch/i386/kernel/io_apic.c
--- ../linux-2.6.12-RT-51-23/arch/i386/kernel/io_apic.c	2005-07-09 23:49:21.000000000 +0200
+++ ./arch/i386/kernel/io_apic.c	2005-07-12 01:08:34.000000000 +0200
@@ -31,6 +31,7 @@
 #include <linux/mc146818rtc.h>
 #include <linux/compiler.h>
 #include <linux/acpi.h>
+#include <linux/bootmem.h>
 
 #include <linux/sysdev.h>
 #include <asm/io.h>
@@ -55,11 +56,6 @@
 int sis_apic_bug = -1;
 
 /*
- * # of IRQ routing registers
- */
-int nr_ioapic_registers[MAX_IO_APICS];
-
-/*
  * Rough estimation of how many shared IRQs there are, can
  * be changed anytime.
  */
@@ -132,88 +128,74 @@
 # define IOAPIC_CACHE
 #endif
 
-#ifdef IOAPIC_CACHE
-# define MAX_IOAPIC_CACHE 512
 
-/*
- * Cache register values:
- */
-static struct {
-	unsigned int reg;
-	unsigned int val[MAX_IOAPIC_CACHE];
-} io_apic_cache[MAX_IO_APICS]
-		____cacheline_aligned_in_smp;
+
+struct ioapic_data_struct {
+	struct sys_device dev;
+	int nr_registers;	//  # of IRQ routing registers
+	volatile unsigned int *base;
+	struct IO_APIC_route_entry *entry;
+#ifdef IOAPIC_CACHE
+	unsigned int reg_set;
+	u32 cached_val[0];
 #endif
+};
 
-volatile unsigned int *io_apic_base[MAX_IO_APICS];
+static struct ioapic_data_struct *ioapic_data[MAX_IO_APICS];
 
-static inline unsigned int __raw_io_apic_read(unsigned int apic, unsigned int reg)
+
+static inline unsigned int __raw_io_apic_read(struct ioapic_data_struct *ioapic, unsigned int reg)
 {
-	volatile unsigned int *io_apic;
-#ifdef IOAPIC_CACHE
-	io_apic_cache[apic].reg = reg;
-#endif
-	io_apic = io_apic_base[apic];
-	io_apic[0] = reg;
-	return io_apic[4];
+# ifdef IOAPIC_CACHE
+	ioapic->reg_set = reg;
+# endif
+	ioapic->base[0] = reg;
+	return ioapic->base[4];
 }
 
-unsigned int raw_io_apic_read(unsigned int apic, unsigned int reg)
+
+# ifdef IOAPIC_CACHE
+static void __init ioapic_cache_init(struct ioapic_data_struct *ioapic)
 {
-	unsigned int val = __raw_io_apic_read(apic, reg);
+	int reg;
+	for (reg = 0; reg < (ioapic->nr_registers + 10); reg++)
+		ioapic->cached_val[reg] = __raw_io_apic_read(ioapic, reg);
+}
+# endif
 
-#ifdef IOAPIC_CACHE
-	io_apic_cache[apic].val[reg] = val;
-#endif
+
+static unsigned int raw_io_apic_read(struct ioapic_data_struct *ioapic, unsigned int reg)
+{
+	unsigned int val = __raw_io_apic_read(ioapic, reg);
+
+# ifdef IOAPIC_CACHE
+	ioapic->cached_val[reg] = val;
+# endif
 	return val;
 }
 
-unsigned int io_apic_read(unsigned int apic, unsigned int reg)
+static unsigned int io_apic_read(struct ioapic_data_struct *ioapic, unsigned int reg)
 {
-#ifdef IOAPIC_CACHE
-	if (unlikely(reg >= MAX_IOAPIC_CACHE)) {
-		static int once = 1;
-
-		if (once) {
-			once = 0;
-			printk("WARNING: ioapic register cache overflow: %d.\n",
-				reg);
-			dump_stack();
-		}
-		return __raw_io_apic_read(apic, reg);
-	}
-	if (io_apic_cache[apic].val[reg] && !sis_apic_bug) {
-		io_apic_cache[apic].reg = -1;
-		return io_apic_cache[apic].val[reg];
+# ifdef IOAPIC_CACHE
+	if (likely(!sis_apic_bug)) {
+		ioapic->reg_set = -1;
+		return ioapic->cached_val[reg];
 	}
-#endif
-	return raw_io_apic_read(apic, reg);
+# endif
+	return raw_io_apic_read(ioapic, reg);
 }
 
-void io_apic_write(unsigned int apic, unsigned int reg, unsigned int val)
+static void io_apic_write(struct ioapic_data_struct *ioapic, unsigned int reg, unsigned int val)
 {
-	volatile unsigned int *io_apic;
-#ifdef IOAPIC_CACHE
-	if (unlikely(reg >= MAX_IOAPIC_CACHE)) {
-		static int once = 1;
-
-		if (once) {
-			once = 0;
-			printk("WARNING: ioapic register cache overflow: %d.\n",
-				reg);
-			dump_stack();
-		}
-	} else
-		io_apic_cache[apic].val[reg] = val;
-#endif
-	io_apic = io_apic_base[apic];
-#ifdef IOAPIC_CACHE
-	io_apic_cache[apic].reg = reg;
-#endif
-	io_apic[0] = reg;
-	io_apic[4] = val;
+# ifdef IOAPIC_CACHE
+	ioapic->cached_val[reg] = val;
+	ioapic->reg_set = reg;
+# endif
+	ioapic->base[0] = reg;
+	ioapic->base[4] = val;
 }
 
+
 /*
  * Some systems need a POST flush or else level-triggered interrupts
  * generate lots of spurious interrupts due to the POST-ed write not
@@ -231,44 +213,42 @@
  *
  * Older SiS APIC requires we rewrite the index regiser
  */
-void io_apic_modify(unsigned int apic, unsigned int reg, unsigned int val)
+static void io_apic_modify(struct ioapic_data_struct *ioapic, unsigned int reg, unsigned int val)
 {
-	volatile unsigned int *io_apic;
-#ifdef IOAPIC_CACHE
-	io_apic_cache[apic].val[reg] = val;
-#endif
-	io_apic = io_apic_base[apic];
 #ifdef IOAPIC_CACHE
-	if (io_apic_cache[apic].reg != reg || sis_apic_bug) {
-		io_apic_cache[apic].reg = reg;
+	ioapic->cached_val[reg] = val;
+	if (ioapic->reg_set != reg || sis_apic_bug) {
+		ioapic->reg_set = reg;
 #else
 	if (unlikely(sis_apic_bug)) {
 #endif
-		io_apic[0] = reg;
+		ioapic->base[0] = reg;
 	}
-	io_apic[4] = val;
+	ioapic->base[4] = val;
 #ifndef IOAPIC_POSTFLUSH
 	if (unlikely(sis_apic_bug))
 #endif
 		/*
 		 * Force POST flush by reading:
  		 */
-		val = io_apic[4];
+		val = ioapic->base[4];
 }
 
 static void __modify_IO_APIC_irq (unsigned int irq, unsigned long enable, unsigned long disable)
 {
 	struct irq_pin_list *entry = irq_2_pin + irq;
 	unsigned int pin, val;
+	struct ioapic_data_struct *ioapic;
 
 	for (;;) {
 		pin = entry->pin;
 		if (pin == -1)
 			break;
-		val = io_apic_read(entry->apic, 0x10 + pin*2);
+		ioapic = ioapic_data[entry->apic];
+		val = io_apic_read(ioapic, 0x10 + pin*2);
 		val &= ~disable;
 		val |= enable;
-		io_apic_modify(entry->apic, 0x10 + pin*2, val);
+		io_apic_modify(ioapic, 0x10 + pin*2, val);
 		if (!entry->next)
 			break;
 		entry = irq_2_pin + entry->next;
@@ -305,15 +285,15 @@
 	spin_unlock_irqrestore(&ioapic_lock, flags);
 }
 
-static void clear_IO_APIC_pin(unsigned int apic, unsigned int pin)
+static void clear_IO_APIC_pin(struct ioapic_data_struct *ioapic, unsigned int pin)
 {
 	struct IO_APIC_route_entry entry;
 	unsigned long flags;
 	
 	/* Check delivery_mode to be sure we're not clearing an SMI pin */
 	spin_lock_irqsave(&ioapic_lock, flags);
-	*(((int*)&entry) + 0) = io_apic_read(apic, 0x10 + 2 * pin);
-	*(((int*)&entry) + 1) = io_apic_read(apic, 0x11 + 2 * pin);
+	*(((int*)&entry) + 0) = io_apic_read(ioapic, 0x10 + 2 * pin);
+	*(((int*)&entry) + 1) = io_apic_read(ioapic, 0x11 + 2 * pin);
 	spin_unlock_irqrestore(&ioapic_lock, flags);
 	if (entry.delivery_mode == dest_SMI)
 		return;
@@ -324,8 +304,8 @@
 	memset(&entry, 0, sizeof(entry));
 	entry.mask = 1;
 	spin_lock_irqsave(&ioapic_lock, flags);
-	io_apic_write(apic, 0x10 + 2 * pin, *(((int *)&entry) + 0));
-	io_apic_write(apic, 0x11 + 2 * pin, *(((int *)&entry) + 1));
+	io_apic_write(ioapic, 0x10 + 2 * pin, *(((int *)&entry) + 0));
+	io_apic_write(ioapic, 0x11 + 2 * pin, *(((int *)&entry) + 1));
 	spin_unlock_irqrestore(&ioapic_lock, flags);
 }
 
@@ -334,11 +314,12 @@
 	int apic, pin;
 
 	for (apic = 0; apic < nr_ioapics; apic++) {
+		struct ioapic_data_struct *ioapic = ioapic_data[apic];
 #ifdef IOAPIC_CACHE
-		io_apic_cache[apic].reg = -1;
+		ioapic->reg_set = -1;
 #endif
-		for (pin = 0; pin < nr_ioapic_registers[apic]; pin++)
-			clear_IO_APIC_pin(apic, pin);
+		for (pin = 0; pin < ioapic->nr_registers; pin++)
+			clear_IO_APIC_pin(ioapic, pin);
 	}
 }
 
@@ -357,7 +338,7 @@
 		pin = entry->pin;
 		if (pin == -1)
 			break;
-		io_apic_write(entry->apic, 0x10 + 1 + pin*2, apicid_value);
+		io_apic_write(ioapic_data[entry->apic], 0x10 + 1 + pin*2, apicid_value);
 		if (!entry->next)
 			break;
 		entry = irq_2_pin + entry->next;
@@ -947,7 +928,7 @@
 		return;
 
 	for (ioapic = 0; ioapic < nr_ioapics; ioapic++) {
-		for (pin = 0; pin < nr_ioapic_registers[ioapic]; pin++) {
+		for (pin = 0; pin < ioapic_data[ioapic]->nr_registers; pin++) {
 			irq_entry = find_irq_entry(ioapic, pin, mp_INT);
 			if (irq_entry == -1)
 				continue;
@@ -1190,7 +1171,7 @@
 			 */
 			i = irq = 0;
 			while (i < apic)
-				irq += nr_ioapic_registers[i++];
+				irq += ioapic_data[i++]->nr_registers;
 			irq += pin;
 
 			/*
@@ -1233,7 +1214,7 @@
 	int apic, idx, pin;
 
 	for (apic = 0; apic < nr_ioapics; apic++) {
-		for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
+		for (pin = 0; pin < ioapic_data[apic]->nr_registers; pin++) {
 			idx = find_irq_entry(apic,pin,mp_INT);
 			if ((idx != -1) && (irq == pin_2_irq(idx,apic,pin)))
 				return irq_trigger(idx);
@@ -1305,11 +1286,13 @@
 	struct IO_APIC_route_entry entry;
 	int apic, pin, idx, irq, first_notcon = 1, vector;
 	unsigned long flags;
+	struct ioapic_data_struct *ioapic;
 
 	apic_printk(APIC_VERBOSE, KERN_DEBUG "init IO_APIC IRQs\n");
 
 	for (apic = 0; apic < nr_ioapics; apic++) {
-	for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
+		ioapic = ioapic_data[apic];
+	for (pin = 0; pin < ioapic->nr_registers; pin++) {
 
 		/*
 		 * add it to the IO-APIC irq-routing table:
@@ -1366,8 +1349,8 @@
 				disable_8259A_irq(irq);
 		}
 		spin_lock_irqsave(&ioapic_lock, flags);
-		io_apic_write(apic, 0x11+2*pin, *(((int *)&entry)+1));
-		io_apic_write(apic, 0x10+2*pin, *(((int *)&entry)+0));
+		io_apic_write(ioapic, 0x11+2*pin, *(((int *)&entry)+1));
+		io_apic_write(ioapic, 0x10+2*pin, *(((int *)&entry)+0));
 		spin_unlock_irqrestore(&ioapic_lock, flags);
 	}
 	}
@@ -1432,6 +1415,7 @@
 	union IO_APIC_reg_02 reg_02;
 	union IO_APIC_reg_03 reg_03;
 	unsigned long flags;
+	struct ioapic_data_struct *ioapic;
 
 	if (apic_verbosity == APIC_QUIET)
 		return;
@@ -1439,7 +1423,7 @@
  	printk(KERN_DEBUG "number of MP IRQ sources: %d.\n", mp_irq_entries);
 	for (i = 0; i < nr_ioapics; i++)
 		printk(KERN_DEBUG "number of IO-APIC #%d registers: %d.\n",
-		       mp_ioapics[i].mpc_apicid, nr_ioapic_registers[i]);
+		       mp_ioapics[i].mpc_apicid, ioapic_data[i]->nr_registers);
 
 	/*
 	 * We are a bit conservative about what we expect.  We have to
@@ -1448,14 +1432,14 @@
 	printk(KERN_INFO "testing the IO APIC.......................\n");
 
 	for (apic = 0; apic < nr_ioapics; apic++) {
-
+	ioapic = ioapic_data[apic];
 	spin_lock_irqsave(&ioapic_lock, flags);
-	reg_00.raw = io_apic_read(apic, 0);
-	reg_01.raw = io_apic_read(apic, 1);
+	reg_00.raw = io_apic_read(ioapic, 0);
+	reg_01.raw = io_apic_read(ioapic, 1);
 	if (reg_01.bits.version >= 0x10)
-		reg_02.raw = io_apic_read(apic, 2);
+		reg_02.raw = io_apic_read(ioapic, 2);
 	if (reg_01.bits.version >= 0x20)
-		reg_03.raw = io_apic_read(apic, 3);
+		reg_03.raw = io_apic_read(ioapic, 3);
 	spin_unlock_irqrestore(&ioapic_lock, flags);
 
 	printk(KERN_DEBUG "IO APIC #%d......\n", mp_ioapics[apic].mpc_apicid);
@@ -1526,8 +1510,8 @@
 		struct IO_APIC_route_entry entry;
 
 		spin_lock_irqsave(&ioapic_lock, flags);
-		*(((int *)&entry)+0) = raw_io_apic_read(apic, 0x10+i*2);
-		*(((int *)&entry)+1) = raw_io_apic_read(apic, 0x11+i*2);
+		*(((int *)&entry)+0) = raw_io_apic_read(ioapic, 0x10+i*2);
+		*(((int *)&entry)+1) = raw_io_apic_read(ioapic, 0x11+i*2);
 		spin_unlock_irqrestore(&ioapic_lock, flags);
 
 		printk(KERN_DEBUG " %02x %03X %02X  ",
@@ -1720,9 +1704,7 @@
 
 static void __init enable_IO_APIC(void)
 {
-	union IO_APIC_reg_01 reg_01;
 	int i;
-	unsigned long flags;
 
 	for (i = 0; i < PIN_MAP_SIZE; i++) {
 		irq_2_pin[i].pin = -1;
@@ -1733,16 +1715,6 @@
 			pirq_entries[i] = -1;
 
 	/*
-	 * The number of IO-APIC IRQ registers (== #pins):
-	 */
-	for (i = 0; i < nr_ioapics; i++) {
-		spin_lock_irqsave(&ioapic_lock, flags);
-		reg_01.raw = io_apic_read(i, 1);
-		spin_unlock_irqrestore(&ioapic_lock, flags);
-		nr_ioapic_registers[i] = reg_01.bits.entries+1;
-	}
-
-	/*
 	 * Do not trust the IO-APIC being empty at bootup
 	 */
 	clear_IO_APIC();
@@ -1777,6 +1749,7 @@
 	int i;
 	unsigned char old_id;
 	unsigned long flags;
+	struct ioapic_data_struct *ioapic;
 
 	/*
 	 * This is broken; anything with a real cpu count has to
@@ -1788,10 +1761,10 @@
 	 * Set the IOAPIC ID to the value stored in the MPC table.
 	 */
 	for (apic = 0; apic < nr_ioapics; apic++) {
-
+		ioapic = ioapic_data[apic];
 		/* Read the register 0 value */
 		spin_lock_irqsave(&ioapic_lock, flags);
-		reg_00.raw = io_apic_read(apic, 0);
+		reg_00.raw = io_apic_read(ioapic, 0);
 		spin_unlock_irqrestore(&ioapic_lock, flags);
 		
 		old_id = mp_ioapics[apic].mpc_apicid;
@@ -1856,14 +1829,14 @@
 
 		reg_00.bits.ID = mp_ioapics[apic].mpc_apicid;
 		spin_lock_irqsave(&ioapic_lock, flags);
-		io_apic_write(apic, 0, reg_00.raw);
+		io_apic_write(ioapic, 0, reg_00.raw);
 		spin_unlock_irqrestore(&ioapic_lock, flags);
 
 		/*
 		 * Sanity check
 		 */
 		spin_lock_irqsave(&ioapic_lock, flags);
-		reg_00.raw = io_apic_read(apic, 0);
+		reg_00.raw = io_apic_read(ioapic, 0);
 		spin_unlock_irqrestore(&ioapic_lock, flags);
 		if (reg_00.bits.ID != mp_ioapics[apic].mpc_apicid)
 			printk("could not set ID!\n");
@@ -2230,7 +2203,7 @@
  * cycles as some i82489DX-based boards have glue logic that keeps the
  * 8259A interrupt line asserted until INTA.  --macro
  */
-static inline void unlock_ExtINT_logic(void)
+static void __init unlock_ExtINT_logic(void)
 {
 	int pin, i;
 	struct IO_APIC_route_entry entry0, entry1;
@@ -2291,7 +2264,7 @@
  * is so screwy.  Thanks to Brian Perkins for testing/hacking this beast
  * fanatically on his truly buggy board.
  */
-static inline void check_timer(void)
+static void __init check_timer(void)
 {
 	int pin1, pin2;
 	int vector;
@@ -2402,6 +2375,43 @@
 		"report.  Then try booting with the 'noapic' option");
 }
 
+void __init setup_IO_APIC_early(int _ioapic)
+{
+	union IO_APIC_reg_01 reg_01;
+	unsigned long flags;
+	int size, nr_ioapic_registers;
+	volatile int *ioapic;
+	if (ioapic_data[_ioapic]) {
+		printk("been in %s before !!!!!\n", __FUNCTION__);
+		return;
+	}
+
+	/*
+	 * The number of IO-APIC IRQ registers (== #pins):
+	 */
+	ioapic = IO_APIC_BASE(_ioapic);
+	spin_lock_irqsave(&ioapic_lock, flags);
+	ioapic[0] = 1;
+	reg_01.raw = ioapic[4];
+	spin_unlock_irqrestore(&ioapic_lock, flags);
+	nr_ioapic_registers = reg_01.bits.entries+1;
+
+	/*
+	 * Initialsize ioapic_data struct:
+	 */
+	size = sizeof(struct ioapic_data_struct);
+#ifdef IOAPIC_CACHE
+	size += 0x10 * sizeof(u32) + nr_ioapic_registers * sizeof(struct IO_APIC_route_entry);
+#endif
+	ioapic_data[_ioapic] = alloc_bootmem(size);
+	memset(ioapic_data[_ioapic], 0, size);
+	ioapic_data[_ioapic]->nr_registers = nr_ioapic_registers;
+	ioapic_data[_ioapic]->base = ioapic;
+#ifdef IOAPIC_CACHE
+	ioapic_cache_init(ioapic_data[_ioapic]);
+#endif
+}
+
 /*
  *
  * IRQ's that are handled by the PIC in the MPS IOAPIC case.
@@ -2449,25 +2459,22 @@
 
 late_initcall(io_apic_bug_finalize);
 
-struct sysfs_ioapic_data {
-	struct sys_device dev;
-	struct IO_APIC_route_entry entry[0];
-};
-static struct sysfs_ioapic_data * mp_ioapic_data[MAX_IO_APICS];
-
 static int ioapic_suspend(struct sys_device *dev, pm_message_t state)
 {
 	struct IO_APIC_route_entry *entry;
-	struct sysfs_ioapic_data *data;
+	struct ioapic_data_struct *data;
 	unsigned long flags;
 	int i;
+	struct ioapic_data_struct *ioapic;
 	
-	data = container_of(dev, struct sysfs_ioapic_data, dev);
+	data = container_of(dev, struct ioapic_data_struct, dev);
 	entry = data->entry;
+
+	ioapic = ioapic_data[dev->id];
 	spin_lock_irqsave(&ioapic_lock, flags);
-	for (i = 0; i < nr_ioapic_registers[dev->id]; i ++, entry ++ ) {
-		*(((int *)entry) + 1) = io_apic_read(dev->id, 0x11 + 2 * i);
-		*(((int *)entry) + 0) = io_apic_read(dev->id, 0x10 + 2 * i);
+	for (i = 0; i < ioapic_data[dev->id]->nr_registers; i ++, entry ++) {
+		*(((int *)entry) + 1) = io_apic_read(ioapic, 0x11 + 2 * i);
+		*(((int *)entry) + 0) = io_apic_read(ioapic, 0x10 + 2 * i);
 	}
 	spin_unlock_irqrestore(&ioapic_lock, flags);
 
@@ -2477,23 +2484,25 @@
 static int ioapic_resume(struct sys_device *dev)
 {
 	struct IO_APIC_route_entry *entry;
-	struct sysfs_ioapic_data *data;
+	struct ioapic_data_struct *data;
 	unsigned long flags;
 	union IO_APIC_reg_00 reg_00;
 	int i;
-	
-	data = container_of(dev, struct sysfs_ioapic_data, dev);
+	struct ioapic_data_struct *ioapic;
+
+	data = container_of(dev, struct ioapic_data_struct, dev);
 	entry = data->entry;
 
+	ioapic = ioapic_data[dev->id];
 	spin_lock_irqsave(&ioapic_lock, flags);
-	reg_00.raw = io_apic_read(dev->id, 0);
+	reg_00.raw = io_apic_read(ioapic, 0);
 	if (reg_00.bits.ID != mp_ioapics[dev->id].mpc_apicid) {
 		reg_00.bits.ID = mp_ioapics[dev->id].mpc_apicid;
-		io_apic_write(dev->id, 0, reg_00.raw);
+		io_apic_write(ioapic, 0, reg_00.raw);
 	}
-	for (i = 0; i < nr_ioapic_registers[dev->id]; i ++, entry ++ ) {
-		io_apic_write(dev->id, 0x11+2*i, *(((int *)entry)+1));
-		io_apic_write(dev->id, 0x10+2*i, *(((int *)entry)+0));
+	for (i = 0; i < ioapic_data[dev->id]->nr_registers; i ++, entry ++) {
+		io_apic_write(ioapic, 0x11+2*i, *(((int *)entry)+1));
+		io_apic_write(ioapic, 0x10+2*i, *(((int *)entry)+0));
 	}
 	spin_unlock_irqrestore(&ioapic_lock, flags);
 
@@ -2516,21 +2525,20 @@
 		return error;
 
 	for (i = 0; i < nr_ioapics; i++ ) {
-		size = sizeof(struct sys_device) + nr_ioapic_registers[i] 
-			* sizeof(struct IO_APIC_route_entry);
-		mp_ioapic_data[i] = kmalloc(size, GFP_KERNEL);
-		if (!mp_ioapic_data[i]) {
+		size = ioapic_data[i]->nr_registers * sizeof(struct IO_APIC_route_entry);
+		ioapic_data[i]->entry = kmalloc(size, GFP_KERNEL);
+		if (!ioapic_data[i]->entry) {
 			printk(KERN_ERR "Can't suspend/resume IOAPIC %d\n", i);
 			continue;
 		}
-		memset(mp_ioapic_data[i], 0, size);
-		dev = &mp_ioapic_data[i]->dev;
+		memset(ioapic_data[i]->entry, 0, size);
+		dev = &ioapic_data[i]->dev;
 		dev->id = i; 
 		dev->cls = &ioapic_sysdev_class;
 		error = sysdev_register(dev);
 		if (error) {
-			kfree(mp_ioapic_data[i]);
-			mp_ioapic_data[i] = NULL;
+			kfree(ioapic_data[i]->entry);
+			ioapic_data[i]->entry = NULL;
 			printk(KERN_ERR "Can't suspend/resume IOAPIC %d\n", i);
 			continue;
 		}
@@ -2547,13 +2555,14 @@
 
 #ifdef CONFIG_ACPI_BOOT
 
-int __init io_apic_get_unique_id (int ioapic, int apic_id)
+int __init io_apic_get_unique_id (int apic, int apic_id)
 {
 	union IO_APIC_reg_00 reg_00;
 	static physid_mask_t apic_id_map = PHYSID_MASK_NONE;
 	physid_mask_t tmp;
 	unsigned long flags;
 	int i = 0;
+	struct ioapic_data_struct *ioapic = ioapic_data[apic];
 
 	/*
 	 * The P4 platform supports up to 256 APIC IDs on two separate APIC 
@@ -2573,7 +2582,7 @@
 
 	if (apic_id >= get_physical_broadcast()) {
 		printk(KERN_WARNING "IOAPIC[%d]: Invalid apic_id %d, trying "
-			"%d\n", ioapic, apic_id, reg_00.bits.ID);
+			"%d\n", apic, apic_id, reg_00.bits.ID);
 		apic_id = reg_00.bits.ID;
 	}
 
@@ -2592,7 +2601,7 @@
 			panic("Max apic_id exceeded!\n");
 
 		printk(KERN_WARNING "IOAPIC[%d]: apic_id %d already used, "
-			"trying %d\n", ioapic, apic_id, i);
+			"trying %d\n", apic, apic_id, i);
 
 		apic_id = i;
 	} 
@@ -2610,50 +2619,50 @@
 
 		/* Sanity check */
 		if (reg_00.bits.ID != apic_id)
-			panic("IOAPIC[%d]: Unable change apic_id!\n", ioapic);
+			panic("IOAPIC[%d]: Unable change apic_id!\n", apic);
 	}
 
 	apic_printk(APIC_VERBOSE, KERN_INFO
-			"IOAPIC[%d]: Assigned apic_id %d\n", ioapic, apic_id);
+			"IOAPIC[%d]: Assigned apic_id %d\n", apic, apic_id);
 
 	return apic_id;
 }
 
 
-int __init io_apic_get_version (int ioapic)
+int __init io_apic_get_version (int apic)
 {
 	union IO_APIC_reg_01	reg_01;
 	unsigned long flags;
 
 	spin_lock_irqsave(&ioapic_lock, flags);
-	reg_01.raw = io_apic_read(ioapic, 1);
+	reg_01.raw = io_apic_read(ioapic_data[apic], 1);
 	spin_unlock_irqrestore(&ioapic_lock, flags);
 
 	return reg_01.bits.version;
 }
 
 
-int __init io_apic_get_redir_entries (int ioapic)
+int __init io_apic_get_redir_entries (int apic)
 {
 	union IO_APIC_reg_01	reg_01;
 	unsigned long flags;
 
 	spin_lock_irqsave(&ioapic_lock, flags);
-	reg_01.raw = io_apic_read(ioapic, 1);
+	reg_01.raw = io_apic_read(ioapic_data[apic], 1);
 	spin_unlock_irqrestore(&ioapic_lock, flags);
 
 	return reg_01.bits.entries;
 }
 
 
-int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int active_high_low)
+int io_apic_set_pci_routing (int apic, int pin, int irq, int edge_level, int active_high_low)
 {
 	struct IO_APIC_route_entry entry;
 	unsigned long flags;
-
+	struct ioapic_data_struct *ioapic = ioapic_data[apic];
 	if (!IO_APIC_IRQ(irq)) {
 		printk(KERN_ERR "IOAPIC[%d]: Invalid reference to IRQ 0\n",
-			ioapic);
+			apic);
 		return -EINVAL;
 	}
 
@@ -2676,18 +2685,18 @@
 	 * IRQs < 16 are already in the irq_2_pin[] map
 	 */
 	if (irq >= 16)
-		add_pin_to_irq(irq, ioapic, pin);
+		add_pin_to_irq(irq, apic, pin);
 
 	entry.vector = assign_irq_vector(irq);
 
 	apic_printk(APIC_DEBUG, KERN_DEBUG "IOAPIC[%d]: Set PCI routing entry "
-		"(%d-%d -> 0x%x -> IRQ %d Mode:%i Active:%i)\n", ioapic,
-		mp_ioapics[ioapic].mpc_apicid, pin, entry.vector, irq,
+		"(%d-%d -> 0x%x -> IRQ %d Mode:%i Active:%i)\n", apic,
+		mp_ioapics[apic].mpc_apicid, pin, entry.vector, irq,
 		edge_level, active_high_low);
 
 	ioapic_register_intr(irq, entry.vector, edge_level);
 
-	if (!ioapic && (irq < 16))
+	if (!apic && (irq < 16))
 		disable_8259A_irq(irq);
 
 	spin_lock_irqsave(&ioapic_lock, flags);
diff -ur ../linux-2.6.12-RT-51-23/arch/i386/kernel/mpparse.c ./arch/i386/kernel/mpparse.c
--- ../linux-2.6.12-RT-51-23/arch/i386/kernel/mpparse.c	2005-07-09 23:53:19.000000000 +0200
+++ ./arch/i386/kernel/mpparse.c	2005-07-11 20:30:55.000000000 +0200
@@ -263,7 +263,7 @@
 		return;
 	}
 	mp_ioapics[nr_ioapics] = *m;
-	io_apic_base[nr_ioapics] = IO_APIC_BASE(nr_ioapics);
+	setup_IO_APIC_early(nr_ioapics);
 	nr_ioapics++;
 }
 
@@ -915,7 +915,7 @@
 	mp_ioapics[idx].mpc_apicaddr = address;
 
 	set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address);
-	io_apic_base[idx] = IO_APIC_BASE(idx);
+	setup_IO_APIC_early(idx);
 	mp_ioapics[idx].mpc_apicid = io_apic_get_unique_id(idx, id);
 	mp_ioapics[idx].mpc_apicver = io_apic_get_version(idx);
 	
diff -ur ../linux-2.6.12-RT-51-23/include/asm-i386/io_apic.h ./include/asm-i386/io_apic.h
--- ../linux-2.6.12-RT-51-23/include/asm-i386/io_apic.h	2005-07-09 23:55:50.000000000 +0200
+++ ./include/asm-i386/io_apic.h	2005-07-11 20:28:42.000000000 +0200
@@ -155,15 +155,14 @@
 /* MP IRQ source entries */
 extern struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES];
 
-extern volatile unsigned int *io_apic_base[MAX_IO_APICS];
-
 /* non-0 if default (table-less) MP configuration */
 extern int mpc_default_type;
 
-extern unsigned int raw_io_apic_read(unsigned int apic, unsigned int reg);
-extern unsigned int io_apic_read(unsigned int apic, unsigned int reg);
-extern void io_apic_write(unsigned int apic, unsigned int reg, unsigned int value);
-extern void io_apic_modify(unsigned int apic, unsigned int reg, unsigned int value);
+extern void setup_IO_APIC_early(int ioapic);
 extern int sis_apic_bug;
 
 /* 1 if "noapic" boot option passed */

^ permalink raw reply	[flat|nested] 179+ messages in thread

end of thread, other threads:[~2005-07-16 19:33 UTC | newest]

Thread overview: 179+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-06-08 11:28 [patch] Real-Time Preemption, -RT-2.6.12-rc6-V0.7.48-00 Ingo Molnar
2005-06-08 14:18 ` Michal Schmidt
2005-06-08 14:40   ` Keith Owens
2005-06-08 14:41   ` Paulo Marques
2005-06-08 15:04     ` Michal Schmidt
2005-06-08 15:23       ` Keith Owens
2005-06-08 15:56         ` Paulo Marques
2005-06-08 14:32 ` Michal Schmidt
2005-06-08 15:48 ` K.R. Foley
2005-06-08 16:08   ` K.R. Foley
2005-06-08 16:26     ` K.R. Foley
2005-06-08 17:26   ` K.R. Foley
2005-06-08 19:18     ` Ingo Molnar
2005-06-09 11:39       ` Ingo Molnar
2005-06-10 13:34         ` K.R. Foley
2005-06-09  8:47     ` Serge Noiraud
2005-06-09 11:55       ` Ingo Molnar
2005-06-09 15:12         ` Serge Noiraud
2005-06-09 16:34           ` Daniel Walker
2005-06-13  8:53             ` Serge Noiraud
2005-06-13  9:07               ` Ingo Molnar
2005-06-08 17:51 ` Michal Schmidt
2005-06-09 11:45   ` Ingo Molnar
2005-06-09 12:09     ` Michal Schmidt
2005-06-09 12:13       ` Ingo Molnar
2005-06-09 12:48         ` Michal Schmidt
2005-06-10  8:56         ` Esben Nielsen
2005-06-08 19:58 ` Daniel Walker
2005-06-09 21:24 ` Michal Schmidt
2005-06-09 21:34   ` Michal Schmidt
2005-06-11  7:32   ` Ingo Molnar
2005-06-11  8:10     ` Ingo Molnar
2005-06-11 16:35 ` Peter Zijlstra
2005-06-11 18:48   ` Ingo Molnar
2005-06-11 21:14     ` Peter Zijlstra
2005-06-12  1:40     ` Gene Heskett
2005-06-12  6:49       ` Ingo Molnar
2005-06-12  9:02         ` Gene Heskett
2005-06-12 10:35           ` Ingo Molnar
2005-06-12 13:40             ` Gene Heskett
2005-06-12 13:49               ` Ingo Molnar
2005-06-12 14:23                 ` Gene Heskett
2005-06-13  2:11                 ` Gene Heskett
2005-06-13  6:09                   ` Ingo Molnar
2005-06-13  8:37                     ` Gene Heskett
2005-06-14 18:24 ` K.R. Foley
2005-06-14 18:54   ` Ingo Molnar
2005-06-14 22:45     ` Daniel Walker
2005-06-15  6:12       ` Ingo Molnar
2005-06-15  9:13         ` Esben Nielsen
2005-06-14 20:37 ` Paul E. McKenney
2005-06-16  3:51 ` K.R. Foley
2005-06-16  7:29   ` Ingo Molnar
2005-06-16 11:22     ` K.R. Foley
2005-06-16 17:32       ` Ingo Molnar
2005-06-16 17:59         ` K.R. Foley
2005-06-16 20:37           ` K.R. Foley
2005-06-17 11:08             ` Ingo Molnar
2005-06-16 20:43           ` Ingo Molnar
2005-06-17  2:06             ` Gene Heskett
2005-06-17  4:53             ` Gene Heskett
2005-06-17 11:18             ` Ingo Molnar
2005-06-17 14:12               ` K.R. Foley
2005-06-17 15:33               ` K.R. Foley
2005-06-17 19:28         ` William Weston
2005-06-17 21:30           ` William Weston
2005-06-18 12:28             ` Ingo Molnar
2005-06-21  1:18               ` William Weston
2005-06-23  2:05               ` William Weston
2005-06-23  7:56                 ` Ingo Molnar
2005-06-23 13:45                   ` Gene Heskett
2005-06-21 13:10           ` Ingo Molnar
2005-06-21 19:08             ` William Weston
2005-06-21 20:17             ` Benjamin LaHaise
2005-06-21 20:37               ` William Weston
2005-06-21 20:48                 ` Benjamin LaHaise
2005-06-22  2:42               ` Gene Heskett
2005-06-22  7:40                 ` Ingo Molnar
2005-06-22 13:27                   ` Gene Heskett
2005-06-22 13:51                     ` Gene Heskett
2005-06-22 14:08                       ` Gene Heskett
2005-06-25  4:41                     ` Ingo Molnar
2005-06-25  4:47                       ` Ingo Molnar
2005-06-25  5:39                         ` Gene Heskett
2005-06-25  7:26                           ` Gene Heskett
2005-06-25  9:12                             ` Ingo Molnar
2005-06-25 13:19                               ` Gene Heskett
2005-06-25 14:39                                 ` Gene Heskett
2005-06-27 19:01                                   ` Real-Time Preemption, -RT-2.6.12-final-V0.7.50-24 Chuck Harding
2005-06-27 19:42                                     ` Chuck Harding
2005-06-27 21:08                                       ` Gene Heskett
2005-06-27 20:09                                     ` Daniel Walker
2005-06-27 20:28                                       ` Chuck Harding
2005-06-28  0:50                                         ` Daniel Walker
2005-06-28  7:53                                       ` Steven Rostedt
2005-06-28  8:18                                         ` Ingo Molnar
2005-06-28  8:34                                           ` Steven Rostedt
2005-06-28  9:12                                           ` Ingo Molnar
2005-06-28 15:26                                             ` Michal Schmidt
2005-06-28 15:31                                               ` Ingo Molnar
2005-06-28 18:50                                                 ` Chuck Harding
2005-06-28 22:16                                             ` Chuck Harding
2005-06-29  0:32                                               ` Chuck Harding
2005-06-28 15:54                                         ` Daniel Walker
2005-06-21 13:12           ` [patch] Real-Time Preemption, -RT-2.6.12-rc6-V0.7.48-00 Ingo Molnar
     [not found]             ` <Pine.LNX.4.58.0506211228210.16701@echo.lysdexia.org>
2005-06-22  8:03               ` Ingo Molnar
2005-06-22  8:24               ` Ingo Molnar
2005-06-22 10:08                 ` Ingo Molnar
2005-06-22 21:53                 ` William Weston
2005-06-22 22:00                   ` Ingo Molnar
2005-06-22 23:06                     ` William Weston
2005-06-23  0:10                       ` Ingo Molnar
2005-06-23 22:11                         ` William Weston
2005-06-24  1:46                           ` William Weston
2005-06-24  7:06                             ` Ingo Molnar
2005-06-24 22:31                               ` William Weston
2005-06-25  4:14                                 ` Ingo Molnar
2005-06-27  4:21                                   ` William Weston
2005-06-27  8:15                                     ` Ingo Molnar
2005-06-28  3:32                                       ` William Weston
2005-06-28  8:10                                         ` Ingo Molnar
2005-06-28 11:15                                           ` Ingo Molnar
     [not found]                                           ` <Pine.LNX.4.58.0506281745040.10406@echo.lysdexia.org>
2005-06-29 12:54                                             ` Ingo Molnar
2005-06-30  0:29                                               ` William Weston
2005-06-27  5:43                                   ` Gene Heskett
2005-06-27  8:17                                     ` Ingo Molnar
2005-06-27 17:29                                       ` Gene Heskett
2005-06-27 19:54                                         ` Ingo Molnar
2005-06-27 21:17                                           ` Gene Heskett
2005-06-28  8:28                                             ` Ingo Molnar
2005-06-28 17:27 Real-Time Preemption, -RT-2.6.12-final-V0.7.50-24 Karsten Wiese
2005-06-28 20:21 ` Ingo Molnar
2005-06-28 20:30   ` Ingo Molnar
2005-06-28 23:51     ` Karsten Wiese
2005-06-29  6:34       ` Ingo Molnar
2005-06-29  7:00         ` Ingo Molnar
2005-06-29  9:15           ` William Weston
2005-06-29 12:56             ` Ingo Molnar
2005-06-30  1:50               ` William Weston
2005-06-29 14:48             ` Karsten Wiese
2005-06-29 19:38               ` Ingo Molnar
2005-06-29 23:36                 ` Karsten Wiese
2005-06-30 17:52                   ` Karsten Wiese
2005-06-30 20:50                     ` Ingo Molnar
2005-06-30 22:27                       ` Karsten Wiese
2005-06-30 22:59                         ` William Weston
2005-07-01  1:00                           ` William Weston
2005-07-01  0:15                         ` Karsten Wiese
2005-07-01  7:18                         ` Ingo Molnar
2005-07-01 19:34                           ` Chuck Harding
2005-07-02  1:46                           ` William Weston
2005-07-02  2:02                             ` Lee Revell
2005-07-04  8:53                               ` William Weston
2005-07-04 11:16                                 ` Ingo Molnar
2005-07-13  1:18                                   ` Lee Revell
2005-07-13  1:28                                     ` Lee Revell
2005-07-13  6:35                                       ` Ingo Molnar
2005-07-13 17:20                                         ` Lee Revell
2005-07-03 14:04                             ` Ingo Molnar
2005-07-03 18:12                               ` Ingo Molnar
2005-07-07  1:26                                 ` William Weston
2005-07-07 10:48                                   ` Ingo Molnar
2005-07-12 10:23 Karsten Wiese
2005-07-12 14:02 ` Ingo Molnar
2005-07-12 14:25   ` Daniel Walker
2005-07-12 14:28     ` Ingo Molnar
2005-07-12 14:31       ` Daniel Walker
2005-07-12 14:46         ` Ingo Molnar
2005-07-12 14:56           ` Daniel Walker
2005-07-16  2:11             ` Daniel Walker
2005-07-16 17:11               ` Ingo Molnar
2005-07-12 14:47       ` K.R. Foley
2005-07-12 16:01         ` Ingo Molnar
2005-07-12 16:16           ` K.R. Foley
2005-07-13  0:02           ` William Weston
2005-07-13  0:04     ` Karsten Wiese
2005-07-13  0:08       ` William Weston
2005-07-15 12:05         ` Karsten Wiese
2005-07-16 19:32           ` Ingo Molnar

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).