Skip to content

Commit 2c95a32

Browse files
Asias Herustyrussell
Asias He
authored andcommitted
virtio-blk: Use block layer provided spinlock
Block layer will allocate a spinlock for the queue if the driver does not provide one in blk_init_queue(). The reason to use the internal spinlock is that blk_cleanup_queue() will switch to use the internal spinlock in the cleanup code path. if (q->queue_lock != &q->__queue_lock) q->queue_lock = &q->__queue_lock; However, processes which are in D state might have taken the driver provided spinlock, when the processes wake up, they would release the block provided spinlock. ===================================== [ BUG: bad unlock balance detected! ] 3.4.0-rc7+ raspberrypi#238 Not tainted ------------------------------------- fio/3587 is trying to release lock (&(&q->__queue_lock)->rlock) at: [<ffffffff813274d2>] blk_queue_bio+0x2a2/0x380 but there are no more locks to release! other info that might help us debug this: 1 lock held by fio/3587: #0: (&(&vblk->lock)->rlock){......}, at: [<ffffffff8132661a>] get_request_wait+0x19a/0x250 Other drivers use block layer provided spinlock as well, e.g. SCSI. Switching to the block layer provided spinlock saves a bit of memory and does not increase lock contention. Performance test shows no real difference is observed before and after this patch. Changes in v2: Improve commit log as Michael suggested. Cc: [email protected] Cc: [email protected] Cc: [email protected] Signed-off-by: Asias He <[email protected]> Acked-by: Michael S. Tsirkin <[email protected]> Signed-off-by: Rusty Russell <[email protected]>
1 parent 483001c commit 2c95a32

File tree

1 file changed

+3
-6
lines changed

1 file changed

+3
-6
lines changed

drivers/block/virtio_blk.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@ struct workqueue_struct *virtblk_wq;
2121

2222
struct virtio_blk
2323
{
24-
spinlock_t lock;
25-
2624
struct virtio_device *vdev;
2725
struct virtqueue *vq;
2826

@@ -65,7 +63,7 @@ static void blk_done(struct virtqueue *vq)
6563
unsigned int len;
6664
unsigned long flags;
6765

68-
spin_lock_irqsave(&vblk->lock, flags);
66+
spin_lock_irqsave(vblk->disk->queue->queue_lock, flags);
6967
while ((vbr = virtqueue_get_buf(vblk->vq, &len)) != NULL) {
7068
int error;
7169

@@ -99,7 +97,7 @@ static void blk_done(struct virtqueue *vq)
9997
}
10098
/* In case queue is stopped waiting for more buffers. */
10199
blk_start_queue(vblk->disk->queue);
102-
spin_unlock_irqrestore(&vblk->lock, flags);
100+
spin_unlock_irqrestore(vblk->disk->queue->queue_lock, flags);
103101
}
104102

105103
static bool do_req(struct request_queue *q, struct virtio_blk *vblk,
@@ -431,7 +429,6 @@ static int __devinit virtblk_probe(struct virtio_device *vdev)
431429
goto out_free_index;
432430
}
433431

434-
spin_lock_init(&vblk->lock);
435432
vblk->vdev = vdev;
436433
vblk->sg_elems = sg_elems;
437434
sg_init_table(vblk->sg, vblk->sg_elems);
@@ -456,7 +453,7 @@ static int __devinit virtblk_probe(struct virtio_device *vdev)
456453
goto out_mempool;
457454
}
458455

459-
q = vblk->disk->queue = blk_init_queue(do_virtblk_request, &vblk->lock);
456+
q = vblk->disk->queue = blk_init_queue(do_virtblk_request, NULL);
460457
if (!q) {
461458
err = -ENOMEM;
462459
goto out_put_disk;

0 commit comments

Comments
 (0)