Skip to content

Commit 6d9d63b

Browse files
sswenJames Bottomley
authored andcommitted
[SCSI] zfcp: Add some statistics provided by the FCP adapter to the sysfs
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 <[email protected]> Signed-off-by: Christof Schmitt <[email protected]> Signed-off-by: James Bottomley <[email protected]>
1 parent ec258fe commit 6d9d63b

File tree

2 files changed

+130
-2
lines changed

2 files changed

+130
-2
lines changed

drivers/s390/scsi/zfcp_fsf.h

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@
213213
#define FSF_FEATURE_HBAAPI_MANAGEMENT 0x00000010
214214
#define FSF_FEATURE_ELS_CT_CHAINED_SBALS 0x00000020
215215
#define FSF_FEATURE_UPDATE_ALERT 0x00000100
216+
#define FSF_FEATURE_MEASUREMENT_DATA 0x00000200
216217

217218
/* host connection features */
218219
#define FSF_FEATURE_NPIV_MODE 0x00000001
@@ -340,6 +341,15 @@ struct fsf_qtcb_prefix {
340341
u8 res1[20];
341342
} __attribute__ ((packed));
342343

344+
struct fsf_statistics_info {
345+
u64 input_req;
346+
u64 output_req;
347+
u64 control_req;
348+
u64 input_mb;
349+
u64 output_mb;
350+
u64 seconds_act;
351+
} __attribute__ ((packed));
352+
343353
union fsf_status_qual {
344354
u8 byte[FSF_STATUS_QUALIFIER_SIZE];
345355
u16 halfword[FSF_STATUS_QUALIFIER_SIZE / sizeof (u16)];
@@ -436,7 +446,8 @@ struct fsf_qtcb_bottom_config {
436446
u32 hardware_version;
437447
u8 serial_number[32];
438448
struct fsf_nport_serv_param plogi_payload;
439-
u8 res4[160];
449+
struct fsf_statistics_info stat_info;
450+
u8 res4[112];
440451
} __attribute__ ((packed));
441452

442453
struct fsf_qtcb_bottom_port {
@@ -469,7 +480,10 @@ struct fsf_qtcb_bottom_port {
469480
u64 control_requests;
470481
u64 input_mb; /* where 1 MByte == 1.000.000 Bytes */
471482
u64 output_mb; /* where 1 MByte == 1.000.000 Bytes */
472-
u8 res2[256];
483+
u8 cp_util;
484+
u8 cb_util;
485+
u8 a_util;
486+
u8 res2[253];
473487
} __attribute__ ((packed));
474488

475489
union fsf_qtcb_bottom {

drivers/s390/scsi/zfcp_scsi.c

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ static struct zfcp_unit *zfcp_unit_lookup(struct zfcp_adapter *, int,
4040
unsigned int, unsigned int);
4141

4242
static struct device_attribute *zfcp_sysfs_sdev_attrs[];
43+
static struct device_attribute *zfcp_a_stats_attrs[];
4344

4445
struct zfcp_data zfcp_data = {
4546
.scsi_host_template = {
@@ -61,6 +62,7 @@ struct zfcp_data zfcp_data = {
6162
.use_clustering = 1,
6263
.sdev_attrs = zfcp_sysfs_sdev_attrs,
6364
.max_sectors = ZFCP_MAX_SECTORS,
65+
.shost_attrs = zfcp_a_stats_attrs,
6466
},
6567
.driver_version = ZFCP_VERSION,
6668
};
@@ -809,4 +811,116 @@ static struct device_attribute *zfcp_sysfs_sdev_attrs[] = {
809811
NULL
810812
};
811813

814+
static ssize_t zfcp_sysfs_adapter_util_show(struct device *dev,
815+
struct device_attribute *attr,
816+
char *buf)
817+
{
818+
struct Scsi_Host *scsi_host = dev_to_shost(dev);
819+
struct fsf_qtcb_bottom_port *qtcb_port;
820+
int retval;
821+
struct zfcp_adapter *adapter;
822+
823+
adapter = (struct zfcp_adapter *) scsi_host->hostdata[0];
824+
if (!(adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA))
825+
return -EOPNOTSUPP;
826+
827+
qtcb_port = kzalloc(sizeof(struct fsf_qtcb_bottom_port), GFP_KERNEL);
828+
if (!qtcb_port)
829+
return -ENOMEM;
830+
831+
retval = zfcp_fsf_exchange_port_data_sync(adapter, qtcb_port);
832+
if (!retval)
833+
retval = sprintf(buf, "%u %u %u\n", qtcb_port->cp_util,
834+
qtcb_port->cb_util, qtcb_port->a_util);
835+
kfree(qtcb_port);
836+
return retval;
837+
}
838+
839+
static int zfcp_sysfs_adapter_ex_config(struct device *dev,
840+
struct fsf_statistics_info *stat_inf)
841+
{
842+
int retval;
843+
struct fsf_qtcb_bottom_config *qtcb_config;
844+
struct Scsi_Host *scsi_host = dev_to_shost(dev);
845+
struct zfcp_adapter *adapter;
846+
847+
adapter = (struct zfcp_adapter *) scsi_host->hostdata[0];
848+
if (!(adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA))
849+
return -EOPNOTSUPP;
850+
851+
qtcb_config = kzalloc(sizeof(struct fsf_qtcb_bottom_config),
852+
GFP_KERNEL);
853+
if (!qtcb_config)
854+
return -ENOMEM;
855+
856+
retval = zfcp_fsf_exchange_config_data_sync(adapter, qtcb_config);
857+
if (!retval)
858+
*stat_inf = qtcb_config->stat_info;
859+
860+
kfree(qtcb_config);
861+
return retval;
862+
}
863+
864+
static ssize_t zfcp_sysfs_adapter_request_show(struct device *dev,
865+
struct device_attribute *attr,
866+
char *buf)
867+
{
868+
struct fsf_statistics_info stat_info;
869+
int retval;
870+
871+
retval = zfcp_sysfs_adapter_ex_config(dev, &stat_info);
872+
if (retval)
873+
return retval;
874+
875+
return sprintf(buf, "%llu %llu %llu\n",
876+
(unsigned long long) stat_info.input_req,
877+
(unsigned long long) stat_info.output_req,
878+
(unsigned long long) stat_info.control_req);
879+
}
880+
881+
static ssize_t zfcp_sysfs_adapter_mb_show(struct device *dev,
882+
struct device_attribute *attr,
883+
char *buf)
884+
{
885+
struct fsf_statistics_info stat_info;
886+
int retval;
887+
888+
retval = zfcp_sysfs_adapter_ex_config(dev, &stat_info);
889+
if (retval)
890+
return retval;
891+
892+
return sprintf(buf, "%llu %llu\n",
893+
(unsigned long long) stat_info.input_mb,
894+
(unsigned long long) stat_info.output_mb);
895+
}
896+
897+
static ssize_t zfcp_sysfs_adapter_sec_active_show(struct device *dev,
898+
struct device_attribute *attr,
899+
char *buf)
900+
{
901+
struct fsf_statistics_info stat_info;
902+
int retval;
903+
904+
retval = zfcp_sysfs_adapter_ex_config(dev, &stat_info);
905+
if (retval)
906+
return retval;
907+
908+
return sprintf(buf, "%llu\n",
909+
(unsigned long long) stat_info.seconds_act);
910+
}
911+
912+
static DEVICE_ATTR(utilization, S_IRUGO, zfcp_sysfs_adapter_util_show, NULL);
913+
static DEVICE_ATTR(requests, S_IRUGO, zfcp_sysfs_adapter_request_show, NULL);
914+
static DEVICE_ATTR(megabytes, S_IRUGO, zfcp_sysfs_adapter_mb_show, NULL);
915+
static DEVICE_ATTR(seconds_active, S_IRUGO,
916+
zfcp_sysfs_adapter_sec_active_show, NULL);
917+
918+
static struct device_attribute *zfcp_a_stats_attrs[] = {
919+
&dev_attr_utilization,
920+
&dev_attr_requests,
921+
&dev_attr_megabytes,
922+
&dev_attr_seconds_active,
923+
NULL
924+
};
925+
812926
#undef ZFCP_LOG_AREA

0 commit comments

Comments
 (0)