33#include "opt_ratelimit.h"
36#include <sys/malloc.h>
39#include <sys/taskqueue.h>
40#include <sys/sysctl.h>
51 return (val < 0 || (val <= hi && val >= lo));
78 int rc, top_speed, fw_level, fw_mode, fw_rateunit, fw_ratemode;
81 bool check_pktsize =
false;
147 check_pktsize =
true;
221 fw_mode, fw_rateunit, fw_ratemode, p->
channel, p->
cl,
237 tc->
flags &= ~CF_USER;
238 CH_ERR(pi,
"failed to configure traffic class %d: %d. "
239 "params: mode %d, rateunit %d, ratemode %d, "
240 "channel %d, minrate %d, maxrate %d, pktsize %d, "
241 "burstsize %d\n", p->
cl, rc, fw_mode, fw_rateunit,
264 for (j = 0; j < n; j++, tc++) {
265 MPASS(mtx_owned(&sc->
tc_lock));
292 CH_ERR(pi,
"failed to configure traffic class %d: %d. "
293 "params: mode %d, rateunit %d, ratemode %d, "
294 "channel %d, minrate %d, maxrate %d, pktsize %d, "
324 uint32_t fw_mnem, fw_class;
367 fw_class = idx < 0 ? 0xffffffff : idx;
460 mtx_init(&sc->
tc_lock,
"tx_sched lock", NULL, MTX_DEF);
476 taskqueue_drain(taskqueue_thread, &sc->
tc_task);
479 if (sc->
port[i] != NULL)
483 if (mtx_initialized(&sc->
tc_lock))
493 taskqueue_enqueue(taskqueue_thread, &sc->
tc_task);
500 int rc = 0, fa, fa2, i, pktsize, burstsize;
505 MPASS(
port_id >= 0 && port_id < sc->params.nports);
511 pktsize = pi->
vi[0].
ifp->if_mtu;
515 burstsize = pktsize * 4;
541 if (fa2 < 0 && tc->refcount == 0 && !(tc->
flags &
CF_USER)) {
553 MPASS(fa >= 0 && fa < sc->params.nsched_cls);
581 MPASS(port_id >= 0 && port_id < sc->params.nports);
582 MPASS(
tc_idx >= 0 && tc_idx < sc->params.nsched_cls);
597 int qidx = arg2, rc,
tc_idx;
599 MPASS(qidx >= vi->
first_txq && qidx < vi->first_txq + vi->
ntxq);
603 rc = sysctl_handle_int(oidp, &
tc_idx, 0, req);
604 if (rc != 0 || req->newptr == NULL)
621 int i, rc, port_id, mbps, gbps;
623 rc = sysctl_wire_old_buffer(req, 0);
627 sb = sbuf_new_for_sysctl(NULL, NULL, 4096, req);
631 port_id = arg2 >> 16;
632 MPASS(port_id < sc->params.nports);
633 MPASS(sc->
port[port_id] != NULL);
635 MPASS(i < sc->params.nsched_cls);
642 sbuf_printf(sb,
"uninitialized");
652 sbuf_printf(sb,
"%u%% of %uGbps", tc.
maxrate, gbps);
657 if (tc.
maxrate == gbps * 1000000)
658 sbuf_printf(sb,
"%uGbps", gbps);
659 else if (tc.
maxrate == mbps * 1000)
660 sbuf_printf(sb,
"%uMbps", mbps);
662 sbuf_printf(sb,
"%uKbps", tc.
maxrate);
670 sbuf_printf(sb,
"%upps", tc.
maxrate);
680 sbuf_printf(sb,
" aggregate");
683 sbuf_printf(sb,
" per-flow");
685 sbuf_printf(sb,
" pkt-size %u", tc.
pktsize);
687 sbuf_printf(sb,
" burst-size %u", tc.
burstsize);
696 rc = sbuf_finish(sb);
704t4_init_etid_table(
struct adapter *sc)
715 mtx_init(&t->etid_lock,
"etid lock", NULL, MTX_DEF);
720 for (i = 1; i < t->
netids; i++)
726t4_free_etid_table(
struct adapter *sc)
739 if (mtx_initialized(&t->etid_lock))
740 mtx_destroy(&t->etid_lock);
745static void free_etid(
struct adapter *,
int);
753 mtx_lock(&t->etid_lock);
762 mtx_unlock(&t->etid_lock);
775free_etid(
struct adapter *sc,
int etid)
780 mtx_lock(&t->etid_lock);
784 mtx_unlock(&t->etid_lock);
787static int cxgbe_rate_tag_modify(
struct m_snd_tag *,
788 union if_snd_tag_modify_params *);
789static int cxgbe_rate_tag_query(
struct m_snd_tag *,
790 union if_snd_tag_query_params *);
791static void cxgbe_rate_tag_free(
struct m_snd_tag *);
793static const struct if_snd_tag_sw cxgbe_rate_tag_sw = {
794 .snd_tag_modify = cxgbe_rate_tag_modify,
795 .snd_tag_query = cxgbe_rate_tag_query,
796 .snd_tag_free = cxgbe_rate_tag_free,
797 .type = IF_SND_TAG_TYPE_RATE_LIMIT
801cxgbe_rate_tag_alloc(
struct ifnet *
ifp,
union if_snd_tag_alloc_params *params,
802 struct m_snd_tag **pt)
810 MPASS(params->hdr.type == IF_SND_TAG_TYPE_RATE_LIMIT);
813 (params->rate_limit.max_rate * 8ULL / 1000), &
schedcl);
816 MPASS(
schedcl >= 0 && schedcl < sc->params.nsched_cls);
818 cst = malloc(
sizeof(*cst), M_CXGBE, M_ZERO | M_NOWAIT);
825 cst->
etid = alloc_etid(sc, cst);
831 mtx_init(&cst->
lock,
"cst_lock", NULL, MTX_DEF);
832 mbufq_init(&cst->pending_tx, INT_MAX);
834 m_snd_tag_init(&cst->
com,
ifp, &cxgbe_rate_tag_sw);
839 cst->
max_rate = params->rate_limit.max_rate;
859cxgbe_rate_tag_modify(
struct m_snd_tag *mst,
860 union if_snd_tag_modify_params *params)
869 mtx_lock(&cst->
lock);
872 (
params->rate_limit.max_rate * 8ULL / 1000), &schedcl);
879 mtx_unlock(&cst->
lock);
885cxgbe_rate_tag_query(
struct m_snd_tag *mst,
886 union if_snd_tag_query_params *
params)
890 params->rate_limit.max_rate = cst->
max_rate;
892#define CST_TO_MST_QLEVEL_SCALE (IF_SND_QUEUE_LEVEL_MAX / cst->tx_total)
893 params->rate_limit.queue_level =
907 mtx_assert(&cst->
lock, MA_OWNED);
910 MPASS(cst->
plen == 0);
911 MPASS(mbufq_first(&cst->pending_tx) == NULL);
915 free_etid(sc, cst->
etid);
918 mtx_unlock(&cst->
lock);
919 mtx_destroy(&cst->
lock);
924cxgbe_rate_tag_free(
struct m_snd_tag *mst)
928 mtx_lock(&cst->
lock);
932 cst->
flags &= ~EO_SND_TAG_REF;
941 cxgbe_rate_tag_free_locked(cst);
944 send_etid_flush_wr(cst);
946 mtx_unlock(&cst->
lock);
950cxgbe_ratelimit_query(
struct ifnet *
ifp,
struct if_ratelimit_query_results *q)
955 q->rate_table = NULL;
956 q->
flags = RT_IS_SELECTABLE;
964 q->min_segment_burst = 4;
969 MPASS(q->min_segment_burst == 4);
970 q->max_flows = min(4000, q->max_flows);
973 q->max_flows = min(4000, q->max_flows);
988 q->number_of_rates /= 4;
int begin_synchronized_op(struct adapter *, struct vi_info *, int, char *)
@ CS_HW_UPDATE_IN_PROGRESS
static bool hw_off_limits(struct adapter *sc)
void end_synchronized_op(struct adapter *, int)
#define for_each_txq(vi, iter, q)
int t4_sched_config(struct adapter *adapter, int type, int minmaxen, int sleep_ok)
static int chip_id(struct adapter *adap)
#define for_each_port(adapter, iter)
int t4_set_params(struct adapter *adap, unsigned int mbox, unsigned int pf, unsigned int vf, unsigned int nparams, const u32 *params, const u32 *val)
int t4_sched_params(struct adapter *adapter, int type, int level, int mode, int rateunit, int ratemode, int channel, int cl, int minrate, int maxrate, int weight, int pktsize, int burstsize, int sleep_ok)
static int is_ethoffload(const struct adapter *adap)
static int port_top_speed(const struct port_info *pi)
static struct cxgbe_rate_tag * mst_to_crt(struct m_snd_tag *t)
#define CH_ERR(adap, fmt,...)
uint8_t chan_map[MAX_NCHAN]
const struct chip_params * chip_params
struct adapter_params params
struct port_info * port[MAX_NPORTS]
struct mbufq pending_tx pending_fwack
struct tx_sched_params * sched_params
struct t4_sched_class_params params
struct t4_sched_params::@94::@95 config
union t4_sched_params::@94 u
union etid_entry * etid_tab
enum fw_sched_params_rate ratemode
enum fw_sched_params_unit rateunit
enum fw_sched_params_mode mode
struct tx_cl_rl_params cl_rl[]
@ SCHED_CLASS_RATEUNIT_BITS
@ SCHED_CLASS_RATEUNIT_PKTS
@ SCHED_CLASS_LEVEL_CL_WRR
@ SCHED_CLASS_LEVEL_CH_RL
@ SCHED_CLASS_LEVEL_CL_RL
@ SCHED_CLASS_TYPE_PACKET
@ SCHED_CLASS_RATEMODE_REL
@ SCHED_CLASS_RATEMODE_ABS
@ SCHED_CLASS_SUBCMD_PARAMS
@ SCHED_CLASS_SUBCMD_CONFIG
#define V_TXPKT_VF_VLD(x)
#define V_TXPKT_OPCODE(x)
void t4_release_cl_rl(struct adapter *sc, int port_id, int tc_idx)
int sysctl_tc_params(SYSCTL_HANDLER_ARGS)
static int set_sched_class_config(struct adapter *sc, int minmax)
int t4_free_tx_sched(struct adapter *sc)
int t4_set_sched_class(struct adapter *sc, struct t4_sched_params *p)
static int bind_txq_to_traffic_class(struct adapter *sc, struct sge_txq *txq, int idx)
static int in_range(int val, int lo, int hi)
int t4_init_tx_sched(struct adapter *sc)
int t4_reserve_cl_rl_kbps(struct adapter *sc, int port_id, u_int maxrate, int *tc_idx)
void t4_update_tx_sched(struct adapter *sc)
int sysctl_tc(SYSCTL_HANDLER_ARGS)
static void update_tx_sched(void *context, int pending)
int t4_set_sched_queue(struct adapter *sc, struct t4_sched_queue *p)
static int set_sched_class_params(struct adapter *sc, struct t4_sched_class_params *p, int sleep_ok)
@ FW_SCHED_PARAMS_UNIT_PKTRATE
@ FW_SCHED_PARAMS_UNIT_BITRATE
#define V_FW_PARAMS_PARAM_YZ(x)
@ FW_SCHED_PARAMS_MODE_CLASS
@ FW_SCHED_PARAMS_MODE_FLOW
#define V_FW_PARAMS_MNEM(x)
@ FW_SCHED_PARAMS_LEVEL_CL_RL
@ FW_SCHED_PARAMS_LEVEL_CH_RL
@ FW_SCHED_PARAMS_LEVEL_CL_WRR
#define V_FW_PARAMS_PARAM_X(x)
@ FW_PARAMS_PARAM_DMAQ_EQ_SCHEDCLASS_ETH
@ FW_SCHED_PARAMS_RATE_REL
@ FW_SCHED_PARAMS_RATE_ABS
struct cxgbe_rate_tag * cst