From dbe44a554a2938703675d101e62711a415e58814 Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Sat, 23 Jun 2007 09:25:02 +0000 Subject: [PATCH] - Add hw.skcX.imtime sysctl node and hw.skc.imtime tunable for interrupt moderation time. Adjusting of hw.skcX.imtime will be committed to NIC immediately. - Increase default interrupt moderation time from 100 usec to 160 usec. This reduces host interrupt load without noticable performance impact. --- sys/dev/netif/sk/if_sk.c | 88 ++++++++++++++++++++++++++++++++----- sys/dev/netif/sk/if_skreg.h | 5 ++- sys/dev/netif/sk/if_skvar.h | 6 ++- 3 files changed, 85 insertions(+), 14 deletions(-) diff --git a/sys/dev/netif/sk/if_sk.c b/sys/dev/netif/sk/if_sk.c index 557c73c278..b785bc9b81 100644 --- a/sys/dev/netif/sk/if_sk.c +++ b/sys/dev/netif/sk/if_sk.c @@ -31,7 +31,7 @@ * * $OpenBSD: if_sk.c,v 1.129 2006/10/16 12:30:08 tom Exp $ * $FreeBSD: /c/ncvs/src/sys/pci/if_sk.c,v 1.20 2000/04/22 02:16:37 wpaul Exp $ - * $DragonFly: src/sys/dev/netif/sk/if_sk.c,v 1.52 2006/12/22 23:26:22 swildner Exp $ + * $DragonFly: src/sys/dev/netif/sk/if_sk.c,v 1.53 2007/06/23 09:25:02 sephe Exp $ */ /* @@ -98,6 +98,7 @@ #include #include #include +#include #include #include @@ -175,6 +176,8 @@ static int skc_probe(device_t); static int skc_attach(device_t); static int skc_detach(device_t); static void skc_shutdown(device_t); +static int skc_sysctl_imtime(SYSCTL_HANDLER_ARGS); + static int sk_probe(device_t); static int sk_attach(device_t); static int sk_detach(device_t); @@ -248,6 +251,10 @@ static void sk_dump_bytes(const char *, int); #define DPRINTFN(n,x) #endif +/* Interrupt moderation time. */ +static int skc_imtime = SK_IMTIME_DEFAULT; +TUNABLE_INT("hw.skc.imtime", &skc_imtime); + /* * Note that we have newbus methods for both the GEnesis controller * itself and the XMAC(s). The XMACs are children of the GEnesis, and @@ -1039,8 +1046,6 @@ skc_probe(device_t dev) static void sk_reset(struct sk_softc *sc) { - uint32_t imtimer_ticks; - DPRINTFN(2, ("sk_reset\n")); CSR_WRITE_2(sc, SK_CSR, SK_CSR_SW_RESET); @@ -1080,14 +1085,8 @@ sk_reset(struct sk_softc *sc) * microseconds, we have to multiply by the correct number of * ticks-per-microsecond. */ - switch (sc->sk_type) { - case SK_GENESIS: - imtimer_ticks = SK_IMTIMER_TICKS_GENESIS; - break; - default: - imtimer_ticks = SK_IMTIMER_TICKS_YUKON; - } - sk_win_write_4(sc, SK_IMTIMERINIT, SK_IM_USECS(100)); + KKASSERT(sc->sk_imtimer_ticks != 0 && sc->sk_imtime != 0); + sk_win_write_4(sc, SK_IMTIMERINIT, SK_IM_USECS(sc, sc->sk_imtime)); sk_win_write_4(sc, SK_IMMR, SK_ISR_TX1_S_EOF|SK_ISR_TX2_S_EOF| SK_ISR_RX1_EOF|SK_ISR_RX2_EOF); sk_win_write_1(sc, SK_IMTIMERCTL, SK_IMCTL_START); @@ -1392,6 +1391,16 @@ skc_attach(device_t dev) goto fail; } + switch (sc->sk_type) { + case SK_GENESIS: + sc->sk_imtimer_ticks = SK_IMTIMER_TICKS_GENESIS; + break; + default: + sc->sk_imtimer_ticks = SK_IMTIMER_TICKS_YUKON; + break; + } + sc->sk_imtime = skc_imtime; + /* Reset the adapter. */ sk_reset(sc); @@ -1460,6 +1469,26 @@ skc_attach(device_t dev) } } + /* + * Create sysctl nodes. + */ + sysctl_ctx_init(&sc->sk_sysctl_ctx); + sc->sk_sysctl_tree = SYSCTL_ADD_NODE(&sc->sk_sysctl_ctx, + SYSCTL_STATIC_CHILDREN(_hw), + OID_AUTO, + device_get_nameunit(dev), + CTLFLAG_RD, 0, ""); + if (sc->sk_sysctl_tree == NULL) { + device_printf(dev, "can't add sysctl node\n"); + error = ENXIO; + goto fail; + } + SYSCTL_ADD_PROC(&sc->sk_sysctl_ctx, + SYSCTL_CHILDREN(sc->sk_sysctl_tree), + OID_AUTO, "imtime", CTLTYPE_INT | CTLFLAG_RW, + sc, 0, skc_sysctl_imtime, "I", + "Interrupt moderation time (usec)."); + sc->sk_devs[SK_PORT_A] = device_add_child(dev, "sk", -1); port = kmalloc(sizeof(*port), M_DEVBUF, M_WAITOK); *port = SK_PORT_A; @@ -1552,6 +1581,9 @@ skc_detach(device_t dev) sc->sk_res); } + if (sc->sk_sysctl_tree != NULL) + sysctl_ctx_free(&sc->sk_sysctl_ctx); + return 0; } @@ -3208,3 +3240,37 @@ sk_dmamem_addr(void *arg, bus_dma_segment_t *seg, int nseg, int error) KASSERT(nseg == 1, ("too many segments %d", nseg)); *((bus_addr_t *)arg) = seg->ds_addr; } + +static int +skc_sysctl_imtime(SYSCTL_HANDLER_ARGS) +{ + struct sk_softc *sc = arg1; + struct lwkt_serialize *slize = &sc->sk_serializer; + int error = 0, v; + + lwkt_serialize_enter(slize); + + v = sc->sk_imtime; + error = sysctl_handle_int(oidp, &v, 0, req); + if (error || req->newptr == NULL) + goto back; + if (v <= 0) { + error = EINVAL; + goto back; + } + + if (sc->sk_imtime != v) { + sc->sk_imtime = v; + sk_win_write_4(sc, SK_IMTIMERINIT, + SK_IM_USECS(sc, sc->sk_imtime)); + + /* + * Force interrupt moderation timer to + * reload new value. + */ + sk_win_write_4(sc, SK_IMTIMER, 0); + } +back: + lwkt_serialize_exit(slize); + return error; +} diff --git a/sys/dev/netif/sk/if_skreg.h b/sys/dev/netif/sk/if_skreg.h index e84a34d32c..d22895b00c 100644 --- a/sys/dev/netif/sk/if_skreg.h +++ b/sys/dev/netif/sk/if_skreg.h @@ -31,7 +31,7 @@ * * $FreeBSD: /c/ncvs/src/sys/pci/if_skreg.h,v 1.9 2000/04/22 02:16:37 wpaul Exp $ * $OpenBSD: if_skreg.h,v 1.39 2006/08/20 19:15:46 brad Exp $ - * $DragonFly: src/sys/dev/netif/sk/if_skreg.h,v 1.12 2006/11/14 12:52:31 sephe Exp $ + * $DragonFly: src/sys/dev/netif/sk/if_skreg.h,v 1.13 2007/06/23 09:25:02 sephe Exp $ */ /* @@ -337,7 +337,8 @@ #define SK_IMTIMER_TICKS_GENESIS 53 #define SK_IMTIMER_TICKS_YUKON 78 #define SK_IMTIMER_TICKS_YUKON_EC 125 -#define SK_IM_USECS(x) ((x) * imtimer_ticks) +#define SK_IMTIME_DEFAULT 160 /* microseconds */ +#define SK_IM_USECS(sc, x) ((x) * (sc)->sk_imtimer_ticks) /* * The SK_EPROM0 register contains a byte that describes the diff --git a/sys/dev/netif/sk/if_skvar.h b/sys/dev/netif/sk/if_skvar.h index 89bfa5d0d7..8c90ca348f 100644 --- a/sys/dev/netif/sk/if_skvar.h +++ b/sys/dev/netif/sk/if_skvar.h @@ -66,7 +66,7 @@ * $FreeBSD: /c/ncvs/src/sys/pci/if_skreg.h,v 1.9 2000/04/22 02:16:37 wpaul Exp $ * $NetBSD: if_skvar.h,v 1.6 2005/05/30 04:35:22 christos Exp $ * $OpenBSD: if_skvar.h,v 1.2 2005/12/22 20:54:47 brad Exp $ - * $DragonFly: src/sys/dev/netif/sk/if_skvar.h,v 1.2 2006/12/21 14:13:04 sephe Exp $ + * $DragonFly: src/sys/dev/netif/sk/if_skvar.h,v 1.3 2007/06/23 09:25:02 sephe Exp $ */ /* @@ -169,6 +169,10 @@ struct sk_softc { uint32_t sk_rboff; /* RAMbuffer offset */ uint32_t sk_ramsize; /* amount of RAM on NIC */ uint32_t sk_intrmask; + uint32_t sk_imtimer_ticks; + int sk_imtime; + struct sysctl_ctx_list sk_sysctl_ctx; + struct sysctl_oid *sk_sysctl_tree; struct lwkt_serialize sk_serializer; struct sk_if_softc *sk_if[2]; device_t sk_devs[2]; -- 2.41.0