[S390] qdio: outbound tasklet scan threshold
Introduce a scan treshold for the qdio outbound queues. By setting the threshold the driver can tell qdio after how much used SBALs qdio should schedule the outbound tasklet that scans the queue for finished SBALs. The threshold is specific by the drivers because a Hipersockets device is much faster in utilizing outbound buffers than a ZFCP or OSA device. The default values after how many used SBALs the tasklet should run are: OSA: > 31 SBALs Hipersockets: > 7 SBALs zfcp: > 55 SBALs 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
4f325184f2
commit
3d6c76ff32
6 changed files with 15 additions and 1 deletions
|
@ -361,6 +361,7 @@ struct qdio_initialize {
|
||||||
qdio_handler_t *input_handler;
|
qdio_handler_t *input_handler;
|
||||||
qdio_handler_t *output_handler;
|
qdio_handler_t *output_handler;
|
||||||
void (*queue_start_poll) (struct ccw_device *, int, unsigned long);
|
void (*queue_start_poll) (struct ccw_device *, int, unsigned long);
|
||||||
|
int scan_threshold;
|
||||||
unsigned long int_parm;
|
unsigned long int_parm;
|
||||||
void **input_sbal_addr_array;
|
void **input_sbal_addr_array;
|
||||||
void **output_sbal_addr_array;
|
void **output_sbal_addr_array;
|
||||||
|
|
|
@ -249,6 +249,8 @@ struct qdio_output_q {
|
||||||
int use_enh_siga;
|
int use_enh_siga;
|
||||||
/* timer to check for more outbound work */
|
/* timer to check for more outbound work */
|
||||||
struct timer_list timer;
|
struct timer_list timer;
|
||||||
|
/* used SBALs before tasklet schedule */
|
||||||
|
int scan_threshold;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -1492,7 +1492,13 @@ static int handle_outbound(struct qdio_q *q, unsigned int callflags,
|
||||||
qperf_inc(q, fast_requeue);
|
qperf_inc(q, fast_requeue);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
tasklet_schedule(&q->tasklet);
|
/* in case of SIGA errors we must process the error immediately */
|
||||||
|
if (used >= q->u.out.scan_threshold || rc)
|
||||||
|
tasklet_schedule(&q->tasklet);
|
||||||
|
else
|
||||||
|
/* free the SBALs in case of no further traffic */
|
||||||
|
if (!timer_pending(&q->u.out.timer))
|
||||||
|
mod_timer(&q->u.out.timer, jiffies + HZ);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -178,6 +178,7 @@ static void setup_queues(struct qdio_irq *irq_ptr,
|
||||||
setup_queues_misc(q, irq_ptr, qdio_init->output_handler, i);
|
setup_queues_misc(q, irq_ptr, qdio_init->output_handler, i);
|
||||||
|
|
||||||
q->is_input_q = 0;
|
q->is_input_q = 0;
|
||||||
|
q->u.out.scan_threshold = qdio_init->scan_threshold;
|
||||||
setup_storage_lists(q, irq_ptr, output_sbal_array, i);
|
setup_storage_lists(q, irq_ptr, output_sbal_array, i);
|
||||||
output_sbal_array += QDIO_MAX_BUFFERS_PER_Q;
|
output_sbal_array += QDIO_MAX_BUFFERS_PER_Q;
|
||||||
|
|
||||||
|
|
|
@ -3831,6 +3831,8 @@ static int qeth_qdio_establish(struct qeth_card *card)
|
||||||
init_data.int_parm = (unsigned long) card;
|
init_data.int_parm = (unsigned long) card;
|
||||||
init_data.input_sbal_addr_array = (void **) in_sbal_ptrs;
|
init_data.input_sbal_addr_array = (void **) in_sbal_ptrs;
|
||||||
init_data.output_sbal_addr_array = (void **) out_sbal_ptrs;
|
init_data.output_sbal_addr_array = (void **) out_sbal_ptrs;
|
||||||
|
init_data.scan_threshold =
|
||||||
|
(card->info.type == QETH_CARD_TYPE_IQD) ? 8 : 32;
|
||||||
|
|
||||||
if (atomic_cmpxchg(&card->qdio.state, QETH_QDIO_ALLOCATED,
|
if (atomic_cmpxchg(&card->qdio.state, QETH_QDIO_ALLOCATED,
|
||||||
QETH_QDIO_ESTABLISHED) == QETH_QDIO_ALLOCATED) {
|
QETH_QDIO_ESTABLISHED) == QETH_QDIO_ALLOCATED) {
|
||||||
|
|
|
@ -292,6 +292,8 @@ static void zfcp_qdio_setup_init_data(struct qdio_initialize *id,
|
||||||
id->int_parm = (unsigned long) qdio;
|
id->int_parm = (unsigned long) qdio;
|
||||||
id->input_sbal_addr_array = (void **) (qdio->res_q);
|
id->input_sbal_addr_array = (void **) (qdio->res_q);
|
||||||
id->output_sbal_addr_array = (void **) (qdio->req_q);
|
id->output_sbal_addr_array = (void **) (qdio->req_q);
|
||||||
|
id->scan_threshold =
|
||||||
|
QDIO_MAX_BUFFERS_PER_Q - ZFCP_QDIO_MAX_SBALS_PER_REQ * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Reference in a new issue