ifpoll: Factor out code for devices which does not support multiple queues
authorSepherosa Ziehau <sephe@dragonflybsd.org>
Sun, 28 Oct 2012 13:11:43 +0000 (21:11 +0800)
committerSepherosa Ziehau <sephe@dragonflybsd.org>
Sun, 28 Oct 2012 13:11:43 +0000 (21:11 +0800)
Mainly avoid code duplication.

While I'm here, fix a typo in em(4) which always enable interrupt during
interface initialization.

sys/dev/netif/bnx/if_bnx.c
sys/dev/netif/bnx/if_bnxvar.h
sys/dev/netif/em/if_em.c
sys/dev/netif/em/if_em.h
sys/net/if_poll.c
sys/net/if_poll.h

index dbd8d74..1f5abb1 100644 (file)
@@ -230,10 +230,6 @@ static int bnx_sysctl_rx_coal_bds_int(SYSCTL_HANDLER_ARGS);
 static int     bnx_sysctl_tx_coal_bds_int(SYSCTL_HANDLER_ARGS);
 static int     bnx_sysctl_coal_chg(SYSCTL_HANDLER_ARGS, uint32_t *,
                    int, int, uint32_t);
-#ifdef IFPOLL_ENABLE
-static int     bnx_sysctl_npoll_stfrac(SYSCTL_HANDLER_ARGS);
-static int     bnx_sysctl_npoll_cpuid(SYSCTL_HANDLER_ARGS);
-#endif
 
 static int     bnx_msi_enable = 1;
 TUNABLE_INT("hw.bnx.msi.enable", &bnx_msi_enable);
@@ -2101,11 +2097,6 @@ bnx_attach(device_t dev)
                }
        }
 
-#ifdef IFPOLL_ENABLE
-       sc->bnx_npoll_stfrac = 40 - 1;  /* 1/40 polling freq */
-       sc->bnx_npoll_cpuid = device_get_unit(dev) % ncpus2;
-#endif
-
        /*
         * Create sysctl nodes.
         */
@@ -2166,17 +2157,6 @@ bnx_attach(device_t dev)
            "force_defrag", CTLFLAG_RW, &sc->bnx_force_defrag, 0,
            "Force defragment on TX path");
 
