* Lower interrupt moderation timer 200->100.
Obtained from: NetBSD if_sk.c rev. 1.11 * Make interrupt moderation configurable via sysctl/tuneable. PR: kern/41220 Approved by: rwatson (mentor)
This commit is contained in:
parent
342779d193
commit
e2f49ebf07
@ -94,6 +94,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/module.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_arp.h>
|
||||
@ -241,6 +242,9 @@ static void sk_setfilt(struct sk_if_softc *, caddr_t, int);
|
||||
static void sk_setmulti(struct sk_if_softc *);
|
||||
static void sk_setpromisc(struct sk_if_softc *);
|
||||
|
||||
static int sysctl_int_range(SYSCTL_HANDLER_ARGS, int low, int high);
|
||||
static int sysctl_hw_sk_int_mod(SYSCTL_HANDLER_ARGS);
|
||||
|
||||
#ifdef SK_USEIOSPACE
|
||||
#define SK_RES SYS_RES_IOPORT
|
||||
#define SK_RID SK_PCI_LOIO
|
||||
@ -1307,7 +1311,9 @@ sk_reset(sc)
|
||||
* register represents 18.825ns, so to specify a timeout in
|
||||
* microseconds, we have to multiply by 54.
|
||||
*/
|
||||
sk_win_write_4(sc, SK_IMTIMERINIT, SK_IM_USECS(200));
|
||||
printf("skc%d: interrupt moderation is %d us\n",
|
||||
sc->sk_unit, sc->sk_int_mod);
|
||||
sk_win_write_4(sc, SK_IMTIMERINIT, SK_IM_USECS(sc->sk_int_mod));
|
||||
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);
|
||||
@ -1577,6 +1583,25 @@ skc_attach(dev)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
|
||||
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
|
||||
OID_AUTO, "int_mod", CTLTYPE_INT|CTLFLAG_RW,
|
||||
&sc->sk_int_mod, 0, sysctl_hw_sk_int_mod, "I",
|
||||
"SK interrupt moderation");
|
||||
|
||||
/* Pull in device tunables. */
|
||||
sc->sk_int_mod = SK_IM_DEFAULT;
|
||||
error = resource_int_value(device_get_name(dev), unit,
|
||||
"int_mod", &sc->sk_int_mod);
|
||||
if (error == 0) {
|
||||
if (sc->sk_int_mod < SK_IM_MIN ||
|
||||
sc->sk_int_mod > SK_IM_MAX) {
|
||||
printf("skc%d: int_mod value out of range; "
|
||||
"using default: %d\n", unit, SK_IM_DEFAULT);
|
||||
sc->sk_int_mod = SK_IM_DEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset the adapter. */
|
||||
sk_reset(sc);
|
||||
|
||||
@ -2648,6 +2673,7 @@ sk_init(xsc)
|
||||
struct ifnet *ifp;
|
||||
struct mii_data *mii;
|
||||
u_int16_t reg;
|
||||
u_int32_t imr;
|
||||
|
||||
SK_IF_LOCK(sc_if);
|
||||
|
||||
@ -2745,6 +2771,16 @@ sk_init(xsc)
|
||||
}
|
||||
sk_init_tx_ring(sc_if);
|
||||
|
||||
/* Set interrupt moderation if changed via sysctl. */
|
||||
/* SK_LOCK(sc); */
|
||||
imr = sk_win_read_4(sc, SK_IMTIMERINIT);
|
||||
if (imr != SK_IM_USECS(sc->sk_int_mod)) {
|
||||
sk_win_write_4(sc, SK_IMTIMERINIT, SK_IM_USECS(sc->sk_int_mod));
|
||||
printf("skc%d: interrupt moderation is %d us\n",
|
||||
sc->sk_unit, sc->sk_int_mod);
|
||||
}
|
||||
/* SK_UNLOCK(sc); */
|
||||
|
||||
/* Configure interrupt handling */
|
||||
CSR_READ_4(sc, SK_ISSR);
|
||||
if (sc_if->sk_port == SK_PORT_A)
|
||||
@ -2864,3 +2900,26 @@ sk_stop(sc_if)
|
||||
SK_IF_UNLOCK(sc_if);
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
sysctl_int_range(SYSCTL_HANDLER_ARGS, int low, int high)
|
||||
{
|
||||
int error, value;
|
||||
|
||||
if (!arg1)
|
||||
return (EINVAL);
|
||||
value = *(int *)arg1;
|
||||
error = sysctl_handle_int(oidp, &value, 0, req);
|
||||
if (error || !req->newptr)
|
||||
return (error);
|
||||
if (value < low || value > high)
|
||||
return (EINVAL);
|
||||
*(int *)arg1 = value;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
sysctl_hw_sk_int_mod(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
return (sysctl_int_range(oidp, arg1, arg2, req, SK_IM_MIN, SK_IM_MAX));
|
||||
}
|
||||
|
@ -376,6 +376,10 @@
|
||||
#define SK_IMTIMER_TICKS 54
|
||||
#define SK_IM_USECS(x) ((x) * SK_IMTIMER_TICKS)
|
||||
|
||||
#define SK_IM_MIN 10
|
||||
#define SK_IM_DEFAULT 100
|
||||
#define SK_IM_MAX 10000
|
||||
|
||||
/*
|
||||
* The SK_EPROM0 register contains a byte that describes the
|
||||
* amount of SRAM mounted on the NIC. The value also tells if
|
||||
@ -1442,6 +1446,7 @@ struct sk_softc {
|
||||
u_int32_t sk_ramsize; /* amount of RAM on NIC */
|
||||
u_int32_t sk_pmd; /* physical media type */
|
||||
u_int32_t sk_intrmask;
|
||||
int sk_int_mod;
|
||||
struct sk_if_softc *sk_if[2];
|
||||
device_t sk_devs[2];
|
||||
struct mtx sk_mtx;
|
||||
|
@ -94,6 +94,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/module.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_arp.h>
|
||||
@ -241,6 +242,9 @@ static void sk_setfilt(struct sk_if_softc *, caddr_t, int);
|
||||
static void sk_setmulti(struct sk_if_softc *);
|
||||
static void sk_setpromisc(struct sk_if_softc *);
|
||||
|
||||
static int sysctl_int_range(SYSCTL_HANDLER_ARGS, int low, int high);
|
||||
static int sysctl_hw_sk_int_mod(SYSCTL_HANDLER_ARGS);
|
||||
|
||||
#ifdef SK_USEIOSPACE
|
||||
#define SK_RES SYS_RES_IOPORT
|
||||
#define SK_RID SK_PCI_LOIO
|
||||
@ -1307,7 +1311,9 @@ sk_reset(sc)
|
||||
* register represents 18.825ns, so to specify a timeout in
|
||||
* microseconds, we have to multiply by 54.
|
||||
*/
|
||||
sk_win_write_4(sc, SK_IMTIMERINIT, SK_IM_USECS(200));
|
||||
printf("skc%d: interrupt moderation is %d us\n",
|
||||
sc->sk_unit, sc->sk_int_mod);
|
||||
sk_win_write_4(sc, SK_IMTIMERINIT, SK_IM_USECS(sc->sk_int_mod));
|
||||
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);
|
||||
@ -1577,6 +1583,25 @@ skc_attach(dev)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
|
||||
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
|
||||
OID_AUTO, "int_mod", CTLTYPE_INT|CTLFLAG_RW,
|
||||
&sc->sk_int_mod, 0, sysctl_hw_sk_int_mod, "I",
|
||||
"SK interrupt moderation");
|
||||
|
||||
/* Pull in device tunables. */
|
||||
sc->sk_int_mod = SK_IM_DEFAULT;
|
||||
error = resource_int_value(device_get_name(dev), unit,
|
||||
"int_mod", &sc->sk_int_mod);
|
||||
if (error == 0) {
|
||||
if (sc->sk_int_mod < SK_IM_MIN ||
|
||||
sc->sk_int_mod > SK_IM_MAX) {
|
||||
printf("skc%d: int_mod value out of range; "
|
||||
"using default: %d\n", unit, SK_IM_DEFAULT);
|
||||
sc->sk_int_mod = SK_IM_DEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset the adapter. */
|
||||
sk_reset(sc);
|
||||
|
||||
@ -2648,6 +2673,7 @@ sk_init(xsc)
|
||||
struct ifnet *ifp;
|
||||
struct mii_data *mii;
|
||||
u_int16_t reg;
|
||||
u_int32_t imr;
|
||||
|
||||
SK_IF_LOCK(sc_if);
|
||||
|
||||
@ -2745,6 +2771,16 @@ sk_init(xsc)
|
||||
}
|
||||
sk_init_tx_ring(sc_if);
|
||||
|
||||
/* Set interrupt moderation if changed via sysctl. */
|
||||
/* SK_LOCK(sc); */
|
||||
imr = sk_win_read_4(sc, SK_IMTIMERINIT);
|
||||
if (imr != SK_IM_USECS(sc->sk_int_mod)) {
|
||||
sk_win_write_4(sc, SK_IMTIMERINIT, SK_IM_USECS(sc->sk_int_mod));
|
||||
printf("skc%d: interrupt moderation is %d us\n",
|
||||
sc->sk_unit, sc->sk_int_mod);
|
||||
}
|
||||
/* SK_UNLOCK(sc); */
|
||||
|
||||
/* Configure interrupt handling */
|
||||
CSR_READ_4(sc, SK_ISSR);
|
||||
if (sc_if->sk_port == SK_PORT_A)
|
||||
@ -2864,3 +2900,26 @@ sk_stop(sc_if)
|
||||
SK_IF_UNLOCK(sc_if);
|
||||
return;
|
||||
}
|
||||
|
||||
static int
|
||||
sysctl_int_range(SYSCTL_HANDLER_ARGS, int low, int high)
|
||||
{
|
||||
int error, value;
|
||||
|
||||
if (!arg1)
|
||||
return (EINVAL);
|
||||
value = *(int *)arg1;
|
||||
error = sysctl_handle_int(oidp, &value, 0, req);
|
||||
if (error || !req->newptr)
|
||||
return (error);
|
||||
if (value < low || value > high)
|
||||
return (EINVAL);
|
||||
*(int *)arg1 = value;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
sysctl_hw_sk_int_mod(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
return (sysctl_int_range(oidp, arg1, arg2, req, SK_IM_MIN, SK_IM_MAX));
|
||||
}
|
||||
|
@ -376,6 +376,10 @@
|
||||
#define SK_IMTIMER_TICKS 54
|
||||
#define SK_IM_USECS(x) ((x) * SK_IMTIMER_TICKS)
|
||||
|
||||
#define SK_IM_MIN 10
|
||||
#define SK_IM_DEFAULT 100
|
||||
#define SK_IM_MAX 10000
|
||||
|
||||
/*
|
||||
* The SK_EPROM0 register contains a byte that describes the
|
||||
* amount of SRAM mounted on the NIC. The value also tells if
|
||||
@ -1442,6 +1446,7 @@ struct sk_softc {
|
||||
u_int32_t sk_ramsize; /* amount of RAM on NIC */
|
||||
u_int32_t sk_pmd; /* physical media type */
|
||||
u_int32_t sk_intrmask;
|
||||
int sk_int_mod;
|
||||
struct sk_if_softc *sk_if[2];
|
||||
device_t sk_devs[2];
|
||||
struct mtx sk_mtx;
|
||||
|
Loading…
x
Reference in New Issue
Block a user