svn commit: r205609 - stable/8/sys/dev/msk

Pyun YongHyeon yongari at FreeBSD.org
Wed Mar 24 17:11:01 UTC 2010


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;


More information about the svn-src-all mailing list