Skip to contentSkip to conversation

Clean up x86 interrupt entry code

PATCH In review Brian Gerst 3 participants 5 messages Apr 6, 2002

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Clean up x86 interrupt entry code

This patch moves the generation of the asm interrupt entry stubs from i8259.c to entry.S. This allows it to be done with less code and without needing duplicate definitions of SAVE_ALL, GET_CURRENT, etc.

Signature · 1 line
						Brian Gerst
arch/i386/kernel/entry.S +69 -7
diff -urN linux-2.5.8-pre2/arch/i386/kernel/entry.S linux/arch/i386/kernel/entry.S
@@ -47,6 +47,7 @@
 #include <asm/errno.h>
 #include <asm/segment.h>
 #include <asm/smp.h>
+#include <asm/irq_vectors.h>
 
 EBX		= 0x00
 ECX		= 0x04
@@ -94,12 +95,12 @@
 
 #ifdef CONFIG_PREEMPT
 #define preempt_stop cli
-#define init_ret_intr \
-	cli; \
-	decl TI_PRE_COUNT(%ebx);
+#define INC_PRE_COUNT(reg) incl TI_PRE_COUNT(reg);
+#define DEC_PRE_COUNT(reg) decl TI_PRE_COUNT(reg);
 #else
 #define preempt_stop
-#define init_ret_intr
+#define INC_PRE_COUNT(reg)
+#define DEC_PRE_COUNT(reg)
 #define resume_kernel restore_all
 #endif
 
@@ -210,9 +211,9 @@
 
 	# userspace resumption stub bypassing syscall exit tracing
 	ALIGN
-ENTRY(ret_from_intr)
-	GET_THREAD_INFO(%ebx)
-	init_ret_intr
+ret_from_intr:
+	preempt_stop
+	DEC_PRE_COUNT(%ebx)
 ret_from_exception:
 	movl EFLAGS(%esp), %eax		# mix EFLAGS and CS
 	movb CS(%esp), %al
@@ -335,6 +336,67 @@
 	movl $-ENOSYS,EAX(%esp)
 	jmp resume_userspace
 
+/*
+ * Build the entry stubs and pointer table with
+ * some assembler magic.
+ */
+.data
+ENTRY(interrupt)
+.text
+
+vector=0
+ENTRY(irq_entries_start)
+.rept NR_IRQS
+	ALIGN
+1:	pushl $vector-256
+	jmp common_interrupt
+.data
+	.long 1b
+.text
+vector=vector+1
+.endr
+
+	ALIGN
+common_interrupt:
+	SAVE_ALL
+	GET_THREAD_INFO(%ebx)
+	INC_PRE_COUNT(%ebx)
+	call SYMBOL_NAME(do_IRQ)
+	jmp ret_from_intr
+
+#define BUILD_INTERRUPT(name, nr)	\
+ENTRY(name)				\
+	pushl $nr-256;			\
+	SAVE_ALL			\
+	GET_THREAD_INFO(%ebx);		\
+	INC_PRE_COUNT(%ebx)		\
+	call SYMBOL_NAME(smp_/**/name);	\
+	jmp ret_from_intr;
+
+/*
+ * The following vectors are part of the Linux architecture, there
+ * is no hardware IRQ pin equivalent for them, they are triggered
+ * through the ICC by us (IPIs)
+ */
+#ifdef CONFIG_SMP
+BUILD_INTERRUPT(reschedule_interrupt,RESCHEDULE_VECTOR)
+BUILD_INTERRUPT(invalidate_interrupt,INVALIDATE_TLB_VECTOR)
+BUILD_INTERRUPT(call_function_interrupt,CALL_FUNCTION_VECTOR)
+#endif
+
+/*
+ * every pentium local APIC has two 'local interrupts', with a
+ * soft-definable vector attached to both interrupts, one of
+ * which is a timer interrupt, the other one is error counter
+ * overflow. Linux uses the local APIC timer interrupt to get
+ * a much simpler SMP time architecture:
+ */
+#ifdef CONFIG_X86_LOCAL_APIC
+BUILD_INTERRUPT(apic_timer_interrupt,LOCAL_TIMER_VECTOR)
+BUILD_INTERRUPT(error_interrupt,ERROR_APIC_VECTOR)
+BUILD_INTERRUPT(spurious_interrupt,SPURIOUS_APIC_VECTOR)
+#endif
+
 ENTRY(divide_error)
 	pushl $0			# no error code
 	pushl $ SYMBOL_NAME(do_divide_error)
