aboutsummaryrefslogtreecommitdiff
path: root/drivers/s390/cio/qdio_thinint.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-03-26 16:04:22 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2009-03-26 16:04:22 -0700
commit21cdbc1378e8aa96e1ed4a606dce1a8e7daf7fdf (patch)
tree55b6c294b912ccdc3eede15960b0ece53a69d902 /drivers/s390/cio/qdio_thinint.c
parent86d9c070175de65890794fa227b68297da6206d8 (diff)
parentef3500b2b2955af4fa6b0564b51c0c604e38c571 (diff)
Merge branch 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6
* 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6: (81 commits) [S390] remove duplicated #includes [S390] cpumask: use mm_cpumask() wrapper [S390] cpumask: Use accessors code. [S390] cpumask: prepare for iterators to only go to nr_cpu_ids/nr_cpumask_bits. [S390] cpumask: remove cpu_coregroup_map [S390] fix clock comparator save area usage [S390] Add hwcap flag for the etf3 enhancement facility [S390] Ensure that ipl panic notifier is called late. [S390] fix dfp elf hwcap/facility bit detection [S390] smp: perform initial cpu reset before starting a cpu [S390] smp: fix memory leak on __cpu_up [S390] ipl: Improve checking logic and remove switch defaults. [S390] s390dbf: Remove needless check for NULL pointer. [S390] s390dbf: Remove redundant initilizations. [S390] use kzfree() [S390] BUG to BUG_ON changes [S390] zfcpdump: Prevent zcore from beeing built as a kernel module. [S390] Use csum_partial in checksum.h [S390] cleanup lowcore.h [S390] eliminate ipl_device from lowcore ...
Diffstat (limited to 'drivers/s390/cio/qdio_thinint.c')
-rw-r--r--drivers/s390/cio/qdio_thinint.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/drivers/s390/cio/qdio_thinint.c b/drivers/s390/cio/qdio_thinint.c
index 8e90e147b74..c655d011a78 100644
--- a/drivers/s390/cio/qdio_thinint.c
+++ b/drivers/s390/cio/qdio_thinint.c
@@ -31,6 +31,7 @@
/* list of thin interrupt input queues */
static LIST_HEAD(tiq_list);
+DEFINE_MUTEX(tiq_list_lock);
/* adapter local summary indicator */
static unsigned char *tiqdio_alsi;
@@ -95,12 +96,11 @@ void tiqdio_add_input_queues(struct qdio_irq *irq_ptr)
if (!css_qdio_omit_svs && irq_ptr->siga_flag.sync)
css_qdio_omit_svs = 1;
- for_each_input_queue(irq_ptr, q, i) {
+ mutex_lock(&tiq_list_lock);
+ for_each_input_queue(irq_ptr, q, i)
list_add_rcu(&q->entry, &tiq_list);
- synchronize_rcu();
- }
+ mutex_unlock(&tiq_list_lock);
xchg(irq_ptr->dsci, 1);
- tasklet_schedule(&tiqdio_tasklet);
}
/*
@@ -118,7 +118,10 @@ void tiqdio_remove_input_queues(struct qdio_irq *irq_ptr)
/* if establish triggered an error */
if (!q || !q->entry.prev || !q->entry.next)
continue;
+
+ mutex_lock(&tiq_list_lock);
list_del_rcu(&q->entry);
+ mutex_unlock(&tiq_list_lock);
synchronize_rcu();
}
}
@@ -155,15 +158,15 @@ static void __tiqdio_inbound_processing(struct qdio_q *q)
*/
qdio_check_outbound_after_thinint(q);
-again:
if (!qdio_inbound_q_moved(q))
return;
- qdio_kick_inbound_handler(q);
+ qdio_kick_handler(q);
if (!tiqdio_inbound_q_done(q)) {
qdio_perf_stat_inc(&perf_stats.thinint_inbound_loop);
- goto again;
+ if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED))
+ tasklet_schedule(&q->tasklet);
}
qdio_stop_polling(q);
@@ -173,7 +176,8 @@ again:
*/
if (!tiqdio_inbound_q_done(q)) {
qdio_perf_stat_inc(&perf_stats.thinint_inbound_loop2);
- goto again;
+ if (likely(q->irq_ptr->state != QDIO_IRQ_STATE_STOPPED))
+ tasklet_schedule(&q->tasklet);
}
}
@@ -366,10 +370,11 @@ void qdio_shutdown_thinint(struct qdio_irq *irq_ptr)
void __exit tiqdio_unregister_thinints(void)
{
- tasklet_disable(&tiqdio_tasklet);
+ WARN_ON(!list_empty(&tiq_list));
if (tiqdio_alsi) {
s390_unregister_adapter_interrupt(tiqdio_alsi, QDIO_AIRQ_ISC);
isc_unregister(QDIO_AIRQ_ISC);
}
+ tasklet_kill(&tiqdio_tasklet);
}