diff options
Diffstat (limited to 'drivers/s390')
-rw-r--r-- | drivers/s390/scsi/zfcp_aux.c | 1 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_def.h | 3 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_qdio.c | 20 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_sysfs.c | 3 |
4 files changed, 26 insertions, 1 deletions
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c index 497986f6d643..969a3f093037 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 56302a1a4b68..a0cd4b080175 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 33e0a206a0a4..3d0687090274 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 */ | ||
81 | static 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 | |||
80 | static void zfcp_qdio_int_req(struct ccw_device *cdev, unsigned int qdio_err, | 97 | static 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 899af2b45b1e..9e9931af1b5d 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 | } |
492 | static DEVICE_ATTR(queue_full, S_IRUGO, zfcp_sysfs_adapter_q_full_show, NULL); | 493 | static DEVICE_ATTR(queue_full, S_IRUGO, zfcp_sysfs_adapter_q_full_show, NULL); |
493 | 494 | ||