svn commit: r282527 - head/sys/dev/mrsas
Kashyap D Desai
kadesai at FreeBSD.org
Wed May 6 10:41:29 UTC 2015
Author: kadesai
Date: Wed May 6 10:41:27 2015
New Revision: 282527
URL: https://svnweb.freebsd.org/changeset/base/282527
Log:
Current driver does fast path read load balancing between arm and mirror disk
for two Drive Raid-1 configuration only.
Now, Driver support fast path read load balancing for all (any number of disk) Raid-1 configuration.
Reviewed by: ambrisko
MFC after: 2 weeks
Sponsored by: AVAGO Technologies
Modified:
head/sys/dev/mrsas/mrsas.c
head/sys/dev/mrsas/mrsas.h
head/sys/dev/mrsas/mrsas_cam.c
head/sys/dev/mrsas/mrsas_fp.c
Modified: head/sys/dev/mrsas/mrsas.c
==============================================================================
--- head/sys/dev/mrsas/mrsas.c Wed May 6 10:36:53 2015 (r282526)
+++ head/sys/dev/mrsas/mrsas.c Wed May 6 10:41:27 2015 (r282527)
@@ -462,6 +462,11 @@ mrsas_get_tunables(struct mrsas_softc *s
*/
TUNABLE_INT_FETCH("hw.mrsas.debug_level", &sc->mrsas_debug);
+ /*
+ * Grab the global variables.
+ */
+ TUNABLE_INT_FETCH("hw.mrsas.lb_pending_cmds", &sc->lb_pending_cmds);
+
/* Grab the unit-instance variables */
snprintf(tmpstr, sizeof(tmpstr), "dev.mrsas.%d.debug_level",
device_get_unit(sc->mrsas_dev));
@@ -1468,7 +1473,7 @@ mrsas_complete_cmd(struct mrsas_softc *s
MRSAS_RAID_SCSI_IO_REQUEST *scsi_io_req;
struct mrsas_mpt_cmd *cmd_mpt;
struct mrsas_mfi_cmd *cmd_mfi;
- u_int8_t arm, reply_descript_type;
+ u_int8_t reply_descript_type;
u_int16_t smid, num_completed;
u_int8_t status, extStatus;
union desc_value desc_val;
@@ -1506,8 +1511,7 @@ mrsas_complete_cmd(struct mrsas_softc *s
device_id = cmd_mpt->ccb_ptr->ccb_h.target_id;
lbinfo = &sc->load_balance_info[device_id];
if (cmd_mpt->load_balance == MRSAS_LOAD_BALANCE_FLAG) {
- arm = lbinfo->raid1DevHandle[0] == scsi_io_req->DevHandle ? 0 : 1;
- mrsas_atomic_dec(&lbinfo->scsi_pending_cmds[arm]);
+ mrsas_atomic_dec(&lbinfo->scsi_pending_cmds[cmd_mpt->pd_r1_lb]);
cmd_mpt->load_balance &= ~MRSAS_LOAD_BALANCE_FLAG;
}
/* Fall thru and complete IO */
@@ -2331,6 +2335,7 @@ mrsas_ioc_init(struct mrsas_softc *sc)
init_frame->driver_ver_lo = (bus_addr_t)sc->verbuf_phys_addr;
init_frame->driver_ver_hi = 0;
}
+ init_frame->driver_operations.mfi_capabilities.support_ndrive_r1_lb = 1;
init_frame->driver_operations.mfi_capabilities.support_max_255lds = 1;
init_frame->driver_operations.mfi_capabilities.security_protocol_cmds_fw = 1;
phys_addr = (bus_addr_t)sc->ioc_init_phys_mem + 1024;
Modified: head/sys/dev/mrsas/mrsas.h
==============================================================================
--- head/sys/dev/mrsas/mrsas.h Wed May 6 10:36:53 2015 (r282526)
+++ head/sys/dev/mrsas/mrsas.h Wed May 6 10:41:27 2015 (r282527)
@@ -813,9 +813,8 @@ typedef struct _MR_DRV_RAID_MAP_ALL {
typedef struct _LD_LOAD_BALANCE_INFO {
u_int8_t loadBalanceFlag;
u_int8_t reserved1;
- u_int16_t raid1DevHandle[2];
- mrsas_atomic_t scsi_pending_cmds[2];
- u_int64_t last_accessed_block[2];
+ mrsas_atomic_t scsi_pending_cmds[MAX_PHYSICAL_DEVICES];
+ u_int64_t last_accessed_block[MAX_PHYSICAL_DEVICES];
} LD_LOAD_BALANCE_INFO, *PLD_LOAD_BALANCE_INFO;
/* SPAN_SET is info caclulated from span info from Raid map per ld */
@@ -858,6 +857,9 @@ struct IO_REQUEST_INFO {
u_int8_t start_span;
u_int8_t reserved;
u_int64_t start_row;
+ /* span[7:5], arm[4:0] */
+ u_int8_t span_arm;
+ u_int8_t pd_after_lb;
};
typedef struct _MR_LD_TARGET_SYNC {
@@ -1357,6 +1359,7 @@ struct mrsas_mpt_cmd {
u_int32_t sync_cmd_idx;
u_int32_t index;
u_int8_t flags;
+ u_int8_t pd_r1_lb;
u_int8_t load_balance;
bus_size_t length;
u_int32_t error_code;
@@ -2734,6 +2737,7 @@ struct mrsas_softc {
struct task ev_task;
u_int32_t CurLdCount;
u_int64_t reset_flags;
+ int lb_pending_cmds;
LD_LOAD_BALANCE_INFO load_balance_info[MAX_LOGICAL_DRIVES_EXT];
LD_SPAN_INFO log_to_span[MAX_LOGICAL_DRIVES_EXT];
Modified: head/sys/dev/mrsas/mrsas_cam.c
==============================================================================
--- head/sys/dev/mrsas/mrsas_cam.c Wed May 6 10:36:53 2015 (r282526)
+++ head/sys/dev/mrsas/mrsas_cam.c Wed May 6 10:41:27 2015 (r282527)
@@ -112,9 +112,8 @@ MR_BuildRaidContext(struct mrsas_softc *
extern u_int16_t
MR_LdSpanArrayGet(u_int32_t ld, u_int32_t span,
MR_DRV_RAID_MAP_ALL * map);
-extern u_int16_t
-mrsas_get_updated_dev_handle(PLD_LOAD_BALANCE_INFO lbInfo,
- struct IO_REQUEST_INFO *io_info);
+extern u_int16_t mrsas_get_updated_dev_handle(struct mrsas_softc *sc,
+ PLD_LOAD_BALANCE_INFO lbInfo, struct IO_REQUEST_INFO *io_info);
extern u_int8_t
megasas_get_best_arm(PLD_LOAD_BALANCE_INFO lbInfo, u_int8_t arm,
u_int64_t block, u_int32_t count);
@@ -824,9 +823,10 @@ mrsas_setup_io(struct mrsas_softc *sc, s
if ((sc->load_balance_info[device_id].loadBalanceFlag) &&
(io_info.isRead)) {
io_info.devHandle =
- mrsas_get_updated_dev_handle(&sc->load_balance_info[device_id],
- &io_info);
+ mrsas_get_updated_dev_handle(sc,
+ &sc->load_balance_info[device_id], &io_info);
cmd->load_balance = MRSAS_LOAD_BALANCE_FLAG;
+ cmd->pd_r1_lb = io_info.pd_after_lb;
} else
cmd->load_balance = 0;
cmd->request_desc->SCSIIO.DevHandle = io_info.devHandle;
Modified: head/sys/dev/mrsas/mrsas_fp.c
==============================================================================
--- head/sys/dev/mrsas/mrsas_fp.c Wed May 6 10:36:53 2015 (r282526)
+++ head/sys/dev/mrsas/mrsas_fp.c Wed May 6 10:41:27 2015 (r282527)
@@ -54,9 +54,8 @@ __FBSDID("$FreeBSD$");
* Function prototypes
*/
u_int8_t MR_ValidateMapInfo(struct mrsas_softc *sc);
-u_int8_t
-mrsas_get_best_arm(PLD_LOAD_BALANCE_INFO lbInfo, u_int8_t arm,
- u_int64_t block, u_int32_t count);
+u_int8_t mrsas_get_best_arm_pd(struct mrsas_softc *sc,
+ PLD_LOAD_BALANCE_INFO lbInfo, struct IO_REQUEST_INFO *io_info);
u_int8_t
MR_BuildRaidContext(struct mrsas_softc *sc,
struct IO_REQUEST_INFO *io_info,
@@ -69,17 +68,15 @@ MR_GetPhyParams(struct mrsas_softc *sc,
u_int16_t MR_TargetIdToLdGet(u_int32_t ldTgtId, MR_DRV_RAID_MAP_ALL * map);
u_int32_t MR_LdBlockSizeGet(u_int32_t ldTgtId, MR_DRV_RAID_MAP_ALL * map);
u_int16_t MR_GetLDTgtId(u_int32_t ld, MR_DRV_RAID_MAP_ALL * map);
-u_int16_t
-mrsas_get_updated_dev_handle(PLD_LOAD_BALANCE_INFO lbInfo,
- struct IO_REQUEST_INFO *io_info);
+u_int16_t mrsas_get_updated_dev_handle(struct mrsas_softc *sc,
+ PLD_LOAD_BALANCE_INFO lbInfo, struct IO_REQUEST_INFO *io_info);
u_int32_t mega_mod64(u_int64_t dividend, u_int32_t divisor);
u_int32_t
MR_GetSpanBlock(u_int32_t ld, u_int64_t row, u_int64_t *span_blk,
MR_DRV_RAID_MAP_ALL * map, int *div_error);
u_int64_t mega_div64_32(u_int64_t dividend, u_int32_t divisor);
-void
-mrsas_update_load_balance_params(MR_DRV_RAID_MAP_ALL * map,
- PLD_LOAD_BALANCE_INFO lbInfo);
+void mrsas_update_load_balance_params(struct mrsas_softc *sc,
+ MR_DRV_RAID_MAP_ALL *map, PLD_LOAD_BALANCE_INFO lbInfo);
void
mrsas_set_pd_lba(MRSAS_RAID_SCSI_IO_REQUEST * io_request,
u_int8_t cdb_len, struct IO_REQUEST_INFO *io_info, union ccb *ccb,
@@ -146,6 +143,8 @@ typedef u_int32_t REGION_LEN;
#define FALSE 0
#define TRUE 1
+#define LB_PENDING_CMDS_DEFAULT 4
+
/*
* Related Macros
@@ -379,7 +378,7 @@ MR_ValidateMapInfo(struct mrsas_softc *s
printf("Updating span set\n\n");
mr_update_span_set(drv_map, ldSpanInfo);
}
- mrsas_update_load_balance_params(drv_map, sc->load_balance_info);
+ mrsas_update_load_balance_params(sc, drv_map, sc->load_balance_info);
return 0;
}
@@ -723,9 +722,11 @@ get_arm(struct mrsas_softc *sc, u_int32_
* This routine calculates the arm, span and block for the specified stripe and
* reference in stripe using spanset
*
- * Inputs : Logical drive number
- * stripRow: Stripe number
- * stripRef: Reference in stripe
+ * Inputs :
+ * sc - HBA instance
+ * ld - Logical drive number
+ * stripRow: Stripe number
+ * stripRef: Reference in stripe
*
* Outputs : span - Span number block - Absolute Block
* number in the physical disk
@@ -785,6 +786,7 @@ mr_spanset_get_phy_params(struct mrsas_s
*pdBlock += stripRef + MR_LdSpanPtrGet(ld, span, map)->startBlk;
pRAID_Context->spanArm = (span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm;
+ io_info->span_arm = pRAID_Context->spanArm;
return retval;
}
@@ -1097,46 +1099,39 @@ mr_update_span_set(MR_DRV_RAID_MAP_ALL *
/*
* mrsas_update_load_balance_params: Update load balance parmas
- * Inputs: map pointer
- * Load balance info
+ * Inputs:
+ * sc - driver softc instance
+ * drv_map - driver RAID map
+ * lbInfo - Load balance info
*
* This function updates the load balance parameters for the LD config of a two
* drive optimal RAID-1.
*/
void
-mrsas_update_load_balance_params(MR_DRV_RAID_MAP_ALL * map,
- PLD_LOAD_BALANCE_INFO lbInfo)
+mrsas_update_load_balance_params(struct mrsas_softc *sc,
+ MR_DRV_RAID_MAP_ALL * drv_map, PLD_LOAD_BALANCE_INFO lbInfo)
{
int ldCount;
u_int16_t ld;
- u_int32_t pd, arRef;
MR_LD_RAID *raid;
- for (ldCount = 0; ldCount < MAX_LOGICAL_DRIVES; ldCount++) {
- ld = MR_TargetIdToLdGet(ldCount, map);
- if (ld >= MAX_LOGICAL_DRIVES) {
+ if(sc->lb_pending_cmds > 128 || sc->lb_pending_cmds < 1)
+ sc-> lb_pending_cmds = LB_PENDING_CMDS_DEFAULT;
+
+ for (ldCount = 0; ldCount < MAX_LOGICAL_DRIVES_EXT; ldCount++) {
+ ld = MR_TargetIdToLdGet(ldCount, drv_map);
+ if (ld >= MAX_LOGICAL_DRIVES_EXT) {
lbInfo[ldCount].loadBalanceFlag = 0;
continue;
}
- raid = MR_LdRaidGet(ld, map);
- /* Two drive Optimal RAID 1 */
- if ((raid->level == 1) && (raid->rowSize == 2) &&
- (raid->spanDepth == 1)
- && raid->ldState == MR_LD_STATE_OPTIMAL) {
- lbInfo[ldCount].loadBalanceFlag = 1;
-
- /* Get the array on which this span is present */
- arRef = MR_LdSpanArrayGet(ld, 0, map);
-
- /* Get the PD */
- pd = MR_ArPdGet(arRef, 0, map);
- /* Get dev handle from PD */
- lbInfo[ldCount].raid1DevHandle[0] = MR_PdDevHandleGet(pd, map);
- pd = MR_ArPdGet(arRef, 1, map);
- lbInfo[ldCount].raid1DevHandle[1] = MR_PdDevHandleGet(pd, map);
- } else
+ raid = MR_LdRaidGet(ld, drv_map);
+ if ((raid->level != 1) ||
+ (raid->ldState != MR_LD_STATE_OPTIMAL)) {
lbInfo[ldCount].loadBalanceFlag = 0;
+ continue;
+ }
+ lbInfo[ldCount].loadBalanceFlag = 1;
}
}
@@ -1332,57 +1327,92 @@ mrsas_set_pd_lba(MRSAS_RAID_SCSI_IO_REQU
}
/*
- * mrsas_get_best_arm: Determine the best spindle arm
- * Inputs: Load balance info
+ * mrsas_get_best_arm_pd: Determine the best spindle arm
+ * Inputs:
+ * sc - HBA instance
+ * lbInfo - Load balance info
+ * io_info - IO request info
*
* This function determines and returns the best arm by looking at the
* parameters of the last PD access.
*/
-u_int8_t
-mrsas_get_best_arm(PLD_LOAD_BALANCE_INFO lbInfo, u_int8_t arm,
- u_int64_t block, u_int32_t count)
+u_int8_t mrsas_get_best_arm_pd(struct mrsas_softc *sc,
+ PLD_LOAD_BALANCE_INFO lbInfo, struct IO_REQUEST_INFO *io_info)
{
- u_int16_t pend0, pend1;
+ MR_LD_RAID *raid;
+ MR_DRV_RAID_MAP_ALL *drv_map;
+ u_int16_t pend0, pend1, ld;
u_int64_t diff0, diff1;
- u_int8_t bestArm;
+ u_int8_t bestArm, pd0, pd1, span, arm;
+ u_int32_t arRef, span_row_size;
+
+ u_int64_t block = io_info->ldStartBlock;
+ u_int32_t count = io_info->numBlocks;
+
+ span = ((io_info->span_arm & RAID_CTX_SPANARM_SPAN_MASK)
+ >> RAID_CTX_SPANARM_SPAN_SHIFT);
+ arm = (io_info->span_arm & RAID_CTX_SPANARM_ARM_MASK);
+
+ drv_map = sc->ld_drv_map[(sc->map_id & 1)];
+ ld = MR_TargetIdToLdGet(io_info->ldTgtId, drv_map);
+ raid = MR_LdRaidGet(ld, drv_map);
+ span_row_size = sc->UnevenSpanSupport ?
+ SPAN_ROW_SIZE(drv_map, ld, span) : raid->rowSize;
+
+ arRef = MR_LdSpanArrayGet(ld, span, drv_map);
+ pd0 = MR_ArPdGet(arRef, arm, drv_map);
+ pd1 = MR_ArPdGet(arRef, (arm + 1) >= span_row_size ?
+ (arm + 1 - span_row_size): arm + 1, drv_map);
/* get the pending cmds for the data and mirror arms */
- pend0 = mrsas_atomic_read(&lbInfo->scsi_pending_cmds[0]);
- pend1 = mrsas_atomic_read(&lbInfo->scsi_pending_cmds[1]);
+ pend0 = mrsas_atomic_read(&lbInfo->scsi_pending_cmds[pd0]);
+ pend1 = mrsas_atomic_read(&lbInfo->scsi_pending_cmds[pd1]);
/* Determine the disk whose head is nearer to the req. block */
- diff0 = ABS_DIFF(block, lbInfo->last_accessed_block[0]);
- diff1 = ABS_DIFF(block, lbInfo->last_accessed_block[1]);
- bestArm = (diff0 <= diff1 ? 0 : 1);
+ diff0 = ABS_DIFF(block, lbInfo->last_accessed_block[pd0]);
+ diff1 = ABS_DIFF(block, lbInfo->last_accessed_block[pd1]);
+ bestArm = (diff0 <= diff1 ? arm : arm ^ 1);
- if ((bestArm == arm && pend0 > pend1 + 16) || (bestArm != arm && pend1 > pend0 + 16))
+ if ((bestArm == arm && pend0 > pend1 + sc->lb_pending_cmds) ||
+ (bestArm != arm && pend1 > pend0 + sc->lb_pending_cmds))
bestArm ^= 1;
/* Update the last accessed block on the correct pd */
- lbInfo->last_accessed_block[bestArm] = block + count - 1;
+ lbInfo->last_accessed_block[bestArm==arm ? pd0 : pd1] = block + count - 1;
+ io_info->span_arm = (span << RAID_CTX_SPANARM_SPAN_SHIFT) | bestArm;
+ io_info->pd_after_lb = (bestArm == arm) ? pd0:pd1;
+#if SPAN_DEBUG
+ if(arm != bestArm)
+ printf("LSI Debug R1 Load balance occur - span 0x%x arm 0x%x bestArm 0x%x "
+ "io_info->span_arm 0x%x\n",
+ span, arm, bestArm, io_info->span_arm);
+#endif
- return bestArm;
+ return io_info->pd_after_lb;
}
/*
* mrsas_get_updated_dev_handle: Get the update dev handle
- * Inputs: Load balance info io_info pointer
+ * Inputs:
+ * sc - Adapter instance soft state
+ * lbInfo - Load balance info
+ * io_info - io_info pointer
*
* This function determines and returns the updated dev handle.
*/
-u_int16_t
-mrsas_get_updated_dev_handle(PLD_LOAD_BALANCE_INFO lbInfo,
- struct IO_REQUEST_INFO *io_info)
+u_int16_t mrsas_get_updated_dev_handle(struct mrsas_softc *sc,
+ PLD_LOAD_BALANCE_INFO lbInfo, struct IO_REQUEST_INFO *io_info)
{
- u_int8_t arm, old_arm;
+ u_int8_t arm_pd;
u_int16_t devHandle;
+ MR_DRV_RAID_MAP_ALL *drv_map;
- old_arm = lbInfo->raid1DevHandle[0] == io_info->devHandle ? 0 : 1;
+ drv_map = sc->ld_drv_map[(sc->map_id & 1)];
/* get best new arm */
- arm = mrsas_get_best_arm(lbInfo, old_arm, io_info->ldStartBlock, io_info->numBlocks);
- devHandle = lbInfo->raid1DevHandle[arm];
- mrsas_atomic_inc(&lbInfo->scsi_pending_cmds[arm]);
+ arm_pd = mrsas_get_best_arm_pd(sc, lbInfo, io_info);
+ devHandle = MR_PdDevHandleGet(arm_pd, drv_map);
+ mrsas_atomic_inc(&lbInfo->scsi_pending_cmds[arm_pd]);
return devHandle;
}
@@ -1471,6 +1501,7 @@ MR_GetPhyParams(struct mrsas_softc *sc,
*pdBlock += stripRef + MR_LdSpanPtrGet(ld, span, map)->startBlk;
pRAID_Context->spanArm = (span << RAID_CTX_SPANARM_SPAN_SHIFT) | physArm;
+ io_info->span_arm = pRAID_Context->spanArm;
return retval;
}
More information about the svn-src-all
mailing list