From owner-svn-src-all@FreeBSD.ORG Wed May 6 10:41:29 2015 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id A362D3B7; Wed, 6 May 2015 10:41:29 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 9113C1362; Wed, 6 May 2015 10:41:29 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t46AfTre015896; Wed, 6 May 2015 10:41:29 GMT (envelope-from kadesai@FreeBSD.org) Received: (from kadesai@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t46AfSHm015890; Wed, 6 May 2015 10:41:28 GMT (envelope-from kadesai@FreeBSD.org) Message-Id: <201505061041.t46AfSHm015890@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: kadesai set sender to kadesai@FreeBSD.org using -f From: Kashyap D Desai Date: Wed, 6 May 2015 10:41:28 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r282527 - head/sys/dev/mrsas X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 06 May 2015 10:41:29 -0000 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; }