Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F153539188
D22072.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
14 KB
Referenced Files
None
Subscribers
None
D22072.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D22072: Split Chelsio send tags into a generic base tag and a ratelimit tag.
Attached
Detach File
Event Timeline
Log In to Comment