From owner-svn-src-stable@FreeBSD.ORG Wed Mar 24 17:11:01 2010 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 627F8106566C; Wed, 24 Mar 2010 17:11:01 +0000 (UTC) (envelope-from yongari@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 500FE8FC0C; Wed, 24 Mar 2010 17:11:01 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o2OHB1If061069; Wed, 24 Mar 2010 17:11:01 GMT (envelope-from yongari@svn.freebsd.org) Received: (from yongari@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o2OHB13t061066; Wed, 24 Mar 2010 17:11:01 GMT (envelope-from yongari@svn.freebsd.org) Message-Id: <201003241711.o2OHB13t061066@svn.freebsd.org> From: Pyun YongHyeon Date: Wed, 24 Mar 2010 17:11:01 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r205609 - stable/8/sys/dev/msk X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 24 Mar 2010 17:11:01 -0000 Author: yongari Date: Wed Mar 24 17:11:01 2010 New Revision: 205609 URL: http://svn.freebsd.org/changeset/base/205609 Log: MFC r204541: Implement rudimentary interrupt moderation with programmable countdown timer register. The timer resolution may vary among controllers but the value would be represented by core clock cycles. msk(4) will automatically computes number of required clock cycles from given micro-seconds unit. The default interrupt holdoff timer value is 100us which will ensure less than 10k interrupts under load. The timer value can be changed with dev.mskc.0.int_holdoff sysctl node. Note, the interrupt moderation is shared resource on dual-port controllers so you can't use separate interrupt moderation value for each port. This means we can't stop interrupt moderation in driver stop routine. Also have msk_tick() reclaim transmitted Tx buffers as safety belt. With this change there is no need to check missing Tx completion interrupt in watchdog handler, so remove it. Modified: stable/8/sys/dev/msk/if_msk.c stable/8/sys/dev/msk/if_mskreg.h Directory Properties: stable/8/sys/ (props changed) stable/8/sys/amd64/include/xen/ (props changed) stable/8/sys/cddl/contrib/opensolaris/ (props changed) stable/8/sys/contrib/dev/acpica/ (props changed) stable/8/sys/contrib/pf/ (props changed) stable/8/sys/dev/xen/xenpci/ (props changed) stable/8/sys/net/ (props changed) Modified: stable/8/sys/dev/msk/if_msk.c ============================================================================== --- stable/8/sys/dev/msk/if_msk.c Wed Mar 24 16:47:12 2010 (r205608) +++ stable/8/sys/dev/msk/if_msk.c Wed Mar 24 17:11:01 2010 (r205609) @@ -1661,6 +1661,14 @@ mskc_attach(device_t dev) } } + sc->msk_int_holdoff = MSK_INT_HOLDOFF_DEFAULT; + SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), + SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, + "int_holdoff", CTLFLAG_RW, &sc->msk_int_holdoff, 0, + "Maximum number of time to delay interrupts"); + resource_int_value(device_get_name(dev), device_get_unit(dev), + "int_holdoff", &sc->msk_int_holdoff); + /* Soft reset. */ CSR_WRITE_2(sc, B0_CTST, CS_RST_SET); CSR_WRITE_2(sc, B0_CTST, CS_RST_CLR); @@ -2803,8 +2811,6 @@ static void msk_watchdog(struct msk_if_softc *sc_if) { struct ifnet *ifp; - uint32_t ridx; - int idx; MSK_IF_LOCK_ASSERT(sc_if); @@ -2821,24 +2827,6 @@ msk_watchdog(struct msk_if_softc *sc_if) return; } - /* - * Reclaim first as there is a possibility of losing Tx completion - * interrupts. - */ - ridx = sc_if->msk_port == MSK_PORT_A ? STAT_TXA1_RIDX : STAT_TXA2_RIDX; - idx = CSR_READ_2(sc_if->msk_softc, ridx); - if (sc_if->msk_cdata.msk_tx_cons != idx) { - msk_txeof(sc_if, idx); - if (sc_if->msk_cdata.msk_tx_cnt == 0) { - if_printf(ifp, "watchdog timeout (missed Tx interrupts) " - "-- recovering\n"); - if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) - taskqueue_enqueue(taskqueue_fast, - &sc_if->msk_tx_task); - return; - } - } - if_printf(ifp, "watchdog timeout\n"); ifp->if_oerrors++; ifp->if_drv_flags &= ~IFF_DRV_RUNNING; @@ -3168,6 +3156,7 @@ msk_tick(void *xsc_if) mii_tick(mii); if ((sc_if->msk_flags & MSK_FLAG_LINK) == 0) msk_miibus_statchg(sc_if->msk_if_dev); + msk_handle_events(sc_if->msk_softc); msk_watchdog(sc_if); callout_reset(&sc_if->msk_tick_ch, hz, msk_tick, sc_if); } @@ -3906,6 +3895,17 @@ msk_init_locked(struct msk_if_softc *sc_ sc->msk_intrmask |= Y2_IS_PORT_B; sc->msk_intrhwemask |= Y2_HWE_L2_MASK; } + /* Configure IRQ moderation mask. */ + CSR_WRITE_4(sc, B2_IRQM_MSK, sc->msk_intrmask); + if (sc->msk_int_holdoff > 0) { + /* Configure initial IRQ moderation timer value. */ + CSR_WRITE_4(sc, B2_IRQM_INI, + MSK_USECS(sc, sc->msk_int_holdoff)); + CSR_WRITE_4(sc, B2_IRQM_VAL, + MSK_USECS(sc, sc->msk_int_holdoff)); + /* Start IRQ moderation. */ + CSR_WRITE_1(sc, B2_IRQM_CTRL, TIM_START); + } CSR_WRITE_4(sc, B0_HWE_IMSK, sc->msk_intrhwemask); CSR_READ_4(sc, B0_HWE_IMSK); CSR_WRITE_4(sc, B0_IMSK, sc->msk_intrmask); Modified: stable/8/sys/dev/msk/if_mskreg.h ============================================================================== --- stable/8/sys/dev/msk/if_mskreg.h Wed Mar 24 16:47:12 2010 (r205608) +++ stable/8/sys/dev/msk/if_mskreg.h Wed Mar 24 17:11:01 2010 (r205609) @@ -2406,6 +2406,8 @@ struct msk_ring_data { #define MSK_PROC_MIN 30 #define MSK_PROC_MAX (MSK_RX_RING_CNT - 1) +#define MSK_INT_HOLDOFF_DEFAULT 100 + #define MSK_TX_TIMEOUT 5 #define MSK_PUT_WM 10 @@ -2496,6 +2498,7 @@ struct msk_softc { bus_dmamap_t msk_stat_map; struct msk_stat_desc *msk_stat_ring; bus_addr_t msk_stat_ring_paddr; + int msk_int_holdoff; int msk_process_limit; int msk_stat_cons; struct taskqueue *msk_tq;