arch/i386/kernel/i8259.c +0 -96

102 lines not on this page · raw message

arch/i386/kernel/io_apic.c +0 -1
diff -urN linux-2.5.8-pre2/arch/i386/kernel/io_apic.c linux/arch/i386/kernel/io_apic.c
@@ -597,7 +597,6 @@
 	return current_vector;
 }
 
-extern void (*interrupt[NR_IRQS])(void);
 static struct hw_interrupt_type ioapic_level_irq_type;
 static struct hw_interrupt_type ioapic_edge_irq_type;
 
include/asm-i386/hw_irq.h +16 -131

165 lines not on this page · raw message

include/asm-i386/irq.h +1 -17
diff -urN linux-2.5.8-pre2/include/asm-i386/irq.h linux/include/asm-i386/irq.h
@@ -12,23 +12,7 @@
 
 #include <linux/config.h>
 #include <linux/sched.h>
-
-#define TIMER_IRQ 0
-
-/*
- * 16 8259A IRQ's, 208 potential APIC interrupt sources.
- * Right now the APIC is mostly only used for SMP.
- * 256 vectors is an architectural limit. (we can have
- * more than 256 devices theoretically, but they will
- * have to use shared interrupts)
- * Since vectors 0x00-0x1f are used/reserved for the CPU,
- * the usable vector space is 0x20-0xff (224 vectors)
- */
-#ifdef CONFIG_X86_IO_APIC
-#define NR_IRQS 224
-#else
-#define NR_IRQS 16
-#endif
+#include <asm/irq_vectors.h>
 
 static __inline__ int irq_cannonicalize(int irq)
 {
include/asm-i386/irq_vectors.h +64 -0

64 lines not on this page · raw message

#1 lore raw

arch/i386/kernel/entry.S line 216

Quoted 6 lines · Brian Gerst
arch/i386/kernel/entry.S +3 -3
-ENTRY(ret_from_intr)
-	GET_THREAD_INFO(%ebx)
-	init_ret_intr
+ret_from_intr:
+	preempt_stop
+	DEC_PRE_COUNT(%ebx)

You removed GET_THREAD_INFO and there does not seem to be a replacement. Is there some assurance *thread_info is now pointed to by %ebx here?

Robert Love

#2 lore raw
Quoted 4 lines · Robert Love

You removed GET_THREAD_INFO and there does not seem to be a replacement. Is there some assurance *thread_info is now pointed to by %ebx here?

It seems to be always loaded by the common interrupt code (and %ebx is a call-saved register, so calling the interrupt handlers and returning doesn't clobber it).

But testing it may be a good idea ;^p

Linus

#3 lore raw
Quoted 3 lines · Linus Torvalds

It seems to be always loaded by the common interrupt code (and %ebx is a call-saved register, so calling the interrupt handlers and returning doesn't clobber it).

True enough. I guess I should of done this from the beginning ...

Quoted 1 line

But testing it may be a good idea ;^p

Of course I will, but it is hard (and subject to Heisenberg principals) to test that we preempt whenever necessary. Only with the patch I sent you earlier am I seeing no missed preemptions ... now to work on the egregiously long-held locks.

Robert Love

#4 lore raw
In reply to Brian Gerst
Quoted 15 lines · Robert Love

arch/i386/kernel/entry.S line 216

Quoted 6 lines · Brian Gerst
arch/i386/kernel/entry.S +3 -3
-ENTRY(ret_from_intr)
-	GET_THREAD_INFO(%ebx)
-	init_ret_intr
+ret_from_intr:
+	preempt_stop
+	DEC_PRE_COUNT(%ebx)

You removed GET_THREAD_INFO and there does not seem to be a replacement. Is there some assurance *thread_info is now pointed to by %ebx here?

Quoted 2 lines

Robert Love

Yes. It is set before the INC_PRE_COUNT and since it is preserved by called functions it is still set when it gets to ret_from_intr.

Signature · 1 line
						Brian Gerst