]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blob - src/patches/suse-2.6.27.31/patches.arch/s390-02-09-tape-lock.patch
Reenabled linux-xen, added patches for Xen Kernel Version 2.6.27.31,
[people/teissler/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.arch / s390-02-09-tape-lock.patch
1 From: Gerald Schaefer <geraldsc@de.ibm.com>
2 Subject: tape device driver: improve locking
3 References: bnc#434333
4
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.
13
14 Acked-by: John Jolly <jjolly@suse.de>
15 ---
16 drivers/s390/char/tape_block.c | 6 ++++--
17 drivers/s390/char/tape_core.c | 8 ++++----
18 2 files changed, 8 insertions(+), 6 deletions(-)
19
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
25 static void
26 tapeblock_end_request(struct request *req, int error)
27 {
28 - if (__blk_end_request(req, error, blk_rq_bytes(req)))
29 + if (blk_end_request(req, error, blk_rq_bytes(req)))
30 BUG();
31 }
32
33 @@ -166,7 +166,7 @@ tapeblock_requeue(struct work_struct *wo
34 nr_queued++;
35 spin_unlock(get_ccwdev_lock(device->cdev));
36
37 - spin_lock(&device->blk_data.request_queue_lock);
38 + spin_lock_irq(&device->blk_data.request_queue_lock);
39 while (
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);
49 continue;
50 }
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)
57 {
58 int rc;
59
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");
64 rc = -ENODEV;
65 @@ -1217,7 +1217,7 @@ tape_open(struct tape_device *device)
66 tape_state_set(device, TS_IN_USE);
67 rc = 0;
68 }
69 - spin_unlock(get_ccwdev_lock(device->cdev));
70 + spin_unlock_irq(get_ccwdev_lock(device->cdev));
71 return rc;
72 }
73
74 @@ -1227,11 +1227,11 @@ tape_open(struct tape_device *device)
75 int
76 tape_release(struct tape_device *device)
77 {
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));
85 return 0;
86 }
87