Date: Fri, 18 May 2018 06:09:16 +0000 (UTC) From: Navdeep Parhar <np@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r333782 - head/sys/dev/cxgbe Message-ID: <201805180609.w4I69GsS042506@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: np Date: Fri May 18 06:09:15 2018 New Revision: 333782 URL: https://svnweb.freebsd.org/changeset/base/333782 Log: cxgbe(4): Implement ifnet callbacks that deal with send tags. An etid (ethoffload tid) is allocated for a send tag and it acquires a reference on the traffic class that matches the send parameters associated with the tag. Sponsored by: Chelsio Communications Modified: head/sys/dev/cxgbe/adapter.h head/sys/dev/cxgbe/offload.h head/sys/dev/cxgbe/t4_main.c head/sys/dev/cxgbe/t4_sched.c Modified: head/sys/dev/cxgbe/adapter.h ============================================================================== --- head/sys/dev/cxgbe/adapter.h Fri May 18 04:13:58 2018 (r333781) +++ head/sys/dev/cxgbe/adapter.h Fri May 18 06:09:15 2018 (r333782) @@ -1236,6 +1236,15 @@ int t4_free_tx_sched(struct adapter *); void t4_update_tx_sched(struct adapter *); int t4_reserve_cl_rl_kbps(struct adapter *, int, u_int, int *); void t4_release_cl_rl_kbps(struct adapter *, int, int); +#ifdef RATELIMIT +void t4_init_etid_table(struct adapter *); +void t4_free_etid_table(struct adapter *); +int cxgbe_snd_tag_alloc(struct ifnet *, union if_snd_tag_alloc_params *, + struct m_snd_tag **); +int cxgbe_snd_tag_modify(struct m_snd_tag *, union if_snd_tag_modify_params *); +int cxgbe_snd_tag_query(struct m_snd_tag *, union if_snd_tag_query_params *); +void cxgbe_snd_tag_free(struct m_snd_tag *); +#endif /* t4_filter.c */ int get_filter_mode(struct adapter *, uint32_t *); Modified: head/sys/dev/cxgbe/offload.h ============================================================================== --- head/sys/dev/cxgbe/offload.h Fri May 18 04:13:58 2018 (r333781) +++ head/sys/dev/cxgbe/offload.h Fri May 18 06:09:15 2018 (r333782) @@ -79,6 +79,38 @@ union aopen_entry { union aopen_entry *next; }; +struct cxgbe_snd_tag { + struct m_snd_tag com; + struct adapter *adapter; + u_int flags; + struct mtx lock; + int port_id; + int etid; + struct sge_wrq *eo_txq; + uint16_t iqid; + int8_t schedcl; + uint64_t max_rate; /* in bytes/s */ + int8_t next_credits; /* need these many tx credits next */ + uint8_t next_nsegs; /* next WR will have these many GL segs total */ + uint8_t next_msegs; /* max segs for a single mbuf in next chain */ + uint8_t tx_total; /* total tx WR credits (in 16B units) */ + uint8_t tx_credits; /* tx WR credits (in 16B units) available */ + uint8_t tx_nocompl; /* tx WR credits since last compl request */ + uint8_t ncompl; /* # of completions outstanding. */ +}; + +static inline struct cxgbe_snd_tag * +mst_to_cst(struct m_snd_tag *t) +{ + + return (__containerof(t, struct cxgbe_snd_tag, com)); +} + +union etid_entry { + struct cxgbe_snd_tag *cst; + union etid_entry *next; +}; + /* * Holds the size, base address, free list start, etc of the TID, server TID, * and active-open TID tables. The tables themselves are allocated dynamically. @@ -98,8 +130,8 @@ struct tid_info { struct mtx atid_lock __aligned(CACHE_LINE_SIZE); union aopen_entry *atid_tab; - u_int natids; union aopen_entry *afree; + u_int natids; u_int atids_in_use; struct mtx ftid_lock __aligned(CACHE_LINE_SIZE); @@ -115,9 +147,11 @@ struct tid_info { /* ntids, tids_in_use */ struct mtx etid_lock __aligned(CACHE_LINE_SIZE); - struct etid_entry *etid_tab; + union etid_entry *etid_tab; + union etid_entry *efree; u_int netids; u_int etid_base; + u_int etids_in_use; }; struct t4_range { Modified: head/sys/dev/cxgbe/t4_main.c ============================================================================== --- head/sys/dev/cxgbe/t4_main.c Fri May 18 04:13:58 2018 (r333781) +++ head/sys/dev/cxgbe/t4_main.c Fri May 18 06:09:15 2018 (r333782) @@ -1105,6 +1105,9 @@ t4_attach(device_t dev) t4_init_l2t(sc, M_WAITOK); t4_init_tx_sched(sc); +#ifdef RATELIMIT + t4_init_etid_table(sc); +#endif /* * Second pass over the ports. This time we know the number of rx and @@ -1375,6 +1378,9 @@ t4_detach_common(device_t dev) if (sc->l2t) t4_free_l2t(sc->l2t); +#ifdef RATELIMIT + t4_free_etid_table(sc); +#endif #if defined(TCP_OFFLOAD) || defined(RATELIMIT) free(sc->sge.ofld_txq, M_CXGBE); @@ -1486,6 +1492,12 @@ cxgbe_vi_attach(device_t dev, struct vi_info *vi) ifp->if_transmit = cxgbe_transmit; ifp->if_qflush = cxgbe_qflush; ifp->if_get_counter = cxgbe_get_counter; +#ifdef RATELIMIT + ifp->if_snd_tag_alloc = cxgbe_snd_tag_alloc; + ifp->if_snd_tag_modify = cxgbe_snd_tag_modify; + ifp->if_snd_tag_query = cxgbe_snd_tag_query; + ifp->if_snd_tag_free = cxgbe_snd_tag_free; +#endif ifp->if_capabilities = T4_CAP; #ifdef TCP_OFFLOAD @@ -7928,8 +7940,8 @@ sysctl_tids(SYSCTL_HANDLER_ARGS) } if (t->netids) { - sbuf_printf(sb, "ETID range: %u-%u\n", t->etid_base, - t->etid_base + t->netids - 1); + sbuf_printf(sb, "ETID range: %u-%u, in use: %u\n", t->etid_base, + t->etid_base + t->netids - 1, t->etids_in_use); } sbuf_printf(sb, "HW TID usage: %u IP users, %u IPv6 users", Modified: head/sys/dev/cxgbe/t4_sched.c ============================================================================== --- head/sys/dev/cxgbe/t4_sched.c Fri May 18 04:13:58 2018 (r333781) +++ head/sys/dev/cxgbe/t4_sched.c Fri May 18 06:09:15 2018 (r333782) @@ -30,6 +30,7 @@ __FBSDID("$FreeBSD$"); #include "opt_inet.h" #include "opt_inet6.h" +#include "opt_ratelimit.h" #include <sys/types.h> #include <sys/malloc.h> @@ -463,3 +464,197 @@ t4_release_cl_rl_kbps(struct adapter *sc, int port_id, tc->refcount--; mtx_unlock(&sc->tc_lock); } + +#ifdef RATELIMIT +void +t4_init_etid_table(struct adapter *sc) +{ + int i; + struct tid_info *t; + + if (!is_ethoffload(sc)) + return; + + t = &sc->tids; + MPASS(t->netids > 0); + + mtx_init(&t->etid_lock, "etid lock", NULL, MTX_DEF); + t->etid_tab = malloc(sizeof(*t->etid_tab) * t->netids, M_CXGBE, + M_ZERO | M_WAITOK); + t->efree = t->etid_tab; + t->etids_in_use = 0; + for (i = 1; i < t->netids; i++) + t->etid_tab[i - 1].next = &t->etid_tab[i]; + t->etid_tab[t->netids - 1].next = NULL; +} + +void +t4_free_etid_table(struct adapter *sc) +{ + struct tid_info *t; + + if (!is_ethoffload(sc)) + return; + + t = &sc->tids; + MPASS(t->netids > 0); + + free(t->etid_tab, M_CXGBE); + t->etid_tab = NULL; + + if (mtx_initialized(&t->etid_lock)) + mtx_destroy(&t->etid_lock); +} + +/* etid services */ +static int alloc_etid(struct adapter *, struct cxgbe_snd_tag *); +static void free_etid(struct adapter *, int); + +static int +alloc_etid(struct adapter *sc, struct cxgbe_snd_tag *cst) +{ + struct tid_info *t = &sc->tids; + int etid = -1; + + mtx_lock(&t->etid_lock); + if (t->efree) { + union etid_entry *p = t->efree; + + etid = p - t->etid_tab + t->etid_base; + t->efree = p->next; + p->cst = cst; + t->etids_in_use++; + } + mtx_unlock(&t->etid_lock); + return (etid); +} + +#ifdef notyet +struct cxgbe_snd_tag * +lookup_etid(struct adapter *sc, int etid) +{ + struct tid_info *t = &sc->tids; + + return (t->etid_tab[etid - t->etid_base].cst); +} +#endif + +static void +free_etid(struct adapter *sc, int etid) +{ + struct tid_info *t = &sc->tids; + union etid_entry *p = &t->etid_tab[etid - t->etid_base]; + + mtx_lock(&t->etid_lock); + p->next = t->efree; + t->efree = p; + t->etids_in_use--; + mtx_unlock(&t->etid_lock); +} + +int +cxgbe_snd_tag_alloc(struct ifnet *ifp, union if_snd_tag_alloc_params *params, + struct m_snd_tag **pt) +{ + int rc, schedcl; + struct vi_info *vi = ifp->if_softc; + struct port_info *pi = vi->pi; + struct adapter *sc = pi->adapter; + struct cxgbe_snd_tag *cst; + + if (params->hdr.type != IF_SND_TAG_TYPE_RATE_LIMIT) + return (ENOTSUP); + + rc = t4_reserve_cl_rl_kbps(sc, pi->port_id, + (params->rate_limit.max_rate * 8ULL / 1000), &schedcl); + if (rc != 0) + return (rc); + MPASS(schedcl >= 0 && schedcl < sc->chip_params->nsched_cls); + + cst = malloc(sizeof(*cst), M_CXGBE, M_ZERO | M_NOWAIT); + if (cst == NULL) { +failed: + t4_release_cl_rl_kbps(sc, pi->port_id, schedcl); + return (ENOMEM); + } + + cst->etid = alloc_etid(sc, cst); + if (cst->etid < 0) { + free(cst, M_CXGBE); + goto failed; + } + + mtx_init(&cst->lock, "cst_lock", NULL, MTX_DEF); + cst->com.ifp = ifp; + cst->adapter = sc; + cst->port_id = pi->port_id; + cst->schedcl = schedcl; + cst->max_rate = params->rate_limit.max_rate; + cst->next_credits = -1; + cst->tx_credits = sc->params.ofldq_wr_cred; + cst->tx_total = cst->tx_credits; + + /* + * Queues will be selected later when the connection flowid is available. + */ + + *pt = &cst->com; + return (0); +} + +/* + * Change in parameters, no change in ifp. + */ +int +cxgbe_snd_tag_modify(struct m_snd_tag *mst, + union if_snd_tag_modify_params *params) +{ + int rc, schedcl; + struct cxgbe_snd_tag *cst = mst_to_cst(mst); + struct adapter *sc = cst->adapter; + + /* XXX: is schedcl -1 ok here? */ + MPASS(cst->schedcl >= 0 && cst->schedcl < sc->chip_params->nsched_cls); + + rc = t4_reserve_cl_rl_kbps(sc, cst->port_id, + (params->rate_limit.max_rate * 8ULL / 1000), &schedcl); + if (rc != 0) + return (rc); + MPASS(schedcl >= 0 && schedcl < sc->chip_params->nsched_cls); + t4_release_cl_rl_kbps(sc, cst->port_id, cst->schedcl); + cst->schedcl = schedcl; + cst->max_rate = params->rate_limit.max_rate; + + return (0); +} + +int +cxgbe_snd_tag_query(struct m_snd_tag *mst, + union if_snd_tag_query_params *params) +{ + struct cxgbe_snd_tag *cst = mst_to_cst(mst); + + params->rate_limit.max_rate = cst->max_rate; + +#define CST_TO_MST_QLEVEL_SCALE (IF_SND_QUEUE_LEVEL_MAX / cst->tx_total) + params->rate_limit.queue_level = + (cst->tx_total - cst->tx_credits) * CST_TO_MST_QLEVEL_SCALE; + + return (0); +} + +void +cxgbe_snd_tag_free(struct m_snd_tag *mst) +{ + struct cxgbe_snd_tag *cst = mst_to_cst(mst); + struct adapter *sc = cst->adapter; + + if (cst->etid >= 0) + free_etid(sc, cst->etid); + if (cst->schedcl != -1) + t4_release_cl_rl_kbps(sc, cst->port_id, cst->schedcl); + if (mtx_initialized(&cst->lock)) + mtx_destroy(&cst->lock); + free(cst, M_CXGBE); +} +#endif
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201805180609.w4I69GsS042506>