[SCSI] zfcp: add measurement data for average qdio queue utilisation
[linux-2.6.git] / drivers / s390 / scsi / zfcp_qdio.c
index 33e0a20..3d06870 100644 (file)
@@ -77,6 +77,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)
@@ -93,6 +110,7 @@ static void zfcp_qdio_int_req(struct ccw_device *cdev, unsigned int qdio_err,
        /* 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);
 }
@@ -359,6 +377,8 @@ int zfcp_qdio_send(struct zfcp_fsf_req *fsf_req)
                sbale->flags |= SBAL_FLAGS0_PCI;
        }
 
+       zfcp_qdio_account(adapter);
+
        retval = do_QDIO(adapter->ccw_device, QDIO_FLAG_SYNC_OUTPUT, 0, first,
                         count);
        if (unlikely(retval)) {