Commit cf9a031c authored by Jan Glauber's avatar Jan Glauber Committed by Martin Schwidefsky

[S390] qdio: merge AI tasklet into interrupt handler

Since the adapter interrupt tasklet only schedules the queue tasklets
and contains no code that requires serialization in can be merged
with the adapter interrupt handler. That possibly safes some CPU
cycles.
Signed-off-by: default avatarJan Glauber <jang@linux.vnet.ibm.com>
Signed-off-by: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent 36e3e721
...@@ -43,9 +43,6 @@ struct indicator_t { ...@@ -43,9 +43,6 @@ struct indicator_t {
}; };
static struct indicator_t *q_indicators; static struct indicator_t *q_indicators;
static void tiqdio_tasklet_fn(unsigned long data);
static DECLARE_TASKLET(tiqdio_tasklet, tiqdio_tasklet_fn, 0);
static int css_qdio_omit_svs; static int css_qdio_omit_svs;
static inline unsigned long do_clear_global_summary(void) static inline unsigned long do_clear_global_summary(void)
...@@ -103,11 +100,6 @@ void tiqdio_add_input_queues(struct qdio_irq *irq_ptr) ...@@ -103,11 +100,6 @@ void tiqdio_add_input_queues(struct qdio_irq *irq_ptr)
xchg(irq_ptr->dsci, 1); xchg(irq_ptr->dsci, 1);
} }
/*
* we cannot stop the tiqdio tasklet here since it is for all
* thinint qdio devices and it must run as long as there is a
* thinint device left
*/
void tiqdio_remove_input_queues(struct qdio_irq *irq_ptr) void tiqdio_remove_input_queues(struct qdio_irq *irq_ptr)
{ {
struct qdio_q *q; struct qdio_q *q;
...@@ -131,17 +123,34 @@ static inline int shared_ind(struct qdio_irq *irq_ptr) ...@@ -131,17 +123,34 @@ static inline int shared_ind(struct qdio_irq *irq_ptr)
return irq_ptr->dsci == &q_indicators[TIQDIO_SHARED_IND].ind; return irq_ptr->dsci == &q_indicators[TIQDIO_SHARED_IND].ind;
} }
/* check for work on all inbound thinint queues */ /**
static void tiqdio_tasklet_fn(unsigned long data) * tiqdio_thinint_handler - thin interrupt handler for qdio
* @ind: pointer to adapter local summary indicator
* @drv_data: NULL
*/
static void tiqdio_thinint_handler(void *ind, void *drv_data)
{ {
struct qdio_q *q; struct qdio_q *q;
qdio_perf_stat_inc(&perf_stats.tasklet_thinint); qdio_perf_stat_inc(&perf_stats.thin_int);
again:
/*
* SVS only when needed: issue SVS to benefit from iqdio interrupt
* avoidance (SVS clears adapter interrupt suppression overwrite)
*/
if (!css_qdio_omit_svs)
do_clear_global_summary();
/*
* reset local summary indicator (tiqdio_alsi) to stop adapter
* interrupts for now
*/
xchg((u8 *)ind, 0);
/* protect tiq_list entries, only changed in activate or shutdown */ /* protect tiq_list entries, only changed in activate or shutdown */
rcu_read_lock(); rcu_read_lock();
/* check for work on all inbound thinint queues */
list_for_each_entry_rcu(q, &tiq_list, entry) list_for_each_entry_rcu(q, &tiq_list, entry)
/* only process queues from changed sets */ /* only process queues from changed sets */
if (*q->irq_ptr->dsci) { if (*q->irq_ptr->dsci) {
...@@ -169,37 +178,6 @@ static void tiqdio_tasklet_fn(unsigned long data) ...@@ -169,37 +178,6 @@ static void tiqdio_tasklet_fn(unsigned long data)
if (*tiqdio_alsi) if (*tiqdio_alsi)
xchg(&q_indicators[TIQDIO_SHARED_IND].ind, 1); xchg(&q_indicators[TIQDIO_SHARED_IND].ind, 1);
} }
/* check for more work */
if (*tiqdio_alsi) {
xchg(tiqdio_alsi, 0);
qdio_perf_stat_inc(&perf_stats.tasklet_thinint_loop);
goto again;
}
}
/**
* tiqdio_thinint_handler - thin interrupt handler for qdio
* @ind: pointer to adapter local summary indicator
* @drv_data: NULL
*/
static void tiqdio_thinint_handler(void *ind, void *drv_data)
{
qdio_perf_stat_inc(&perf_stats.thin_int);
/*
* SVS only when needed: issue SVS to benefit from iqdio interrupt
* avoidance (SVS clears adapter interrupt suppression overwrite)
*/
if (!css_qdio_omit_svs)
do_clear_global_summary();
/*
* reset local summary indicator (tiqdio_alsi) to stop adapter
* interrupts for now, the tasklet will clean all dsci's
*/
xchg((u8 *)ind, 0);
tasklet_hi_schedule(&tiqdio_tasklet);
} }
static int set_subchannel_ind(struct qdio_irq *irq_ptr, int reset) static int set_subchannel_ind(struct qdio_irq *irq_ptr, int reset)
...@@ -319,5 +297,4 @@ void __exit tiqdio_unregister_thinints(void) ...@@ -319,5 +297,4 @@ void __exit tiqdio_unregister_thinints(void)
s390_unregister_adapter_interrupt(tiqdio_alsi, QDIO_AIRQ_ISC); s390_unregister_adapter_interrupt(tiqdio_alsi, QDIO_AIRQ_ISC);
isc_unregister(QDIO_AIRQ_ISC); isc_unregister(QDIO_AIRQ_ISC);
} }
tasklet_kill(&tiqdio_tasklet);
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment