]>
Commit | Line | Data |
---|---|---|
00e5a55c BS |
1 | From: Gerald Schaefer <geraldsc@de.ibm.com> |
2 | Subject: (kernel):FCP - Performance Data colletion & analysis | |
3 | References: bnc#417243 | |
4 | ||
5 | This patch writes the channel and fabric latencies in nanoseconds per | |
6 | request via blktrace for later analysis. The utilization of the inbound | |
7 | and outbound adapter queue is also reported. | |
8 | ||
9 | Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com> | |
10 | Signed-off-by: Martin Peschke <mp3@de.ibm.com> | |
11 | Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com> | |
12 | ||
13 | Acked-by: John Jolly <jjolly@suse.de> | |
14 | ||
15 | --- | |
16 | drivers/s390/scsi/zfcp_def.h | 2 ++ | |
17 | drivers/s390/scsi/zfcp_fsf.c | 34 ++++++++++++++++++++++++++++++++++ | |
18 | drivers/s390/scsi/zfcp_fsf.h | 12 ++++++++++++ | |
19 | drivers/s390/scsi/zfcp_qdio.c | 1 + | |
20 | 4 files changed, 49 insertions(+) | |
21 | ||
22 | --- a/drivers/s390/scsi/zfcp_fsf.c | |
23 | +++ b/drivers/s390/scsi/zfcp_fsf.c | |
24 | @@ -6,6 +6,7 @@ | |
25 | * Copyright IBM Corporation 2002, 2008 | |
26 | */ | |
27 | ||
28 | +#include <linux/blktrace_api.h> | |
29 | #include "zfcp_ext.h" | |
30 | ||
31 | static void zfcp_fsf_request_timeout_handler(unsigned long data) | |
32 | @@ -834,6 +835,7 @@ static int zfcp_fsf_req_send(struct zfcp | |
33 | list_add_tail(&req->list, &adapter->req_list[idx]); | |
34 | spin_unlock(&adapter->req_list_lock); | |
35 | ||
36 | + req->qdio_outb_usage = atomic_read(&req_q->count); | |
37 | req->issued = get_clock(); | |
38 | if (zfcp_qdio_send(req)) { | |
39 | /* Queues are down..... */ | |
40 | @@ -2036,6 +2038,36 @@ static void zfcp_fsf_req_latency(struct | |
41 | spin_unlock_irqrestore(&unit->latencies.lock, flags); | |
42 | } | |
43 | ||
44 | +#ifdef CONFIG_BLK_DEV_IO_TRACE | |
45 | +static void zfcp_fsf_trace_latency(struct zfcp_fsf_req *fsf_req) | |
46 | +{ | |
47 | + struct fsf_qual_latency_info *lat_inf; | |
48 | + struct scsi_cmnd *scsi_cmnd = (struct scsi_cmnd *)fsf_req->data; | |
49 | + struct request *req = scsi_cmnd->request; | |
50 | + struct zfcp_blk_drv_data trace; | |
51 | + int ticks = fsf_req->adapter->timer_ticks; | |
52 | + | |
53 | + trace.flags = 0; | |
54 | + trace.magic = ZFCP_BLK_DRV_DATA_MAGIC; | |
55 | + if (fsf_req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA) { | |
56 | + trace.flags |= ZFCP_BLK_LAT_VALID; | |
57 | + lat_inf = &fsf_req->qtcb->prefix.prot_status_qual.latency_info; | |
58 | + trace.channel_lat = lat_inf->channel_lat * ticks; | |
59 | + trace.fabric_lat = lat_inf->fabric_lat * ticks; | |
60 | + } | |
61 | + if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR) | |
62 | + trace.flags |= ZFCP_BLK_REQ_ERROR; | |
63 | + trace.inb_usage = fsf_req->qdio_inb_usage; | |
64 | + trace.outb_usage = fsf_req->qdio_outb_usage; | |
65 | + | |
66 | + blk_add_driver_data(req->q, req, &trace, sizeof(trace)); | |
67 | +} | |
68 | +#else | |
69 | +static inline void zfcp_fsf_trace_latency(struct zfcp_fsf_req *fsf_req) | |
70 | +{ | |
71 | +} | |
72 | +#endif | |
73 | + | |
74 | static void zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *req) | |
75 | { | |
76 | struct scsi_cmnd *scpnt = req->data; | |
77 | @@ -2068,6 +2100,8 @@ static void zfcp_fsf_send_fcp_command_ta | |
78 | if (req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA) | |
79 | zfcp_fsf_req_latency(req); | |
80 | ||
81 | + zfcp_fsf_trace_latency(req); | |
82 | + | |
83 | if (unlikely(fcp_rsp_iu->validity.bits.fcp_rsp_len_valid)) { | |
84 | if (fcp_rsp_info[3] == RSP_CODE_GOOD) | |
85 | set_host_byte(scpnt, DID_OK); | |
86 | --- a/drivers/s390/scsi/zfcp_def.h | |
87 | +++ b/drivers/s390/scsi/zfcp_def.h | |
88 | @@ -638,6 +638,8 @@ struct zfcp_fsf_req { | |
89 | unsigned long long issued; /* request sent time (STCK) */ | |
90 | struct zfcp_unit *unit; | |
91 | void (*handler)(struct zfcp_fsf_req *); | |
92 | + u16 qdio_outb_usage;/* usage of outbound queue */ | |
93 | + u16 qdio_inb_usage; /* usage of inbound queue */ | |
94 | }; | |
95 | ||
96 | /* driver data */ | |
97 | --- a/drivers/s390/scsi/zfcp_qdio.c | |
98 | +++ b/drivers/s390/scsi/zfcp_qdio.c | |
99 | @@ -115,6 +115,7 @@ static void zfcp_qdio_reqid_check(struct | |
100 | spin_unlock_irqrestore(&adapter->req_list_lock, flags); | |
101 | ||
102 | fsf_req->sbal_response = sbal_idx; | |
103 | + fsf_req->qdio_inb_usage = atomic_read(&adapter->resp_q.count); | |
104 | zfcp_fsf_req_complete(fsf_req); | |
105 | } | |
106 | ||
107 | --- a/drivers/s390/scsi/zfcp_fsf.h | |
108 | +++ b/drivers/s390/scsi/zfcp_fsf.h | |
109 | @@ -514,4 +514,16 @@ struct fsf_qtcb { | |
110 | u8 log[FSF_QTCB_LOG_SIZE]; | |
111 | } __attribute__ ((packed)); | |
112 | ||
113 | +struct zfcp_blk_drv_data { | |
114 | +#define ZFCP_BLK_DRV_DATA_MAGIC 0x1 | |
115 | + u32 magic; | |
116 | +#define ZFCP_BLK_LAT_VALID 0x1 | |
117 | +#define ZFCP_BLK_REQ_ERROR 0x2 | |
118 | + u16 flags; | |
119 | + u8 inb_usage; | |
120 | + u8 outb_usage; | |
121 | + u64 channel_lat; | |
122 | + u64 fabric_lat; | |
123 | +} __attribute__ ((packed)); | |
124 | + | |
125 | #endif /* FSF_H */ |