@@ -2,6 +2,7 @@
* Copyright(c) 2010-2014 Intel Corporation
*/
+#include <stdint.h>
#include <stdio.h>
#include <string.h>
@@ -101,6 +102,16 @@ enum grinder_state {
e_GRINDER_READ_MBUF
};
+struct rte_sched_subport_profile {
+ /* Token bucket (TB) */
+ uint64_t tb_period;
+ uint64_t tb_credits_per_period;
+ uint64_t tb_size;
+
+ uint64_t tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
+ uint64_t tc_period;
+};
+
struct rte_sched_grinder {
/* Pipe cache */
uint16_t pcache_qmask[RTE_SCHED_GRINDER_PCACHE_SIZE];
@@ -139,18 +150,13 @@ struct rte_sched_grinder {
};
struct rte_sched_subport {
- /* Token bucket (TB) */
+
uint64_t tb_time; /* time of last update */
- uint64_t tb_period;
- uint64_t tb_credits_per_period;
- uint64_t tb_size;
uint64_t tb_credits;
/* Traffic classes (TCs) */
uint64_t tc_time; /* time of next update */
- uint64_t tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
uint64_t tc_credits[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
- uint64_t tc_period;
/* TC oversubscription */
uint64_t tc_ov_wm;
@@ -164,6 +170,8 @@ struct rte_sched_subport {
/* Statistics */
struct rte_sched_subport_stats stats __rte_cache_aligned;
+ /* subport profile flag */
+ uint32_t profile;
/* Subport pipes */
uint32_t n_pipes_per_subport_enabled;
uint32_t n_pipe_profiles;
@@ -212,6 +220,8 @@ struct rte_sched_port {
uint16_t pipe_queue[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
uint8_t pipe_tc[RTE_SCHED_QUEUES_PER_PIPE];
uint8_t tc_queue[RTE_SCHED_QUEUES_PER_PIPE];
+ uint32_t n_subport_profiles;
+ uint32_t n_max_subport_profiles;
uint64_t rate;
uint32_t mtu;
uint32_t frame_overhead;
@@ -229,6 +239,7 @@ struct rte_sched_port {
uint32_t subport_id;
/* Large data structures */
+ struct rte_sched_subport_profile *subport_profiles;
struct rte_sched_subport *subports[0] __rte_cache_aligned;
} __rte_cache_aligned;
@@ -375,6 +386,56 @@ pipe_profile_check(struct rte_sched_pipe_params *params,
}
static int
+subport_profile_check(struct rte_sched_subport_profile_params *params,
+ uint64_t rate)
+{
+ uint32_t i;
+
+ /* Check user parameters */
+ if (params == NULL) {
+ RTE_LOG(ERR, SCHED,
+ "%s: Incorrect value for parameter params\n", __func__);
+ return -EINVAL;
+ }
+
+ if (params->tb_rate == 0 || params->tb_rate > rate) {
+ RTE_LOG(ERR, SCHED,
+ "%s: Incorrect value for tb rate\n", __func__);
+ return -EINVAL;
+ }
+
+ if (params->tb_size == 0) {
+ RTE_LOG(ERR, SCHED,
+ "%s: Incorrect value for tb size\n", __func__);
+ return -EINVAL;
+ }
+
+ for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) {
+ uint64_t tc_rate = params->tc_rate[i];
+
+ if (tc_rate == 0 || (tc_rate > params->tb_rate)) {
+ RTE_LOG(ERR, SCHED,
+ "%s: Incorrect value for tc rate\n", __func__);
+ return -EINVAL;
+ }
+ }
+
+ if (params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE] == 0) {
+ RTE_LOG(ERR, SCHED,
+ "%s: Incorrect tc rate(best effort)\n", __func__);
+ return -EINVAL;
+ }
+
+ if (params->tc_period == 0) {
+ RTE_LOG(ERR, SCHED,
+ "%s: Incorrect value for tc period\n", __func__);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int
rte_sched_port_check_params(struct rte_sched_port_params *params)
{
if (params == NULL) {
@@ -517,13 +578,14 @@ rte_sched_port_log_pipe_profile(struct rte_sched_subport *subport, uint32_t i)
struct rte_sched_pipe_profile *p = subport->pipe_profiles + i;
RTE_LOG(DEBUG, SCHED, "Low level config for pipe profile %u:\n"
- " Token bucket: period = %"PRIu64", credits per period = %"PRIu64", size = %"PRIu64"\n"
- " Traffic classes: period = %"PRIu64",\n"
- " credits per period = [%"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64
- ", %"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64
- ", %"PRIu64", %"PRIu64", %"PRIu64"]\n"
- " Best-effort traffic class oversubscription: weight = %hhu\n"
- " WRR cost: [%hhu, %hhu, %hhu, %hhu]\n",
+ "Token bucket: period = %"PRIu64", credits per period = %"PRIu64""
+ " size = %"PRIu64",\n"
+ " Traffic classes: period = %"PRIu64",\n"
+ " credits per period = [%"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64""
+ ", %"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64""
+ ", %"PRIu64", %"PRIu64", %"PRIu64"]\n"
+ " Best-effort traffic class oversubscription: weight = %hhu\n"
+ " WRR cost: [%hhu, %hhu, %hhu, %hhu]\n",
i,
/* Token bucket */
@@ -554,6 +616,42 @@ rte_sched_port_log_pipe_profile(struct rte_sched_subport *subport, uint32_t i)
p->wrr_cost[0], p->wrr_cost[1], p->wrr_cost[2], p->wrr_cost[3]);
}
+static void
+rte_sched_port_log_subport_profile(struct rte_sched_port *port, uint32_t i)
+{
+ struct rte_sched_subport_profile *p = port->subport_profiles + i;
+
+ RTE_LOG(DEBUG, SCHED, "Low level config for subport profile %u:\n"
+ "Token bucket: period = %"PRIu64", credits per period = %"PRIu64",\
+ size = %"PRIu64"\n"
+ "Traffic classes: period = %"PRIu64",\n"
+ "credits per period = [%"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64
+ " %"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64
+ " %"PRIu64", %"PRIu64", %"PRIu64"]\n",
+ i,
+
+ /* Token bucket */
+ p->tb_period,
+ p->tb_credits_per_period,
+ p->tb_size,
+
+ /* Traffic classes */
+ p->tc_period,
+ p->tc_credits_per_period[0],
+ p->tc_credits_per_period[1],
+ p->tc_credits_per_period[2],
+ p->tc_credits_per_period[3],
+ p->tc_credits_per_period[4],
+ p->tc_credits_per_period[5],
+ p->tc_credits_per_period[6],
+ p->tc_credits_per_period[7],
+ p->tc_credits_per_period[8],
+ p->tc_credits_per_period[9],
+ p->tc_credits_per_period[10],
+ p->tc_credits_per_period[11],
+ p->tc_credits_per_period[12]);
+}
+
static inline uint64_t
rte_sched_time_ms_to_bytes(uint64_t time_ms, uint64_t rate)
{
@@ -623,6 +721,37 @@ rte_sched_pipe_profile_convert(struct rte_sched_subport *subport,
}
static void
+rte_sched_subport_profile_convert(struct rte_sched_subport_profile_params *src,
+ struct rte_sched_subport_profile *dst,
+ uint64_t rate)
+{
+ uint32_t i;
+
+ /* Token Bucket */
+ if (src->tb_rate == rate) {
+ dst->tb_credits_per_period = 1;
+ dst->tb_period = 1;
+ } else {
+ double tb_rate = (double) src->tb_rate
+ / (double) rate;
+ double d = RTE_SCHED_TB_RATE_CONFIG_ERR;
+
+ rte_approx_64(tb_rate, d, &dst->tb_credits_per_period,
+ &dst->tb_period);
+ }
+
+ dst->tb_size = src->tb_size;
+
+ /* Traffic Classes */
+ dst->tc_period = rte_sched_time_ms_to_bytes(src->tc_period, rate);
+
+ for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++)
+ dst->tc_credits_per_period[i]
+ = rte_sched_time_ms_to_bytes(src->tc_period,
+ src->tc_rate[i]);
+}
+
+static void
rte_sched_subport_config_pipe_profile_table(struct rte_sched_subport *subport,
struct rte_sched_subport_params *params, uint32_t rate)
{
@@ -646,6 +775,24 @@ rte_sched_subport_config_pipe_profile_table(struct rte_sched_subport *subport,
}
}
+static void
+rte_sched_port_config_subport_profile_table(struct rte_sched_port *port,
+ struct rte_sched_port_params *params,
+ uint64_t rate)
+{
+ uint32_t i;
+
+ for (i = 0; i < port->n_subport_profiles; i++) {
+ struct rte_sched_subport_profile_params *src
+ = params->subport_profiles + i;
+ struct rte_sched_subport_profile *dst
+ = port->subport_profiles + i;
+
+ rte_sched_subport_profile_convert(src, dst, rate);
+ rte_sched_port_log_subport_profile(port, i);
+ }
+}
+
static int
rte_sched_subport_check_params(struct rte_sched_subport_params *params,
uint32_t n_max_pipes_per_subport,
@@ -149,18 +149,6 @@ struct rte_sched_pipe_params {
* byte.
*/
struct rte_sched_subport_params {
- /** Token bucket rate (measured in bytes per second) */
- uint64_t tb_rate;
-
- /** Token bucket size (measured in credits) */
- uint64_t tb_size;
-
- /** Traffic class rates (measured in bytes per second) */
- uint64_t tc_rate[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
-
- /** Enforcement period for rates (measured in milliseconds) */
- uint64_t tc_period;
-
/** Number of subport pipes.
* The subport can enable/allocate fewer pipes than the maximum
* number set through struct port_params::n_max_pipes_per_subport,
@@ -192,6 +180,20 @@ struct rte_sched_subport_params {
#endif
};
+struct rte_sched_subport_profile_params {
+ /** Token bucket rate (measured in bytes per second) */
+ uint64_t tb_rate;
+
+ /** Token bucket size (measured in credits) */
+ uint64_t tb_size;
+
+ /** Traffic class rates (measured in bytes per second) */
+ uint64_t tc_rate[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE];
+
+ /** Enforcement period for rates (measured in milliseconds) */
+ uint64_t tc_period;
+};
+
/** Subport statistics */
struct rte_sched_subport_stats {
/** Number of packets successfully written */
@@ -254,6 +256,17 @@ struct rte_sched_port_params {
/** Number of subports */
uint32_t n_subports_per_port;
+ /** subport profile table.
+ * Every pipe is configured using one of the profiles from this table.
+ */
+ struct rte_sched_subport_profile_params *subport_profiles;
+
+ /** Profiles in the pipe profile table */
+ uint32_t n_subport_profiles;
+
+ /** Max allowed profiles in the pipe profile table */
+ uint32_t n_max_subport_profiles;
+
/** Maximum number of subport pipes.
* This parameter is used to reserve a fixed number of bits
* in struct rte_mbuf::sched.queue_id for the pipe_id for all