lkml.org 
[lkml]   [2005]   [Apr]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    SubjectRe: [PATCH scsi-misc-2.6 01/04] scsi: consolidate error handling out of scsi_init_io() into scsi_prep_fn()
    Date
    01_scsi_reqfn_consolidate_error_handling.patch

    This patch fixes a queue stall bug which occurred when sgtable
    allocation failed and device_busy == 0. When scsi_init_io()
    returns BLKPREP_DEFER or BLKPREP_KILL, it's supposed to free
    resources itself. This patch consolidates defer and kill
    handling into scsi_prep_fn().

    Note that this patch doesn't consolidate state defer/kill
    handlings in scsi_prep_fn(). They were omitted as all state
    checks will be moved into scsi_reques_fn() by the following
    reqfn_reimpl patch.

    ret value checking was changed to switch() as in James's
    patch. Also, kill: comment is copied from James's patch.

    Signed-off-by: Tejun Heo <htejun@gmail.com>

    scsi_lib.c | 46 +++++++++++++++++++++++++++++++---------------
    1 files changed, 31 insertions(+), 15 deletions(-)

    Index: scsi-reqfn-export/drivers/scsi/scsi_lib.c
    ===================================================================
    --- scsi-reqfn-export.orig/drivers/scsi/scsi_lib.c 2005-04-12 19:27:55.000000000 +0900
    +++ scsi-reqfn-export/drivers/scsi/scsi_lib.c 2005-04-12 19:27:55.000000000 +0900
    @@ -945,10 +945,8 @@ static int scsi_init_io(struct scsi_cmnd
    * if sg table allocation fails, requeue request later.
    */
    sgpnt = scsi_alloc_sgtable(cmd, GFP_ATOMIC);
    - if (unlikely(!sgpnt)) {
    - req->flags |= REQ_SOFTBARRIER;
    + if (unlikely(!sgpnt))
    return BLKPREP_DEFER;
    - }

    cmd->request_buffer = (char *) sgpnt;
    cmd->request_bufflen = req->nr_sectors << 9;
    @@ -975,9 +973,6 @@ static int scsi_init_io(struct scsi_cmnd
    printk(KERN_ERR "req nr_sec %lu, cur_nr_sec %u\n", req->nr_sectors,
    req->current_nr_sectors);

    - /* release the command and kill it */
    - scsi_release_buffers(cmd);
    - scsi_put_command(cmd);
    return BLKPREP_KILL;
    }

    @@ -1145,18 +1140,24 @@ static int scsi_prep_fn(struct request_q
    * required).
    */
    ret = scsi_init_io(cmd);
    - if (ret) /* BLKPREP_KILL return also releases the command */
    - return ret;
    + switch (ret) {
    + case 0:
    + /* Successful initialization. */
    + break;
    + case BLKPREP_DEFER:
    + goto defer;
    + default:
    + /* Unknown return value, fall through. */
    + case BLKPREP_KILL:
    + goto kill;
    + }

    /*
    * Initialize the actual SCSI command for this request.
    */
    drv = *(struct scsi_driver **)req->rq_disk->private_data;
    - if (unlikely(!drv->init_command(cmd))) {
    - scsi_release_buffers(cmd);
    - scsi_put_command(cmd);
    - return BLKPREP_KILL;
    - }
    + if (unlikely(!drv->init_command(cmd)))
    + goto kill;
    }

    /*
    @@ -1166,12 +1167,27 @@ static int scsi_prep_fn(struct request_q
    return BLKPREP_OK;

    defer:
    - /* If we defer, the elv_next_request() returns NULL, but the
    + /*
    + * If we defer, the elv_next_request() returns NULL, but the
    * queue must be restarted, so we plug here if no returning
    - * command will automatically do that. */
    + * command will automatically do that. Also, the request may
    + * have its cmd allocated, so we set REQ_SOFTBARRIER.
    + */
    if (sdev->device_busy == 0)
    blk_plug_device(q);
    + req->flags |= REQ_SOFTBARRIER;
    return BLKPREP_DEFER;
    +
    + kill:
    + /*
    + * Here we have to release every resource associated with the
    + * request because this will complete at the request level
    + * (req->end_io), not the scsi command level, so no scsi
    + * routine will get to free the associated resources.
    + */
    + scsi_release_buffers(cmd);
    + scsi_put_command(cmd);
    + return BLKPREP_KILL;
    }

    /*
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2005-04-12 13:32    [W:6.672 / U:0.528 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site