Skip to content

Commit

Permalink
scsi/sd: remove big kernel lock
Browse files Browse the repository at this point in the history
Every user of the BKL in the sd driver is the
result of the pushdown from the block layer
into the open/close/ioctl functions.

The only place that used to rely on the BKL is
the sdkp->openers variable, which gets converted
into an atomic_t.

Nothing else seems to rely on the BKL, since the
functions do not touch global data without holding
another lock, and the open/close functions are
still protected from concurrent execution using
the bdev->bd_mutex.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Cc: linux-scsi@vger.kernel.org
Cc: "James E.J. Bottomley" <James.Bottomley@suse.de>
Acked-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
  • Loading branch information
Arnd Bergmann authored and Jens Axboe committed Aug 7, 2010
1 parent 15392ef commit 409f349
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 11 deletions.
17 changes: 7 additions & 10 deletions drivers/scsi/sd.c
Original file line number Diff line number Diff line change
Expand Up @@ -783,6 +783,8 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq)
* or from within the kernel (e.g. as a result of a mount(1) ).
* In the latter case @inode and @filp carry an abridged amount
* of information as noted above.
*
* Locking: called with bdev->bd_mutex held.
**/
static int sd_open(struct block_device *bdev, fmode_t mode)
{
Expand All @@ -795,7 +797,6 @@ static int sd_open(struct block_device *bdev, fmode_t mode)

SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, "sd_open\n"));

lock_kernel();
sdev = sdkp->device;

/*
Expand Down Expand Up @@ -834,17 +835,15 @@ static int sd_open(struct block_device *bdev, fmode_t mode)
if (!scsi_device_online(sdev))
goto error_out;

if (!sdkp->openers++ && sdev->removable) {
if ((atomic_inc_return(&sdkp->openers) == 1) && sdev->removable) {
if (scsi_block_when_processing_errors(sdev))
scsi_set_medium_removal(sdev, SCSI_REMOVAL_PREVENT);
}

unlock_kernel();
return 0;

error_out:
scsi_disk_put(sdkp);
unlock_kernel();
return retval;
}

Expand All @@ -858,6 +857,8 @@ static int sd_open(struct block_device *bdev, fmode_t mode)
*
* Note: may block (uninterruptible) if error recovery is underway
* on this disk.
*
* Locking: called with bdev->bd_mutex held.
**/
static int sd_release(struct gendisk *disk, fmode_t mode)
{
Expand All @@ -866,8 +867,7 @@ static int sd_release(struct gendisk *disk, fmode_t mode)

SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, "sd_release\n"));

lock_kernel();
if (!--sdkp->openers && sdev->removable) {
if (atomic_dec_return(&sdkp->openers) && sdev->removable) {
if (scsi_block_when_processing_errors(sdev))
scsi_set_medium_removal(sdev, SCSI_REMOVAL_ALLOW);
}
Expand All @@ -877,7 +877,6 @@ static int sd_release(struct gendisk *disk, fmode_t mode)
* XXX is followed by a "rmmod sd_mod"?
*/
scsi_disk_put(sdkp);
unlock_kernel();
return 0;
}

Expand Down Expand Up @@ -930,7 +929,6 @@ static int sd_ioctl(struct block_device *bdev, fmode_t mode,
SCSI_LOG_IOCTL(1, printk("sd_ioctl: disk=%s, cmd=0x%x\n",
disk->disk_name, cmd));

lock_kernel();
/*
* If we are in the middle of error recovery, don't let anyone
* else try and use this device. Also, if error recovery fails, it
Expand Down Expand Up @@ -960,7 +958,6 @@ static int sd_ioctl(struct block_device *bdev, fmode_t mode,
break;
}
out:
unlock_kernel();
return error;
}

Expand Down Expand Up @@ -2346,7 +2343,7 @@ static int sd_probe(struct device *dev)
sdkp->driver = &sd_template;
sdkp->disk = gd;
sdkp->index = index;
sdkp->openers = 0;
atomic_set(&sdkp->openers, 0);
sdkp->previous_state = 1;

if (!sdp->request_queue->rq_timeout) {
Expand Down
2 changes: 1 addition & 1 deletion drivers/scsi/sd.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ struct scsi_disk {
struct scsi_device *device;
struct device dev;
struct gendisk *disk;
unsigned int openers; /* protected by BKL for now, yuck */
atomic_t openers;
sector_t capacity; /* size in 512-byte sectors */
u32 index;
unsigned short hw_sector_size;
Expand Down

0 comments on commit 409f349

Please sign in to comment.