summaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/s390_ext.c
diff options
context:
space:
mode:
authorHeiko Carstens <heiko.carstens@de.ibm.com>2005-07-27 20:45:00 +0200
committerLinus Torvalds <torvalds@g5.osdl.org>2005-07-28 01:26:04 +0200
commit99b2d8df1d06f1072a949fc1e01a08b94b084d5f (patch)
treee5be46e9fbee8b68ab1743ef29037c0596a7265f /arch/s390/kernel/s390_ext.c
parent[PATCH] s390: atomic64 inline functions (diff)
downloadlinux-99b2d8df1d06f1072a949fc1e01a08b94b084d5f.tar.xz
linux-99b2d8df1d06f1072a949fc1e01a08b94b084d5f.zip
[PATCH] s390: external call performance
The kernel uses the SIGP external call order code to signal other CPUs. When running with dedicated CPUs external calls don't get delivered immediately but within a fixed polling invervall. This can lead to delays where the system appears to do nothing. Replace the SIGP external call order with the SIGP emergency call order since this one gets delivered immediately. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/s390/kernel/s390_ext.c')
-rw-r--r--arch/s390/kernel/s390_ext.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/arch/s390/kernel/s390_ext.c b/arch/s390/kernel/s390_ext.c
index 3bdd38ec71da..207bc511a6e3 100644
--- a/arch/s390/kernel/s390_ext.c
+++ b/arch/s390/kernel/s390_ext.c
@@ -19,7 +19,6 @@
#include <asm/irq.h>
/*
- * Simple hash strategy: index = code & 0xff;
* ext_int_hash[index] is the start of the list for all external interrupts
* that hash to this index. With the current set of external interrupts
* (0x1202 external call, 0x1004 cpu timer, 0x2401 hwc console, 0x4000
@@ -27,6 +26,11 @@
*/
ext_int_info_t *ext_int_hash[256] = { 0, };
+static inline int ext_hash(__u16 code)
+{
+ return (code + (code >> 9)) & 0xff;
+}
+
int register_external_interrupt(__u16 code, ext_int_handler_t handler)
{
ext_int_info_t *p;
@@ -37,7 +41,7 @@ int register_external_interrupt(__u16 code, ext_int_handler_t handler)
return -ENOMEM;
p->code = code;
p->handler = handler;
- index = code & 0xff;
+ index = ext_hash(code);
p->next = ext_int_hash[index];
ext_int_hash[index] = p;
return 0;
@@ -52,7 +56,7 @@ int register_early_external_interrupt(__u16 code, ext_int_handler_t handler,
return -EINVAL;
p->code = code;
p->handler = handler;
- index = code & 0xff;
+ index = ext_hash(code);
p->next = ext_int_hash[index];
ext_int_hash[index] = p;
return 0;
@@ -63,7 +67,7 @@ int unregister_external_interrupt(__u16 code, ext_int_handler_t handler)
ext_int_info_t *p, *q;
int index;
- index = code & 0xff;
+ index = ext_hash(code);
q = NULL;
p = ext_int_hash[index];
while (p != NULL) {
@@ -90,7 +94,7 @@ int unregister_early_external_interrupt(__u16 code, ext_int_handler_t handler,
if (p == NULL || p->code != code || p->handler != handler)
return -EINVAL;
- index = code & 0xff;
+ index = ext_hash(code);
q = ext_int_hash[index];
if (p != q) {
while (q != NULL) {
@@ -120,7 +124,7 @@ void do_extint(struct pt_regs *regs, unsigned short code)
*/
account_ticks(regs);
kstat_cpu(smp_processor_id()).irqs[EXTERNAL_INTERRUPT]++;
- index = code & 0xff;
+ index = ext_hash(code);
for (p = ext_int_hash[index]; p; p = p->next) {
if (likely(p->code == code)) {
if (likely(p->handler))