diff options
Diffstat (limited to 'drivers/s390/scsi/zfcp_qdio.c')
-rw-r--r-- | drivers/s390/scsi/zfcp_qdio.c | 47 |
1 files changed, 25 insertions, 22 deletions
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c index 33e0a206a0a4..e0a215309df0 100644 --- a/drivers/s390/scsi/zfcp_qdio.c +++ b/drivers/s390/scsi/zfcp_qdio.c @@ -11,9 +11,6 @@ #include "zfcp_ext.h" -/* FIXME(tune): free space should be one max. SBAL chain plus what? */ -#define ZFCP_QDIO_PCI_INTERVAL (QDIO_MAX_BUFFERS_PER_Q \ - - (FSF_MAX_SBALS_PER_REQ + 4)) #define QBUFF_PER_PAGE (PAGE_SIZE / sizeof(struct qdio_buffer)) static int zfcp_qdio_buffers_enqueue(struct qdio_buffer **sbal) @@ -58,7 +55,7 @@ void zfcp_qdio_free(struct zfcp_adapter *adapter) } } -static void zfcp_qdio_handler_error(struct zfcp_adapter *adapter, u8 id) +static void zfcp_qdio_handler_error(struct zfcp_adapter *adapter, char *id) { dev_warn(&adapter->ccw_device->dev, "A QDIO problem occurred\n"); @@ -77,6 +74,23 @@ static void zfcp_qdio_zero_sbals(struct qdio_buffer *sbal[], int first, int cnt) } } +/* this needs to be called prior to updating the queue fill level */ +static void zfcp_qdio_account(struct zfcp_adapter *adapter) +{ + ktime_t now; + s64 span; + int free, used; + + spin_lock(&adapter->qdio_stat_lock); + now = ktime_get(); + span = ktime_us_delta(now, adapter->req_q_time); + free = max(0, atomic_read(&adapter->req_q.count)); + used = QDIO_MAX_BUFFERS_PER_Q - free; + adapter->req_q_util += used * span; + adapter->req_q_time = now; + spin_unlock(&adapter->qdio_stat_lock); +} + static void zfcp_qdio_int_req(struct ccw_device *cdev, unsigned int qdio_err, int queue_no, int first, int count, unsigned long parm) @@ -86,13 +100,14 @@ static void zfcp_qdio_int_req(struct ccw_device *cdev, unsigned int qdio_err, if (unlikely(qdio_err)) { zfcp_hba_dbf_event_qdio(adapter, qdio_err, first, count); - zfcp_qdio_handler_error(adapter, 140); + zfcp_qdio_handler_error(adapter, "qdireq1"); return; } /* cleanup all SBALs being program-owned now */ zfcp_qdio_zero_sbals(queue->sbal, first, count); + zfcp_qdio_account(adapter); atomic_add(count, &queue->count); wake_up(&adapter->request_wq); } @@ -154,7 +169,7 @@ static void zfcp_qdio_int_resp(struct ccw_device *cdev, unsigned int qdio_err, if (unlikely(qdio_err)) { zfcp_hba_dbf_event_qdio(adapter, qdio_err, first, count); - zfcp_qdio_handler_error(adapter, 147); + zfcp_qdio_handler_error(adapter, "qdires1"); return; } @@ -346,21 +361,12 @@ int zfcp_qdio_send(struct zfcp_fsf_req *fsf_req) struct zfcp_qdio_queue *req_q = &adapter->req_q; int first = fsf_req->sbal_first; int count = fsf_req->sbal_number; - int retval, pci, pci_batch; - struct qdio_buffer_element *sbale; + int retval; + unsigned int qdio_flags = QDIO_FLAG_SYNC_OUTPUT; - /* acknowledgements for transferred buffers */ - pci_batch = adapter->req_q_pci_batch + count; - if (unlikely(pci_batch >= ZFCP_QDIO_PCI_INTERVAL)) { - pci_batch %= ZFCP_QDIO_PCI_INTERVAL; - pci = first + count - (pci_batch + 1); - pci %= QDIO_MAX_BUFFERS_PER_Q; - sbale = zfcp_qdio_sbale(req_q, pci, 0); - sbale->flags |= SBAL_FLAGS0_PCI; - } + zfcp_qdio_account(adapter); - retval = do_QDIO(adapter->ccw_device, QDIO_FLAG_SYNC_OUTPUT, 0, first, - count); + retval = do_QDIO(adapter->ccw_device, qdio_flags, 0, first, count); if (unlikely(retval)) { zfcp_qdio_zero_sbals(req_q->sbal, first, count); return retval; @@ -370,7 +376,6 @@ int zfcp_qdio_send(struct zfcp_fsf_req *fsf_req) atomic_sub(count, &req_q->count); req_q->first += count; req_q->first %= QDIO_MAX_BUFFERS_PER_Q; - adapter->req_q_pci_batch = pci_batch; return 0; } @@ -441,7 +446,6 @@ void zfcp_qdio_close(struct zfcp_adapter *adapter) } req_q->first = 0; atomic_set(&req_q->count, 0); - adapter->req_q_pci_batch = 0; adapter->resp_q.first = 0; atomic_set(&adapter->resp_q.count, 0); } @@ -479,7 +483,6 @@ int zfcp_qdio_open(struct zfcp_adapter *adapter) /* set index of first avalable SBALS / number of available SBALS */ adapter->req_q.first = 0; atomic_set(&adapter->req_q.count, QDIO_MAX_BUFFERS_PER_Q); - adapter->req_q_pci_batch = 0; return 0; |