summaryrefslogtreecommitdiff
path: root/sys/net
diff options
context:
space:
mode:
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/hfsc.c44
-rw-r--r--sys/net/if.c136
-rw-r--r--sys/net/if.h5
-rw-r--r--sys/net/if_mpw.c6
-rw-r--r--sys/net/if_var.h9
-rw-r--r--sys/net/if_vlan.c18
-rw-r--r--sys/net/ifq.c51
-rw-r--r--sys/net/ifq.h30
8 files changed, 222 insertions, 77 deletions
diff --git a/sys/net/hfsc.c b/sys/net/hfsc.c
index 447ca4f9cd0..f8e67722bb7 100644
--- a/sys/net/hfsc.c
+++ b/sys/net/hfsc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: hfsc.c,v 1.34 2017/01/22 04:48:23 dlg Exp $ */
+/* $OpenBSD: hfsc.c,v 1.35 2017/01/24 03:57:35 dlg Exp $ */
/*
* Copyright (c) 2012-2013 Henning Brauer <henning@openbsd.org>
@@ -259,20 +259,22 @@ struct pool hfsc_class_pl, hfsc_internal_sc_pl;
* ifqueue glue.
*/
-void *hfsc_alloc(void *);
-void hfsc_free(void *);
+unsigned int hfsc_idx(unsigned int, const struct mbuf *);
int hfsc_enq(struct ifqueue *, struct mbuf *);
struct mbuf *hfsc_deq_begin(struct ifqueue *, void **);
void hfsc_deq_commit(struct ifqueue *, struct mbuf *, void *);
void hfsc_purge(struct ifqueue *, struct mbuf_list *);
+void *hfsc_alloc(unsigned int, void *);
+void hfsc_free(unsigned int, void *);
const struct ifq_ops hfsc_ops = {
- hfsc_alloc,
- hfsc_free,
+ hfsc_idx,
hfsc_enq,
hfsc_deq_begin,
hfsc_deq_commit,
hfsc_purge,
+ hfsc_alloc,
+ hfsc_free,
};
const struct ifq_ops * const ifq_hfsc_ops = &hfsc_ops;
@@ -414,13 +416,26 @@ hfsc_pf_qstats(struct pf_queuespec *q, void *ubuf, int *nbytes)
void
hfsc_pf_free(struct hfsc_if *hif)
{
- hfsc_free(hif);
+ hfsc_free(0, hif);
+}
+
+unsigned int
+hfsc_idx(unsigned int nqueues, const struct mbuf *m)
+{
+ /*
+ * hfsc can only function on a single ifq and the stack understands
+ * this. when the first ifq on an interface is switched to hfsc,
+ * this gets used to map all mbufs to the first and only ifq that
+ * is set up for hfsc.
+ */
+ return (0);
}
void *
-hfsc_alloc(void *q)
+hfsc_alloc(unsigned int idx, void *q)
{
struct hfsc_if *hif = q;
+ KASSERT(idx == 0); /* when hfsc is enabled we only use the first ifq */
KASSERT(hif != NULL);
timeout_add(&hif->hif_defer, 1);
@@ -428,12 +443,13 @@ hfsc_alloc(void *q)
}
void
-hfsc_free(void *q)
+hfsc_free(unsigned int idx, void *q)
{
struct hfsc_if *hif = q;
int i;
KERNEL_ASSERT_LOCKED();
+ KASSERT(idx == 0); /* when hfsc is enabled we only use the first ifq */
timeout_del(&hif->hif_defer);
@@ -758,18 +774,16 @@ void
hfsc_deferred(void *arg)
{
struct ifnet *ifp = arg;
+ struct ifqueue *ifq = &ifp->if_snd;
struct hfsc_if *hif;
- int s;
KERNEL_ASSERT_LOCKED();
- KASSERT(HFSC_ENABLED(&ifp->if_snd));
+ KASSERT(HFSC_ENABLED(ifq));
- s = splnet();
- if (!IFQ_IS_EMPTY(&ifp->if_snd))
- if_start(ifp);
- splx(s);
+ if (!ifq_empty(ifq))
+ (*ifp->if_qstart)(ifq);
- hif = ifp->if_snd.ifq_q;
+ hif = ifq->ifq_q;
/* XXX HRTIMER nearest virtual/fit time is likely less than 1/HZ. */
timeout_add(&hif->hif_defer, 1);
diff --git a/sys/net/if.c b/sys/net/if.c
index b01f9a539d5..3e10955e1be 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if.c,v 1.478 2017/01/23 11:37:29 mpi Exp $ */
+/* $OpenBSD: if.c,v 1.479 2017/01/24 03:57:35 dlg Exp $ */
/* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */
/*
@@ -136,7 +136,7 @@ void if_attach_common(struct ifnet *);
int if_setrdomain(struct ifnet *, int);
void if_slowtimo(void *);
-void if_detached_start(struct ifnet *);
+void if_detached_qstart(struct ifqueue *);
int if_detached_ioctl(struct ifnet *, u_long, caddr_t);
int if_getgroup(caddr_t, struct ifnet *);
@@ -161,7 +161,7 @@ void if_netisr(void *);
void ifa_print_all(void);
#endif
-void if_start_locked(struct ifnet *);
+void if_qstart_compat(struct ifqueue *);
/*
* interface index map
@@ -527,12 +527,53 @@ if_attach(struct ifnet *ifp)
}
void
+if_attach_queues(struct ifnet *ifp, unsigned int nqs)
+{
+ struct ifqueue **map;
+ struct ifqueue *ifq;
+ int i;
+
+ KASSERT(ifp->if_ifqs == ifp->if_snd.ifq_ifqs);
+ KASSERT(nqs != 0);
+
+ map = mallocarray(sizeof(*map), nqs, M_DEVBUF, M_WAITOK);
+
+ ifp->if_snd.ifq_softc = NULL;
+ map[0] = &ifp->if_snd;
+
+ for (i = 1; i < nqs; i++) {
+ ifq = malloc(sizeof(*ifq), M_DEVBUF, M_WAITOK|M_ZERO);
+ ifq_set_maxlen(ifq, ifp->if_snd.ifq_maxlen);
+ ifq_init(ifq, ifp, i);
+ map[i] = ifq;
+ }
+
+ ifp->if_ifqs = map;
+ ifp->if_nifqs = nqs;
+}
+
+void
if_attach_common(struct ifnet *ifp)
{
TAILQ_INIT(&ifp->if_addrlist);
TAILQ_INIT(&ifp->if_maddrlist);
- ifq_init(&ifp->if_snd, ifp);
+ if (!ISSET(ifp->if_xflags, IFXF_MPSAFE)) {
+ KASSERTMSG(ifp->if_qstart == NULL,
+ "%s: if_qstart set without MPSAFE set", ifp->if_xname);
+ ifp->if_qstart = if_qstart_compat;
+ } else {
+ KASSERTMSG(ifp->if_start == NULL,
+ "%s: if_start set with MPSAFE set", ifp->if_xname);
+ KASSERTMSG(ifp->if_qstart != NULL,
+ "%s: if_qstart not set with MPSAFE set", ifp->if_xname);
+ }
+
+ ifq_init(&ifp->if_snd, ifp, 0);
+
+ ifp->if_snd.ifq_ifqs[0] = &ifp->if_snd;
+ ifp->if_ifqs = ifp->if_snd.ifq_ifqs;
+ ifp->if_nifqs = 1;
ifp->if_addrhooks = malloc(sizeof(*ifp->if_addrhooks),
M_TEMP, M_WAITOK);
@@ -560,22 +601,44 @@ if_attach_common(struct ifnet *ifp)
}
void
-if_start(struct ifnet *ifp)
+if_attach_ifq(struct ifnet *ifp, const struct ifq_ops *newops, void *args)
{
- if (ISSET(ifp->if_xflags, IFXF_MPSAFE))
- ifq_start(&ifp->if_snd);
- else
- if_start_locked(ifp);
+ /*
+ * only switch the ifq_ops on the first ifq on an interface.
+ *
+ * the only ifq_ops we provide priq and hfsc, and hfsc only
+ * works on a single ifq. because the code uses the ifq_ops
+ * on the first ifq (if_snd) to select a queue for an mbuf,
+ * by switching only the first one we change both the algorithm
+ * and force the routing of all new packets to it.
+ */
+ ifq_attach(&ifp->if_snd, newops, args);
}
void
-if_start_locked(struct ifnet *ifp)
+if_start(struct ifnet *ifp)
{
+ KASSERT(ifp->if_qstart == if_qstart_compat);
+ if_qstart_compat(&ifp->if_snd);
+}
+void
+if_qstart_compat(struct ifqueue *ifq)
+{
+ struct ifnet *ifp = ifq->ifq_if;
int s;
+ /*
+ * the stack assumes that an interface can have multiple
+ * transmit rings, but a lot of drivers are still written
+ * so that interfaces and send rings have a 1:1 mapping.
+ * this provides compatability between the stack and the older
+ * drivers by translating from the only queue they have
+ * (ifp->if_snd) back to the interface and calling if_start.
+ */
+
KERNEL_LOCK();
s = splnet();
- ifp->if_start(ifp);
+ (*ifp->if_start)(ifp);
splx(s);
KERNEL_UNLOCK();
}
@@ -583,7 +646,9 @@ if_start_locked(struct ifnet *ifp)
int
if_enqueue(struct ifnet *ifp, struct mbuf *m)
{
- int error = 0;
+ unsigned int idx;
+ struct ifqueue *ifq;
+ int error;
#if NBRIDGE > 0
if (ifp->if_bridgeport && (m->m_flags & M_PROTO1) == 0) {
@@ -599,14 +664,17 @@ if_enqueue(struct ifnet *ifp, struct mbuf *m)
#endif /* NPF > 0 */
/*
- * Queue message on interface, and start output if interface
- * not yet active.
+ * use the operations on the first ifq to pick which of the array
+ * gets this mbuf.
*/
- IFQ_ENQUEUE(&ifp->if_snd, m, error);
+ idx = ifq_idx(&ifp->if_snd, ifp->if_nifqs, m);
+ ifq = ifp->if_ifqs[idx];
+
+ error = ifq_enqueue(ifq, m);
if (error)
return (error);
- if_start(ifp);
+ ifq_start(ifq);
return (0);
}
@@ -943,7 +1011,7 @@ if_detach(struct ifnet *ifp)
/* Other CPUs must not have a reference before we start destroying. */
if_idxmap_remove(ifp);
- ifp->if_start = if_detached_start;
+ ifp->if_qstart = if_detached_qstart;
ifp->if_ioctl = if_detached_ioctl;
ifp->if_watchdog = NULL;
@@ -1017,7 +1085,16 @@ if_detach(struct ifnet *ifp)
splx(s2);
NET_UNLOCK(s);
- ifq_destroy(&ifp->if_snd);
+ for (i = 0; i < ifp->if_nifqs; i++)
+ ifq_destroy(ifp->if_ifqs[i]);
+ if (ifp->if_ifqs != ifp->if_snd.ifq_ifqs) {
+ for (i = 1; i < ifp->if_nifqs; i++) {
+ free(ifp->if_ifqs[i], M_DEVBUF,
+ sizeof(struct ifqueue));
+ }
+ free(ifp->if_ifqs, M_DEVBUF,
+ sizeof(struct ifqueue *) * ifp->if_nifqs);
+ }
}
/*
@@ -2166,21 +2243,24 @@ ifconf(u_long cmd, caddr_t data)
void
if_getdata(struct ifnet *ifp, struct if_data *data)
{
+ unsigned int i;
struct ifqueue *ifq;
uint64_t opackets = 0;
uint64_t obytes = 0;
uint64_t omcasts = 0;
uint64_t oqdrops = 0;
- ifq = &ifp->if_snd;
+ for (i = 0; i < ifp->if_nifqs; i++) {
+ ifq = ifp->if_ifqs[i];
- mtx_enter(&ifq->ifq_mtx);
- opackets += ifq->ifq_packets;
- obytes += ifq->ifq_bytes;
- oqdrops += ifq->ifq_qdrops;
- omcasts += ifq->ifq_mcasts;
- /* ifq->ifq_errors */
- mtx_leave(&ifq->ifq_mtx);
+ mtx_enter(&ifq->ifq_mtx);
+ opackets += ifq->ifq_packets;
+ obytes += ifq->ifq_bytes;
+ oqdrops += ifq->ifq_qdrops;
+ omcasts += ifq->ifq_mcasts;
+ mtx_leave(&ifq->ifq_mtx);
+ /* ifq->ifq_errors */
+ }
*data = ifp->if_data;
data->ifi_opackets += opackets;
@@ -2195,9 +2275,9 @@ if_getdata(struct ifnet *ifp, struct if_data *data)
* fiddle with the if during detach.
*/
void
-if_detached_start(struct ifnet *ifp)
+if_detached_qstart(struct ifqueue *ifq)
{
- IFQ_PURGE(&ifp->if_snd);
+ ifq_purge(ifq);
}
int
diff --git a/sys/net/if.h b/sys/net/if.h
index cbc25aaecb5..549f854993a 100644
--- a/sys/net/if.h
+++ b/sys/net/if.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if.h,v 1.184 2017/01/23 11:37:29 mpi Exp $ */
+/* $OpenBSD: if.h,v 1.185 2017/01/24 03:57:35 dlg Exp $ */
/* $NetBSD: if.h,v 1.23 1996/05/07 02:40:27 thorpej Exp $ */
/*
@@ -457,10 +457,13 @@ struct if_parent {
#ifdef _KERNEL
struct socket;
struct ifnet;
+struct ifq_ops;
void if_alloc_sadl(struct ifnet *);
void if_free_sadl(struct ifnet *);
void if_attach(struct ifnet *);
+void if_attach_queues(struct ifnet *, unsigned int);
+void if_attach_ifq(struct ifnet *, const struct ifq_ops *, void *);
void if_attachtail(struct ifnet *);
void if_attachhead(struct ifnet *);
void if_deactivate(struct ifnet *);
diff --git a/sys/net/if_mpw.c b/sys/net/if_mpw.c
index cd51b2387e9..aaabf84498f 100644
--- a/sys/net/if_mpw.c
+++ b/sys/net/if_mpw.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_mpw.c,v 1.17 2017/01/23 11:37:29 mpi Exp $ */
+/* $OpenBSD: if_mpw.c,v 1.18 2017/01/24 03:57:35 dlg Exp $ */
/*
* Copyright (c) 2015 Rafael Zalamena <rzalamena@openbsd.org>
@@ -333,7 +333,7 @@ mpw_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *sa,
}
#if NVLAN > 0
-extern void vlan_start(struct ifnet *ifp);
+extern void vlan_start(struct ifqueue *);
/*
* This routine handles VLAN tag reinsertion in packets flowing through
@@ -350,7 +350,7 @@ mpw_vlan_handle(struct mbuf *m, struct mpw_softc *sc)
uint16_t tag = 0;
ifp = if_get(m->m_pkthdr.ph_ifidx);
- if (ifp != NULL && ifp->if_start == vlan_start &&
+ if (ifp != NULL && ifp->if_qstart == vlan_start &&
ISSET(ifp->if_flags, IFF_RUNNING)) {
ifv = ifp->if_softc;
type = ifv->ifv_type;
diff --git a/sys/net/if_var.h b/sys/net/if_var.h
index 3059acef552..dab939a648c 100644
--- a/sys/net/if_var.h
+++ b/sys/net/if_var.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_var.h,v 1.79 2017/01/21 01:32:19 patrick Exp $ */
+/* $OpenBSD: if_var.h,v 1.80 2017/01/24 03:57:35 dlg Exp $ */
/* $NetBSD: if.h,v 1.23 1996/05/07 02:40:27 thorpej Exp $ */
/*
@@ -157,7 +157,12 @@ struct ifnet { /* and the entries */
/* timer routine */
void (*if_watchdog)(struct ifnet *);
int (*if_wol)(struct ifnet *, int);
- struct ifqueue if_snd; /* output queue */
+
+ struct ifqueue if_snd; /* transmit queue */
+ struct ifqueue **if_ifqs; /* pointer to an array of sndqs */
+ void (*if_qstart)(struct ifqueue *);
+ unsigned int if_nifqs;
+
struct sockaddr_dl *if_sadl; /* pointer to our sockaddr_dl */
void *if_afdata[AF_MAX];
diff --git a/sys/net/if_vlan.c b/sys/net/if_vlan.c
index 8ec731e89c3..a0166e6b8c7 100644
--- a/sys/net/if_vlan.c
+++ b/sys/net/if_vlan.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_vlan.c,v 1.169 2017/01/23 11:37:29 mpi Exp $ */
+/* $OpenBSD: if_vlan.c,v 1.170 2017/01/24 03:57:35 dlg Exp $ */
/*
* Copyright 1998 Massachusetts Institute of Technology
@@ -85,7 +85,7 @@ int vlan_clone_create(struct if_clone *, int);
int vlan_clone_destroy(struct ifnet *);
int vlan_input(struct ifnet *, struct mbuf *, void *);
-void vlan_start(struct ifnet *ifp);
+void vlan_start(struct ifqueue *ifq);
int vlan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr);
int vlan_up(struct ifvlan *);
@@ -175,7 +175,7 @@ vlan_clone_create(struct if_clone *ifc, int unit)
ifp->if_flags = IFF_BROADCAST | IFF_MULTICAST;
ifp->if_xflags = IFXF_CLONED|IFXF_MPSAFE;
- ifp->if_start = vlan_start;
+ ifp->if_qstart = vlan_start;
ifp->if_ioctl = vlan_ioctl;
ifp->if_hardmtu = 0xffff;
ifp->if_link_state = LINK_STATE_DOWN;
@@ -238,8 +238,9 @@ vlan_mplstunnel(int ifidx)
}
void
-vlan_start(struct ifnet *ifp)
+vlan_start(struct ifqueue *ifq)
{
+ struct ifnet *ifp = ifq->ifq_if;
struct ifvlan *ifv;
struct ifnet *ifp0;
struct mbuf *m;
@@ -249,15 +250,11 @@ vlan_start(struct ifnet *ifp)
ifp0 = if_get(ifv->ifv_ifp0);
if (ifp0 == NULL || (ifp0->if_flags & (IFF_UP|IFF_RUNNING)) !=
(IFF_UP|IFF_RUNNING)) {
- ifq_purge(&ifp->if_snd);
+ ifq_purge(ifq);
goto leave;
}
- for (;;) {
- IFQ_DEQUEUE(&ifp->if_snd, m);
- if (m == NULL)
- break;
-
+ while ((m = ifq_dequeue(ifq)) != NULL) {
#if NBPFILTER > 0
if (ifp->if_bpf)
bpf_mtap_ether(ifp->if_bpf, m, BPF_DIRECTION_OUT);
@@ -296,6 +293,7 @@ vlan_start(struct ifnet *ifp)
if (if_enqueue(ifp0, m)) {
ifp->if_oerrors++;
+ ifq->ifq_errors++;
continue;
}
}
diff --git a/sys/net/ifq.c b/sys/net/ifq.c
index e92d6f09490..40731637a2c 100644
--- a/sys/net/ifq.c
+++ b/sys/net/ifq.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ifq.c,v 1.5 2017/01/20 03:48:03 dlg Exp $ */
+/* $OpenBSD: ifq.c,v 1.6 2017/01/24 03:57:35 dlg Exp $ */
/*
* Copyright (c) 2015 David Gwynne <dlg@openbsd.org>
@@ -28,20 +28,23 @@
/*
* priq glue
*/
-void *priq_alloc(void *);
-void priq_free(void *);
+unsigned int priq_idx(unsigned int, const struct mbuf *);
int priq_enq(struct ifqueue *, struct mbuf *);
struct mbuf *priq_deq_begin(struct ifqueue *, void **);
void priq_deq_commit(struct ifqueue *, struct mbuf *, void *);
void priq_purge(struct ifqueue *, struct mbuf_list *);
+void *priq_alloc(unsigned int, void *);
+void priq_free(unsigned int, void *);
+
const struct ifq_ops priq_ops = {
- priq_alloc,
- priq_free,
+ priq_idx,
priq_enq,
priq_deq_begin,
priq_deq_commit,
priq_purge,
+ priq_alloc,
+ priq_free,
};
const struct ifq_ops * const ifq_priq_ops = &priq_ops;
@@ -119,7 +122,7 @@ ifq_start_task(void *p)
ifq_empty(ifq) || ifq_is_oactive(ifq))
return;
- ifp->if_start(ifp);
+ ifp->if_qstart(ifq);
}
void
@@ -129,7 +132,7 @@ ifq_restart_task(void *p)
struct ifnet *ifp = ifq->ifq_if;
ifq_clr_oactive(ifq);
- ifp->if_start(ifp);
+ ifp->if_qstart(ifq);
}
void
@@ -167,19 +170,26 @@ ifq_barrier_task(void *p)
*/
void
-ifq_init(struct ifqueue *ifq, struct ifnet *ifp)
+ifq_init(struct ifqueue *ifq, struct ifnet *ifp, unsigned int idx)
{
ifq->ifq_if = ifp;
+ ifq->ifq_softc = NULL;
mtx_init(&ifq->ifq_mtx, IPL_NET);
ifq->ifq_qdrops = 0;
/* default to priq */
ifq->ifq_ops = &priq_ops;
- ifq->ifq_q = priq_ops.ifqop_alloc(NULL);
+ ifq->ifq_q = priq_ops.ifqop_alloc(idx, NULL);
ifq->ifq_len = 0;
+ ifq->ifq_packets = 0;
+ ifq->ifq_bytes = 0;
+ ifq->ifq_qdrops = 0;
+ ifq->ifq_errors = 0;
+ ifq->ifq_mcasts = 0;
+
mtx_init(&ifq->ifq_task_mtx, IPL_NET);
TAILQ_INIT(&ifq->ifq_task_list);
ifq->ifq_serializer = NULL;
@@ -189,6 +199,8 @@ ifq_init(struct ifqueue *ifq, struct ifnet *ifp)
if (ifq->ifq_maxlen == 0)
ifq_set_maxlen(ifq, IFQ_MAXLEN);
+
+ ifq->ifq_idx = idx;
}
void
@@ -200,7 +212,7 @@ ifq_attach(struct ifqueue *ifq, const struct ifq_ops *newops, void *opsarg)
const struct ifq_ops *oldops;
void *newq, *oldq;
- newq = newops->ifqop_alloc(opsarg);
+ newq = newops->ifqop_alloc(ifq->ifq_idx, opsarg);
mtx_enter(&ifq->ifq_mtx);
ifq->ifq_ops->ifqop_purge(ifq, &ml);
@@ -221,7 +233,7 @@ ifq_attach(struct ifqueue *ifq, const struct ifq_ops *newops, void *opsarg)
}
mtx_leave(&ifq->ifq_mtx);
- oldops->ifqop_free(oldq);
+ oldops->ifqop_free(ifq->ifq_idx, oldq);
ml_purge(&free_ml);
}
@@ -234,7 +246,7 @@ ifq_destroy(struct ifqueue *ifq)
/* don't need to lock because this is the last use of the ifq */
ifq->ifq_ops->ifqop_purge(ifq, &ml);
- ifq->ifq_ops->ifqop_free(ifq->ifq_q);
+ ifq->ifq_ops->ifqop_free(ifq->ifq_idx, ifq->ifq_q);
ml_purge(&ml);
}
@@ -368,14 +380,25 @@ ifq_q_leave(struct ifqueue *ifq, void *q)
* priq implementation
*/
+unsigned int
+priq_idx(unsigned int nqueues, const struct mbuf *m)
+{
+ unsigned int flow = 0;
+
+ if (ISSET(m->m_pkthdr.ph_flowid, M_FLOWID_VALID))
+ flow = m->m_pkthdr.ph_flowid & M_FLOWID_MASK;
+
+ return (flow % nqueues);
+}
+
void *
-priq_alloc(void *null)
+priq_alloc(unsigned int idx, void *null)
{
return (malloc(sizeof(struct priq), M_DEVBUF, M_WAITOK | M_ZERO));
}
void
-priq_free(void *pq)
+priq_free(unsigned int idx, void *pq)
{
free(pq, M_DEVBUF, sizeof(struct priq));
}
diff --git a/sys/net/ifq.h b/sys/net/ifq.h
index 4dbef36090e..d159f80d0fe 100644
--- a/sys/net/ifq.h
+++ b/sys/net/ifq.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: ifq.h,v 1.7 2017/01/22 04:48:23 dlg Exp $ */
+/* $OpenBSD: ifq.h,v 1.8 2017/01/24 03:57:35 dlg Exp $ */
/*
* Copyright (c) 2015 David Gwynne <dlg@openbsd.org>
@@ -25,6 +25,18 @@ struct ifq_ops;
struct ifqueue {
struct ifnet *ifq_if;
+ union {
+ void *_ifq_softc;
+ /*
+ * a rings sndq is found by looking up an array of pointers.
+ * by default we only have one sndq and the default drivers
+ * dont use ifq_softc, so we can borrow it for the map until
+ * we need to allocate a proper map.
+ */
+ struct ifqueue *_ifq_ifqs[1];
+ } _ifq_ptr;
+#define ifq_softc _ifq_ptr._ifq_softc
+#define ifq_ifqs _ifq_ptr._ifq_ifqs
/* mbuf handling */
struct mutex ifq_mtx;
@@ -49,7 +61,9 @@ struct ifqueue {
struct task ifq_start;
struct task ifq_restart;
+ /* properties */
unsigned int ifq_maxlen;
+ unsigned int ifq_idx;
};
#ifdef _KERNEL
@@ -308,21 +322,23 @@ struct ifqueue {
*/
struct ifq_ops {
- void *(*ifqop_alloc)(void *);
- void (*ifqop_free)(void *);
+ unsigned int (*ifqop_idx)(unsigned int,
+ const struct mbuf *);
int (*ifqop_enq)(struct ifqueue *, struct mbuf *);
struct mbuf *(*ifqop_deq_begin)(struct ifqueue *, void **);
void (*ifqop_deq_commit)(struct ifqueue *,
struct mbuf *, void *);
void (*ifqop_purge)(struct ifqueue *,
struct mbuf_list *);
+ void *(*ifqop_alloc)(unsigned int, void *);
+ void (*ifqop_free)(unsigned int, void *);
};
/*
* Interface send queues.
*/
-void ifq_init(struct ifqueue *, struct ifnet *);
+void ifq_init(struct ifqueue *, struct ifnet *, unsigned int);
void ifq_attach(struct ifqueue *, const struct ifq_ops *, void *);
void ifq_destroy(struct ifqueue *);
int ifq_enqueue_try(struct ifqueue *, struct mbuf *);
@@ -372,6 +388,12 @@ ifq_restart(struct ifqueue *ifq)
ifq_serialize(ifq, &ifq->ifq_restart);
}
+static inline unsigned int
+ifq_idx(struct ifqueue *ifq, unsigned int nifqs, const struct mbuf *m)
+{
+ return ((*ifq->ifq_ops->ifqop_idx)(nifqs, m));
+}
+
#define IFQ_ASSERT_SERIALIZED(_ifq) KASSERT(ifq_is_serialized(_ifq))
extern const struct ifq_ops * const ifq_priq_ops;