lkml.org 
[lkml]   [2003]   [Aug]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patches in this message
    /
    Date
    From
    SubjectRe: OOps in 2.6.0-test4-mm3-1
    Mike Fedyk <mfedyk@matchmail.com> wrote:
    >
    > It's vanilla mm3-1 with this one patch added from Neil Brown. I don't think
    > it has anything to do with it (it looks like a driver issue to me). But it
    > can't hurt to mention it.
    >

    No, it is not an MD thing.

    You need two patches. It's up to the scsi guys to decide if they're the
    right way to go. I think they are.




    Some drivers such as aha1542 and aic7xxx_old will call scsi_register() and
    then, if some succeeding operations fails they will call scsi_unregister(),
    without an intervening scsi_set_host().

    This causes an oops in scsi_put_device(), because kobj->parent is NULL.

    In other words, scsi_register() immediately followed by scsi_unregister()
    is guaranteed to oops.

    The patch makes scsi_host_dev_release() more robust against this usage
    pattern.


    drivers/scsi/hosts.c | 8 +++++++-
    1 files changed, 7 insertions(+), 1 deletion(-)

    diff -puN drivers/scsi/hosts.c~aha1542-oops-fix drivers/scsi/hosts.c
    --- 25/drivers/scsi/hosts.c~aha1542-oops-fix 2003-08-29 19:48:37.000000000 -0700
    +++ 25-akpm/drivers/scsi/hosts.c 2003-08-29 20:02:49.000000000 -0700
    @@ -158,7 +158,13 @@ static void scsi_host_dev_release(struct
    scsi_proc_hostdir_rm(shost->hostt);
    scsi_destroy_command_freelist(shost);

    - put_device(parent);
    + /*
    + * Some drivers (eg aha1542) do scsi_register()/scsi_unregister()
    + * during probing without performing a scsi_set_device() in between.
    + * In this case dev->parent is NULL.
    + */
    + if (parent)
    + put_device(parent);
    kfree(shost);
    }

    _



    and





    scsi_unregister() unconditionally does list_del(&shost->sht_legacy_list).

    But scsi_register() leaves that list_head uninitialised if scsi_host_alloc()
    returned NULL.

    In other words: scsi_unregister() is guaranteed to oops if scsi_host_alloc()
    fails.

    Fix it by initialising the list_head in scsi_register().


    drivers/scsi/hosts.c | 6 +++++-
    1 files changed, 5 insertions(+), 1 deletion(-)
    diff -puN drivers/scsi/hosts.c~scsi_unregister-oops-fix drivers/scsi/hosts.c
    --- 25/drivers/scsi/hosts.c~scsi_unregister-oops-fix 2003-08-29 20:02:53.000000000 -0700
    +++ 25-akpm/drivers/scsi/hosts.c 2003-08-29 20:02:53.000000000 -0700
    @@ -297,8 +297,12 @@ struct Scsi_Host *scsi_register(struct s
    dump_stack();
    }

    - if (shost)
    + if (shost) {
    list_add_tail(&shost->sht_legacy_list, &sht->legacy_hosts);
    + } else {
    + /* Do this to keep scsi_unregister() happy */
    + INIT_LIST_HEAD(&shost->sht_legacy_list);
    + }
    return shost;
    }

    _

    -
    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-03-22 13:48    [W:2.212 / U:0.260 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site