aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Glauber <jang@linux.vnet.ibm.com>2009-03-26 10:24:24 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2009-03-26 10:24:19 -0400
commitb454740246d14b0a9c00220696f9020eaa15ca12 (patch)
tree8d0deb7de94992548aae364ef39f34c4c67cf096
parentfeed9b62da6e2997612143ae4b857ec7f33c810d (diff)
[S390] qdio: add missing tiq_list locking
Add a mutex to protect the tiq_list. Although reading the list is done using RCU adding and removing elements from the list must still happen locked since multiple qdio devices may change the list in parallel otherwise. Signed-off-by: Jan Glauber <jang@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r--drivers/s390/cio/qdio_main.c1
-rw-r--r--drivers/s390/cio/qdio_thinint.c10
2 files changed, 8 insertions, 3 deletions
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index 10cb0f8726e5..5100996201d1 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -1112,6 +1112,7 @@ int qdio_shutdown(struct ccw_device *cdev, int how)
1112 if (!irq_ptr) 1112 if (!irq_ptr)
1113 return -ENODEV; 1113 return -ENODEV;
1114 1114
1115 BUG_ON(irqs_disabled());
1115 DBF_EVENT("qshutdown:%4x", cdev->private->schid.sch_no); 1116 DBF_EVENT("qshutdown:%4x", cdev->private->schid.sch_no);
1116 1117
1117 mutex_lock(&irq_ptr->setup_mutex); 1118 mutex_lock(&irq_ptr->setup_mutex);
diff --git a/drivers/s390/cio/qdio_thinint.c b/drivers/s390/cio/qdio_thinint.c
index 8e90e147b746..981044c83864 100644
--- a/drivers/s390/cio/qdio_thinint.c
+++ b/drivers/s390/cio/qdio_thinint.c
@@ -31,6 +31,7 @@
31 31
32/* list of thin interrupt input queues */ 32/* list of thin interrupt input queues */
33static LIST_HEAD(tiq_list); 33static LIST_HEAD(tiq_list);
34DEFINE_MUTEX(tiq_list_lock);
34 35
35/* adapter local summary indicator */ 36/* adapter local summary indicator */
36static unsigned char *tiqdio_alsi; 37static unsigned char *tiqdio_alsi;
@@ -95,10 +96,10 @@ void tiqdio_add_input_queues(struct qdio_irq *irq_ptr)
95 if (!css_qdio_omit_svs && irq_ptr->siga_flag.sync) 96 if (!css_qdio_omit_svs && irq_ptr->siga_flag.sync)
96 css_qdio_omit_svs = 1; 97 css_qdio_omit_svs = 1;
97 98
98 for_each_input_queue(irq_ptr, q, i) { 99 mutex_lock(&tiq_list_lock);
100 for_each_input_queue(irq_ptr, q, i)
99 list_add_rcu(&q->entry, &tiq_list); 101 list_add_rcu(&q->entry, &tiq_list);
100 synchronize_rcu(); 102 mutex_unlock(&tiq_list_lock);
101 }
102 xchg(irq_ptr->dsci, 1); 103 xchg(irq_ptr->dsci, 1);
103 tasklet_schedule(&tiqdio_tasklet); 104 tasklet_schedule(&tiqdio_tasklet);
104} 105}
@@ -118,7 +119,10 @@ void tiqdio_remove_input_queues(struct qdio_irq *irq_ptr)
118 /* if establish triggered an error */ 119 /* if establish triggered an error */
119 if (!q || !q->entry.prev || !q->entry.next) 120 if (!q || !q->entry.prev || !q->entry.next)
120 continue; 121 continue;
122
123 mutex_lock(&tiq_list_lock);
121 list_del_rcu(&q->entry); 124 list_del_rcu(&q->entry);
125 mutex_unlock(&tiq_list_lock);
122 synchronize_rcu(); 126 synchronize_rcu();
123 } 127 }
124} 128}