Skip to content

Instantly share code, notes, and snippets.

@ozaki-r
Created January 14, 2016 09:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ozaki-r/4b871fdf16d88ef3f75c to your computer and use it in GitHub Desktop.
Save ozaki-r/4b871fdf16d88ef3f75c to your computer and use it in GitHub Desktop.
Softint-based if_input
commit c5aabdbef5a06cea62245930c906fb7058426a1c
Author: Ryota Ozaki <ozaki-r@iij.ad.jp>
Date: Thu Jan 14 11:25:25 2016 +0900
Implement softint-based if_input
diff --git a/sys/dev/pci/if_wm.c b/sys/dev/pci/if_wm.c
index 4124859..de23f5c 100644
--- a/sys/dev/pci/if_wm.c
+++ b/sys/dev/pci/if_wm.c
@@ -2445,6 +2445,7 @@ alloc_retry:
/* Attach the interface. */
if_attach(ifp);
+ if_init_softint_input(ifp);
ether_ifattach(ifp, enaddr);
ether_set_ifflags_cb(&sc->sc_ethercom, wm_ifflags_cb);
rnd_attach_source(&sc->rnd_source, xname, RND_TYPE_NET,
@@ -7117,11 +7118,7 @@ wm_rxeof(struct wm_rxqueue *rxq)
WM_RX_UNLOCK(rxq);
- /* Pass this up to any BPF listeners. */
- bpf_mtap(ifp, m);
-
- /* Pass it on. */
- (*ifp->if_input)(ifp, m);
+ if_input(ifp, m);
WM_RX_LOCK(rxq);
diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c
index 100c112..7f9fd98 100644
--- a/sys/kern/init_main.c
+++ b/sys/kern/init_main.c
@@ -485,6 +485,8 @@ main(void)
/* Initialize sockets thread(s) */
soinit1();
+ ipi_sysinit();
+
/* Configure the system hardware. This will enable interrupts. */
configure();
@@ -499,8 +501,6 @@ main(void)
configure2();
- ipi_sysinit();
-
/* Now timer is working. Enable preemption. */
kpreempt_enable();
diff --git a/sys/net/if.c b/sys/net/if.c
index e7721a7..65e0444 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -118,6 +118,7 @@ __KERNEL_RCSID(0, "$NetBSD: if.c,v 1.320 2016/01/04 09:08:38 ozaki-r Exp $");
#include <sys/kmem.h>
#include <sys/xcall.h>
+#include <net/bpf.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <net/if_ether.h>
@@ -2442,6 +2443,37 @@ if_mcast_op(ifnet_t *ifp, const unsigned long cmd, const struct sockaddr *sa)
}
static void
+if_input_pktq(void *arg)
+{
+ struct ifnet *ifp = arg;
+ struct mbuf *m;
+
+ while ((m = pktq_dequeue(ifp->if_input_pktq)) != NULL) {
+ ifp->if_input(ifp, m);
+ }
+}
+
+void
+if_init_softint_input(struct ifnet *ifp)
+{
+
+ ifp->if_input_pktq = pktq_create(IFQ_MAXLEN, if_input_pktq, ifp);
+}
+
+void
+if_input(struct ifnet *ifp, struct mbuf *m)
+{
+
+ bpf_mtap(ifp, m);
+
+ if (ifp->if_input_pktq) {
+ pktq_enqueue(ifp->if_input_pktq, m, curcpu()->ci_index);
+ } else {
+ (*ifp->if_input)(ifp, m);
+ }
+}
+
+static void
sysctl_sndq_setup(struct sysctllog **clog, const char *ifname,
struct ifaltq *ifq)
{
diff --git a/sys/net/if.h b/sys/net/if.h
index f8051e4..2fac224 100644
--- a/sys/net/if.h
+++ b/sys/net/if.h
@@ -357,6 +357,7 @@ typedef struct ifnet {
#else
struct krwlock *if_afdata_lock;
#endif
+ pktqueue_t *if_input_pktq;
} ifnet_t;
#define if_mtu if_data.ifi_mtu
@@ -946,6 +947,8 @@ int if_do_dad(struct ifnet *);
int if_mcast_op(ifnet_t *, const unsigned long, const struct sockaddr *);
int if_flags_set(struct ifnet *, const short);
int if_clone_list(int, char *, int *);
+void if_init_softint_input(struct ifnet *);
+void if_input(struct ifnet *, struct mbuf *);
void ifa_insert(struct ifnet *, struct ifaddr *);
void ifa_remove(struct ifnet *, struct ifaddr *);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment