block: unify request timeout handling

Right now SCSI and others do their own command timeout handling.
Move those bits to the block layer.

Instead of having a timer per command, we try to be a bit more clever
and simply have one per-queue. This avoids the overhead of having to
tear down and setup a timer for each command, so it will result in a lot
less timer fiddling.

Signed-off-by: Mike Anderson <andmike@linux.vnet.ibm.com>
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
This commit is contained in:
Jens Axboe
2008-09-14 05:55:09 -07:00
parent 608aeef17a
commit 242f9dcb8b
39 changed files with 399 additions and 339 deletions

View File

@ -748,69 +748,3 @@ static void gdth_wait_completion(gdth_ha_str *ha, int busnum, int id)
}
spin_unlock_irqrestore(&ha->smp_lock, flags);
}
static void gdth_stop_timeout(gdth_ha_str *ha, int busnum, int id)
{
ulong flags;
Scsi_Cmnd *scp;
unchar b, t;
spin_lock_irqsave(&ha->smp_lock, flags);
for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) {
struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp);
if (!cmndinfo->internal_command) {
b = scp->device->channel;
t = scp->device->id;
if (t == (unchar)id && b == (unchar)busnum) {
TRACE2(("gdth_stop_timeout(): update_timeout()\n"));
cmndinfo->timeout = gdth_update_timeout(scp, 0);
}
}
}
spin_unlock_irqrestore(&ha->smp_lock, flags);
}
static void gdth_start_timeout(gdth_ha_str *ha, int busnum, int id)
{
ulong flags;
Scsi_Cmnd *scp;
unchar b, t;
spin_lock_irqsave(&ha->smp_lock, flags);
for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) {
struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp);
if (!cmndinfo->internal_command) {
b = scp->device->channel;
t = scp->device->id;
if (t == (unchar)id && b == (unchar)busnum) {
TRACE2(("gdth_start_timeout(): update_timeout()\n"));
gdth_update_timeout(scp, cmndinfo->timeout);
}
}
}
spin_unlock_irqrestore(&ha->smp_lock, flags);
}
static int gdth_update_timeout(Scsi_Cmnd *scp, int timeout)
{
int oldto;
oldto = scp->timeout_per_command;
scp->timeout_per_command = timeout;
if (timeout == 0) {
del_timer(&scp->eh_timeout);
scp->eh_timeout.data = (unsigned long) NULL;
scp->eh_timeout.expires = 0;
} else {
if (scp->eh_timeout.data != (unsigned long) NULL)
del_timer(&scp->eh_timeout);
scp->eh_timeout.data = (unsigned long) scp;
scp->eh_timeout.expires = jiffies + timeout;
add_timer(&scp->eh_timeout);
}
return oldto;
}