diff options
author | Christof Schmitt <christof.schmitt@de.ibm.com> | 2008-05-06 05:00:05 -0400 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-06-05 10:23:42 -0400 |
commit | c9615858a81d2424c78b10a2f689ba24b156937c (patch) | |
tree | 34af50eaeb958a95d13b4f1b6ec9da7ea89f7024 /drivers/s390/scsi/zfcp_fsf.c | |
parent | 688864e29869a71a8183e4e2f96ccf9f2de1375f (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/scsi/zfcp_fsf.c')
-rw-r--r-- | drivers/s390/scsi/zfcp_fsf.c | 44 |
1 files changed, 44 insertions, 0 deletions
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 | ||
3653 | static 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 | |||
3662 | static 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"); |