Split Chelsio send tags into a generic base tag and a ratelimit tag.
NIC KTLS will add a new TLS send tag type in cxgbe(4) that is a distinct tag from a ratelimit tag. To support this, refactor cxgbe_snd_tag to be a simple send tag with a type and convert the existing ratelimit tag to a new cxgbe_rate_tag structure. Reviewed by: np Sponsored by: Chelsio Communications Differential Revision: https://reviews.freebsd.org/D22072
This commit is contained in:
parent
866a7f286f
commit
e38a50e8b6
@ -1155,6 +1155,7 @@ int update_mac_settings(struct ifnet *, int);
|
||||
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_cpl_handler(int, cpl_handler_t);
|
||||
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 @@ int sysctl_tc_params(SYSCTL_HANDLER_ARGS);
|
||||
#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
|
||||
|
||||
|
@ -79,7 +79,7 @@ union aopen_entry {
|
||||
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 @@ enum {
|
||||
|
||||
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 @@ mst_to_cst(struct m_snd_tag *t)
|
||||
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;
|
||||
};
|
||||
|
||||
|
@ -230,6 +230,15 @@ static void cxgbe_init(void *);
|
||||
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 @@ cxgbe_transmit(struct ifnet *ifp, struct mbuf *m)
|
||||
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 @@ cxgbe_transmit(struct ifnet *ifp, struct mbuf *m)
|
||||
}
|
||||
#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
|
||||
|
||||
@ -2222,6 +2239,87 @@ cxgbe_get_counter(struct ifnet *ifp, ift_counter 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
|
||||
* the requeste.
|
||||
|
@ -711,11 +711,11 @@ t4_free_etid_table(struct adapter *sc)
|
||||
}
|
||||
|
||||
/* 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 @@ alloc_etid(struct adapter *sc, struct cxgbe_snd_tag *cst)
|
||||
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 @@ free_etid(struct adapter *sc, int etid)
|
||||
}
|
||||
|
||||
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 @@ failed:
|
||||
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 @@ failed:
|
||||
* Queues will be selected later when the connection flowid is available.
|
||||
*/
|
||||
|
||||
*pt = &cst->com;
|
||||
*pt = &cst->com.com;
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -814,11 +813,11 @@ failed:
|
||||
* 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 @@ cxgbe_snd_tag_modify(struct m_snd_tag *mst,
|
||||
}
|
||||
|
||||
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 @@ cxgbe_snd_tag_query(struct m_snd_tag *mst,
|
||||
* 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 @@ cxgbe_snd_tag_free_locked(struct cxgbe_snd_tag *cst)
|
||||
}
|
||||
|
||||
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 @@ cxgbe_snd_tag_free(struct m_snd_tag *mst)
|
||||
* 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);
|
||||
|
@ -2307,10 +2307,10 @@ set_mbuf_eo_tsclk_tsoff(struct mbuf *m, uint8_t tsclk_tsoff)
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@ -2541,6 +2541,9 @@ parse_pkt(struct adapter *sc, struct mbuf **mp)
|
||||
void *l3hdr;
|
||||
#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 @@ restart:
|
||||
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 @@ restart:
|
||||
* 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 @@ restart:
|
||||
#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 @@ done:
|
||||
#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 @@ send_etid_flowc_wr(struct cxgbe_snd_tag *cst, struct port_info *pi,
|
||||
#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 @@ send_etid_flush_wr(struct cxgbe_snd_tag *cst)
|
||||
}
|
||||
|
||||
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 @@ write_ethofld_wr(struct cxgbe_snd_tag *cst, struct fw_eth_tx_eo_wr *wr,
|
||||
}
|
||||
|
||||
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 @@ ethofld_tx(struct cxgbe_snd_tag *cst)
|
||||
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 @@ ethofld_tx(struct cxgbe_snd_tag *cst)
|
||||
/*
|
||||
* 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 @@ ethofld_tx(struct cxgbe_snd_tag *cst)
|
||||
*/
|
||||
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 @@ ethofld_tx(struct cxgbe_snd_tag *cst)
|
||||
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_transmit(struct ifnet *ifp, struct mbuf *m0)
|
||||
* 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 @@ ethofld_fw4_ack(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m0
|
||||
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 @@ ethofld_fw4_ack(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m0
|
||||
|
||||
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 @@ ethofld_fw4_ack(struct sge_iq *iq, const struct rss_header *rss, struct mbuf *m0
|
||||
* 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
|
||||
|
Loading…
x
Reference in New Issue
Block a user