Commit 7dbe32be authored by Jens Axboe's avatar Jens Axboe Committed by Linus Torvalds

[PATCH] fix scsi oops on failed sg table allocation

This patch fixes the deliberate BUG_ON() on failed sgtable allocations.
I left that in because I was too lazy to fix it at the time...

Basically make scsi_init_io() return 0 on failure (like before) but this
time allow us to recover. scsi_init_io() will end_request on a fatal
condition. So now just mark the device/host as starved if needed, and
leave the request at the front of the queue for next service.
parent 76e4b1f8
......@@ -963,21 +963,22 @@ void scsi_request_fn(request_queue_t * q)
/*
* This sets up the scatter-gather table (allocating if
* required). Hosts that need bounce buffers will also
* get those allocated here.
* required).
*/
if (!scsi_init_io(SCpnt)) {
SCpnt = __scsi_end_request(SCpnt, 0,
SCpnt->request.nr_sectors, 0, 0);
if( SCpnt != NULL )
{
panic("Should not have leftover blocks\n");
}
spin_lock_irq(q->queue_lock);
SHpnt->host_busy--;
SDpnt->device_busy--;
continue;
if (SDpnt->device_busy == 0) {
SDpnt->starved = 1;
SHpnt->some_device_starved = 1;
}
SCpnt->request.special = SCpnt;
SCpnt->request.flags |= REQ_SPECIAL;
_elv_add_request(q, &SCpnt->request, 0, 0);
break;
}
/*
* Initialize the actual SCSI command for this request.
*/
......
......@@ -78,8 +78,12 @@ int scsi_init_io(Scsi_Cmnd *SCpnt)
if (in_interrupt())
gfp_mask &= ~__GFP_WAIT;
/*
* if sg table allocation fails, requeue request later.
*/
sgpnt = scsi_alloc_sgtable(SCpnt, gfp_mask);
BUG_ON(!sgpnt);
if (!sgpnt)
return 0;
SCpnt->request_buffer = (char *) sgpnt;
SCpnt->request_bufflen = req->nr_sectors << 9;
......@@ -102,8 +106,13 @@ int scsi_init_io(Scsi_Cmnd *SCpnt)
printk("Incorrect number of segments after building list\n");
printk("counted %d, received %d\n", count, SCpnt->use_sg);
printk("req nr_sec %lu, cur_nr_sec %u\n", req->nr_sectors, req->current_nr_sectors);
BUG();
return 0; /* ahem */
/*
* kill it. there should be no leftover blocks in this request
*/
SCpnt = scsi_end_request(SCpnt, 0, req->nr_sectors);
BUG_ON(SCpnt);
return 0;
}
/*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment