Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > fc11cd6e1c513a17304da94a5390f3cd > files > 3116

kernel-2.6.18-194.11.1.el5.src.rpm

From: Hans-Joachim Picht <hpicht@redhat.com>
Date: Thu, 31 Jan 2008 11:22:16 +0100
Subject: [s390] dasd: fix loop in request expiration handling
Message-id: 20080131102216.GB16660@redhat.com
O-Subject: [RHEL5 U2 PATCH 2/4] s390 - dasd: fix loop in request expiration handling
Bugzilla: 430592

Description
============

I/O on a DASD is blocked and the message log shows a lot
of messages that say 'termination failed, retrying in 5s'
but the message repeats several times a second and not
just every 5 seconds.

The first thing we do in the dasd device tasklet is to
check for expired requests. When a expired cqr is found,
we try to terminate that request so that we can give it
a fresh start. If this termination fails, we want to
wait for 5 seconds and do the same check/termination
again.

We set up a timer, which will schedule the tasklet in 5
seconds.

Unfortunately the termination function itself
schedules the tasklet, so the tasklet will be
executed again right after it finished and will find the
expired cqr.

If the termination failed due to a hardware
problem it will probably fail again, and we are stuck
in a loop until the hardware allows termination again.

The schedule in the termination function may be needed
other contexts, so if we want to give a request some
more time, we need to add this time to it's 'expires'
value.

Bugzilla
=========

BZ 430592
https://bugzilla.redhat.com/show_bug.cgi?id=430592

Upstream status of the patch:
=============================
Patch is upstream in git commit 7dc1da9ffae5a344f7115d019e2be069d3e1bb8d

Test status:
============
Kernel with patch was built and successfully tested

Please ACK.

With best regards,

Hans

diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 7a65b13..1e033b8 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -1270,12 +1270,13 @@ __dasd_check_expire(struct dasd_device * device)
 	    (time_after_eq(jiffies, cqr->expires + cqr->starttime))) {
 		if (device->discipline->term_IO(cqr) != 0) {
 			/* Hmpf, try again in 5 sec */
-			dasd_set_timer(device, 5*HZ);
 			DEV_MESSAGE(KERN_ERR, device,
 				    "internal error - timeout (%is) expired "
 				    "for cqr %p, termination failed, "
 				    "retrying in 5s",
 				    (cqr->expires/HZ), cqr);
+			cqr->expires += 5*HZ;
+			dasd_set_timer(device, 5*HZ);
 		} else {
 			DEV_MESSAGE(KERN_ERR, device,
 				    "internal error - timeout (%is) expired "