diff --git a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c index 46e54b441663d501c33944e46411117af9c4da40..11ef9d9ea139316e454cfae3d3b10f7aaab71959 100644 --- a/drivers/block/ll_rw_blk.c +++ b/drivers/block/ll_rw_blk.c @@ -1715,6 +1715,15 @@ request_queue_t *blk_init_queue(request_fn_proc *rfn, spinlock_t *lock) if (blk_init_free_list(q)) goto out_init; + /* + * if caller didn't supply a lock, they get per-queue locking with + * our embedded lock + */ + if (!lock) { + spin_lock_init(&q->__queue_lock); + lock = &q->__queue_lock; + } + q->request_fn = rfn; q->back_merge_fn = ll_back_merge_fn; q->front_merge_fn = ll_front_merge_fn; diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 7cbc4127fb5a6375e870920dd3f7b19199d59a90..d230c699c728e3a8db456034bf5bf30c7b1c5452 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -360,9 +360,9 @@ void scsi_device_unbusy(struct scsi_device *sdev) shost->host_failed)) scsi_eh_wakeup(shost); spin_unlock(shost->host_lock); - spin_lock(&sdev->sdev_lock); + spin_lock(sdev->request_queue->queue_lock); sdev->device_busy--; - spin_unlock_irqrestore(&sdev->sdev_lock, flags); + spin_unlock_irqrestore(sdev->request_queue->queue_lock, flags); } /* @@ -1425,7 +1425,7 @@ struct request_queue *scsi_alloc_queue(struct scsi_device *sdev) struct Scsi_Host *shost = sdev->host; struct request_queue *q; - q = blk_init_queue(scsi_request_fn, &sdev->sdev_lock); + q = blk_init_queue(scsi_request_fn, NULL); if (!q) return NULL; diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index a8a37a338c02f70ea4e04c9cbcab29559c0d3492..287d197a7c17f8527668ee162361b9552f04d948 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -249,7 +249,6 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget, */ sdev->borken = 1; - spin_lock_init(&sdev->sdev_lock); sdev->request_queue = scsi_alloc_queue(sdev); if (!sdev->request_queue) { /* release fn is set up in scsi_sysfs_device_initialise, so diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 70ac2860a605342199b4d68c2215154eb2921645..ef1afc178c0a2df9569daf3312e33911a0e89bf2 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -355,8 +355,11 @@ struct request_queue unsigned long queue_flags; /* - * protects queue structures from reentrancy + * protects queue structures from reentrancy. ->__queue_lock should + * _never_ be used directly, it is queue private. always use + * ->queue_lock. */ + spinlock_t __queue_lock; spinlock_t *queue_lock; /* diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 07d974051b0c10b1381ea4b0a675076fe5210e71..f6d051318299c17bf10240b042bca624e96ee97e 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -44,7 +44,6 @@ struct scsi_device { struct list_head same_target_siblings; /* just the devices sharing same target id */ volatile unsigned short device_busy; /* commands actually active on low-level */ - spinlock_t sdev_lock; /* also the request queue_lock */ spinlock_t list_lock; struct list_head cmd_list; /* queue of in use SCSI Command structures */ struct list_head starved_entry;