* [patch 1/3] zfcp: Wait for free SBAL during exchange config
2008-04-24 17:35 [patch 0/3] zfcp: Add sysfs attributes for polling adapter data Christof Schmitt
@ 2008-04-24 17:35 ` Christof Schmitt
2008-04-24 17:35 ` [patch 2/3] zfcp: Print some messages only during ERP Christof Schmitt
2008-04-24 17:35 ` [patch 3/3] zfcp: Add some statistics provided by the FCP adapter to the sysfs Christof Schmitt
2 siblings, 0 replies; 4+ messages in thread
From: Christof Schmitt @ 2008-04-24 17:35 UTC (permalink / raw)
To: James Bottomley; +Cc: linux-scsi, linux-s390, Swen Schillig, Christof Schmitt
[-- Attachment #1: zfcp-stat-sbal-wait.diff --]
[-- Type: text/plain, Size: 993 bytes --]
From: Swen Schillig <swen@vnet.ibm.com>
When sending a exchange config data command, wait for a free SBAL.
This does not matter during adapter initialization, but this is
required for pulling adapter statistics during high I/O load.
Signed-off-by: Swen Schillig <swen@vnet.ibm.com>
Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com>
---
drivers/s390/scsi/zfcp_fsf.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/s390/scsi/zfcp_fsf.c 2008-04-24 15:06:33.000000000 +0200
+++ b/drivers/s390/scsi/zfcp_fsf.c 2008-04-24 15:06:34.000000000 +0200
@@ -1927,7 +1927,8 @@ zfcp_fsf_exchange_config_data_sync(struc
/* setup new FSF request */
retval = zfcp_fsf_req_create(adapter, FSF_QTCB_EXCHANGE_CONFIG_DATA,
- 0, NULL, &lock_flags, &fsf_req);
+ ZFCP_WAIT_FOR_SBAL, NULL, &lock_flags,
+ &fsf_req);
if (retval) {
ZFCP_LOG_INFO("error: Could not create exchange configuration "
"data request for adapter %s.\n",
--
^ permalink raw reply [flat|nested] 4+ messages in thread* [patch 2/3] zfcp: Print some messages only during ERP
2008-04-24 17:35 [patch 0/3] zfcp: Add sysfs attributes for polling adapter data Christof Schmitt
2008-04-24 17:35 ` [patch 1/3] zfcp: Wait for free SBAL during exchange config Christof Schmitt
@ 2008-04-24 17:35 ` Christof Schmitt
2008-04-24 17:35 ` [patch 3/3] zfcp: Add some statistics provided by the FCP adapter to the sysfs Christof Schmitt
2 siblings, 0 replies; 4+ messages in thread
From: Christof Schmitt @ 2008-04-24 17:35 UTC (permalink / raw)
To: James Bottomley; +Cc: linux-scsi, linux-s390, Swen Schillig, Christof Schmitt
[-- Attachment #1: zfcp-stat-message.diff --]
[-- Type: text/plain, Size: 2333 bytes --]
From: Swen Schillig <swen@vnet.ibm.com>
When statistics are polled from sysfs, the statistics use the same
commands as the adapter initialization. Change the messages printed
here, so they are only printed during initialization and not for each
poll of adapter data.
Signed-off-by: Swen Schillig <swen@vnet.ibm.com>
Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com>
---
drivers/s390/scsi/zfcp_fsf.c | 36 +++++++++++++++++++-----------------
1 file changed, 19 insertions(+), 17 deletions(-)
--- a/drivers/s390/scsi/zfcp_fsf.c 2008-04-24 15:06:34.000000000 +0200
+++ b/drivers/s390/scsi/zfcp_fsf.c 2008-04-24 15:06:38.000000000 +0200
@@ -2036,21 +2036,21 @@ zfcp_fsf_exchange_config_evaluate(struct
min(FC_SERIAL_NUMBER_SIZE, 17));
}
- ZFCP_LOG_NORMAL("The adapter %s reported the following "
- "characteristics:\n"
- "WWNN 0x%016Lx, "
- "WWPN 0x%016Lx, "
- "S_ID 0x%06x,\n"
- "adapter version 0x%x, "
- "LIC version 0x%x, "
- "FC link speed %d Gb/s\n",
- zfcp_get_busid_by_adapter(adapter),
- (wwn_t) fc_host_node_name(shost),
- (wwn_t) fc_host_port_name(shost),
- fc_host_port_id(shost),
- adapter->hydra_version,
- adapter->fsf_lic_version,
- fc_host_speed(shost));
+ if (fsf_req->erp_action)
+ ZFCP_LOG_NORMAL("The adapter %s reported the following "
+ "characteristics:\n"
+ "WWNN 0x%016Lx, WWPN 0x%016Lx, "
+ "S_ID 0x%06x,\n"
+ "adapter version 0x%x, "
+ "LIC version 0x%x, "
+ "FC link speed %d Gb/s\n",
+ zfcp_get_busid_by_adapter(adapter),
+ (wwn_t) fc_host_node_name(shost),
+ (wwn_t) fc_host_port_name(shost),
+ fc_host_port_id(shost),
+ adapter->hydra_version,
+ adapter->fsf_lic_version,
+ fc_host_speed(shost));
if (ZFCP_QTCB_VERSION < bottom->low_qtcb_version) {
ZFCP_LOG_NORMAL("error: the adapter %s "
"only supports newer control block "
@@ -2115,8 +2115,10 @@ zfcp_fsf_exchange_config_data_handler(st
zfcp_erp_adapter_shutdown(adapter, 0, 127, fsf_req);
return -EIO;
case FC_PORTTYPE_NPORT:
- ZFCP_LOG_NORMAL("Switched fabric fibrechannel "
- "network detected at adapter %s.\n",
+ if (fsf_req->erp_action)
+ ZFCP_LOG_NORMAL("Switched fabric fibrechannel "
+ "network detected at adapter "
+ "%s.\n",
zfcp_get_busid_by_adapter(adapter));
break;
default:
--
^ permalink raw reply [flat|nested] 4+ messages in thread* [patch 3/3] zfcp: Add some statistics provided by the FCP adapter to the sysfs
2008-04-24 17:35 [patch 0/3] zfcp: Add sysfs attributes for polling adapter data Christof Schmitt
2008-04-24 17:35 ` [patch 1/3] zfcp: Wait for free SBAL during exchange config Christof Schmitt
2008-04-24 17:35 ` [patch 2/3] zfcp: Print some messages only during ERP Christof Schmitt
@ 2008-04-24 17:35 ` Christof Schmitt
2 siblings, 0 replies; 4+ messages in thread
From: Christof Schmitt @ 2008-04-24 17:35 UTC (permalink / raw)
To: James Bottomley; +Cc: linux-scsi, linux-s390, Swen Schillig, Christof Schmitt
[-- Attachment #1: zfcp-stat-sysfs.diff --]
[-- Type: text/plain, Size: 6486 bytes --]
From: Swen Schillig <swen@vnet.ibm.com>
The new FCP adapter statistics provide a variety of information about
the virtual adapter (subchannel). In order to collect this information
the zfcp driver is extended to query this information.
The information provided by the new FCP adapter statistics can be
fetched by reading from the following files in the sysfs filesystem
/sys/class/scsi_host/host<n>/seconds_active
/sys/class/scsi_host/host<n>/requests
/sys/class/scsi_host/host<n>/megabytes
/sys/class/scsi_host/host<n>/utilization
These are the statistics on a virtual adapter (subchannel) level.
The information provided is raw and not modified or interpreted by any
means. No interpretation or modification of the values is done by the
zfcp driver.
Signed-off-by: Swen Schillig <swen@vnet.ibm.com>
Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com>
---
drivers/s390/scsi/zfcp_fsf.h | 18 +++++-
drivers/s390/scsi/zfcp_scsi.c | 114 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 130 insertions(+), 2 deletions(-)
--- a/drivers/s390/scsi/zfcp_fsf.h 2008-04-24 15:06:33.000000000 +0200
+++ b/drivers/s390/scsi/zfcp_fsf.h 2008-04-24 15:06:42.000000000 +0200
@@ -213,6 +213,7 @@
#define FSF_FEATURE_HBAAPI_MANAGEMENT 0x00000010
#define FSF_FEATURE_ELS_CT_CHAINED_SBALS 0x00000020
#define FSF_FEATURE_UPDATE_ALERT 0x00000100
+#define FSF_FEATURE_MEASUREMENT_DATA 0x00000200
/* host connection features */
#define FSF_FEATURE_NPIV_MODE 0x00000001
@@ -340,6 +341,15 @@ struct fsf_qtcb_prefix {
u8 res1[20];
} __attribute__ ((packed));
+struct fsf_statistics_info {
+ u64 input_req;
+ u64 output_req;
+ u64 control_req;
+ u64 input_mb;
+ u64 output_mb;
+ u64 seconds_act;
+} __attribute__ ((packed));
+
union fsf_status_qual {
u8 byte[FSF_STATUS_QUALIFIER_SIZE];
u16 halfword[FSF_STATUS_QUALIFIER_SIZE / sizeof (u16)];
@@ -436,7 +446,8 @@ struct fsf_qtcb_bottom_config {
u32 hardware_version;
u8 serial_number[32];
struct fsf_nport_serv_param plogi_payload;
- u8 res4[160];
+ struct fsf_statistics_info stat_info;
+ u8 res4[112];
} __attribute__ ((packed));
struct fsf_qtcb_bottom_port {
@@ -469,7 +480,10 @@ struct fsf_qtcb_bottom_port {
u64 control_requests;
u64 input_mb; /* where 1 MByte == 1.000.000 Bytes */
u64 output_mb; /* where 1 MByte == 1.000.000 Bytes */
- u8 res2[256];
+ u8 cp_util;
+ u8 cb_util;
+ u8 a_util;
+ u8 res2[253];
} __attribute__ ((packed));
union fsf_qtcb_bottom {
--- a/drivers/s390/scsi/zfcp_scsi.c 2008-04-24 15:06:33.000000000 +0200
+++ b/drivers/s390/scsi/zfcp_scsi.c 2008-04-24 15:06:42.000000000 +0200
@@ -40,6 +40,7 @@ static struct zfcp_unit *zfcp_unit_looku
unsigned int, unsigned int);
static struct device_attribute *zfcp_sysfs_sdev_attrs[];
+static struct device_attribute *zfcp_a_stats_attrs[];
struct zfcp_data zfcp_data = {
.scsi_host_template = {
@@ -61,6 +62,7 @@ struct zfcp_data zfcp_data = {
.use_clustering = 1,
.sdev_attrs = zfcp_sysfs_sdev_attrs,
.max_sectors = ZFCP_MAX_SECTORS,
+ .shost_attrs = zfcp_a_stats_attrs,
},
.driver_version = ZFCP_VERSION,
};
@@ -809,4 +811,116 @@ static struct device_attribute *zfcp_sys
NULL
};
+static ssize_t zfcp_sysfs_adapter_util_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct Scsi_Host *scsi_host = dev_to_shost(dev);
+ struct fsf_qtcb_bottom_port *qtcb_port;
+ int retval;
+ struct zfcp_adapter *adapter;
+
+ adapter = (struct zfcp_adapter *) scsi_host->hostdata[0];
+ if (!(adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA))
+ return -EOPNOTSUPP;
+
+ qtcb_port = kzalloc(sizeof(struct fsf_qtcb_bottom_port), GFP_KERNEL);
+ if (!qtcb_port)
+ return -ENOMEM;
+
+ retval = zfcp_fsf_exchange_port_data_sync(adapter, qtcb_port);
+ if (!retval)
+ retval = sprintf(buf, "%u %u %u\n", qtcb_port->cp_util,
+ qtcb_port->cb_util, qtcb_port->a_util);
+ kfree(qtcb_port);
+ return retval;
+}
+
+static int zfcp_sysfs_adapter_ex_config(struct device *dev,
+ struct fsf_statistics_info *stat_inf)
+{
+ int retval;
+ struct fsf_qtcb_bottom_config *qtcb_config;
+ struct Scsi_Host *scsi_host = dev_to_shost(dev);
+ struct zfcp_adapter *adapter;
+
+ adapter = (struct zfcp_adapter *) scsi_host->hostdata[0];
+ if (!(adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA))
+ return -EOPNOTSUPP;
+
+ qtcb_config = kzalloc(sizeof(struct fsf_qtcb_bottom_config),
+ GFP_KERNEL);
+ if (!qtcb_config)
+ return -ENOMEM;
+
+ retval = zfcp_fsf_exchange_config_data_sync(adapter, qtcb_config);
+ if (!retval)
+ *stat_inf = qtcb_config->stat_info;
+
+ kfree(qtcb_config);
+ return retval;
+}
+
+static ssize_t zfcp_sysfs_adapter_request_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct fsf_statistics_info stat_info;
+ int retval;
+
+ retval = zfcp_sysfs_adapter_ex_config(dev, &stat_info);
+ if (retval)
+ return retval;
+
+ return sprintf(buf, "%llu %llu %llu\n",
+ (unsigned long long) stat_info.input_req,
+ (unsigned long long) stat_info.output_req,
+ (unsigned long long) stat_info.control_req);
+}
+
+static ssize_t zfcp_sysfs_adapter_mb_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct fsf_statistics_info stat_info;
+ int retval;
+
+ retval = zfcp_sysfs_adapter_ex_config(dev, &stat_info);
+ if (retval)
+ return retval;
+
+ return sprintf(buf, "%llu %llu\n",
+ (unsigned long long) stat_info.input_mb,
+ (unsigned long long) stat_info.output_mb);
+}
+
+static ssize_t zfcp_sysfs_adapter_sec_active_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct fsf_statistics_info stat_info;
+ int retval;
+
+ retval = zfcp_sysfs_adapter_ex_config(dev, &stat_info);
+ if (retval)
+ return retval;
+
+ return sprintf(buf, "%llu\n",
+ (unsigned long long) stat_info.seconds_act);
+}
+
+static DEVICE_ATTR(utilization, S_IRUGO, zfcp_sysfs_adapter_util_show, NULL);
+static DEVICE_ATTR(requests, S_IRUGO, zfcp_sysfs_adapter_request_show, NULL);
+static DEVICE_ATTR(megabytes, S_IRUGO, zfcp_sysfs_adapter_mb_show, NULL);
+static DEVICE_ATTR(seconds_active, S_IRUGO,
+ zfcp_sysfs_adapter_sec_active_show, NULL);
+
+static struct device_attribute *zfcp_a_stats_attrs[] = {
+ &dev_attr_utilization,
+ &dev_attr_requests,
+ &dev_attr_megabytes,
+ &dev_attr_seconds_active,
+ NULL
+};
+
#undef ZFCP_LOG_AREA
--
^ permalink raw reply [flat|nested] 4+ messages in thread