Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 42a8e6e2 authored by Krishna Gudipati's avatar Krishna Gudipati Committed by James Bottomley
Browse files

[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: default avatarKrishna Gudipati <kgudipat@brocade.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent f2ee7601
Loading
Loading
Loading
Loading
+73 −0
Original line number Diff line number Diff line
@@ -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)
{
+18 −8
Original line number Diff line number Diff line
@@ -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)
+53 −0
Original line number Diff line number Diff line
@@ -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;
+18 −0
Original line number Diff line number Diff line
@@ -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;