1 From: Gerald Schaefer <geraldsc@de.ibm.com>
2 Subject: tape device driver: improve locking
5 Symptom: 1. message "Badness at include/linux/blkdev.h"
6 2. lockdep message "INFO: inconsistent lock state"
7 Problem: 1. Tape block device driver does not hold request queue lock
8 when completing request via __blk_end_request.
9 2. During open() processing tape device driver receives
10 interrupt while holding the tape device lock.
11 Solution: 1. Use blk_end_request rather than __blk_end_request
12 2. Use spin_lock_irq to disable interrupts rather than spin_lock.
14 Acked-by: John Jolly <jjolly@suse.de>
16 drivers/s390/char/tape_block.c | 6 ++++--
17 drivers/s390/char/tape_core.c | 8 ++++----
18 2 files changed, 8 insertions(+), 6 deletions(-)
20 Index: temp_orig/drivers/s390/char/tape_block.c
21 ===================================================================
22 --- temp_orig.orig/drivers/s390/char/tape_block.c
23 +++ temp_orig/drivers/s390/char/tape_block.c
24 @@ -76,7 +76,7 @@ tapeblock_trigger_requeue(struct tape_de
26 tapeblock_end_request(struct request *req, int error)
28 - if (__blk_end_request(req, error, blk_rq_bytes(req)))
29 + if (blk_end_request(req, error, blk_rq_bytes(req)))
33 @@ -166,7 +166,7 @@ tapeblock_requeue(struct work_struct *wo
35 spin_unlock(get_ccwdev_lock(device->cdev));
37 - spin_lock(&device->blk_data.request_queue_lock);
38 + spin_lock_irq(&device->blk_data.request_queue_lock);
40 !blk_queue_plugged(queue) &&
41 elv_next_request(queue) &&
42 @@ -176,7 +176,9 @@ tapeblock_requeue(struct work_struct *wo
43 if (rq_data_dir(req) == WRITE) {
44 DBF_EVENT(1, "TBLOCK: Rejecting write request\n");
45 blkdev_dequeue_request(req);
46 + spin_unlock_irq(&device->blk_data.request_queue_lock);
47 tapeblock_end_request(req, -EIO);
48 + spin_lock_irq(&device->blk_data.request_queue_lock);
51 blkdev_dequeue_request(req);
52 Index: temp_orig/drivers/s390/char/tape_core.c
53 ===================================================================
54 --- temp_orig.orig/drivers/s390/char/tape_core.c
55 +++ temp_orig/drivers/s390/char/tape_core.c
56 @@ -1199,7 +1199,7 @@ tape_open(struct tape_device *device)
60 - spin_lock(get_ccwdev_lock(device->cdev));
61 + spin_lock_irq(get_ccwdev_lock(device->cdev));
62 if (device->tape_state == TS_NOT_OPER) {
63 DBF_EVENT(6, "TAPE:nodev\n");
65 @@ -1217,7 +1217,7 @@ tape_open(struct tape_device *device)
66 tape_state_set(device, TS_IN_USE);
69 - spin_unlock(get_ccwdev_lock(device->cdev));
70 + spin_unlock_irq(get_ccwdev_lock(device->cdev));
74 @@ -1227,11 +1227,11 @@ tape_open(struct tape_device *device)
76 tape_release(struct tape_device *device)
78 - spin_lock(get_ccwdev_lock(device->cdev));
79 + spin_lock_irq(get_ccwdev_lock(device->cdev));
80 if (device->tape_state == TS_IN_USE)
81 tape_state_set(device, TS_UNUSED);
82 module_put(device->discipline->owner);
83 - spin_unlock(get_ccwdev_lock(device->cdev));
84 + spin_unlock_irq(get_ccwdev_lock(device->cdev));