summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLu Qiuwen <[email protected]>2024-04-14 15:27:56 +0800
committerLu Qiuwen <[email protected]>2024-04-14 15:27:56 +0800
commit9eb77ccde03572cf2e67900c4369446b5166fe0d (patch)
tree6c84d7a2796560f33224a4fa7e1e935ab15cf4a5
parenta8281bd82e65dcc56e969c226f10759a1f787f31 (diff)
support tx meter and df calculate.v4.8.2-20240416
-rw-r--r--service/include/sc_devmgr.h15
-rw-r--r--service/src/devmgr.c71
-rw-r--r--service/src/node_phydev.c215
3 files changed, 279 insertions, 22 deletions
diff --git a/service/include/sc_devmgr.h b/service/include/sc_devmgr.h
index 3787fe9..d6ad8ee 100644
--- a/service/include/sc_devmgr.h
+++ b/service/include/sc_devmgr.h
@@ -177,6 +177,21 @@ struct dpdk_dev
#define __DEV_MAX_DEFAULT_FLOWS 256
struct rte_flow * default_flow_handles[__DEV_MAX_DEFAULT_FLOWS];
unsigned int nr_default_flow_handles;
+
+ /* rx meter */
+ unsigned int en_rx_meter;
+ struct rte_meter_srtcm_profile * rx_meter_profile[MR_SID_MAX];
+ struct rte_meter_srtcm * rx_meter[MR_SID_MAX];
+
+ /* tx meter */
+ unsigned int en_tx_meter;
+ uint64_t tx_meter_cir;
+ uint64_t tx_meter_cbs;
+ uint64_t tx_meter_ebs;
+ unsigned int tx_meter_yellow_pkt_delay_us;
+
+ struct rte_meter_srtcm_profile * tx_meter_profile[MR_SID_MAX];
+ struct rte_meter_srtcm * tx_meter[MR_SID_MAX];
};
struct mr_dev_desc_qid_map
diff --git a/service/src/devmgr.c b/service/src/devmgr.c
index bdf7611..0c204ad 100644
--- a/service/src/devmgr.c
+++ b/service/src/devmgr.c
@@ -1203,6 +1203,42 @@ static int gen_dpdk_dev_ethconf(struct dpdk_dev * dev, unsigned nr_rxq_use, stru
return 0;
}
+static int dpdk_dev_tx_meter_setup(struct dpdk_dev * dev, unsigned int nr_txq, uint64_t cir, uint64_t cbs, uint64_t ebs)
+{
+ for (unsigned int txq = 0; txq < nr_txq; txq++)
+ {
+ dev->tx_meter_profile[txq] = ZMALLOC(sizeof(struct rte_meter_srtcm_profile));
+ MR_VERIFY_MALLOC(dev->tx_meter_profile[txq]);
+
+ dev->tx_meter[txq] = ZMALLOC(sizeof(struct rte_meter_srtcm));
+ MR_VERIFY_MALLOC(dev->tx_meter[txq]);
+
+ struct rte_meter_srtcm_profile * profile = dev->tx_meter_profile[txq];
+ struct rte_meter_srtcm_params params = {
+ .cir = cir / nr_txq,
+ .cbs = cbs / nr_txq,
+ .ebs = ebs / nr_txq,
+ };
+
+ int ret = rte_meter_srtcm_profile_config(profile, &params);
+ if (ret < 0)
+ {
+ MR_ERROR("Failed at setting up tx meter config for device %s, errno = %d", dev->symbol, ret);
+ return ret;
+ }
+
+ ret = rte_meter_srtcm_config(dev->tx_meter[txq], profile);
+ if (ret < 0)
+ {
+ MR_ERROR("Failed at setting up tx meter for device %s, errno = %d", dev->symbol, ret);
+ return ret;
+ }
+ }
+
+ MR_INFO("dpdk device %s: tx_meter enable, cir=%lu, cbs=%lu, ebs=%lu", dev->symbol, cir, cbs, ebs);
+ return 0;
+}
+
static int dpdk_dev_queue_setup_rss(struct dpdk_dev * dev, cpu_set_t * rx_cpu_set, cpu_set_t * tx_cpu_set,
unsigned int rxq_index_begin, unsigned int txq_index_begin)
{
@@ -1493,6 +1529,16 @@ static int dpdk_dev_setup_common(struct devmgr_main * devmgr_main, struct dpdk_d
return RT_ERR;
}
+
+ if(dev->en_tx_meter)
+ {
+ ret = dpdk_dev_tx_meter_setup(dev, nr_txq_use, dev->tx_meter_cir, dev->tx_meter_cbs, dev->tx_meter_ebs);
+ if (ret < 0)
+ {
+ return RT_ERR;
+ }
+ }
+
nr_rxq_index += dev->nr_rxq;
nr_txq_index += dev->nr_txq;
@@ -1631,8 +1677,25 @@ void dpdk_dev_config_load(struct dpdk_dev * dev_dpdk, const char * cfg)
MESA_load_profile_uint_def(cfg, str_section, "promisc", &dev_dpdk->promisc, 0);
// MULTICAST
MESA_load_profile_uint_def(cfg, str_section, "allmulticast", &dev_dpdk->allmulticast, 0);
- // SMARTOFFLOAD
- MESA_load_profile_uint_def(cfg, str_section, "en_smartoffload", &dev_dpdk->en_smartoffload, 0);
+
+ /* tx meter */
+ MESA_load_profile_uint_def(cfg, str_section, "en_tx_meter", &dev_dpdk->en_tx_meter, 0);
+ if(dev_dpdk->en_tx_meter)
+ {
+ unsigned int tx_meter_cir_in_Kbps = 0;
+ unsigned int tx_meter_cbs_in_KB = 0;
+ unsigned int tx_meter_ebs_in_KB = 0;
+
+ MESA_load_profile_uint_def(cfg, str_section, "tx_meter_cir_in_Kbps", &tx_meter_cir_in_Kbps, 0);
+ MESA_load_profile_uint_def(cfg, str_section, "tx_meter_cbs_in_KB", &tx_meter_cbs_in_KB, 0);
+ MESA_load_profile_uint_def(cfg, str_section, "tx_meter_ebs_in_KB", &tx_meter_ebs_in_KB, 0);
+ MESA_load_profile_uint_def(cfg, str_section, "tx_meter_yellow_pkt_delay_in_us",
+ &dev_dpdk->tx_meter_yellow_pkt_delay_us, 1);
+
+ dev_dpdk->tx_meter_cir = (uint64_t)tx_meter_cir_in_Kbps * 1000 / 8;
+ dev_dpdk->tx_meter_cbs = (uint64_t)tx_meter_cbs_in_KB * 1024;
+ dev_dpdk->tx_meter_ebs = (uint64_t)tx_meter_ebs_in_KB * 1024;
+ }
// which mempool used
memset(dev_dpdk->str_direct_pool, 0, sizeof(dev_dpdk->str_direct_pool));
@@ -2335,12 +2398,12 @@ static cJSON * dpdk_dev_monit_stats(struct dpdk_dev * dev)
for (int i = 0; i < RTE_DIM(_dpdk_dev_stat.tx_drop_counter); i++)
{
- user_rx_drop_total += _dpdk_dev_stat.tx_drop_counter[i];
+ user_tx_drop_total += _dpdk_dev_stat.tx_drop_counter[i];
}
for (int i = 0; i < RTE_DIM(_dpdk_dev_stat_last.tx_drop_counter); i++)
{
- user_rx_drop_last += _dpdk_dev_stat_last.tx_drop_counter[i];
+ user_tx_drop_last += _dpdk_dev_stat_last.tx_drop_counter[i];
}
cJSON_AddNumberToObject(j_device_value, "ipackets", _eth_stat.ipackets);
diff --git a/service/src/node_phydev.c b/service/src/node_phydev.c
index c3478b6..aa840b9 100644
--- a/service/src/node_phydev.c
+++ b/service/src/node_phydev.c
@@ -25,6 +25,16 @@ struct dev_node_main
TAILQ_HEAD(dev_node_elem_head, dev_node_elem) elems_head;
};
+struct df_stat_counters
+{
+ volatile uint64_t df_last_tsc;
+ volatile uint64_t df_sum_Sj;
+ volatile uint64_t df_VB_pre;
+ volatile uint64_t df_VB_post;
+ volatile uint64_t df_VB_max;
+ volatile uint64_t df_VB_min;
+};
+
struct phydev_stat_per_core
{
volatile uint64_t total_rx_pkts;
@@ -34,6 +44,21 @@ struct phydev_stat_per_core
volatile uint32_t rx_zero_iterations;
volatile uint32_t rx_non_zero_iterations;
+
+ /* https://www.rfc-editor.org/rfc/rfc4445.html, Section 3.1 Delay Factor
+ VB(i,pre) = sum (Sj) - MR * Ti; where j=1..i-1
+ VB(i,post) = VB(i,pre) + Si
+ */
+
+ /* DF calculate */
+ struct df_stat_counters rx_df;
+ struct df_stat_counters tx_df;
+
+ /* meter */
+ volatile uint64_t tx_meter_red;
+ volatile uint64_t tx_meter_yellow;
+ volatile uint64_t tx_meter_green;
+
} __rte_cache_aligned;
static struct phydev_stat_per_core phydev_stat[RTE_MAX_LCORE];
@@ -41,6 +66,7 @@ static struct phydev_stat_per_core phydev_stat[RTE_MAX_LCORE];
static struct dev_node_main st_dev_node_main;
static struct dev_node_main * p_dev_node_main = &st_dev_node_main;
+#define DF_MR_DEFAULT 50000
static_assert(sizeof(struct dev_node_ctx) <= RTE_NODE_CTX_SZ, "dev_node_ctx size must smaller than RTE_NODE_CTX_SZ");
int mbuf_object_deserialize_from_msgpack(struct sc_main * sc, struct rte_mbuf * mbuf, const char * buf,
@@ -320,6 +346,55 @@ static unsigned int mbufs_msgpack_decode(struct rte_mbuf ** mbufs, unsigned int
return out_nr_mbufs;
}
+
+void df_calculate_packet_input(struct df_stat_counters * df_counters, unsigned int MR,
+ struct rte_mbuf * mbufs[], unsigned int nr_mbufs)
+{
+ /* now tsc */
+ uint64_t now_tsc = rte_get_timer_cycles();
+
+ /* total bytes */
+ uint64_t Sj = 0;
+ for (unsigned int i = 0; i < nr_mbufs; i++)
+ {
+ Sj += mbufs[i]->pkt_len;
+ }
+
+ if(Sj == 0)
+ {
+ return;
+ }
+
+ /* calculate the delay factor */
+ uint64_t delta_tsc = now_tsc - df_counters->df_last_tsc;
+ uint64_t delta_tsc_in_us = delta_tsc / (rte_get_timer_hz() / US_PER_S);
+
+ uint64_t VB_pre = df_counters->df_VB_pre + Sj - MR * delta_tsc_in_us;
+ uint64_t VB_post = VB_pre + Sj;
+
+ /* update the counters */
+ df_counters->df_last_tsc = now_tsc;
+ df_counters->df_sum_Sj += Sj;
+ df_counters->df_VB_pre = VB_pre;
+ df_counters->df_VB_post = VB_post;
+ df_counters->df_VB_max = RTE_MAX(df_counters->df_VB_max, VB_post);
+ df_counters->df_VB_min = RTE_MIN(df_counters->df_VB_min, VB_pre);
+}
+
+uint64_t df_calculate_get_result(struct df_stat_counters * df_counters, uint64_t MR)
+{
+ uint64_t df = (df_counters->df_VB_max - df_counters->df_VB_min) / MR;
+
+ /* clear the counters */
+ df_counters->df_VB_max = df_counters->df_VB_post;
+ df_counters->df_VB_min = df_counters->df_VB_post;
+ df_counters->df_VB_pre = 0;
+ df_counters->df_VB_post = 0;
+ df_counters->df_sum_Sj = 0;
+
+ return df;
+}
+
static __rte_always_inline uint16_t dpdk_msgpack_dev_rx_node_process(struct rte_graph * graph, struct rte_node * node,
void ** objs, uint16_t cnt)
{
@@ -396,6 +471,10 @@ static __rte_always_inline uint16_t dpdk_dev_rx_node_process(struct rte_graph *
stat_per_core->total_rx_pkts+= nr_mbufs;
}
+#if MR_PHYDEV_ENABLE_DF_CALCULATE
+ df_calculate_packet_input(&stat_per_core->rx_df, DF_MR_DEFAULT, (struct rte_mbuf **)node->objs, nr_mbufs);
+#endif
+
/* hash calculate */
node->idx = nr_mbufs;
@@ -459,7 +538,7 @@ static __rte_always_inline uint16_t dpdk_dev_rx_node_process(struct rte_graph *
}
}
- /* move to next node */
+ /* move to the next node */
rte_node_next_stream_move(graph, node, 0);
return nr_mbufs;
}
@@ -528,12 +607,26 @@ static __rte_always_inline uint16_t dpdk_msgpack_dev_tx_node_process(struct rte_
return tx_nr_mbufs;
}
+#define MR_PHYDEV_RETRY_WHEN_TX_FAILED 1
+
+static __rte_always_inline void do_tx_burst(struct rte_graph * graph, struct rte_node * node, struct mr_dev_desc * dev_desc,
+ struct rte_mbuf ** mbufs_to_send, unsigned int nr_mbufs_to_send)
+{
+ unsigned int tx_nr_mbufs = 0;
+ while (tx_nr_mbufs < nr_mbufs_to_send)
+ {
+ struct rte_mbuf ** mbuf_ptr = mbufs_to_send + tx_nr_mbufs;
+ unsigned int tx_cnt = nr_mbufs_to_send - tx_nr_mbufs;
+ tx_nr_mbufs += rte_eth_tx_burst(dev_desc->port_id, graph->id, mbuf_ptr, tx_cnt);
+ }
+}
+
static __rte_always_inline uint16_t dpdk_dev_tx_node_process(struct rte_graph * graph, struct rte_node * node,
void ** objs, uint16_t cnt)
{
struct dev_node_ctx * ctx = (struct dev_node_ctx *)node->ctx;
struct mr_dev_desc * dev_desc = ctx->dev_desc;
- struct dpdk_dev_stats * dev_stat = &ctx->dev_desc->dpdk_dev_desc->stat;
+ struct dpdk_dev * dpdk_dev_desc = dev_desc->dpdk_dev_desc;
struct phydev_stat_per_core * stat_per_core = &phydev_stat[graph->id];
for (unsigned int i = 0; i < cnt; i++)
@@ -551,19 +644,75 @@ static __rte_always_inline uint16_t dpdk_dev_tx_node_process(struct rte_graph *
dp_trace_record_flush(sc_main_get()->trace);
- unsigned int tx_nr_mbufs = rte_eth_tx_burst(dev_desc->port_id, graph->id, (struct rte_mbuf **)objs, cnt);
- if (unlikely(tx_nr_mbufs != cnt))
+ /* do CF calculate */
+#if MR_PHYDEV_ENABLE_DF_CALCULATE
+ df_calculate_packet_input(&stat_per_core->tx_df, DF_MR_DEFAULT, (struct rte_mbuf **)objs, cnt);
+#endif
+
+ struct rte_mbuf * mbufs_to_send[RTE_GRAPH_BURST_SIZE];
+ unsigned int nr_mbufs_to_send = 0;
+
+ struct rte_mbuf * mbufs_to_drop[RTE_GRAPH_BURST_SIZE];
+ unsigned int nr_mbufs_to_drop = 0;
+
+ unsigned int counter_tx_meter_green = 0;
+ unsigned int counter_tx_meter_yellow = 0;
+ unsigned int counter_tx_meter_red = 0;
+
+ if (dpdk_dev_desc->en_tx_meter)
{
- /* redirect unsent packets to drop node */
- stat_per_core->total_tx_drop_pkts += cnt - tx_nr_mbufs;
- dev_stat->tx_drop_counter[graph->id] += cnt - tx_nr_mbufs;
+ struct rte_meter_srtcm * meter = dpdk_dev_desc->tx_meter[graph->id];
+ struct rte_meter_srtcm_profile * profile = dpdk_dev_desc->tx_meter_profile[graph->id];
+ for (unsigned int i = 0; i < cnt; i++)
+ {
+ struct rte_mbuf * mbuf = (struct rte_mbuf *)objs[i];
+ uint64_t tsc = rte_get_timer_cycles();
+ enum rte_color color = rte_meter_srtcm_color_blind_check(meter, profile, tsc, mbuf->pkt_len);
+
+ switch (color)
+ {
+ case RTE_COLORS:
+ case RTE_COLOR_GREEN:
+ mbufs_to_send[nr_mbufs_to_send++] = mbuf;
+ counter_tx_meter_green++;
+ break;
+
+ case RTE_COLOR_YELLOW:
+ mbufs_to_send[nr_mbufs_to_send++] = mbuf;
+ do_tx_burst(graph, node, dev_desc, mbufs_to_send, nr_mbufs_to_send);
+ nr_mbufs_to_send = 0;
- /* stat for dpdk dev */
- rte_node_enqueue(graph, node, 0, &objs[tx_nr_mbufs], cnt - tx_nr_mbufs);
+ rte_delay_us_block(dpdk_dev_desc->tx_meter_yellow_pkt_delay_us);
+ counter_tx_meter_yellow++;
+ break;
+
+ case RTE_COLOR_RED:
+ stat_per_core->tx_meter_red++;
+ mbufs_to_drop[nr_mbufs_to_drop++] = mbuf;
+ break;
+ }
+ }
+ }
+ else
+ {
+ rte_memcpy(mbufs_to_send, objs, cnt * sizeof(void *));
+ nr_mbufs_to_send = cnt;
+ }
+
+ do_tx_burst(graph, node, dev_desc, mbufs_to_send, nr_mbufs_to_send);
+
+ /* enqueue drop packet to next node */
+ if (nr_mbufs_to_drop > 0)
+ {
+ rte_node_enqueue(graph, node, 0, (void **)mbufs_to_drop, nr_mbufs_to_drop);
}
/* stat */
- stat_per_core->total_tx_pkts += tx_nr_mbufs;
+ stat_per_core->tx_meter_red += counter_tx_meter_red;
+ stat_per_core->tx_meter_yellow += counter_tx_meter_yellow;
+ stat_per_core->tx_meter_green += counter_tx_meter_green;
+ stat_per_core->total_tx_pkts += nr_mbufs_to_send;
+ stat_per_core->total_tx_drop_pkts += nr_mbufs_to_drop;
return cnt;
}
@@ -648,11 +797,11 @@ static struct rte_node_register dpdk_dev_tx_node_base = {
},
};
-static struct rte_node_register dpdk_dev_tx_node_periodical = {
- .process = dpdk_dev_tx_periodical_process,
- .name = "dpdk_dev_tx_node_periodical",
- .flags = RTE_NODE_SOURCE_F,
+static struct rte_node_register dpdk_dev_rx_node_periodical = {
+ .process = dpdk_dev_rx_periodical_process,
+ .name = "dpdk_dev_rx_node_periodical",
.init = dev_node_init,
+ .flags = RTE_NODE_SOURCE_F,
.nb_edges = 1,
.next_nodes =
{
@@ -660,11 +809,11 @@ static struct rte_node_register dpdk_dev_tx_node_periodical = {
},
};
-static struct rte_node_register dpdk_dev_rx_node_periodical = {
- .process = dpdk_dev_rx_periodical_process,
- .name = "dpdk_dev_rx_node_periodical",
- .init = dev_node_init,
+static struct rte_node_register dpdk_dev_tx_node_periodical = {
+ .process = dpdk_dev_tx_periodical_process,
+ .name = "dpdk_dev_tx_node_periodical",
.flags = RTE_NODE_SOURCE_F,
+ .init = dev_node_init,
.nb_edges = 1,
.next_nodes =
{
@@ -877,6 +1026,12 @@ cJSON * phydev_rx_node_monit_loop(struct sc_main * sc)
uint64_t total_tx_drop_pkts[RTE_MAX_LCORE];
double rx_spin_time[RTE_MAX_LCORE];
+ uint64_t df_rx[RTE_MAX_LCORE];
+ uint64_t df_tx[RTE_MAX_LCORE];
+
+ uint64_t total_tx_meter_red[RTE_MAX_LCORE];
+ uint64_t total_tx_meter_yellow[RTE_MAX_LCORE];
+ uint64_t total_tx_meter_green[RTE_MAX_LCORE];
for (unsigned int i = 0; i < nr_graphs; i++)
{
@@ -885,6 +1040,10 @@ cJSON * phydev_rx_node_monit_loop(struct sc_main * sc)
total_rx_drop_pkts[i] = phydev_stat[i].total_rx_drop_pkts;
total_tx_drop_pkts[i] = phydev_stat[i].total_tx_drop_pkts;
+ total_tx_meter_green[i] = phydev_stat[i].tx_meter_green;
+ total_tx_meter_yellow[i] = phydev_stat[i].tx_meter_yellow;
+ total_tx_meter_red[i] = phydev_stat[i].tx_meter_red;
+
/* calculate the spin time */
uint32_t rx_zero_iterations = phydev_stat[i].rx_zero_iterations;
uint32_t rx_non_zero_iterations = phydev_stat[i].rx_non_zero_iterations;
@@ -900,6 +1059,10 @@ cJSON * phydev_rx_node_monit_loop(struct sc_main * sc)
{
rx_spin_time[i] = 0;
}
+
+ /* DF calculate */
+ df_rx[i] = df_calculate_get_result(&phydev_stat[i].rx_df, DF_MR_DEFAULT);
+ df_tx[i] = df_calculate_get_result(&phydev_stat[i].tx_df, DF_MR_DEFAULT);
}
cJSON * json_total_rx_pkts = create_uint64_array(total_rx_pkts, nr_graphs);
@@ -914,8 +1077,24 @@ cJSON * phydev_rx_node_monit_loop(struct sc_main * sc)
cJSON * json_total_tx_drop_pkts = create_uint64_array(total_tx_drop_pkts, nr_graphs);
cJSON_AddItemToObject(json_root, "total_tx_drop_pkts", json_total_tx_drop_pkts);
+ cJSON * json_total_tx_meter_red = create_uint64_array(total_tx_meter_red, nr_graphs);
+ cJSON_AddItemToObject(json_root, "total_tx_meter_red", json_total_tx_meter_red);
+
+ cJSON * json_total_tx_meter_yellow = create_uint64_array(total_tx_meter_yellow, nr_graphs);
+ cJSON_AddItemToObject(json_root, "total_tx_meter_yellow", json_total_tx_meter_yellow);
+
+ cJSON * json_total_tx_meter_green = create_uint64_array(total_tx_meter_green, nr_graphs);
+ cJSON_AddItemToObject(json_root, "total_tx_meter_green", json_total_tx_meter_green);
+
cJSON * json_rx_spin_time = cJSON_CreateDoubleArray(rx_spin_time, (int)nr_graphs);
cJSON_AddItemToObject(json_root, "rx_spin_time", json_rx_spin_time);
+
+ cJSON * json_df_rx = create_uint64_array(df_rx, nr_graphs);
+ cJSON_AddItemToObject(json_root, "df_rx", json_df_rx);
+
+ cJSON * json_df_tx = create_uint64_array(df_tx, nr_graphs);
+ cJSON_AddItemToObject(json_root, "df_tx", json_df_tx);
+
return json_root;
}