[SCSI] bfa: Add support for IO profiling.

- Made changes to support IO profiling.
- Added support to configure and query IO profiling info.

Signed-off-by: Krishna Gudipati <kgudipat@brocade.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
This commit is contained in:
Krishna Gudipati 2011-07-20 17:01:52 -07:00 committed by James Bottomley
parent f2ee76017b
commit 42a8e6e298
4 changed files with 162 additions and 8 deletions

View File

@ -437,6 +437,59 @@ bfa_fcpim_port_iostats(struct bfa_s *bfa,
return BFA_STATUS_OK;
}
void
bfa_ioim_profile_comp(struct bfa_ioim_s *ioim)
{
struct bfa_itnim_latency_s *io_lat =
&(ioim->itnim->ioprofile.io_latency);
u32 val, idx;
val = (u32)(jiffies - ioim->start_time);
idx = bfa_ioim_get_index(scsi_bufflen((struct scsi_cmnd *)ioim->dio));
bfa_itnim_ioprofile_update(ioim->itnim, idx);
io_lat->count[idx]++;
io_lat->min[idx] = (io_lat->min[idx] < val) ? io_lat->min[idx] : val;
io_lat->max[idx] = (io_lat->max[idx] > val) ? io_lat->max[idx] : val;
io_lat->avg[idx] += val;
}
void
bfa_ioim_profile_start(struct bfa_ioim_s *ioim)
{
ioim->start_time = jiffies;
}
bfa_status_t
bfa_fcpim_profile_on(struct bfa_s *bfa, u32 time)
{
struct bfa_itnim_s *itnim;
struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa);
struct list_head *qe, *qen;
/* accumulate IO stats from itnim */
list_for_each_safe(qe, qen, &fcpim->itnim_q) {
itnim = (struct bfa_itnim_s *) qe;
bfa_itnim_clear_stats(itnim);
}
fcpim->io_profile = BFA_TRUE;
fcpim->io_profile_start_time = time;
fcpim->profile_comp = bfa_ioim_profile_comp;
fcpim->profile_start = bfa_ioim_profile_start;
return BFA_STATUS_OK;
}
bfa_status_t
bfa_fcpim_profile_off(struct bfa_s *bfa)
{
struct bfa_fcpim_s *fcpim = BFA_FCPIM(bfa);
fcpim->io_profile = BFA_FALSE;
fcpim->io_profile_start_time = 0;
fcpim->profile_comp = NULL;
fcpim->profile_start = NULL;
return BFA_STATUS_OK;
}
u16
bfa_fcpim_qdepth_get(struct bfa_s *bfa)
{
@ -1401,6 +1454,26 @@ bfa_itnim_hold_io(struct bfa_itnim_s *itnim)
bfa_sm_cmp_state(itnim, bfa_itnim_sm_iocdisable));
}
#define bfa_io_lat_clock_res_div HZ
#define bfa_io_lat_clock_res_mul 1000
bfa_status_t
bfa_itnim_get_ioprofile(struct bfa_itnim_s *itnim,
struct bfa_itnim_ioprofile_s *ioprofile)
{
struct bfa_fcpim_s *fcpim = BFA_FCPIM(itnim->bfa);
if (!fcpim->io_profile)
return BFA_STATUS_IOPROFILE_OFF;
itnim->ioprofile.index = BFA_IOBUCKET_MAX;
itnim->ioprofile.io_profile_start_time =
bfa_io_profile_start_time(itnim->bfa);
itnim->ioprofile.clock_res_mul = bfa_io_lat_clock_res_mul;
itnim->ioprofile.clock_res_div = bfa_io_lat_clock_res_div;
*ioprofile = itnim->ioprofile;
return BFA_STATUS_OK;
}
void
bfa_itnim_clear_stats(struct bfa_itnim_s *itnim)
{

View File

@ -79,14 +79,22 @@ bfa_ioim_get_index(u32 n) {
if (n >= (1UL)<<22)
return BFA_IOBUCKET_MAX - 1;
n >>= 8;
if (n >= (1UL)<<16)
n >>= 16; pos += 16;
if (n >= 1 << 8)
n >>= 8; pos += 8;
if (n >= 1 << 4)
n >>= 4; pos += 4;
if (n >= 1 << 2)
n >>= 2; pos += 2;
if (n >= (1UL)<<16) {
n >>= 16;
pos += 16;
}
if (n >= 1 << 8) {
n >>= 8;
pos += 8;
}
if (n >= 1 << 4) {
n >>= 4;
pos += 4;
}
if (n >= 1 << 2) {
n >>= 2;
pos += 2;
}
if (n >= 1 << 1)
pos += 1;
@ -297,6 +305,8 @@ bfa_status_t bfa_fcpim_port_iostats(struct bfa_s *bfa,
struct bfa_itnim_iostats_s *stats, u8 lp_tag);
void bfa_fcpim_add_stats(struct bfa_itnim_iostats_s *fcpim_stats,
struct bfa_itnim_iostats_s *itnim_stats);
bfa_status_t bfa_fcpim_profile_on(struct bfa_s *bfa, u32 time);
bfa_status_t bfa_fcpim_profile_off(struct bfa_s *bfa);
#define bfa_fcpim_ioredirect_enabled(__bfa) \
(((struct bfa_fcpim_s *)(BFA_FCPIM(__bfa)))->ioredirect)

View File

@ -1977,6 +1977,52 @@ bfad_iocmd_porglog_ctl(struct bfad_s *bfad, void *cmd)
return 0;
}
int
bfad_iocmd_fcpim_cfg_profile(struct bfad_s *bfad, void *cmd, unsigned int v_cmd)
{
struct bfa_bsg_fcpim_profile_s *iocmd =
(struct bfa_bsg_fcpim_profile_s *)cmd;
struct timeval tv;
unsigned long flags;
do_gettimeofday(&tv);
spin_lock_irqsave(&bfad->bfad_lock, flags);
if (v_cmd == IOCMD_FCPIM_PROFILE_ON)
iocmd->status = bfa_fcpim_profile_on(&bfad->bfa, tv.tv_sec);
else if (v_cmd == IOCMD_FCPIM_PROFILE_OFF)
iocmd->status = bfa_fcpim_profile_off(&bfad->bfa);
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
return 0;
}
static int
bfad_iocmd_itnim_get_ioprofile(struct bfad_s *bfad, void *cmd)
{
struct bfa_bsg_itnim_ioprofile_s *iocmd =
(struct bfa_bsg_itnim_ioprofile_s *)cmd;
struct bfa_fcs_lport_s *fcs_port;
struct bfa_fcs_itnim_s *itnim;
unsigned long flags;
spin_lock_irqsave(&bfad->bfad_lock, flags);
fcs_port = bfa_fcs_lookup_port(&bfad->bfa_fcs,
iocmd->vf_id, iocmd->lpwwn);
if (!fcs_port)
iocmd->status = BFA_STATUS_UNKNOWN_LWWN;
else {
itnim = bfa_fcs_itnim_lookup(fcs_port, iocmd->rpwwn);
if (itnim == NULL)
iocmd->status = BFA_STATUS_UNKNOWN_RWWN;
else
iocmd->status = bfa_itnim_get_ioprofile(
bfa_fcs_itnim_get_halitn(itnim),
&iocmd->ioprofile);
}
spin_unlock_irqrestore(&bfad->bfad_lock, flags);
return 0;
}
static int
bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd,
unsigned int payload_len)
@ -2238,6 +2284,13 @@ bfad_iocmd_handler(struct bfad_s *bfad, unsigned int cmd, void *iocmd,
case IOCMD_DEBUG_PORTLOG_CTL:
rc = bfad_iocmd_porglog_ctl(bfad, iocmd);
break;
case IOCMD_FCPIM_PROFILE_ON:
case IOCMD_FCPIM_PROFILE_OFF:
rc = bfad_iocmd_fcpim_cfg_profile(bfad, iocmd, cmd);
break;
case IOCMD_ITNIM_GET_IOPROFILE:
rc = bfad_iocmd_itnim_get_ioprofile(bfad, iocmd);
break;
default:
rc = -EINVAL;
break;

View File

@ -116,6 +116,9 @@ enum {
IOCMD_DEBUG_START_DTRC,
IOCMD_DEBUG_STOP_DTRC,
IOCMD_DEBUG_PORTLOG_CTL,
IOCMD_FCPIM_PROFILE_ON,
IOCMD_FCPIM_PROFILE_OFF,
IOCMD_ITNIM_GET_IOPROFILE,
};
struct bfa_bsg_gen_s {
@ -132,6 +135,21 @@ struct bfa_bsg_portlogctl_s {
int inst_no;
};
struct bfa_bsg_fcpim_profile_s {
bfa_status_t status;
u16 bfad_num;
u16 rsvd;
};
struct bfa_bsg_itnim_ioprofile_s {
bfa_status_t status;
u16 bfad_num;
u16 vf_id;
wwn_t lpwwn;
wwn_t rpwwn;
struct bfa_itnim_ioprofile_s ioprofile;
};
struct bfa_bsg_ioc_name_s {
bfa_status_t status;
u16 bfad_num;