From owner-svn-src-all@freebsd.org Tue Apr 12 18:50:39 2016 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 03848B0EF7A; Tue, 12 Apr 2016 18:50:39 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::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 CE26813AA; Tue, 12 Apr 2016 18:50:38 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u3CIocjB000478; Tue, 12 Apr 2016 18:50:38 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u3CIoc9k000477; Tue, 12 Apr 2016 18:50:38 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201604121850.u3CIoc9k000477@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Tue, 12 Apr 2016 18:50:38 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r297867 - head/sys/dev/isp 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.21 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: Tue, 12 Apr 2016 18:50:39 -0000 Author: mav Date: Tue Apr 12 18:50:37 2016 New Revision: 297867 URL: https://svnweb.freebsd.org/changeset/base/297867 Log: Make all CT Pass-Through (name server requests) asynchronous. Previously we had to do it synchronously because we could not drop the lock due to potential scratch memory use conflicts. Previous commits fixed that collision, so here it goes -- slower and less reliable external requests are executed asynchronously without spinning in tight loop and with more safe timeout handling. Modified: head/sys/dev/isp/isp.c Modified: head/sys/dev/isp/isp.c ============================================================================== --- head/sys/dev/isp/isp.c Tue Apr 12 18:24:02 2016 (r297866) +++ head/sys/dev/isp/isp.c Tue Apr 12 18:50:37 2016 (r297867) @@ -3078,20 +3078,31 @@ isp_fclink_test(ispsoftc_t *isp, int cha fcp->isp_fabric_params = mbs.param[7]; fcp->isp_sns_hdl = NPH_SNS_ID; r = isp_register_fc4_type_24xx(isp, chan); - if (r == 0) - isp_register_fc4_features_24xx(isp, chan); - isp_register_port_name_24xx(isp, chan); + if (fcp->isp_loopstate < LOOP_TESTING_LINK) + goto abort; + if (r != 0) + goto not_on_fabric; + r = isp_register_fc4_features_24xx(isp, chan); + if (fcp->isp_loopstate < LOOP_TESTING_LINK) + goto abort; + if (r != 0) + goto not_on_fabric; + r = isp_register_port_name_24xx(isp, chan); + if (fcp->isp_loopstate < LOOP_TESTING_LINK) + goto abort; + if (r != 0) + goto not_on_fabric; isp_register_node_name_24xx(isp, chan); + if (fcp->isp_loopstate < LOOP_TESTING_LINK) + goto abort; } else { fcp->isp_sns_hdl = SNS_ID; r = isp_register_fc4_type(isp, chan); - if (r == 0 && fcp->role == ISP_ROLE_TARGET) + if (r != 0) + goto not_on_fabric; + if (fcp->role == ISP_ROLE_TARGET) isp_send_change_request(isp, chan); } - if (r) { - isp_prt(isp, ISP_LOGWARN|ISP_LOG_SANCFG, "%s: register fc4 type failed", __func__); - return (-1); - } } not_on_fabric: @@ -3505,65 +3516,66 @@ isp_gid_ft_sns(ispsoftc_t *isp, int chan static int isp_ct_passthru(ispsoftc_t *isp, int chan, uint32_t cmd_bcnt, uint32_t rsp_bcnt) { - mbreg_t mbs; fcparam *fcp = FCPARAM(isp, chan); - union { - isp_ct_pt_t plocal; - uint8_t q[QENTRY_LEN]; - } un; - isp_ct_pt_t *pt; - uint8_t *scp = fcp->isp_scratch; + isp_ct_pt_t pt; + void *reqp; + uint8_t resp[QENTRY_LEN]; /* * Build a Passthrough IOCB in memory. */ - pt = &un.plocal; - ISP_MEMZERO(un.q, QENTRY_LEN); - pt->ctp_header.rqs_entry_count = 1; - pt->ctp_header.rqs_entry_type = RQSTYPE_CT_PASSTHRU; - pt->ctp_handle = 0xffffffff; - pt->ctp_nphdl = fcp->isp_sns_hdl; - pt->ctp_cmd_cnt = 1; - pt->ctp_vpidx = ISP_GET_VPIDX(isp, chan); - pt->ctp_time = 10; - pt->ctp_rsp_cnt = 1; - pt->ctp_rsp_bcnt = rsp_bcnt; - pt->ctp_cmd_bcnt = cmd_bcnt; - pt->ctp_dataseg[0].ds_base = DMA_LO32(fcp->isp_scdma+XTXOFF); - pt->ctp_dataseg[0].ds_basehi = DMA_HI32(fcp->isp_scdma+XTXOFF); - pt->ctp_dataseg[0].ds_count = cmd_bcnt; - pt->ctp_dataseg[1].ds_base = DMA_LO32(fcp->isp_scdma); - pt->ctp_dataseg[1].ds_basehi = DMA_HI32(fcp->isp_scdma); - pt->ctp_dataseg[1].ds_count = rsp_bcnt; - isp_put_ct_pt(isp, pt, (isp_ct_pt_t *)&scp[CTXOFF]); - if (isp->isp_dblev & ISP_LOGDEBUG1) - isp_print_bytes(isp, "CT IOCB request", QENTRY_LEN, &scp[CTXOFF]); + ISP_MEMZERO(&pt, sizeof(pt)); + pt.ctp_header.rqs_entry_count = 1; + pt.ctp_header.rqs_entry_type = RQSTYPE_CT_PASSTHRU; + pt.ctp_nphdl = fcp->isp_sns_hdl; + pt.ctp_cmd_cnt = 1; + pt.ctp_vpidx = ISP_GET_VPIDX(isp, chan); + pt.ctp_time = 10; + pt.ctp_rsp_cnt = 1; + pt.ctp_rsp_bcnt = rsp_bcnt; + pt.ctp_cmd_bcnt = cmd_bcnt; + pt.ctp_dataseg[0].ds_base = DMA_LO32(fcp->isp_scdma+XTXOFF); + pt.ctp_dataseg[0].ds_basehi = DMA_HI32(fcp->isp_scdma+XTXOFF); + pt.ctp_dataseg[0].ds_count = cmd_bcnt; + pt.ctp_dataseg[1].ds_base = DMA_LO32(fcp->isp_scdma); + pt.ctp_dataseg[1].ds_basehi = DMA_HI32(fcp->isp_scdma); + pt.ctp_dataseg[1].ds_count = rsp_bcnt; + + /* Prepare space for response in memory */ + memset(resp, 0xff, sizeof(resp)); + pt.ctp_handle = isp_allocate_handle(isp, resp, ISP_HANDLE_CTRL); + if (pt.ctp_handle == 0) { + isp_prt(isp, ISP_LOGERR, + "%s: CTP of Chan %d out of handles", __func__, chan); + return (-1); + } - /* - * Execute the Passthrough IOCB. - */ - ISP_MEMZERO(&scp[ZTXOFF], QENTRY_LEN); - MBSINIT(&mbs, MBOX_EXEC_COMMAND_IOCB_A64, MBLOGALL, - MBCMD_DEFAULT_TIMEOUT + pt->ctp_time * 1000000); - mbs.param[1] = QENTRY_LEN; - mbs.param[2] = DMA_WD1(fcp->isp_scdma + CTXOFF); - mbs.param[3] = DMA_WD0(fcp->isp_scdma + CTXOFF); - mbs.param[6] = DMA_WD3(fcp->isp_scdma + CTXOFF); - mbs.param[7] = DMA_WD2(fcp->isp_scdma + CTXOFF); - MEMORYBARRIER(isp, SYNC_SFORDEV, XTXOFF, 2 * QENTRY_LEN, chan); - isp_mboxcmd(isp, &mbs); - if (mbs.param[0] != MBOX_COMMAND_COMPLETE) { + /* Send request and wait for response. */ + reqp = isp_getrqentry(isp); + if (reqp == NULL) { + isp_prt(isp, ISP_LOGERR, + "%s: CTP of Chan %d out of rqent", __func__, chan); + isp_destroy_handle(isp, pt.ctp_handle); return (-1); } - MEMORYBARRIER(isp, SYNC_SFORCPU, 0, ISP_FC_SCRLEN, chan); + isp_put_ct_pt(isp, &pt, (isp_ct_pt_t *)reqp); if (isp->isp_dblev & ISP_LOGDEBUG1) - isp_print_bytes(isp, "CT IOCB response", QENTRY_LEN, &scp[ZTXOFF]); - pt = &un.plocal; - isp_get_ct_pt(isp, (isp_ct_pt_t *) &scp[ZTXOFF], pt); - if (pt->ctp_status && pt->ctp_status != RQCS_DATA_UNDERRUN) { + isp_print_bytes(isp, "CT IOCB request", QENTRY_LEN, reqp); + ISP_SYNC_REQUEST(isp); + if (msleep(resp, &isp->isp_lock, 0, "CTP", pt.ctp_time*hz) == EWOULDBLOCK) { + isp_prt(isp, ISP_LOGERR, + "%s: CTP of Chan %d timed out", __func__, chan); + isp_destroy_handle(isp, pt.ctp_handle); + return (-1); + } + if (isp->isp_dblev & ISP_LOGDEBUG1) + isp_print_bytes(isp, "CT IOCB response", QENTRY_LEN, resp); + + isp_get_ct_pt(isp, (isp_ct_pt_t *)resp, &pt); + if (pt.ctp_status && pt.ctp_status != RQCS_DATA_UNDERRUN) { isp_prt(isp, ISP_LOGWARN, "Chan %d GID_FT CT Passthrough returned 0x%x", - chan, pt->ctp_status); + chan, pt.ctp_status); return (-1); } @@ -3931,7 +3943,13 @@ isp_send_change_request(ispsoftc_t *isp, mbs.param[1] = 0x03; mbs.param[9] = chan; isp_mboxcmd(isp, &mbs); - return (mbs.param[0] == MBOX_COMMAND_COMPLETE ? 0 : -1); + if (mbs.param[0] == MBOX_COMMAND_COMPLETE) { + return (0); + } else { + isp_prt(isp, ISP_LOGWARN, "Chan %d Send Change Request: 0x%x", + chan, mbs.param[0]); + return (-1); + } } static int @@ -3970,6 +3988,8 @@ isp_register_fc4_type(ispsoftc_t *isp, i if (mbs.param[0] == MBOX_COMMAND_COMPLETE) { return (0); } else { + isp_prt(isp, ISP_LOGWARN, "Chan %d Register FC4 Type: 0x%x", + chan, mbs.param[0]); return (-1); } } @@ -6140,6 +6160,7 @@ isp_handle_other_response(ispsoftc_t *is } } return (1); + case RQSTYPE_CT_PASSTHRU: case RQSTYPE_VP_MODIFY: case RQSTYPE_VP_CTRL: case RQSTYPE_LOGIN: