aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorChristof Schmitt <christof.schmitt@de.ibm.com>2008-05-06 05:00:05 -0400
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-06-05 10:23:42 -0400
commitc9615858a81d2424c78b10a2f689ba24b156937c (patch)
tree34af50eaeb958a95d13b4f1b6ec9da7ea89f7024 /drivers/s390
parent688864e29869a71a8183e4e2f96ccf9f2de1375f (diff)
[SCSI] zfcp: Track fabric and channel latencies provided by FCP adapter
Add the infrastructure to retrieve the fabric and channel latencies from FSF commands for each SCSI command that has been processed. For each unit, the sum, min, max and number of requests is tracked. Signed-off-by: Swen Schillig <swen@vnet.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')
-rw-r--r--drivers/s390/scsi/zfcp_aux.c8
-rw-r--r--drivers/s390/scsi/zfcp_def.h20
-rw-r--r--drivers/s390/scsi/zfcp_fsf.c44
-rw-r--r--drivers/s390/scsi/zfcp_fsf.h11
4 files changed, 82 insertions, 1 deletions
diff --git a/drivers/s390/scsi/zfcp_aux.c b/drivers/s390/scsi/zfcp_aux.c
index 8c7e2b778ef1..d23027a2f2f0 100644
--- a/drivers/s390/scsi/zfcp_aux.c
+++ b/drivers/s390/scsi/zfcp_aux.c
@@ -847,6 +847,14 @@ zfcp_unit_enqueue(struct zfcp_port *port, fcp_lun_t fcp_lun)
847 /* mark unit unusable as long as sysfs registration is not complete */ 847 /* mark unit unusable as long as sysfs registration is not complete */
848 atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status); 848 atomic_set_mask(ZFCP_STATUS_COMMON_REMOVE, &unit->status);
849 849
850 spin_lock_init(&unit->latencies.lock);
851 unit->latencies.write.channel.min = 0xFFFFFFFF;
852 unit->latencies.write.fabric.min = 0xFFFFFFFF;
853 unit->latencies.read.channel.min = 0xFFFFFFFF;
854 unit->latencies.read.fabric.min = 0xFFFFFFFF;
855 unit->latencies.cmd.channel.min = 0xFFFFFFFF;
856 unit->latencies.cmd.fabric.min = 0xFFFFFFFF;
857
850 if (device_register(&unit->sysfs_device)) { 858 if (device_register(&unit->sysfs_device)) {
851 kfree(unit); 859 kfree(unit);
852 return NULL; 860 return NULL;
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h
index bda8c77b22da..306fcd0cae31 100644
--- a/drivers/s390/scsi/zfcp_def.h
+++ b/drivers/s390/scsi/zfcp_def.h
@@ -708,6 +708,24 @@ struct zfcp_erp_action {
708 struct timer_list timer; 708 struct timer_list timer;
709}; 709};
710 710
711struct fsf_latency_record {
712 u32 min;
713 u32 max;
714 u64 sum;
715};
716
717struct latency_cont {
718 struct fsf_latency_record channel;
719 struct fsf_latency_record fabric;
720 u64 counter;
721};
722
723struct zfcp_latencies {
724 struct latency_cont read;
725 struct latency_cont write;
726 struct latency_cont cmd;
727 spinlock_t lock;
728};
711 729
712struct zfcp_adapter { 730struct zfcp_adapter {
713 struct list_head list; /* list of adapters */ 731 struct list_head list; /* list of adapters */
@@ -723,6 +741,7 @@ struct zfcp_adapter {
723 u32 adapter_features; /* FCP channel features */ 741 u32 adapter_features; /* FCP channel features */
724 u32 connection_features; /* host connection features */ 742 u32 connection_features; /* host connection features */
725 u32 hardware_version; /* of FCP channel */ 743 u32 hardware_version; /* of FCP channel */
744 u16 timer_ticks; /* time int for a tick */
726 struct Scsi_Host *scsi_host; /* Pointer to mid-layer */ 745 struct Scsi_Host *scsi_host; /* Pointer to mid-layer */
727 struct list_head port_list_head; /* remote port list */ 746 struct list_head port_list_head; /* remote port list */
728 struct list_head port_remove_lh; /* head of ports to be 747 struct list_head port_remove_lh; /* head of ports to be
@@ -822,6 +841,7 @@ struct zfcp_unit {
822 struct scsi_device *device; /* scsi device struct pointer */ 841 struct scsi_device *device; /* scsi device struct pointer */
823 struct zfcp_erp_action erp_action; /* pending error recovery */ 842 struct zfcp_erp_action erp_action; /* pending error recovery */
824 atomic_t erp_counter; 843 atomic_t erp_counter;
844 struct zfcp_latencies latencies;
825}; 845};
826 846
827/* FSF request */ 847/* FSF request */
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c
index b2ea4ea051f5..1e7136483c1b 100644
--- a/drivers/s390/scsi/zfcp_fsf.c
+++ b/drivers/s390/scsi/zfcp_fsf.c
@@ -2005,6 +2005,7 @@ zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok)
2005 fc_host_supported_classes(shost) = 2005 fc_host_supported_classes(shost) =
2006 FC_COS_CLASS2 | FC_COS_CLASS3; 2006 FC_COS_CLASS2 | FC_COS_CLASS3;
2007 adapter->hydra_version = bottom->adapter_type; 2007 adapter->hydra_version = bottom->adapter_type;
2008 adapter->timer_ticks = bottom->timer_interval;
2008 if (fc_host_permanent_port_name(shost) == -1) 2009 if (fc_host_permanent_port_name(shost) == -1)
2009 fc_host_permanent_port_name(shost) = 2010 fc_host_permanent_port_name(shost) =
2010 fc_host_port_name(shost); 2011 fc_host_port_name(shost);
@@ -3649,6 +3650,46 @@ zfcp_fsf_send_fcp_command_task_management(struct zfcp_adapter *adapter,
3649 return fsf_req; 3650 return fsf_req;
3650} 3651}
3651 3652
3653static void zfcp_fsf_update_lat(struct fsf_latency_record *lat_rec, u32 lat)
3654{
3655 lat_rec->sum += lat;
3656 if (lat_rec->min > lat)
3657 lat_rec->min = lat;
3658 if (lat_rec->max < lat)
3659 lat_rec->max = lat;
3660}
3661
3662static void zfcp_fsf_req_latency(struct zfcp_fsf_req *fsf_req)
3663{
3664 struct fsf_qual_latency_info *lat_inf;
3665 struct latency_cont *lat;
3666 struct zfcp_unit *unit;
3667 unsigned long flags;
3668
3669 lat_inf = &fsf_req->qtcb->prefix.prot_status_qual.latency_info;
3670 unit = fsf_req->unit;
3671
3672 switch (fsf_req->qtcb->bottom.io.data_direction) {
3673 case FSF_DATADIR_READ:
3674 lat = &unit->latencies.read;
3675 break;
3676 case FSF_DATADIR_WRITE:
3677 lat = &unit->latencies.write;
3678 break;
3679 case FSF_DATADIR_CMND:
3680 lat = &unit->latencies.cmd;
3681 break;
3682 default:
3683 return;
3684 }
3685
3686 spin_lock_irqsave(&unit->latencies.lock, flags);
3687 zfcp_fsf_update_lat(&lat->channel, lat_inf->channel_lat);
3688 zfcp_fsf_update_lat(&lat->fabric, lat_inf->fabric_lat);
3689 lat->counter++;
3690 spin_unlock_irqrestore(&unit->latencies.lock, flags);
3691}
3692
3652/* 3693/*
3653 * function: zfcp_fsf_send_fcp_command_handler 3694 * function: zfcp_fsf_send_fcp_command_handler
3654 * 3695 *
@@ -3922,6 +3963,9 @@ zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *fsf_req)
3922 fcp_rsp_iu->fcp_sns_len); 3963 fcp_rsp_iu->fcp_sns_len);
3923 } 3964 }
3924 3965
3966 if (fsf_req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA)
3967 zfcp_fsf_req_latency(fsf_req);
3968
3925 /* check FCP_RSP_INFO */ 3969 /* check FCP_RSP_INFO */
3926 if (unlikely(fcp_rsp_iu->validity.bits.fcp_rsp_len_valid)) { 3970 if (unlikely(fcp_rsp_iu->validity.bits.fcp_rsp_len_valid)) {
3927 ZFCP_LOG_DEBUG("rsp_len is valid\n"); 3971 ZFCP_LOG_DEBUG("rsp_len is valid\n");
diff --git a/drivers/s390/scsi/zfcp_fsf.h b/drivers/s390/scsi/zfcp_fsf.h
index 099970b27001..8b1a7d9c840f 100644
--- a/drivers/s390/scsi/zfcp_fsf.h
+++ b/drivers/s390/scsi/zfcp_fsf.h
@@ -323,11 +323,18 @@ struct fsf_link_down_info {
323 u8 vendor_specific_code; 323 u8 vendor_specific_code;
324} __attribute__ ((packed)); 324} __attribute__ ((packed));
325 325
326struct fsf_qual_latency_info {
327 u32 channel_lat;
328 u32 fabric_lat;
329 u8 res1[8];
330} __attribute__ ((packed));
331
326union fsf_prot_status_qual { 332union fsf_prot_status_qual {
327 u64 doubleword[FSF_PROT_STATUS_QUAL_SIZE / sizeof(u64)]; 333 u64 doubleword[FSF_PROT_STATUS_QUAL_SIZE / sizeof(u64)];
328 struct fsf_qual_version_error version_error; 334 struct fsf_qual_version_error version_error;
329 struct fsf_qual_sequence_error sequence_error; 335 struct fsf_qual_sequence_error sequence_error;
330 struct fsf_link_down_info link_down_info; 336 struct fsf_link_down_info link_down_info;
337 struct fsf_qual_latency_info latency_info;
331} __attribute__ ((packed)); 338} __attribute__ ((packed));
332 339
333struct fsf_qtcb_prefix { 340struct fsf_qtcb_prefix {
@@ -437,7 +444,9 @@ struct fsf_qtcb_bottom_config {
437 u32 fc_link_speed; 444 u32 fc_link_speed;
438 u32 adapter_type; 445 u32 adapter_type;
439 u32 peer_d_id; 446 u32 peer_d_id;
440 u8 res2[12]; 447 u8 res1[2];
448 u16 timer_interval;
449 u8 res2[8];
441 u32 s_id; 450 u32 s_id;
442 struct fsf_nport_serv_param nport_serv_param; 451 struct fsf_nport_serv_param nport_serv_param;
443 u8 reserved_nport_serv_param[16]; 452 u8 reserved_nport_serv_param[16];