summaryrefslogtreecommitdiff
path: root/drivers/s390
diff options
context:
space:
mode:
authorJan Glauber <jang@linux.vnet.ibm.com>2011-01-05 11:47:50 (GMT)
committerMartin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com>2011-01-05 11:47:28 (GMT)
commit3d6c76ff32bb9b2ebf6e859855d315eb42e3df50 (patch)
tree3a69d4f3023e75fee0bc55ba38ca7a54a8e4760c /drivers/s390
parent4f325184f2d4c1f2258873b2a333005dc4dfcbc0 (diff)
downloadlinux-fsl-qoriq-3d6c76ff32bb9b2ebf6e859855d315eb42e3df50.tar.xz
[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>
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/cio/qdio.h2
-rw-r--r--drivers/s390/cio/qdio_main.c8
-rw-r--r--drivers/s390/cio/qdio_setup.c1
-rw-r--r--drivers/s390/net/qeth_core_main.c2
-rw-r--r--drivers/s390/scsi/zfcp_qdio.c2
5 files changed, 14 insertions, 1 deletions
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h
index 9b6ea3c..a77aa91 100644
--- a/drivers/s390/cio/qdio.h
+++ b/drivers/s390/cio/qdio.h
@@ -249,6 +249,8 @@ struct qdio_output_q {
int use_enh_siga;
/* timer to check for more outbound work */
struct timer_list timer;
+ /* used SBALs before tasklet schedule */
+ int scan_threshold;
};
/*
diff --git a/drivers/s390/cio/qdio_main.c b/drivers/s390/cio/qdio_main.c
index 6621de9..4c01099 100644
--- a/drivers/s390/cio/qdio_main.c
+++ b/drivers/s390/cio/qdio_main.c
@@ -1492,7 +1492,13 @@ static int handle_outbound(struct qdio_q *q, unsigned int callflags,
qperf_inc(q, fast_requeue);
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;
}
diff --git a/drivers/s390/cio/qdio_setup.c b/drivers/s390/cio/qdio_setup.c
index a13cf7e..635f35d 100644
--- a/drivers/s390/cio/qdio_setup.c
+++ b/drivers/s390/cio/qdio_setup.c
@@ -178,6 +178,7 @@ static void setup_queues(struct qdio_irq *irq_ptr,
setup_queues_misc(q, irq_ptr, qdio_init->output_handler, i);
q->is_input_q = 0;
+ q->u.out.scan_threshold = qdio_init->scan_threshold;
setup_storage_lists(q, irq_ptr, output_sbal_array, i);
output_sbal_array += QDIO_MAX_BUFFERS_PER_Q;
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index e6b2df0..f65320b 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -3831,6 +3831,8 @@ static int qeth_qdio_establish(struct qeth_card *card)
init_data.int_parm = (unsigned long) card;
init_data.input_sbal_addr_array = (void **) in_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,
QETH_QDIO_ESTABLISHED) == QETH_QDIO_ALLOCATED) {
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c
index a0554be..5ae40ef 100644
--- a/drivers/s390/scsi/zfcp_qdio.c
+++ b/drivers/s390/scsi/zfcp_qdio.c
@@ -292,6 +292,8 @@ static void zfcp_qdio_setup_init_data(struct qdio_initialize *id,
id->int_parm = (unsigned long) qdio;
id->input_sbal_addr_array = (void **) (qdio->res_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;
}
/**