mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-26 02:39:48 +00:00
blktrace: pass zfcp driver data
This patch writes the channel and fabric latencies in nanoseconds per request via blktrace for later analysis. The utilization of the inbound and outbound adapter queue is also reported. Signed-off-by: Stefan Raspl <raspl@linux.vnet.ibm.com> Signed-off-by: Martin Peschke <mp3@de.ibm.com> Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
This commit is contained in:
parent
756f824318
commit
0997f1c5fe
4 changed files with 49 additions and 0 deletions
|
@ -583,6 +583,8 @@ struct zfcp_fsf_req {
|
|||
unsigned long long issued; /* request sent time (STCK) */
|
||||
struct zfcp_unit *unit;
|
||||
void (*handler)(struct zfcp_fsf_req *);
|
||||
u16 qdio_outb_usage;/* usage of outbound queue */
|
||||
u16 qdio_inb_usage; /* usage of inbound queue */
|
||||
};
|
||||
|
||||
/* driver data */
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
* Copyright IBM Corporation 2002, 2008
|
||||
*/
|
||||
|
||||
#include <linux/blktrace_api.h>
|
||||
#include "zfcp_ext.h"
|
||||
|
||||
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)
|
|||
list_add_tail(&req->list, &adapter->req_list[idx]);
|
||||
spin_unlock(&adapter->req_list_lock);
|
||||
|
||||
req->qdio_outb_usage = atomic_read(&req_q->count);
|
||||
req->issued = get_clock();
|
||||
if (zfcp_qdio_send(req)) {
|
||||
/* Queues are down..... */
|
||||
|
@ -2082,6 +2084,36 @@ static void zfcp_fsf_req_latency(struct zfcp_fsf_req *req)
|
|||
spin_unlock_irqrestore(&unit->latencies.lock, flags);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BLK_DEV_IO_TRACE
|
||||
static void zfcp_fsf_trace_latency(struct zfcp_fsf_req *fsf_req)
|
||||
{
|
||||
struct fsf_qual_latency_info *lat_inf;
|
||||
struct scsi_cmnd *scsi_cmnd = (struct scsi_cmnd *)fsf_req->data;
|
||||
struct request *req = scsi_cmnd->request;
|
||||
struct zfcp_blk_drv_data trace;
|
||||
int ticks = fsf_req->adapter->timer_ticks;
|
||||
|
||||
trace.flags = 0;
|
||||
trace.magic = ZFCP_BLK_DRV_DATA_MAGIC;
|
||||
if (fsf_req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA) {
|
||||
trace.flags |= ZFCP_BLK_LAT_VALID;
|
||||
lat_inf = &fsf_req->qtcb->prefix.prot_status_qual.latency_info;
|
||||
trace.channel_lat = lat_inf->channel_lat * ticks;
|
||||
trace.fabric_lat = lat_inf->fabric_lat * ticks;
|
||||
}
|
||||
if (fsf_req->status & ZFCP_STATUS_FSFREQ_ERROR)
|
||||
trace.flags |= ZFCP_BLK_REQ_ERROR;
|
||||
trace.inb_usage = fsf_req->qdio_inb_usage;
|
||||
trace.outb_usage = fsf_req->qdio_outb_usage;
|
||||
|
||||
blk_add_driver_data(req->q, req, &trace, sizeof(trace));
|
||||
}
|
||||
#else
|
||||
static inline void zfcp_fsf_trace_latency(struct zfcp_fsf_req *fsf_req)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
static void zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *req)
|
||||
{
|
||||
struct scsi_cmnd *scpnt = req->data;
|
||||
|
@ -2114,6 +2146,8 @@ static void zfcp_fsf_send_fcp_command_task_handler(struct zfcp_fsf_req *req)
|
|||
if (req->adapter->adapter_features & FSF_FEATURE_MEASUREMENT_DATA)
|
||||
zfcp_fsf_req_latency(req);
|
||||
|
||||
zfcp_fsf_trace_latency(req);
|
||||
|
||||
if (unlikely(fcp_rsp_iu->validity.bits.fcp_rsp_len_valid)) {
|
||||
if (fcp_rsp_info[3] == RSP_CODE_GOOD)
|
||||
set_host_byte(scpnt, DID_OK);
|
||||
|
|
|
@ -439,4 +439,16 @@ struct fsf_qtcb {
|
|||
u8 log[FSF_QTCB_LOG_SIZE];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
struct zfcp_blk_drv_data {
|
||||
#define ZFCP_BLK_DRV_DATA_MAGIC 0x1
|
||||
u32 magic;
|
||||
#define ZFCP_BLK_LAT_VALID 0x1
|
||||
#define ZFCP_BLK_REQ_ERROR 0x2
|
||||
u16 flags;
|
||||
u8 inb_usage;
|
||||
u8 outb_usage;
|
||||
u64 channel_lat;
|
||||
u64 fabric_lat;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#endif /* FSF_H */
|
||||
|
|
|
@ -115,6 +115,7 @@ static void zfcp_qdio_reqid_check(struct zfcp_adapter *adapter,
|
|||
spin_unlock_irqrestore(&adapter->req_list_lock, flags);
|
||||
|
||||
fsf_req->sbal_response = sbal_idx;
|
||||
fsf_req->qdio_inb_usage = atomic_read(&adapter->resp_q.count);
|
||||
zfcp_fsf_req_complete(fsf_req);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue