Page MenuHomeFreeBSD

D22072.diff
No OneTemporary

D22072.diff

Index: head/sys/dev/cxgbe/adapter.h
===================================================================
--- head/sys/dev/cxgbe/adapter.h
+++ head/sys/dev/cxgbe/adapter.h
@@ -1155,6 +1155,7 @@
int adapter_full_init(struct adapter *);
int adapter_full_uninit(struct adapter *);
uint64_t cxgbe_get_counter(struct ifnet *, ift_counter);
+void cxgbe_snd_tag_init(struct cxgbe_snd_tag *, struct ifnet *, int);
int vi_full_init(struct vi_info *);
int vi_full_uninit(struct vi_info *);
void vi_sysctls(struct vi_info *);
@@ -1212,7 +1213,7 @@
void t4_register_shared_cpl_handler(int, cpl_handler_t, int);
#ifdef RATELIMIT
int ethofld_transmit(struct ifnet *, struct mbuf *);
-void send_etid_flush_wr(struct cxgbe_snd_tag *);
+void send_etid_flush_wr(struct cxgbe_rate_tag *);
#endif
/* t4_tracer.c */
@@ -1238,13 +1239,13 @@
#ifdef RATELIMIT
void t4_init_etid_table(struct adapter *);
void t4_free_etid_table(struct adapter *);
-struct cxgbe_snd_tag *lookup_etid(struct adapter *, int);
-int cxgbe_snd_tag_alloc(struct ifnet *, union if_snd_tag_alloc_params *,
+struct cxgbe_rate_tag *lookup_etid(struct adapter *, int);
+int cxgbe_rate_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 *);
-void cxgbe_snd_tag_free_locked(struct cxgbe_snd_tag *);
+int cxgbe_rate_tag_modify(struct m_snd_tag *, union if_snd_tag_modify_params *);
+int cxgbe_rate_tag_query(struct m_snd_tag *, union if_snd_tag_query_params *);
+void cxgbe_rate_tag_free(struct m_snd_tag *);
+void cxgbe_rate_tag_free_locked(struct cxgbe_rate_tag *);
void cxgbe_ratelimit_query(struct ifnet *, struct if_ratelimit_query_results *);
#endif
Index: head/sys/dev/cxgbe/offload.h
===================================================================
--- head/sys/dev/cxgbe/offload.h
+++ head/sys/dev/cxgbe/offload.h
@@ -79,7 +79,7 @@
union aopen_entry *next;
};
-/* cxgbe_snd_tag flags */
+/* cxgbe_rate_tag flags */
enum {
EO_FLOWC_PENDING = (1 << 0), /* flowc needs to be sent */
EO_FLOWC_RPL_PENDING = (1 << 1), /* flowc credits due back */
@@ -89,6 +89,11 @@
struct cxgbe_snd_tag {
struct m_snd_tag com;
+ int type;
+};
+
+struct cxgbe_rate_tag {
+ struct cxgbe_snd_tag com;
struct adapter *adapter;
u_int flags;
struct mtx lock;
@@ -114,8 +119,14 @@
return (__containerof(t, struct cxgbe_snd_tag, com));
}
+static inline struct cxgbe_rate_tag *
+mst_to_crt(struct m_snd_tag *t)
+{
+ return ((struct cxgbe_rate_tag *)mst_to_cst(t));
+}
+
union etid_entry {
- struct cxgbe_snd_tag *cst;
+ struct cxgbe_rate_tag *cst;
union etid_entry *next;
};
Index: head/sys/dev/cxgbe/t4_main.c
===================================================================
--- head/sys/dev/cxgbe/t4_main.c
+++ head/sys/dev/cxgbe/t4_main.c
@@ -230,6 +230,15 @@
static int cxgbe_ioctl(struct ifnet *, unsigned long, caddr_t);
static int cxgbe_transmit(struct ifnet *, struct mbuf *);
static void cxgbe_qflush(struct ifnet *);
+#ifdef RATELIMIT
+static int cxgbe_snd_tag_alloc(struct ifnet *, union if_snd_tag_alloc_params *,
+ struct m_snd_tag **);
+static int cxgbe_snd_tag_modify(struct m_snd_tag *,
+ union if_snd_tag_modify_params *);
+static int cxgbe_snd_tag_query(struct m_snd_tag *,
+ union if_snd_tag_query_params *);
+static void cxgbe_snd_tag_free(struct m_snd_tag *);
+#endif
MALLOC_DEFINE(M_CXGBE, "cxgbe", "Chelsio T4/T5 Ethernet driver and services");
@@ -2044,11 +2053,18 @@
struct port_info *pi = vi->pi;
struct adapter *sc = pi->adapter;
struct sge_txq *txq;
+#ifdef RATELIMIT
+ struct cxgbe_snd_tag *cst;
+#endif
void *items[1];
int rc;
M_ASSERTPKTHDR(m);
MPASS(m->m_nextpkt == NULL); /* not quite ready for this yet */
+#ifdef RATELIMIT
+ if (m->m_pkthdr.csum_flags & CSUM_SND_TAG)
+ MPASS(m->m_pkthdr.snd_tag->ifp == ifp);
+#endif
if (__predict_false(pi->link_cfg.link_ok == false)) {
m_freem(m);
@@ -2063,8 +2079,9 @@
}
#ifdef RATELIMIT
if (m->m_pkthdr.csum_flags & CSUM_SND_TAG) {
- MPASS(m->m_pkthdr.snd_tag->ifp == ifp);
- return (ethofld_transmit(ifp, m));
+ cst = mst_to_cst(m->m_pkthdr.snd_tag);
+ if (cst->type == IF_SND_TAG_TYPE_RATE_LIMIT)
+ return (ethofld_transmit(ifp, m));
}
#endif
@@ -2221,6 +2238,87 @@
return (if_get_counter_default(ifp, c));
}
}
+
+#ifdef RATELIMIT
+void
+cxgbe_snd_tag_init(struct cxgbe_snd_tag *cst, struct ifnet *ifp, int type)
+{
+
+ m_snd_tag_init(&cst->com, ifp);
+ cst->type = type;
+}
+
+static int
+cxgbe_snd_tag_alloc(struct ifnet *ifp, union if_snd_tag_alloc_params *params,
+ struct m_snd_tag **pt)
+{
+ int error;
+
+ switch (params->hdr.type) {
+#ifdef RATELIMIT
+ case IF_SND_TAG_TYPE_RATE_LIMIT:
+ error = cxgbe_rate_tag_alloc(ifp, params, pt);
+ break;
+#endif
+ default:
+ error = EOPNOTSUPP;
+ }
+ if (error == 0)
+ MPASS(mst_to_cst(*pt)->type == params->hdr.type);
+ return (error);
+}
+
+static int
+cxgbe_snd_tag_modify(struct m_snd_tag *mst,
+ union if_snd_tag_modify_params *params)
+{
+ struct cxgbe_snd_tag *cst;
+
+ cst = mst_to_cst(mst);
+ switch (cst->type) {
+#ifdef RATELIMIT
+ case IF_SND_TAG_TYPE_RATE_LIMIT:
+ return (cxgbe_rate_tag_modify(mst, params));
+#endif
+ default:
+ return (EOPNOTSUPP);
+ }
+}
+
+static int
+cxgbe_snd_tag_query(struct m_snd_tag *mst,
+ union if_snd_tag_query_params *params)
+{
+ struct cxgbe_snd_tag *cst;
+
+ cst = mst_to_cst(mst);
+ switch (cst->type) {
+#ifdef RATELIMIT
+ case IF_SND_TAG_TYPE_RATE_LIMIT:
+ return (cxgbe_rate_tag_query(mst, params));
+#endif
+ default:
+ return (EOPNOTSUPP);
+ }
+}
+
+static void
+cxgbe_snd_tag_free(struct m_snd_tag *mst)
+{
+ struct cxgbe_snd_tag *cst;
+
+ cst = mst_to_cst(mst);
+ switch (cst->type) {
+#ifdef RATELIMIT
+ case IF_SND_TAG_TYPE_RATE_LIMIT:
+ cxgbe_rate_tag_free(mst);
+ return;
+#endif
+ default:
+ panic("shouldn't get here");
+ }
+}
+#endif
/*
* The kernel picks a media from the list we had provided but we still validate
Index: head/sys/dev/cxgbe/t4_sched.c
===================================================================
--- head/sys/dev/cxgbe/t4_sched.c
+++ head/sys/dev/cxgbe/t4_sched.c
@@ -711,11 +711,11 @@
}
/* etid services */
-static int alloc_etid(struct adapter *, struct cxgbe_snd_tag *);
+static int alloc_etid(struct adapter *, struct cxgbe_rate_tag *);
static void free_etid(struct adapter *, int);
static int
-alloc_etid(struct adapter *sc, struct cxgbe_snd_tag *cst)
+alloc_etid(struct adapter *sc, struct cxgbe_rate_tag *cst)
{
struct tid_info *t = &sc->tids;
int etid = -1;
@@ -733,7 +733,7 @@
return (etid);
}
-struct cxgbe_snd_tag *
+struct cxgbe_rate_tag *
lookup_etid(struct adapter *sc, int etid)
{
struct tid_info *t = &sc->tids;
@@ -755,17 +755,16 @@
}
int
-cxgbe_snd_tag_alloc(struct ifnet *ifp, union if_snd_tag_alloc_params *params,
+cxgbe_rate_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;
+ struct cxgbe_rate_tag *cst;
- if (params->hdr.type != IF_SND_TAG_TYPE_RATE_LIMIT)
- return (ENOTSUP);
+ MPASS(params->hdr.type == IF_SND_TAG_TYPE_RATE_LIMIT);
rc = t4_reserve_cl_rl_kbps(sc, pi->port_id,
(params->rate_limit.max_rate * 8ULL / 1000), &schedcl);
@@ -789,7 +788,7 @@
mtx_init(&cst->lock, "cst_lock", NULL, MTX_DEF);
mbufq_init(&cst->pending_tx, INT_MAX);
mbufq_init(&cst->pending_fwack, INT_MAX);
- m_snd_tag_init(&cst->com, ifp);
+ cxgbe_snd_tag_init(&cst->com, ifp, IF_SND_TAG_TYPE_RATE_LIMIT);
cst->flags |= EO_FLOWC_PENDING | EO_SND_TAG_REF;
cst->adapter = sc;
cst->port_id = pi->port_id;
@@ -806,7 +805,7 @@
* Queues will be selected later when the connection flowid is available.
*/
- *pt = &cst->com;
+ *pt = &cst->com.com;
return (0);
}
@@ -814,11 +813,11 @@
* Change in parameters, no change in ifp.
*/
int
-cxgbe_snd_tag_modify(struct m_snd_tag *mst,
+cxgbe_rate_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 cxgbe_rate_tag *cst = mst_to_crt(mst);
struct adapter *sc = cst->adapter;
/* XXX: is schedcl -1 ok here? */
@@ -840,10 +839,10 @@
}
int
-cxgbe_snd_tag_query(struct m_snd_tag *mst,
+cxgbe_rate_tag_query(struct m_snd_tag *mst,
union if_snd_tag_query_params *params)
{
- struct cxgbe_snd_tag *cst = mst_to_cst(mst);
+ struct cxgbe_rate_tag *cst = mst_to_crt(mst);
params->rate_limit.max_rate = cst->max_rate;
@@ -858,7 +857,7 @@
* Unlocks cst and frees it.
*/
void
-cxgbe_snd_tag_free_locked(struct cxgbe_snd_tag *cst)
+cxgbe_rate_tag_free_locked(struct cxgbe_rate_tag *cst)
{
struct adapter *sc = cst->adapter;
@@ -879,9 +878,9 @@
}
void
-cxgbe_snd_tag_free(struct m_snd_tag *mst)
+cxgbe_rate_tag_free(struct m_snd_tag *mst)
{
- struct cxgbe_snd_tag *cst = mst_to_cst(mst);
+ struct cxgbe_rate_tag *cst = mst_to_crt(mst);
mtx_lock(&cst->lock);
@@ -896,7 +895,7 @@
* credits for the etid otherwise.
*/
if (cst->tx_credits == cst->tx_total) {
- cxgbe_snd_tag_free_locked(cst);
+ cxgbe_rate_tag_free_locked(cst);
return; /* cst is gone. */
}
send_etid_flush_wr(cst);
Index: head/sys/dev/cxgbe/t4_sge.c
===================================================================
--- head/sys/dev/cxgbe/t4_sge.c
+++ head/sys/dev/cxgbe/t4_sge.c
@@ -2307,10 +2307,10 @@
}
static inline int
-needs_eo(struct mbuf *m)
+needs_eo(struct cxgbe_snd_tag *cst)
{
- return (m->m_pkthdr.csum_flags & CSUM_SND_TAG);
+ return (cst != NULL && cst->type == IF_SND_TAG_TYPE_RATE_LIMIT);
}
#endif
@@ -2542,6 +2542,9 @@
#if defined(INET) || defined(INET6)
struct tcphdr *tcp;
#endif
+#ifdef RATELIMIT
+ struct cxgbe_snd_tag *cst;
+#endif
uint16_t eh_type;
uint8_t cflags;
@@ -2562,6 +2565,12 @@
M_ASSERTPKTHDR(m0);
MPASS(m0->m_pkthdr.len > 0);
nsegs = count_mbuf_nsegs(m0, 0, &cflags);
+#ifdef RATELIMIT
+ if (m0->m_pkthdr.csum_flags & CSUM_SND_TAG)
+ cst = mst_to_cst(m0->m_pkthdr.snd_tag);
+ else
+ cst = NULL;
+#endif
if (nsegs > (needs_tso(m0) ? TX_SGL_SEGS_TSO : TX_SGL_SEGS)) {
if (defragged++ > 0 || (m = m_defrag(m0, M_NOWAIT)) == NULL) {
rc = EFBIG;
@@ -2595,16 +2604,17 @@
* checksumming is enabled. needs_l4_csum happens to check for all the
* right things.
*/
- if (__predict_false(needs_eo(m0) && !needs_l4_csum(m0))) {
+ if (__predict_false(needs_eo(cst) && !needs_l4_csum(m0))) {
m_snd_tag_rele(m0->m_pkthdr.snd_tag);
m0->m_pkthdr.snd_tag = NULL;
m0->m_pkthdr.csum_flags &= ~CSUM_SND_TAG;
+ cst = NULL;
}
#endif
if (!needs_tso(m0) &&
#ifdef RATELIMIT
- !needs_eo(m0) &&
+ !needs_eo(cst) &&
#endif
!(sc->flags & IS_VF && (needs_l3_csum(m0) || needs_l4_csum(m0))))
return (0);
@@ -2666,7 +2676,7 @@
#endif
}
#ifdef RATELIMIT
- if (needs_eo(m0)) {
+ if (needs_eo(cst)) {
u_int immhdrs;
/* EO WRs have the headers in the WR and not the GL. */
@@ -5723,7 +5733,7 @@
#define ETID_FLOWC_LEN16 (howmany(ETID_FLOWC_LEN, 16))
static int
-send_etid_flowc_wr(struct cxgbe_snd_tag *cst, struct port_info *pi,
+send_etid_flowc_wr(struct cxgbe_rate_tag *cst, struct port_info *pi,
struct vi_info *vi)
{
struct wrq_cookie cookie;
@@ -5769,7 +5779,7 @@
#define ETID_FLUSH_LEN16 (howmany(sizeof (struct fw_flowc_wr), 16))
void
-send_etid_flush_wr(struct cxgbe_snd_tag *cst)
+send_etid_flush_wr(struct cxgbe_rate_tag *cst)
{
struct fw_flowc_wr *flowc;
struct wrq_cookie cookie;
@@ -5795,7 +5805,7 @@
}
static void
-write_ethofld_wr(struct cxgbe_snd_tag *cst, struct fw_eth_tx_eo_wr *wr,
+write_ethofld_wr(struct cxgbe_rate_tag *cst, struct fw_eth_tx_eo_wr *wr,
struct mbuf *m0, int compl)
{
struct cpl_tx_pkt_core *cpl;
@@ -5944,7 +5954,7 @@
}
static void
-ethofld_tx(struct cxgbe_snd_tag *cst)
+ethofld_tx(struct cxgbe_rate_tag *cst)
{
struct mbuf *m;
struct wrq_cookie cookie;
@@ -5977,7 +5987,7 @@
cst->tx_credits -= next_credits;
cst->tx_nocompl += next_credits;
compl = cst->ncompl == 0 || cst->tx_nocompl >= cst->tx_total / 2;
- ETHER_BPF_MTAP(cst->com.ifp, m);
+ ETHER_BPF_MTAP(cst->com.com.ifp, m);
write_ethofld_wr(cst, wr, m, compl);
commit_wrq_wr(cst->eo_txq, wr, &cookie);
if (compl) {
@@ -5989,7 +5999,7 @@
/*
* Drop the mbuf's reference on the tag now rather
* than waiting until m_freem(). This ensures that
- * cxgbe_snd_tag_free gets called when the inp drops
+ * cxgbe_rate_tag_free gets called when the inp drops
* its reference on the tag and there are no more
* mbufs in the pending_tx queue and can flush any
* pending requests. Otherwise if the last mbuf
@@ -5998,7 +6008,7 @@
*/
m->m_pkthdr.snd_tag = NULL;
m->m_pkthdr.csum_flags &= ~CSUM_SND_TAG;
- m_snd_tag_rele(&cst->com);
+ m_snd_tag_rele(&cst->com.com);
mbufq_enqueue(&cst->pending_fwack, m);
}
@@ -6007,13 +6017,13 @@
int
ethofld_transmit(struct ifnet *ifp, struct mbuf *m0)
{
- struct cxgbe_snd_tag *cst;
+ struct cxgbe_rate_tag *cst;
int rc;
MPASS(m0->m_nextpkt == NULL);
MPASS(m0->m_pkthdr.csum_flags & CSUM_SND_TAG);
MPASS(m0->m_pkthdr.snd_tag != NULL);
- cst = mst_to_cst(m0->m_pkthdr.snd_tag);
+ cst = mst_to_crt(m0->m_pkthdr.snd_tag);
mtx_lock(&cst->lock);
MPASS(cst->flags & EO_SND_TAG_REF);
@@ -6052,10 +6062,10 @@
* ethofld_tx() in case we are sending the final mbuf after
* the inp was freed.
*/
- m_snd_tag_ref(&cst->com);
+ m_snd_tag_ref(&cst->com.com);
ethofld_tx(cst);
mtx_unlock(&cst->lock);
- m_snd_tag_rele(&cst->com);
+ m_snd_tag_rele(&cst->com.com);
return (0);
done:
@@ -6072,7 +6082,7 @@
const struct cpl_fw4_ack *cpl = (const void *)(rss + 1);
struct mbuf *m;
u_int etid = G_CPL_FW4_ACK_FLOWID(be32toh(OPCODE_TID(cpl)));
- struct cxgbe_snd_tag *cst;
+ struct cxgbe_rate_tag *cst;
uint8_t credits = cpl->credits;
cst = lookup_etid(sc, etid);
@@ -6104,7 +6114,7 @@
cst->flags &= ~EO_FLUSH_RPL_PENDING;
cst->tx_credits += cpl->credits;
- cxgbe_snd_tag_free_locked(cst);
+ cxgbe_rate_tag_free_locked(cst);
return (0); /* cst is gone. */
}
KASSERT(m != NULL,
@@ -6126,12 +6136,12 @@
* As with ethofld_transmit(), hold an extra reference
* so that the tag is stable across ethold_tx().
*/
- m_snd_tag_ref(&cst->com);
+ m_snd_tag_ref(&cst->com.com);
m = mbufq_first(&cst->pending_tx);
if (m != NULL && cst->tx_credits >= mbuf_eo_len16(m))
ethofld_tx(cst);
mtx_unlock(&cst->lock);
- m_snd_tag_rele(&cst->com);
+ m_snd_tag_rele(&cst->com.com);
} else {
/*
* There shouldn't be any pending packets if the tag

File Metadata

Mime Type
text/plain
Expires
Wed, Apr 22, 6:26 PM (20 h, 10 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31993300
Default Alt Text
D22072.diff (14 KB)

Event Timeline