Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

emx: Allow user to specify RX/TX processing CPU's offset

  • Loading branch information...
commit 09f49d522029d6a76976f2a91fca9e9260ec0c03 1 parent b0da0c8
Sepherosa Ziehau authored
Showing with 123 additions and 9 deletions.
  1. +120 −9 sys/dev/netif/emx/if_emx.c
  2. +3 −0  sys/dev/netif/emx/if_emx.h
View
129 sys/dev/netif/emx/if_emx.c
@@ -242,6 +242,10 @@ static int emx_sysctl_stats(SYSCTL_HANDLER_ARGS);
static int emx_sysctl_debug_info(SYSCTL_HANDLER_ARGS);
static int emx_sysctl_int_throttle(SYSCTL_HANDLER_ARGS);
static int emx_sysctl_int_tx_nsegs(SYSCTL_HANDLER_ARGS);
+#ifdef IFPOLL_ENABLE
+static int emx_sysctl_npoll_rxoff(SYSCTL_HANDLER_ARGS);
+static int emx_sysctl_npoll_txoff(SYSCTL_HANDLER_ARGS);
+#endif
static void emx_add_sysctl(struct emx_softc *);
static void emx_serialize_skipmain(struct emx_softc *);
@@ -413,6 +417,9 @@ emx_attach(device_t dev)
u_int intr_flags;
uint16_t eeprom_data, device_id, apme_mask;
driver_intr_t *intr_func;
+#ifdef IFPOLL_ENABLE
+ int offset, offset_def;
+#endif
lwkt_serialize_init(&sc->main_serialize);
lwkt_serialize_init(&sc->tx_serialize);
@@ -689,6 +696,37 @@ emx_attach(device_t dev)
/* XXX disable wol */
sc->wol = 0;
+#ifdef IFPOLL_ENABLE
+ /*
+ * NPOLLING RX CPU offset
+ */
+ if (sc->rx_ring_cnt == ncpus2) {
+ offset = 0;
+ } else {
+ offset_def = (sc->rx_ring_cnt * device_get_unit(dev)) % ncpus2;
+ offset = device_getenv_int(dev, "npoll.rxoff", offset_def);
+ if (offset >= ncpus2 ||
+ offset % sc->rx_ring_cnt != 0) {
+ device_printf(dev, "invalid npoll.rxoff %d, use %d\n",
+ offset, offset_def);
+ offset = offset_def;
+ }
+ }
+ sc->rx_npoll_off = offset;
+
+ /*
+ * NPOLLING TX CPU offset
+ */
+ offset_def = sc->rx_npoll_off;
+ offset = device_getenv_int(dev, "npoll.txoff", offset_def);
+ if (offset >= ncpus2) {
+ device_printf(dev, "invalid npoll.txoff %d, use %d\n",
+ offset, offset_def);
+ offset = offset_def;
+ }
+ sc->tx_npoll_off = offset;
+#endif
+
/* Setup OS specific network interface */
emx_setup_ifp(sc);
@@ -3406,6 +3444,17 @@ emx_add_sysctl(struct emx_softc *sc)
OID_AUTO, "rx_ring_cnt", CTLFLAG_RD,
&sc->rx_ring_cnt, 0, "RX ring count");
+#ifdef IFPOLL_ENABLE
+ SYSCTL_ADD_PROC(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree),
+ OID_AUTO, "npoll_rxoff", CTLTYPE_INT|CTLFLAG_RW,
+ sc, 0, emx_sysctl_npoll_rxoff, "I",
+ "NPOLLING RX cpu offset");
+ SYSCTL_ADD_PROC(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree),
+ OID_AUTO, "npoll_txoff", CTLTYPE_INT|CTLFLAG_RW,
+ sc, 0, emx_sysctl_npoll_txoff, "I",
+ "NPOLLING TX cpu offset");
+#endif
+
#ifdef EMX_RSS_DEBUG
SYSCTL_ADD_INT(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree),
OID_AUTO, "rss_debug", CTLFLAG_RW, &sc->rss_debug,
@@ -3502,6 +3551,62 @@ emx_sysctl_int_tx_nsegs(SYSCTL_HANDLER_ARGS)
return error;
}
+#ifdef IFPOLL_ENABLE
+
+static int
+emx_sysctl_npoll_rxoff(SYSCTL_HANDLER_ARGS)
+{
+ struct emx_softc *sc = (void *)arg1;
+ struct ifnet *ifp = &sc->arpcom.ac_if;
+ int error, off;
+
+ off = sc->rx_npoll_off;
+ error = sysctl_handle_int(oidp, &off, 0, req);
+ if (error || req->newptr == NULL)
+ return error;
+ if (off < 0)
+ return EINVAL;
+
+ ifnet_serialize_all(ifp);
+ if (off >= ncpus2 || off % sc->rx_ring_cnt != 0) {
+ error = EINVAL;
+ } else {
+ error = 0;
+ sc->rx_npoll_off = off;
+ }
+ ifnet_deserialize_all(ifp);
+
+ return error;
+}
+
+static int
+emx_sysctl_npoll_txoff(SYSCTL_HANDLER_ARGS)
+{
+ struct emx_softc *sc = (void *)arg1;
+ struct ifnet *ifp = &sc->arpcom.ac_if;
+ int error, off;
+
+ off = sc->tx_npoll_off;
+ error = sysctl_handle_int(oidp, &off, 0, req);
+ if (error || req->newptr == NULL)
+ return error;
+ if (off < 0)
+ return EINVAL;
+
+ ifnet_serialize_all(ifp);
+ if (off >= ncpus2) {
+ error = EINVAL;
+ } else {
+ error = 0;
+ sc->tx_npoll_off = off;
+ }
+ ifnet_deserialize_all(ifp);
+
+ return error;
+}
+
+#endif /* IFPOLL_ENABLE */
+
static int
emx_dma_alloc(struct emx_softc *sc)
{
@@ -3663,25 +3768,31 @@ emx_npoll(struct ifnet *ifp, struct ifpoll_info *info)
ASSERT_IFNET_SERIALIZED_ALL(ifp);
if (info) {
- int i;
+ int i, off;
info->ifpi_status.status_func = emx_npoll_status;
info->ifpi_status.serializer = &sc->main_serialize;
- info->ifpi_tx[0].poll_func = emx_npoll_tx;
- info->ifpi_tx[0].arg = NULL;
- info->ifpi_tx[0].serializer = &sc->tx_serialize;
+ off = sc->tx_npoll_off;
+ KKASSERT(off < ncpus2);
+ info->ifpi_tx[off].poll_func = emx_npoll_tx;
+ info->ifpi_tx[off].arg = NULL;
+ info->ifpi_tx[off].serializer = &sc->tx_serialize;
+ off = sc->rx_npoll_off;
for (i = 0; i < sc->rx_ring_cnt; ++i) {
- info->ifpi_rx[i].poll_func = emx_npoll_rx;
- info->ifpi_rx[i].arg = &sc->rx_data[i];
- info->ifpi_rx[i].serializer =
- &sc->rx_data[i].rx_serialize;
+ struct emx_rxdata *rdata = &sc->rx_data[i];
+ int idx = i + off;
+
+ KKASSERT(idx < ncpus2);
+ info->ifpi_rx[idx].poll_func = emx_npoll_rx;
+ info->ifpi_rx[idx].arg = rdata;
+ info->ifpi_rx[idx].serializer = &rdata->rx_serialize;
}
if (ifp->if_flags & IFF_RUNNING)
emx_disable_intr(sc);
- ifp->if_npoll_cpuid = 0; /* XXX */
+ ifp->if_npoll_cpuid = sc->tx_npoll_off;
} else {
if (ifp->if_flags & IFF_RUNNING)
emx_enable_intr(sc);
View
3  sys/dev/netif/emx/if_emx.h
@@ -276,6 +276,9 @@ struct emx_softc {
uint32_t smartspeed;
int int_throttle_ceil;
+ int rx_npoll_off;
+ int tx_npoll_off;
+
struct lwkt_serialize main_serialize;
struct lwkt_serialize tx_serialize;
struct lwkt_serialize *serializes[EMX_NSERIALIZE];
Please sign in to comment.
Something went wrong with that request. Please try again.