diff options
author | David Woodhouse <dwmw2@shinybook.infradead.org> | 2006-04-29 01:42:26 +0100 |
---|---|---|
committer | David Woodhouse <dwmw2@infradead.org> | 2006-04-29 01:42:26 +0100 |
commit | d6754b401a15eaa16492ea5dbaa4826361d3f411 (patch) | |
tree | 032f067d3af458527d903a7653885404ed82431e /drivers/s390/s390mach.c | |
parent | acc429a517bd11fdcac9bea97d082d26231beb92 (diff) | |
parent | 693f7d362055261882659475d2ef022e32edbff1 (diff) | |
download | op-kernel-dev-d6754b401a15eaa16492ea5dbaa4826361d3f411.zip op-kernel-dev-d6754b401a15eaa16492ea5dbaa4826361d3f411.tar.gz |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Diffstat (limited to 'drivers/s390/s390mach.c')
-rw-r--r-- | drivers/s390/s390mach.c | 33 |
1 files changed, 28 insertions, 5 deletions
diff --git a/drivers/s390/s390mach.c b/drivers/s390/s390mach.c index 3bf4666..5ae1480 100644 --- a/drivers/s390/s390mach.c +++ b/drivers/s390/s390mach.c @@ -362,12 +362,19 @@ s390_revalidate_registers(struct mci *mci) return kill_task; } +#define MAX_IPD_COUNT 29 +#define MAX_IPD_TIME (5 * 60 * 100 * 1000) /* 5 minutes */ + /* * machine check handler. */ void s390_do_machine_check(struct pt_regs *regs) { + static DEFINE_SPINLOCK(ipd_lock); + static unsigned long long last_ipd; + static int ipd_count; + unsigned long long tmp; struct mci *mci; struct mcck_struct *mcck; int umode; @@ -404,11 +411,27 @@ s390_do_machine_check(struct pt_regs *regs) s390_handle_damage("processing backup machine " "check with damage."); } - if (!umode) - s390_handle_damage("processing backup machine " - "check in kernel mode."); - mcck->kill_task = 1; - mcck->mcck_code = *(unsigned long long *) mci; + + /* + * Nullifying exigent condition, therefore we might + * retry this instruction. + */ + + spin_lock(&ipd_lock); + + tmp = get_clock(); + + if (((tmp - last_ipd) >> 12) < MAX_IPD_TIME) + ipd_count++; + else + ipd_count = 1; + + last_ipd = tmp; + + if (ipd_count == MAX_IPD_COUNT) + s390_handle_damage("too many ipd retries."); + + spin_unlock(&ipd_lock); } else { /* Processing damage -> stopping machine */ |