-#ifdef IFPOLL_ENABLE
-       SYSCTL_ADD_PROC(&sc->bnx_sysctl_ctx,
-           SYSCTL_CHILDREN(sc->bnx_sysctl_tree), OID_AUTO,
-           "npoll_stfrac", CTLTYPE_INT | CTLFLAG_RW,
-           sc, 0, bnx_sysctl_npoll_stfrac, "I", "polling status frac");
-       SYSCTL_ADD_PROC(&sc->bnx_sysctl_ctx,
-           SYSCTL_CHILDREN(sc->bnx_sysctl_tree), OID_AUTO,
-           "npoll_cpuid", CTLTYPE_INT | CTLFLAG_RW,
-           sc, 0, bnx_sysctl_npoll_cpuid, "I", "polling cpuid");
-#endif
-
        SYSCTL_ADD_PROC(&sc->bnx_sysctl_ctx,
            SYSCTL_CHILDREN(sc->bnx_sysctl_tree), OID_AUTO,
            "rx_coal_bds_int", CTLTYPE_INT | CTLFLAG_RW,
@@ -2202,6 +2182,12 @@ bnx_attach(device_t dev)
         */
        ether_ifattach(ifp, ether_addr, NULL);
 
+#ifdef IFPOLL_ENABLE
+       ifpoll_compat_setup(&sc->bnx_npoll,
+           &sc->bnx_sysctl_ctx, sc->bnx_sysctl_tree,
+           device_get_unit(dev), ifp->if_serializer);
+#endif
+
        if (sc->bnx_irq_type == PCI_INTR_TYPE_MSI) {
                if (sc->bnx_flags & BNX_FLAG_ONESHOT_MSI) {
                        intr_func = bnx_msi_oneshot;
@@ -2654,7 +2640,7 @@ bnx_npoll(struct ifnet *ifp, struct ifpoll_info *info)
        ASSERT_SERIALIZED(ifp->if_serializer);
 
        if (info != NULL) {
-               int cpuid = sc->bnx_npoll_cpuid;
+               int cpuid = sc->bnx_npoll.ifpc_cpuid;
 
                info->ifpi_rx[cpuid].poll_func = bnx_npoll_compat;
                info->ifpi_rx[cpuid].arg = NULL;
@@ -2679,8 +2665,8 @@ bnx_npoll_compat(struct ifnet *ifp, void *arg __unused, int cycle __unused)
 
        ASSERT_SERIALIZED(ifp->if_serializer);
 
-       if (sc->bnx_npoll_stcount-- == 0) {
-               sc->bnx_npoll_stcount = sc->bnx_npoll_stfrac;
+       if (sc->bnx_npoll.ifpc_stcount-- == 0) {
+               sc->bnx_npoll.ifpc_stcount = sc->bnx_npoll.ifpc_stfrac;
                /*
                 * Process link state changes.
                 */
@@ -3935,57 +3921,6 @@ bnx_sysctl_coal_chg(SYSCTL_HANDLER_ARGS, uint32_t *coal,
        return error;
 }
 
-#ifdef IFPOLL_ENABLE
-
-static int
-bnx_sysctl_npoll_stfrac(SYSCTL_HANDLER_ARGS)
-{
-       struct bnx_softc *sc = arg1;
-       struct ifnet *ifp = &sc->arpcom.ac_if;
-       int error = 0, stfrac;
-
-       lwkt_serialize_enter(ifp->if_serializer);
-
-       stfrac = sc->bnx_npoll_stfrac + 1;
-       error = sysctl_handle_int(oidp, &stfrac, 0, req);
-       if (!error && req->newptr != NULL) {
-               if (stfrac < 1) {
-                       error = EINVAL;
-               } else {
-                       sc->bnx_npoll_stfrac = stfrac - 1;
-                       if (sc->bnx_npoll_stcount > sc->bnx_npoll_stfrac)
-                               sc->bnx_npoll_stcount = sc->bnx_npoll_stfrac;
-               }
-       }
-
-       lwkt_serialize_exit(ifp->if_serializer);
-       return error;
-}
-
-static int
-bnx_sysctl_npoll_cpuid(SYSCTL_HANDLER_ARGS)
-{
-       struct bnx_softc *sc = arg1;
-       struct ifnet *ifp = &sc->arpcom.ac_if;
-       int error = 0, cpuid;
-
-       lwkt_serialize_enter(ifp->if_serializer);
-
-       cpuid = sc->bnx_npoll_cpuid;
-       error = sysctl_handle_int(oidp, &cpuid, 0, req);
-       if (!error && req->newptr != NULL) {
-               if (cpuid < 0 || cpuid >= ncpus2)
-                       error = EINVAL;
-               else
-                       sc->bnx_npoll_cpuid = cpuid;
-       }
-
-       lwkt_serialize_exit(ifp->if_serializer);
-       return error;
-}
-
-#endif /* IFPOLL_ENABLE */
-
 static void
 bnx_coal_change(struct bnx_softc *sc)
 {
@@ -4172,7 +4107,7 @@ bnx_disable_intr(struct bnx_softc *sc)
        sc->bnx_rx_check_considx = 0;
        sc->bnx_tx_check_considx = 0;
 
-       sc->bnx_npoll_stcount = 0;
+       sc->bnx_npoll.ifpc_stcount = 0;
 
        lwkt_serialize_handler_disable(ifp->if_serializer);
 }
index 35ff861..e9fd29f 100644 (file)
@@ -242,9 +242,7 @@ struct bnx_softc {
        int                     bnx_link_evt;
        int                     bnx_stat_cpuid;
        struct callout          bnx_stat_timer;
-       int                     bnx_npoll_stfrac;
-       int                     bnx_npoll_stcount;
-       int                     bnx_npoll_cpuid;
+       struct ifpoll_compat    bnx_npoll;
 
        uint16_t                bnx_rx_check_considx;
        uint16_t                bnx_tx_check_considx;
index 191ea9a..bbc430e 100644 (file)
@@ -337,10 +337,6 @@ static int em_sysctl_stats(SYSCTL_HANDLER_ARGS);
 static int     em_sysctl_debug_info(SYSCTL_HANDLER_ARGS);
 static int     em_sysctl_int_throttle(SYSCTL_HANDLER_ARGS);
 static int     em_sysctl_int_tx_nsegs(SYSCTL_HANDLER_ARGS);
-#ifdef IFPOLL_ENABLE
-static int     em_sysctl_npoll_stfrac(SYSCTL_HANDLER_ARGS);
-static int     em_sysctl_npoll_cpuid(SYSCTL_HANDLER_ARGS);
-#endif
 static void    em_add_sysctl(struct adapter *adapter);
 
 /* Management and WOL Support */
@@ -781,18 +777,19 @@ em_attach(device_t dev)
        /* XXX disable wol */
        adapter->wol = 0;
 
-       /* Polling setup */
-#ifdef IFPOLL_ENABLE
-       adapter->npoll_stfrac = 40 - 1; /* 1/40 polling freq */
-       adapter->npoll_cpuid = device_get_unit(dev) % ncpus2;
-#endif
-
        /* Setup OS specific network interface */
        em_setup_ifp(adapter);
 
        /* Add sysctl tree, must after em_setup_ifp() */
        em_add_sysctl(adapter);
 
+#ifdef IFPOLL_ENABLE
+       /* Polling setup */
+       ifpoll_compat_setup(&adapter->npoll,
+           &adapter->sysctl_ctx, adapter->sysctl_tree, device_get_unit(dev),
+           ifp->if_serializer);
+#endif
+
        /* Reset the hardware */
        error = em_reset(adapter);
        if (error) {
@@ -1390,7 +1387,7 @@ em_init(void *xsc)
                E1000_WRITE_REG(&adapter->hw, E1000_IVAR, 0x800A0908);
        }
 
-#ifdef IFPOLL_ENBLE
+#ifdef IFPOLL_ENABLE
        /*
         * Only enable interrupts if we are not polling, make sure
         * they are off otherwise.
@@ -1420,10 +1417,10 @@ em_npoll_compat(struct ifnet *ifp, void *arg __unused, int count)
 
        ASSERT_SERIALIZED(ifp->if_serializer);
 
-       if (adapter->npoll_stcount-- == 0) {
+       if (adapter->npoll.ifpc_stcount-- == 0) {
                uint32_t reg_icr;
 
-               adapter->npoll_stcount = adapter->npoll_stfrac;
+               adapter->npoll.ifpc_stcount = adapter->npoll.ifpc_stfrac;
 
                reg_icr = E1000_READ_REG(&adapter->hw, E1000_ICR);
                if (reg_icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
@@ -1449,7 +1446,7 @@ em_npoll(struct ifnet *ifp, struct ifpoll_info *info)
        ASSERT_SERIALIZED(ifp->if_serializer);
 
        if (info != NULL) {
-               int cpuid = adapter->npoll_cpuid;
+               int cpuid = adapter->npoll.ifpc_cpuid;
 
                 info->ifpi_rx[cpuid].poll_func = em_npoll_compat;
                info->ifpi_rx[cpuid].arg = NULL;
@@ -3536,7 +3533,7 @@ em_disable_intr(struct adapter *adapter)
 
        E1000_WRITE_REG(&adapter->hw, E1000_IMC, clear);
 
-       adapter->npoll_stcount = 0;
+       adapter->npoll.ifpc_stcount = 0;
 
        lwkt_serialize_handler_disable(adapter->arpcom.ac_if.if_serializer);
 }
@@ -4045,18 +4042,6 @@ em_add_sysctl(struct adapter *adapter)
                    CTLTYPE_INT|CTLFLAG_RW, adapter, 0,
                    em_sysctl_int_tx_nsegs, "I",
                    "# segments per TX interrupt");
-
-#ifdef IFPOLL_ENABLE
-               SYSCTL_ADD_PROC(&adapter->sysctl_ctx,
-                   SYSCTL_CHILDREN(adapter->sysctl_tree), OID_AUTO,
-                   "npoll_stfrac", CTLTYPE_INT | CTLFLAG_RW,
-                   adapter, 0, em_sysctl_npoll_stfrac, "I",
-                   "polling status frac");
-               SYSCTL_ADD_PROC(&adapter->sysctl_ctx,
-                   SYSCTL_CHILDREN(adapter->sysctl_tree), OID_AUTO,
-                   "npoll_cpuid", CTLTYPE_INT | CTLFLAG_RW,
-                   adapter, 0, em_sysctl_npoll_cpuid, "I", "polling cpuid");
-#endif
        }
 }
 
@@ -4343,54 +4328,3 @@ em_tso_setup(struct adapter *adapter, struct mbuf *mp,
        adapter->next_avail_tx_desc = curr_txd;
        return 1;
 }
-
-#ifdef IFPOLL_ENABLE
-
-static int
-em_sysctl_npoll_stfrac(SYSCTL_HANDLER_ARGS)
-{
-       struct adapter *adapter = arg1;
-       struct ifnet *ifp = &adapter->arpcom.ac_if;
-       int error = 0, stfrac;
-
-       lwkt_serialize_enter(ifp->if_serializer);
-
-       stfrac = adapter->npoll_stfrac + 1;
-       error = sysctl_handle_int(oidp, &stfrac, 0, req);
-       if (!error && req->newptr != NULL) {
-               if (stfrac < 1) {
-                       error = EINVAL;
-               } else {
-                       adapter->npoll_stfrac = stfrac - 1;
-                       if (adapter->npoll_stcount > adapter->npoll_stfrac)
-                               adapter->npoll_stcount = adapter->npoll_stfrac;
-               }
-       }
-
-       lwkt_serialize_exit(ifp->if_serializer);
-       return error;
-}
-
-static int
-em_sysctl_npoll_cpuid(SYSCTL_HANDLER_ARGS)
-{
-       struct adapter *adapter = arg1;
-       struct ifnet *ifp = &adapter->arpcom.ac_if;
-       int error = 0, cpuid;
-
-       lwkt_serialize_enter(ifp->if_serializer);
-
-       cpuid = adapter->npoll_cpuid;
-       error = sysctl_handle_int(oidp, &cpuid, 0, req);
-       if (!error && req->newptr != NULL) {
-               if (cpuid < 0 || cpuid >= ncpus2)
-                       error = EINVAL;
-               else
-                       adapter->npoll_cpuid = cpuid;
-       }
-
-       lwkt_serialize_exit(ifp->if_serializer);
-       return error;
-}
-
-#endif /* IFPOLL_ENABLE */
index 4997312..5ac729f 100644 (file)
@@ -293,9 +293,7 @@ struct adapter {
        int                     int_throttle_ceil;
 
        /* Polling */
-       int                     npoll_stcount;
-       int                     npoll_stfrac;
-       int                     npoll_cpuid;
+       struct ifpoll_compat    npoll;
 
        /*
         * Transmit definitions
index 189fe19..cc24500 100644 (file)
@@ -246,6 +246,8 @@ static void sysctl_txfrac_handler(netmsg_t);
 static int     sysctl_pollhz(SYSCTL_HANDLER_ARGS);
 static int     sysctl_stfrac(SYSCTL_HANDLER_ARGS);
 static int     sysctl_txfrac(SYSCTL_HANDLER_ARGS);
+static int     sysctl_compat_npoll_stfrac(SYSCTL_HANDLER_ARGS);
+static int     sysctl_compat_npoll_cpuid(SYSCTL_HANDLER_ARGS);
 
 static struct stpoll_ctx       stpoll_context;
 static struct poll_comm                *poll_common[MAXCPU];
@@ -1468,3 +1470,72 @@ sysctl_txfrac_handler(netmsg_t nmsg)
 
        lwkt_replymsg(&nmsg->lmsg, 0);
 }
+
+void
+ifpoll_compat_setup(struct ifpoll_compat *cp,
+    struct sysctl_ctx_list *sysctl_ctx,
+    struct sysctl_oid *sysctl_tree,
+    int unit, struct lwkt_serialize *slz)
+{
+       cp->ifpc_stcount = 0;
+       cp->ifpc_stfrac = poll_common[0]->poll_stfrac;
+
+       cp->ifpc_cpuid = unit % ncpus2;
+       cp->ifpc_serializer = slz;
+
+       if (sysctl_ctx != NULL) {
+               SYSCTL_ADD_PROC(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree),
+                   OID_AUTO, "npoll_stfrac", CTLTYPE_INT | CTLFLAG_RW,
+                   cp, 0, sysctl_compat_npoll_stfrac, "I",
+                   "polling status frac");
+               SYSCTL_ADD_PROC(sysctl_ctx, SYSCTL_CHILDREN(sysctl_tree),
+                   OID_AUTO, "npoll_cpuid", CTLTYPE_INT | CTLFLAG_RW,
+                   cp, 0, sysctl_compat_npoll_cpuid, "I",
+                   "polling cpuid");
+       }
+}
+
+static int
+sysctl_compat_npoll_stfrac(SYSCTL_HANDLER_ARGS)
+{
+       struct ifpoll_compat *cp = arg1;
+       int error = 0, stfrac;
+
+       lwkt_serialize_enter(cp->ifpc_serializer);
+
+       stfrac = cp->ifpc_stfrac + 1;
+       error = sysctl_handle_int(oidp, &stfrac, 0, req);
+       if (!error && req->newptr != NULL) {
+               if (stfrac < 1) {
+                       error = EINVAL;
+               } else {
+                       cp->ifpc_stfrac = stfrac - 1;
+                       if (cp->ifpc_stcount > cp->ifpc_stfrac)
+                               cp->ifpc_stcount = cp->ifpc_stfrac;
+               }
+       }
+
+       lwkt_serialize_exit(cp->ifpc_serializer);
+       return error;
+}
+
+static int
+sysctl_compat_npoll_cpuid(SYSCTL_HANDLER_ARGS)
+{
+       struct ifpoll_compat *cp = arg1;
+       int error = 0, cpuid;
+
+       lwkt_serialize_enter(cp->ifpc_serializer);
+
+       cpuid = cp->ifpc_cpuid;
+       error = sysctl_handle_int(oidp, &cpuid, 0, req);
+       if (!error && req->newptr != NULL) {
+               if (cpuid < 0 || cpuid >= ncpus2)
+                       error = EINVAL;
+               else
+                       cp->ifpc_cpuid = cpuid;
+       }
+
+       lwkt_serialize_exit(cp->ifpc_serializer);
+       return error;
+}
index 87898b6..0542ff7 100644 (file)
@@ -3,6 +3,8 @@
 
 #ifdef _KERNEL
 
+struct sysctl_ctx_list;
+struct sysctl_oid;
 struct lwkt_serialize;
 struct ifnet;
 
@@ -27,6 +29,17 @@ struct ifpoll_info {
        struct ifpoll_io        ifpi_tx[MAXCPU];
 };
 
+struct ifpoll_compat {
+       int                     ifpc_stcount;
+       int                     ifpc_stfrac;
+
+       int                     ifpc_cpuid;
+       struct lwkt_serialize   *ifpc_serializer;
+};
+
+void   ifpoll_compat_setup(struct ifpoll_compat *, struct sysctl_ctx_list *,
+           struct sysctl_oid *, int, struct lwkt_serialize *);
+
 #endif /* _KERNEL */
 
 #endif /* !_NET_IF_POLL_H_ */