diff options
author | Stefan Raspl <raspl@linux.vnet.ibm.com> | 2008-10-01 06:42:14 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-10-03 13:11:52 -0400 |
commit | 2450d3e7b8604d0abb042817f2502cb7ee0b782f (patch) | |
tree | b7f319f299fd0ec62e9d6840158c070d9bce0df7 /drivers/s390/scsi | |
parent | 7ae628d9d21a088b4a2d26a9d39c29c0acd2d03b (diff) |
[SCSI] zfcp: add queue_full sysfs attribute
Adds a new sysfs attribute queue_full for adapters that records the number
of incidents where a requests could not be submitted due to insufficient
free space on the request queue.
Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com>
Signed-off-by: Martin Peschke <mp3@de.ibm.com>
Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/s390/scsi')
-rw-r--r-- | drivers/s390/scsi/zfcp_def.h | 1 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_fsf.c | 24 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_qdio.c | 1 | ||||
-rw-r--r-- | drivers/s390/scsi/zfcp_sysfs.c | 13 |
4 files changed, 32 insertions, 7 deletions
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index 67f45fc62f53..74d7529621bb 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h | |||
@@ -568,6 +568,7 @@ struct zfcp_adapter { | |||
568 | struct fsf_qtcb_bottom_port *stats_reset_data; | 568 | struct fsf_qtcb_bottom_port *stats_reset_data; |
569 | unsigned long stats_reset; | 569 | unsigned long stats_reset; |
570 | struct work_struct scan_work; | 570 | struct work_struct scan_work; |
571 | atomic_t qdio_outb_full; /* queue full incidents */ | ||
571 | }; | 572 | }; |
572 | 573 | ||
573 | struct zfcp_port { | 574 | struct zfcp_port { |
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 49dbeb754e5f..9e083a5e2c4e 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c | |||
@@ -717,6 +717,14 @@ static int zfcp_fsf_sbal_check(struct zfcp_qdio_queue *queue) | |||
717 | return 0; | 717 | return 0; |
718 | } | 718 | } |
719 | 719 | ||
720 | static int zfcp_fsf_sbal_available(struct zfcp_adapter *adapter) | ||
721 | { | ||
722 | unsigned int count = atomic_read(&adapter->req_q.count); | ||
723 | if (!count) | ||
724 | atomic_inc(&adapter->qdio_outb_full); | ||
725 | return count > 0; | ||
726 | } | ||
727 | |||
720 | static int zfcp_fsf_req_sbal_get(struct zfcp_adapter *adapter) | 728 | static int zfcp_fsf_req_sbal_get(struct zfcp_adapter *adapter) |
721 | { | 729 | { |
722 | long ret; | 730 | long ret; |
@@ -727,6 +735,8 @@ static int zfcp_fsf_req_sbal_get(struct zfcp_adapter *adapter) | |||
727 | zfcp_fsf_sbal_check(req_q), 5 * HZ); | 735 | zfcp_fsf_sbal_check(req_q), 5 * HZ); |
728 | if (ret > 0) | 736 | if (ret > 0) |
729 | return 0; | 737 | return 0; |
738 | if (!ret) | ||
739 | atomic_inc(&adapter->qdio_outb_full); | ||
730 | 740 | ||
731 | spin_lock_bh(&req_q->lock); | 741 | spin_lock_bh(&req_q->lock); |
732 | return -EIO; | 742 | return -EIO; |
@@ -984,7 +994,7 @@ struct zfcp_fsf_req *zfcp_fsf_abort_fcp_command(unsigned long old_req_id, | |||
984 | struct zfcp_fsf_req *req = NULL; | 994 | struct zfcp_fsf_req *req = NULL; |
985 | 995 | ||
986 | spin_lock(&adapter->req_q.lock); | 996 | spin_lock(&adapter->req_q.lock); |
987 | if (!atomic_read(&adapter->req_q.count)) | 997 | if (!zfcp_fsf_sbal_available(adapter)) |
988 | goto out; | 998 | goto out; |
989 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_ABORT_FCP_CMND, | 999 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_ABORT_FCP_CMND, |
990 | req_flags, adapter->pool.fsf_req_abort); | 1000 | req_flags, adapter->pool.fsf_req_abort); |
@@ -1219,7 +1229,7 @@ int zfcp_fsf_send_els(struct zfcp_send_els *els) | |||
1219 | return -EBUSY; | 1229 | return -EBUSY; |
1220 | 1230 | ||
1221 | spin_lock(&adapter->req_q.lock); | 1231 | spin_lock(&adapter->req_q.lock); |
1222 | if (!atomic_read(&adapter->req_q.count)) | 1232 | if (!zfcp_fsf_sbal_available(adapter)) |
1223 | goto out; | 1233 | goto out; |
1224 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_SEND_ELS, | 1234 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_SEND_ELS, |
1225 | ZFCP_REQ_AUTO_CLEANUP, NULL); | 1235 | ZFCP_REQ_AUTO_CLEANUP, NULL); |
@@ -1264,7 +1274,7 @@ int zfcp_fsf_exchange_config_data(struct zfcp_erp_action *erp_action) | |||
1264 | int retval = -EIO; | 1274 | int retval = -EIO; |
1265 | 1275 | ||
1266 | spin_lock_bh(&adapter->req_q.lock); | 1276 | spin_lock_bh(&adapter->req_q.lock); |
1267 | if (!atomic_read(&adapter->req_q.count)) | 1277 | if (!zfcp_fsf_sbal_available(adapter)) |
1268 | goto out; | 1278 | goto out; |
1269 | req = zfcp_fsf_req_create(adapter, | 1279 | req = zfcp_fsf_req_create(adapter, |
1270 | FSF_QTCB_EXCHANGE_CONFIG_DATA, | 1280 | FSF_QTCB_EXCHANGE_CONFIG_DATA, |
@@ -1360,7 +1370,7 @@ int zfcp_fsf_exchange_port_data(struct zfcp_erp_action *erp_action) | |||
1360 | return -EOPNOTSUPP; | 1370 | return -EOPNOTSUPP; |
1361 | 1371 | ||
1362 | spin_lock_bh(&adapter->req_q.lock); | 1372 | spin_lock_bh(&adapter->req_q.lock); |
1363 | if (!atomic_read(&adapter->req_q.count)) | 1373 | if (!zfcp_fsf_sbal_available(adapter)) |
1364 | goto out; | 1374 | goto out; |
1365 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA, | 1375 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA, |
1366 | ZFCP_REQ_AUTO_CLEANUP, | 1376 | ZFCP_REQ_AUTO_CLEANUP, |
@@ -1406,7 +1416,7 @@ int zfcp_fsf_exchange_port_data_sync(struct zfcp_adapter *adapter, | |||
1406 | return -EOPNOTSUPP; | 1416 | return -EOPNOTSUPP; |
1407 | 1417 | ||
1408 | spin_lock_bh(&adapter->req_q.lock); | 1418 | spin_lock_bh(&adapter->req_q.lock); |
1409 | if (!atomic_read(&adapter->req_q.count)) | 1419 | if (!zfcp_fsf_sbal_available(adapter)) |
1410 | goto out; | 1420 | goto out; |
1411 | 1421 | ||
1412 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA, 0, | 1422 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_PORT_DATA, 0, |
@@ -2224,7 +2234,7 @@ int zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter, | |||
2224 | return -EBUSY; | 2234 | return -EBUSY; |
2225 | 2235 | ||
2226 | spin_lock(&adapter->req_q.lock); | 2236 | spin_lock(&adapter->req_q.lock); |
2227 | if (!atomic_read(&adapter->req_q.count)) | 2237 | if (!zfcp_fsf_sbal_available(adapter)) |
2228 | goto out; | 2238 | goto out; |
2229 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, req_flags, | 2239 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, req_flags, |
2230 | adapter->pool.fsf_req_scsi); | 2240 | adapter->pool.fsf_req_scsi); |
@@ -2347,7 +2357,7 @@ struct zfcp_fsf_req *zfcp_fsf_send_fcp_ctm(struct zfcp_adapter *adapter, | |||
2347 | return NULL; | 2357 | return NULL; |
2348 | 2358 | ||
2349 | spin_lock(&adapter->req_q.lock); | 2359 | spin_lock(&adapter->req_q.lock); |
2350 | if (!atomic_read(&adapter->req_q.count)) | 2360 | if (!zfcp_fsf_sbal_available(adapter)) |
2351 | goto out; | 2361 | goto out; |
2352 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, req_flags, | 2362 | req = zfcp_fsf_req_create(adapter, FSF_QTCB_FCP_CMND, req_flags, |
2353 | adapter->pool.fsf_req_scsi); | 2363 | adapter->pool.fsf_req_scsi); |
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c index 69d632d851d9..cc49eaa9281f 100644 --- a/drivers/s390/scsi/zfcp_qdio.c +++ b/drivers/s390/scsi/zfcp_qdio.c | |||
@@ -282,6 +282,7 @@ static int zfcp_qdio_fill_sbals(struct zfcp_fsf_req *fsf_req, | |||
282 | addr += length, remaining -= length) { | 282 | addr += length, remaining -= length) { |
283 | sbale = zfcp_qdio_sbale_next(fsf_req, sbtype); | 283 | sbale = zfcp_qdio_sbale_next(fsf_req, sbtype); |
284 | if (!sbale) { | 284 | if (!sbale) { |
285 | atomic_inc(&fsf_req->adapter->qdio_outb_full); | ||
285 | zfcp_qdio_undo_sbals(fsf_req); | 286 | zfcp_qdio_undo_sbals(fsf_req); |
286 | return -EINVAL; | 287 | return -EINVAL; |
287 | } | 288 | } |
diff --git a/drivers/s390/scsi/zfcp_sysfs.c b/drivers/s390/scsi/zfcp_sysfs.c index 2e85c6c49e7d..7e857571fe44 100644 --- a/drivers/s390/scsi/zfcp_sysfs.c +++ b/drivers/s390/scsi/zfcp_sysfs.c | |||
@@ -487,10 +487,23 @@ ZFCP_SHOST_ATTR(megabytes, "%llu %llu\n", | |||
487 | ZFCP_SHOST_ATTR(seconds_active, "%llu\n", | 487 | ZFCP_SHOST_ATTR(seconds_active, "%llu\n", |
488 | (unsigned long long) stat_info.seconds_act); | 488 | (unsigned long long) stat_info.seconds_act); |
489 | 489 | ||
490 | static ssize_t zfcp_sysfs_adapter_q_full_show(struct device *dev, | ||
491 | struct device_attribute *attr, | ||
492 | char *buf) | ||
493 | { | ||
494 | struct Scsi_Host *scsi_host = class_to_shost(dev); | ||
495 | struct zfcp_adapter *adapter = | ||
496 | (struct zfcp_adapter *) scsi_host->hostdata[0]; | ||
497 | |||
498 | return sprintf(buf, "%d\n", atomic_read(&adapter->qdio_outb_full)); | ||
499 | } | ||
500 | static DEVICE_ATTR(queue_full, S_IRUGO, zfcp_sysfs_adapter_q_full_show, NULL); | ||
501 | |||
490 | struct device_attribute *zfcp_sysfs_shost_attrs[] = { | 502 | struct device_attribute *zfcp_sysfs_shost_attrs[] = { |
491 | &dev_attr_utilization, | 503 | &dev_attr_utilization, |
492 | &dev_attr_requests, | 504 | &dev_attr_requests, |
493 | &dev_attr_megabytes, | 505 | &dev_attr_megabytes, |
494 | &dev_attr_seconds_active, | 506 | &dev_attr_seconds_active, |
507 | &dev_attr_queue_full, | ||
495 | NULL | 508 | NULL |
496 | }; | 509 | }; |