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 "