• Douglas Gilbert's avatar
    scsi: scsi_debug: Address races following module load · 2aad3cd8
    Douglas Gilbert authored
    When scsi_debug is loaded as a module with many (simulated) hosts, targets,
    and devices (LUs), modprobe can take a long time to return.  Only a small
    amount of this time is spent in the scsi_debug_init(); the rest is other
    parts of the kernel reacting to to the appearance of new storage
    devices. As soon as scsi_debug_init() has completed the user space may call
    'rmmod scsi_debug' and this was found to cause race problems as outlined
    here:
    
        https://bugzilla.kernel.org/show_bug.cgi?id=212337
    
    To reliably generate this race a sysfs parameter called rm_all_hosts was
    added and the code was strengthened in this area. The main change was to
    make the count of scsi_debug hosts present an atomic.  Then it was found
    that the handling of the existing add_host parameter needed the same
    strengthening. Further: 'echo -9999 >
    /sys/bus/pseudo/drivers/scsi_debug/add_host has the same effect as
    rm_all_hosts so rm_all_hosts was not needed.
    
    To inhibit a race between two invocations of writes to add_host, a mutex
    was added. Also address a possible race when rmmod is called but LUs are
    still being added.
    
    The logic to remove (all) hosts is rather crude: it works backwards down a
    linked lists of hosts. Any pending requests are terminated with
    DID_NO_CONNECT as are any new requests. In the case where not all hosts are
    being removed, the ones that remain may have lost requests as just
    outlined. The lowest numbered host (id) hosts will remain.
    
    Cc: Bart Van Assche <bvanassche@acm.org>
    Link: https://lore.kernel.org/r/20220109012853.301953-2-dgilbert@interlog.comSigned-off-by: default avatarDouglas Gilbert <dgilbert@interlog.com>
    Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
    2aad3cd8
scsi_debug.c 227 KB