diff options
| -rw-r--r-- | drivers/s390/scsi/zfcp_def.h | 2 | ||||
| -rw-r--r-- | drivers/s390/scsi/zfcp_fsf.c | 34 | ||||
| -rw-r--r-- | drivers/s390/scsi/zfcp_fsf.h | 12 | ||||
| -rw-r--r-- | drivers/s390/scsi/zfcp_qdio.c | 1 |
4 files changed, 49 insertions, 0 deletions
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h index 8a13071c444..9ce4c75bd19 100644 --- a/drivers/s390/scsi/zfcp_def.h +++ b/drivers/s390/scsi/zfcp_def.h | |||
| @@ -583,6 +583,8 @@ struct zfcp_fsf_req { | |||
| 583 | unsigned long long issued; /* request sent time (STCK) */ | 583 | unsigned long long issued; /* request sent time (STCK) */ |
| 584 | struct zfcp_unit *unit; | 584 | struct zfcp_unit *unit; |
| 585 | void (*handler)(struct zfcp_fsf_req *); | 585 | void (*handler)(struct zfcp_fsf_req *); |
| 586 | u16 qdio_outb_usage;/* usage of outbound queue */ | ||
| 587 | u16 qdio_inb_usage; /* usage of inbound queue */ | ||
| 586 | }; | 588 | }; |
| 587 | 589 | ||
| 588 | /* driver data */ | 590 | /* driver data */ |
diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index 739356a5c12..5ae1d497e5e 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | * Copyright IBM Corporation 2002, 2008 | 6 | * Copyright IBM Corporation 2002, 2008 |
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | #include <linux/blktrace_api.h> | ||
| 9 | #include "zfcp_ext.h" | 10 | #include "zfcp_ext.h" |
| 10 | 11 | ||
| 11 | static void zfcp_fsf_request_timeout_handler(unsigned long data) | 12 | static void zfcp_fsf_request_timeout_handler(unsigned long data) |
| @@ -777,6 +778,7 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *req) | |||
| 777 | list_add_tail(&req->list, &adapter->req_list[idx]); | 778 | list_add_tail(&req->list, &adapter->req_list[idx]); |
| 778 | spin_unlock(&adapter->req_list_lock); | 779 | spin_unlock(&adapter->req_list_lock); |
| 779 | 780 | ||
| 781 | req->qdio_outb_usage = atomic_read(&req_q->count); | ||
| 780 | req->issued = get_clock(); | 782 | req->issued = get_clock(); |
| 781 | if (zfcp_qdio_send(req)) { | 783 | if (zfcp_qdio_send(req)) { |
| 782 | /* Queues are down..... */ | 784 | /* Queues are down..... */ |
| @@ -2082,6 +2084,36 @@ static void zfcp_fsf_req_latency(struct zfcp_fsf_req *req) | |||
| 2082 | spin_unlock_irqrestore(&unit->latencies.lock, flags); | 2084 | spin_unlock_irqrestore(&unit->latencies.lock, flags); |
| 2083 | } | 2085 | } |
| 2084 | 2086 | ||
| 2087 | #ifdef CONFIG_BLK_DEV_IO_TRACE | ||
| 2088 | static void zfcp_fsf_trace_latency(struct zfcp_fsf_req *fsf_req) | ||
| 2089 | { | ||
| 2090 | struct fsf_qual_latency_info *lat_inf; | ||
| 2091 | struct scsi_cmnd *scsi_cmnd = (struct scsi_cmnd *)fsf_req->data; | ||
| 2092 | struct request *req = scsi_cmnd->request; | ||
| 2093 | struct zfcp_blk_drv_data trace; | ||
| 2094 | int ticks = fsf_req->adapter->timer_ticks; | ||
| 2095 | |||
| 2096 | trace.flags = 0; | ||
| 2097 | trace.magic = ZFCP_BLK_DRV_DATA_MAGIC; | ||
| 2098 | if (fsf_req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA) { | ||
| 2099 | trace.flags |= ZFCP_BLK_LAT_VALID; | ||
| 2100 | lat_inf = &fsf_req->qtcb->prefix.prot_status_qual.latency_info; | ||
| 2101 | trace.channel_lat = lat_inf->channel_lat * ticks; | ||
| 2102 | trace.fabric_lat = lat_inf->fabric_lat * ticks; | ||
| 2103 | } | ||
| 2104 | if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) | ||
| 2105 | trace.flags |= ZFCP_BLK_REQ_ERROR; | ||
| 2106 | trace.inb_usage = fsf_req->qdio_inb_usage; | ||
| 2107 | trace.outb_usage = fsf_req->qdio_outb_usage; | ||
| 2108 | |||
| 2109 | blk_add_driver_data(req->q, req, &trace, sizeof(trace)); | ||
| 2110 | } | ||
| 2111 | #else | ||
| 2112 | static inline void zfcp_fsf_trace_latency(struct zfcp_fsf_req *fsf_req) | ||
| 2113 | { | ||
| 2114 | } | ||
| 2115 | #endif | ||
| 2116 | |||
| 2085 | static void zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *req) | 2117 | static void zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *req) |
| 2086 | { | 2118 | { |
| 2087 | struct scsi_cmnd *scpnt = req->data; | 2119 | struct scsi_cmnd *scpnt = req->data; |
| @@ -2114,6 +2146,8 @@ static void zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *req) | |||
| 2114 | if (req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA) | 2146 | if (req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA) |
| 2115 | zfcp_fsf_req_latency(req); | 2147 | zfcp_fsf_req_latency(req); |
| 2116 | 2148 | ||
| 2149 | zfcp_fsf_trace_latency(req); | ||
| 2150 | |||
| 2117 | if (unlikely(fcp_rsp_iu->validity.bits.fcp_rsp_len_valid)) { | 2151 | if (unlikely(fcp_rsp_iu->validity.bits.fcp_rsp_len_valid)) { |
| 2118 | if (fcp_rsp_info[3] == RSP_CODE_GOOD) | 2152 | if (fcp_rsp_info[3] == RSP_CODE_GOOD) |
| 2119 | set_host_byte(scpnt, DID_OK); | 2153 | set_host_byte(scpnt, DID_OK); |
diff --git a/drivers/s390/scsi/zfcp_fsf.h b/drivers/s390/scsi/zfcp_fsf.h index fd3a88777ac..fa2a3178061 100644 --- a/drivers/s390/scsi/zfcp_fsf.h +++ b/drivers/s390/scsi/zfcp_fsf.h | |||
| @@ -439,4 +439,16 @@ struct fsf_qtcb { | |||
| 439 | u8 log[FSF_QTCB_LOG_SIZE]; | 439 | u8 log[FSF_QTCB_LOG_SIZE]; |
| 440 | } __attribute__ ((packed)); | 440 | } __attribute__ ((packed)); |
| 441 | 441 | ||
| 442 | struct zfcp_blk_drv_data { | ||
| 443 | #define ZFCP_BLK_DRV_DATA_MAGIC 0x1 | ||
| 444 | u32 magic; | ||
| 445 | #define ZFCP_BLK_LAT_VALID 0x1 | ||
| 446 | #define ZFCP_BLK_REQ_ERROR 0x2 | ||
| 447 | u16 flags; | ||
| 448 | u8 inb_usage; | ||
| 449 | u8 outb_usage; | ||
| 450 | u64 channel_lat; | ||
| 451 | u64 fabric_lat; | ||
| 452 | } __attribute__ ((packed)); | ||
| 453 | |||
| 442 | #endif /* FSF_H */ | 454 | #endif /* FSF_H */ |
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c index 3e05080e62d..664752f90b2 100644 --- a/drivers/s390/scsi/zfcp_qdio.c +++ b/drivers/s390/scsi/zfcp_qdio.c | |||
| @@ -115,6 +115,7 @@ static void zfcp_qdio_reqid_check(struct zfcp_adapter *adapter, | |||
| 115 | spin_unlock_irqrestore(&adapter->req_list_lock, flags); | 115 | spin_unlock_irqrestore(&adapter->req_list_lock, flags); |
| 116 | 116 | ||
| 117 | fsf_req->sbal_response = sbal_idx; | 117 | fsf_req->sbal_response = sbal_idx; |
| 118 | fsf_req->qdio_inb_usage = atomic_read(&adapter->resp_q.count); | ||
| 118 | zfcp_fsf_req_complete(fsf_req); | 119 | zfcp_fsf_req_complete(fsf_req); |
| 119 | } | 120 | } |
| 120 | 121 | ||
