]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/suse-2.6.27.31/patches.arch/s390-11-06-qdio_tiq_list_lock.patch
Merge branch 'master' into next
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.arch / s390-11-06-qdio_tiq_list_lock.patch
1 From: Gerald Schaefer <geraldsc@de.ibm.com>
2 Subject: qdio: add missing tiq_list locking
3 References: bnc#484767,LTC#52205
4
5 Symptom: The system may hang if multiple qdio devices are added or
6 removed in parallel.
7 Problem: Although reading the tiq_list is done using RCU adding and
8 removing elements from the list must still happen locked since
9 multiple qdio devices may change the list in parallel otherwise.
10 Solution: Add a mutex to protect the tiq_list.
11
12 Acked-by: John Jolly <jjolly@suse.de>
13 ---
14 drivers/s390/cio/qdio_main.c | 1 +
15 drivers/s390/cio/qdio_thinint.c | 10 +++++++---
16 2 files changed, 8 insertions(+), 3 deletions(-)
17
18 Index: linux-sles11/drivers/s390/cio/qdio_main.c
19 ===================================================================
20 --- linux-sles11.orig/drivers/s390/cio/qdio_main.c
21 +++ linux-sles11/drivers/s390/cio/qdio_main.c
22 @@ -1094,6 +1094,7 @@ int qdio_shutdown(struct ccw_device *cde
23 if (!irq_ptr)
24 return -ENODEV;
25
26 + BUG_ON(irqs_disabled());
27 DBF_EVENT("qshutdown:%4x", cdev->private->schid.sch_no);
28
29 mutex_lock(&irq_ptr->setup_mutex);
30 Index: linux-sles11/drivers/s390/cio/qdio_thinint.c
31 ===================================================================
32 --- linux-sles11.orig/drivers/s390/cio/qdio_thinint.c
33 +++ linux-sles11/drivers/s390/cio/qdio_thinint.c
34 @@ -31,6 +31,7 @@
35
36 /* list of thin interrupt input queues */
37 static LIST_HEAD(tiq_list);
38 +DEFINE_MUTEX(tiq_list_lock);
39
40 /* adapter local summary indicator */
41 static unsigned char *tiqdio_alsi;
42 @@ -95,10 +96,10 @@ void tiqdio_add_input_queues(struct qdio
43 if (!css_qdio_omit_svs && irq_ptr->siga_flag.sync)
44 css_qdio_omit_svs = 1;
45
46 - for_each_input_queue(irq_ptr, q, i) {
47 + mutex_lock(&tiq_list_lock);
48 + for_each_input_queue(irq_ptr, q, i)
49 list_add_rcu(&q->entry, &tiq_list);
50 - synchronize_rcu();
51 - }
52 + mutex_unlock(&tiq_list_lock);
53 xchg(irq_ptr->dsci, 1);
54 tasklet_schedule(&tiqdio_tasklet);
55 }
56 @@ -118,7 +119,10 @@ void tiqdio_remove_input_queues(struct q
57 /* if establish triggered an error */
58 if (!q || !q->entry.prev || !q->entry.next)
59 continue;
60 +
61 + mutex_lock(&tiq_list_lock);
62 list_del_rcu(&q->entry);
63 + mutex_unlock(&tiq_list_lock);
64 synchronize_rcu();
65 }
66 }