mirror of
https://github.com/adulau/aha.git
synced 2024-12-28 19:56:18 +00:00
[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: Jan Glauber <jang@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
parent
36e3e72120
commit
cf9a031c2c
1 changed files with 21 additions and 44 deletions
|
@ -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)
|
||||||
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)
|
||||||
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 @@ again:
|
||||||
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)
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue