aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Peschke <mpeschke@linux.vnet.ibm.com>2009-03-02 07:08:56 -0500
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2009-03-12 13:58:18 -0400
commit94506fd1483b39cd5d66b8ccb4ead3c9cc9542ac (patch)
treebb4cc68021eb831b3cab561810a19bdc24993586
parent86f8a1b4b472e4b2b58df5826709d4797d84d46f (diff)
[SCSI] zfcp: add measurement data for average qdio queue utilisation
Provide measurement data for the utilisation of the QDIO outbound queue. The additional value allows to calculate an average queue utilisation by looking at the deltas per time unit. Needed for capacity planning. It is up to user space to handle wrap-arounds of the 64 bit value. The new counter neatly complements the existing counter for queue full conditions. That is why, both statistics counter have been integrated. Signed-off-by: Martin Peschke <mpeschke@linux.vnet.ibm.com> Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
-rw-r--r--drivers/s390/scsi/zfcp_aux.c1
-rw-r--r--drivers/s390/scsi/zfcp_def.h3
-rw-r--r--drivers/s390/scsi/zfcp_qdio.c20
-rw-r--r--drivers/s390/scsi/zfcp_sysfs.c3
4 files changed, 26 insertions, 1 deletions
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index 497986f6d64..969a3f09303 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -501,6 +501,7 @@ int zfcp_adapter_enqueue(struct ccw_device *ccw_device)
501 spin_lock_init(&adapter->scsi_dbf_lock); 501 spin_lock_init(&adapter->scsi_dbf_lock);
502 spin_lock_init(&adapter->rec_dbf_lock); 502 spin_lock_init(&adapter->rec_dbf_lock);
503 spin_lock_init(&adapter->req_q_lock); 503 spin_lock_init(&adapter->req_q_lock);
504 spin_lock_init(&adapter->qdio_stat_lock);
504 505
505 rwlock_init(&adapter->erp_lock); 506 rwlock_init(&adapter->erp_lock);
506 rwlock_init(&adapter->abort_lock); 507 rwlock_init(&adapter->abort_lock);
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h
index 56302a1a4b6..a0cd4b08017 100644
--- a/drivers/s390/scsi/zfcp_def.h
+++ b/drivers/s390/scsi/zfcp_def.h
@@ -445,6 +445,9 @@ struct zfcp_adapter {
445 spinlock_t req_q_lock; /* for operations on queue */ 445 spinlock_t req_q_lock; /* for operations on queue */
446 int req_q_pci_batch; /* SBALs since PCI indication 446 int req_q_pci_batch; /* SBALs since PCI indication
447 was last set */ 447 was last set */
448 ktime_t req_q_time; /* time of last fill level change */
449 u64 req_q_util; /* for accounting */
450 spinlock_t qdio_stat_lock;
448 u32 fsf_req_seq_no; /* FSF cmnd seq number */ 451 u32 fsf_req_seq_no; /* FSF cmnd seq number */
449 wait_queue_head_t request_wq; /* can be used to wait for 452 wait_queue_head_t request_wq; /* can be used to wait for
450 more avaliable SBALs */ 453 more avaliable SBALs */
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c
index 33e0a206a0a..3d068709027 100644
--- a/drivers/s390/scsi/zfcp_qdio.c
+++ b/drivers/s390/scsi/zfcp_qdio.c
@@ -77,6 +77,23 @@ static void zfcp_qdio_zero_sbals(struct qdio_buffer *sbal[], int first, int cnt)
77 } 77 }
78} 78}
79 79
80/* this needs to be called prior to updating the queue fill level */
81static void zfcp_qdio_account(struct zfcp_adapter *adapter)
82{
83 ktime_t now;
84 s64 span;
85 int free, used;
86
87 spin_lock(&adapter->qdio_stat_lock);
88 now = ktime_get();
89 span = ktime_us_delta(now, adapter->req_q_time);
90 free = max(0, atomic_read(&adapter->req_q.count));
91 used = QDIO_MAX_BUFFERS_PER_Q - free;
92 adapter->req_q_util += used * span;
93 adapter->req_q_time = now;
94 spin_unlock(&adapter->qdio_stat_lock);
95}
96
80static void zfcp_qdio_int_req(struct ccw_device *cdev, unsigned int qdio_err, 97static void zfcp_qdio_int_req(struct ccw_device *cdev, unsigned int qdio_err,
81 int queue_no, int first, int count, 98 int queue_no, int first, int count,
82 unsigned long parm) 99 unsigned long parm)
@@ -93,6 +110,7 @@ static void zfcp_qdio_int_req(struct ccw_device *cdev, unsigned int qdio_err,
93 /* cleanup all SBALs being program-owned now */ 110 /* cleanup all SBALs being program-owned now */
94 zfcp_qdio_zero_sbals(queue->sbal, first, count); 111 zfcp_qdio_zero_sbals(queue->sbal, first, count);
95 112
113 zfcp_qdio_account(adapter);
96 atomic_add(count, &queue->count); 114 atomic_add(count, &queue->count);
97 wake_up(&adapter->request_wq); 115 wake_up(&adapter->request_wq);
98} 116}
@@ -359,6 +377,8 @@ int zfcp_qdio_send(struct zfcp_fsf_req *fsf_req)
359 sbale->flags |= SBAL_FLAGS0_PCI; 377 sbale->flags |= SBAL_FLAGS0_PCI;
360 } 378 }
361 379
380 zfcp_qdio_account(adapter);
381
362 retval = do_QDIO(adapter->ccw_device, QDIO_FLAG_SYNC_OUTPUT, 0, first, 382 retval = do_QDIO(adapter->ccw_device, QDIO_FLAG_SYNC_OUTPUT, 0, first,
363 count); 383 count);
364 if (unlikely(retval)) { 384 if (unlikely(retval)) {
diff --git a/drivers/s390/scsi/zfcp_sysfs.c b/drivers/s390/scsi/zfcp_sysfs.c
index 899af2b45b1..9e9931af1b5 100644
--- a/drivers/s390/scsi/zfcp_sysfs.c
+++ b/drivers/s390/scsi/zfcp_sysfs.c
@@ -487,7 +487,8 @@ static ssize_t zfcp_sysfs_adapter_q_full_show(struct device *dev,
487 struct zfcp_adapter *adapter = 487 struct zfcp_adapter *adapter =
488 (struct zfcp_adapter *) scsi_host->hostdata[0]; 488 (struct zfcp_adapter *) scsi_host->hostdata[0];
489 489
490 return sprintf(buf, "%d\n", atomic_read(&adapter->qdio_outb_full)); 490 return sprintf(buf, "%d %llu\n", atomic_read(&adapter->qdio_outb_full),
491 (unsigned long long)adapter->req_q_util);
491} 492}
492static DEVICE_ATTR(queue_full, S_IRUGO, zfcp_sysfs_adapter_q_full_show, NULL); 493static DEVICE_ATTR(queue_full, S_IRUGO, zfcp_sysfs_adapter_q_full_show, NULL);
493 494