From 2cc2f6391cf953ba02d6c69d8282aed2d8d4caa8 Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Sun, 13 Jan 2013 18:42:45 +0800 Subject: [PATCH] if: Multiple TX queue support step 3 of 3; map CPUID to subqueue Add CPUID to subqueue mapping method to ifaltq. Driver could provide its own CPUID to subqueue mapping method through ifnet.if_mapsubq, which is used when ALTQ's packet scheduler is not enabled. ALTQ's packet schedulers always map CPUID to the default subqueue. --- sys/net/altq/altq_cbq.c | 2 +- sys/net/altq/altq_fairq.c | 5 ++--- sys/net/altq/altq_hfsc.c | 2 +- sys/net/altq/altq_priq.c | 2 +- sys/net/altq/altq_subr.c | 3 ++- sys/net/altq/if_altq.h | 9 +++++++-- sys/net/if.c | 28 ++++++++++++++++++++-------- sys/net/if_var.h | 3 ++- sys/net/ifq_var.h | 12 ++++++++++-- 9 files changed, 46 insertions(+), 20 deletions(-) diff --git a/sys/net/altq/altq_cbq.c b/sys/net/altq/altq_cbq.c index 24c221275f..77aee3b56d 100644 --- a/sys/net/altq/altq_cbq.c +++ b/sys/net/altq/altq_cbq.c @@ -221,7 +221,7 @@ get_class_stats(class_stats_t *statsp, struct rm_class *cl) int cbq_pfattach(struct pf_altq *a, struct ifaltq *ifq) { - return altq_attach(ifq, ALTQT_CBQ, a->altq_disc, + return altq_attach(ifq, ALTQT_CBQ, a->altq_disc, ifq_mapsubq_default, cbq_enqueue, cbq_dequeue, cbq_request, NULL, NULL); } diff --git a/sys/net/altq/altq_fairq.c b/sys/net/altq/altq_fairq.c index c55d9dcf0b..951ca529ec 100644 --- a/sys/net/altq/altq_fairq.c +++ b/sys/net/altq/altq_fairq.c @@ -148,9 +148,8 @@ static struct fairq_class *clh_to_clp(struct fairq_if *, uint32_t); int fairq_pfattach(struct pf_altq *a, struct ifaltq *ifq) { - return altq_attach(ifq, ALTQT_FAIRQ, a->altq_disc, - fairq_enqueue, fairq_dequeue, - fairq_request, NULL, NULL); + return altq_attach(ifq, ALTQT_FAIRQ, a->altq_disc, ifq_mapsubq_default, + fairq_enqueue, fairq_dequeue, fairq_request, NULL, NULL); } int diff --git a/sys/net/altq/altq_hfsc.c b/sys/net/altq/altq_hfsc.c index 60f1badf78..6b6ba2b90a 100644 --- a/sys/net/altq/altq_hfsc.c +++ b/sys/net/altq/altq_hfsc.c @@ -146,7 +146,7 @@ static struct hfsc_class *clh_to_clp(struct hfsc_if *, uint32_t); int hfsc_pfattach(struct pf_altq *a, struct ifaltq *ifq) { - return altq_attach(ifq, ALTQT_HFSC, a->altq_disc, + return altq_attach(ifq, ALTQT_HFSC, a->altq_disc, ifq_mapsubq_default, hfsc_enqueue, hfsc_dequeue, hfsc_request, NULL, NULL); } diff --git a/sys/net/altq/altq_priq.c b/sys/net/altq/altq_priq.c index 01335e5afb..6af889d3bd 100644 --- a/sys/net/altq/altq_priq.c +++ b/sys/net/altq/altq_priq.c @@ -87,7 +87,7 @@ static struct priq_class *clh_to_clp(struct priq_if *, uint32_t); int priq_pfattach(struct pf_altq *a, struct ifaltq *ifq) { - return altq_attach(ifq, ALTQT_PRIQ, a->altq_disc, + return altq_attach(ifq, ALTQT_PRIQ, a->altq_disc, ifq_mapsubq_default, priq_enqueue, priq_dequeue, priq_request, NULL, NULL); } diff --git a/sys/net/altq/altq_subr.c b/sys/net/altq/altq_subr.c index 9cd3cf6ff1..a1143e3e9e 100644 --- a/sys/net/altq/altq_subr.c +++ b/sys/net/altq/altq_subr.c @@ -105,6 +105,7 @@ altq_lookup(const char *name, int type) int altq_attach(struct ifaltq *ifq, int type, void *discipline, + altq_mapsubq_t mapsubq, ifsq_enqueue_t enqueue, ifsq_dequeue_t dequeue, ifsq_request_t request, void *clfier, void *(*classify)(struct ifaltq *, struct mbuf *, struct altq_pktattr *)) @@ -117,7 +118,7 @@ altq_attach(struct ifaltq *ifq, int type, void *discipline, ifq->altq_clfier = clfier; ifq->altq_classify = classify; ifq->altq_flags &= (ALTQF_CANTCHANGE|ALTQF_ENABLED); - ifq_set_methods(ifq, enqueue, dequeue, request); + ifq_set_methods(ifq, mapsubq, enqueue, dequeue, request); return 0; } diff --git a/sys/net/altq/if_altq.h b/sys/net/altq/if_altq.h index 195b9a77e2..ecaaf31cd6 100644 --- a/sys/net/altq/if_altq.h +++ b/sys/net/altq/if_altq.h @@ -41,6 +41,8 @@ struct altq_pktattr; struct ifaltq_subque; struct ifaltq; +typedef int (*altq_mapsubq_t)(struct ifaltq *, int); + typedef int (*ifsq_enqueue_t)(struct ifaltq_subque *, struct mbuf *, struct altq_pktattr *); typedef struct mbuf *(*ifsq_dequeue_t)(struct ifaltq_subque *, @@ -107,11 +109,14 @@ struct ifaltq { void *altq_clfier; /* classifier-specific use */ void *(*altq_classify)(struct ifaltq *, struct mbuf *, struct altq_pktattr *); - void *altq_unused; /* token bucket regulator */ struct tb_regulator *altq_tbr; + /* Sub-queues mapping */ + altq_mapsubq_t altq_mapsubq; + uint32_t altq_map_unused; + /* Sub-queues */ int altq_subq_cnt; struct ifaltq_subque *altq_subq; @@ -184,7 +189,7 @@ struct tb_regulator { /* altq request types (currently only purge is defined) */ #define ALTRQ_PURGE 1 /* purge all packets */ -int altq_attach(struct ifaltq *, int, void *, +int altq_attach(struct ifaltq *, int, void *, altq_mapsubq_t, ifsq_enqueue_t, ifsq_dequeue_t, ifsq_request_t, void *, void *(*)(struct ifaltq *, struct mbuf *, struct altq_pktattr *)); int altq_detach(struct ifaltq *); diff --git a/sys/net/if.c b/sys/net/if.c index ee4f4b09c7..a74e1587fa 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -566,6 +566,9 @@ if_attach(struct ifnet *ifp, lwkt_serialize_t serializer) EVENTHANDLER_INVOKE(ifnet_attach_event, ifp); devctl_notify("IFNET", ifp->if_xname, "ATTACH", NULL); + if (ifp->if_mapsubq == NULL) + ifp->if_mapsubq = ifq_mapsubq_default; + ifq = &ifp->if_snd; ifq->altq_type = 0; ifq->altq_disc = NULL; @@ -2433,16 +2436,22 @@ if_free(struct ifnet *ifp) void ifq_set_classic(struct ifaltq *ifq) { - ifq_set_methods(ifq, ifsq_classic_enqueue, ifsq_classic_dequeue, - ifsq_classic_request); + ifq_set_methods(ifq, ifq->altq_ifp->if_mapsubq, + ifsq_classic_enqueue, ifsq_classic_dequeue, ifsq_classic_request); } void -ifq_set_methods(struct ifaltq *ifq, ifsq_enqueue_t enqueue, - ifsq_dequeue_t dequeue, ifsq_request_t request) +ifq_set_methods(struct ifaltq *ifq, altq_mapsubq_t mapsubq, + ifsq_enqueue_t enqueue, ifsq_dequeue_t dequeue, ifsq_request_t request) { int q; + KASSERT(mapsubq != NULL, ("mapsubq is not specified")); + KASSERT(enqueue != NULL, ("enqueue is not specified")); + KASSERT(dequeue != NULL, ("dequeue is not specified")); + KASSERT(request != NULL, ("request is not specified")); + + ifq->altq_mapsubq = mapsubq; for (q = 0; q < ifq->altq_subq_cnt; ++q) { struct ifaltq_subque *ifsq = &ifq->altq_subq[q]; @@ -2580,11 +2589,8 @@ ifq_dispatch(struct ifnet *ifp, struct mbuf *m, struct altq_pktattr *pa) int error, start = 0, len, mcast = 0, avoid_start = 0; struct ifsubq_stage_head *head = NULL; struct ifsubq_stage *stage = NULL; - int qid = 0; /* XXX */ - - /* TODO find qid here */ - ifsq = &ifq->altq_subq[qid]; + ifsq = ifq_map_subq(ifq, mycpuid); ASSERT_IFNET_NOT_SERIALIZED_TX(ifp, ifsq); len = m->m_pkthdr.len; @@ -2996,3 +3002,9 @@ ifq_set_maxlen(struct ifaltq *ifq, int len) { ifq->altq_maxlen = len + (ncpus * ifsq_stage_cntmax); } + +int +ifq_mapsubq_default(struct ifaltq *ifq __unused, int cpuid __unused) +{ + return ALTQ_SUBQ_INDEX_DEFAULT; +} diff --git a/sys/net/if_var.h b/sys/net/if_var.h index dadd590fbd..f683c10436 100644 --- a/sys/net/if_var.h +++ b/sys/net/if_var.h @@ -231,7 +231,8 @@ struct ifnet { (struct ifnet *, struct sockaddr **, struct sockaddr *); void *if_unused5; TAILQ_HEAD(, ifg_list) if_groups; /* linked list of groups per if */ - void (*if_unused1)(void); + int (*if_mapsubq) + (struct ifaltq *, int); int if_unused2; void (*if_serialize) (struct ifnet *, enum ifnet_serialize); diff --git a/sys/net/ifq_var.h b/sys/net/ifq_var.h index bd9f908b02..5f43a0e9ea 100644 --- a/sys/net/ifq_var.h +++ b/sys/net/ifq_var.h @@ -75,8 +75,9 @@ int ifsq_classic_request(struct ifaltq_subque *, int, void *); void ifq_set_classic(struct ifaltq *); void ifq_set_maxlen(struct ifaltq *, int); -void ifq_set_methods(struct ifaltq *, ifsq_enqueue_t, - ifsq_dequeue_t, ifsq_request_t); +void ifq_set_methods(struct ifaltq *, altq_mapsubq_t, + ifsq_enqueue_t, ifsq_dequeue_t, ifsq_request_t); +int ifq_mapsubq_default(struct ifaltq *, int); void ifsq_devstart(struct ifaltq_subque *ifsq); void ifsq_devstart_sched(struct ifaltq_subque *ifsq); @@ -480,6 +481,13 @@ ifq_get_subq(const struct ifaltq *_ifq, int _idx) return &_ifq->altq_subq[_idx]; } +static __inline struct ifaltq_subque * +ifq_map_subq(struct ifaltq *_ifq, int _cpuid) +{ + int _idx = _ifq->altq_mapsubq(_ifq, _cpuid); + return ifq_get_subq(_ifq, _idx); +} + /* COMPAT */ static __inline int ifq_is_oactive(const struct ifaltq *_ifq) -- 2.41.0