X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=lib%2Flibrte_sched%2Frte_sched.c;h=5cd1cda34b20c194de4c731bb6dbc2d3c23d10e4;hb=1c1d4d7a923d4804f1926fc5264f9ecdd8977b04;hp=a75b4b9c81b6ee91e238f57722652c0bf52016f4;hpb=602c9ca33a4ee58e53cc43c51f081b0e13c7232b;p=dpdk.git diff --git a/lib/librte_sched/rte_sched.c b/lib/librte_sched/rte_sched.c index a75b4b9c81..5cd1cda34b 100644 --- a/lib/librte_sched/rte_sched.c +++ b/lib/librte_sched/rte_sched.c @@ -4,32 +4,31 @@ * Copyright(c) 2010-2013 Intel Corporation. All rights reserved. * All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions * are met: * - * * Redistributions of source code must retain the above copyright + * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * */ #include @@ -118,13 +117,13 @@ struct rte_sched_subport { uint32_t tc_period; /* TC oversubscription */ - uint32_t tc_ov_period; - uint64_t tc_ov_time; - uint32_t tc_ov_credits[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; + uint32_t tc_ov_wm; + uint32_t tc_ov_wm_min; + uint32_t tc_ov_wm_max; uint8_t tc_ov_period_id; - uint8_t tc_ov[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; - uint32_t tc_ov_n[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; - double tc_ov_rate[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; + uint8_t tc_ov; + uint32_t tc_ov_n; + double tc_ov_rate; /* Statistics */ struct rte_sched_subport_stats stats; @@ -139,7 +138,7 @@ struct rte_sched_pipe_profile { /* Pipe traffic classes */ uint32_t tc_period; uint32_t tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; - uint8_t tc_ov_weight[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; + uint8_t tc_ov_weight; /* Pipe queues */ uint8_t wrr_cost[RTE_SCHED_QUEUES_PER_PIPE]; @@ -161,12 +160,9 @@ struct rte_sched_pipe { uint8_t wrr_tokens[RTE_SCHED_QUEUES_PER_PIPE]; /* TC oversubscription */ -#ifdef RTE_SCHED_SUBPORT_TC_OV - uint32_t tc_ov_credits[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; + uint32_t tc_ov_credits; uint8_t tc_ov_period_id; -#else - uint64_t reserved; -#endif + uint8_t reserved[3]; } __rte_cache_aligned; struct rte_sched_queue { @@ -219,8 +215,7 @@ struct rte_sched_grinder { uint32_t qpos; struct rte_mbuf *pkt; - double ov_coef; - + /* WRR */ uint16_t wrr_tokens[RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS]; uint16_t wrr_mask[RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS]; uint8_t wrr_cost[RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS]; @@ -231,9 +226,11 @@ struct rte_sched_port { uint32_t n_subports_per_port; uint32_t n_pipes_per_subport; uint32_t rate; + uint32_t mtu; uint32_t frame_overhead; uint16_t qsize[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; uint32_t n_pipe_profiles; + uint32_t pipe_tc3_rate_max; #ifdef RTE_SCHED_RED struct rte_red_config red_config[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE][e_RTE_METER_COLORS]; #endif @@ -324,14 +321,19 @@ rte_sched_port_check_params(struct rte_sched_port_params *params) return -4; } + /* mtu */ + if (params->mtu == 0) { + return -5; + } + /* n_subports_per_port: non-zero, power of 2 */ if ((params->n_subports_per_port == 0) || (!rte_is_power_of_2(params->n_subports_per_port))) { - return -5; + return -6; } /* n_pipes_per_subport: non-zero, power of 2 */ if ((params->n_pipes_per_subport == 0) || (!rte_is_power_of_2(params->n_pipes_per_subport))) { - return -6; + return -7; } /* qsize: non-zero, power of 2, no bigger than 32K (due to 16-bit read/write pointers) */ @@ -339,7 +341,7 @@ rte_sched_port_check_params(struct rte_sched_port_params *params) uint16_t qsize = params->qsize[i]; if ((qsize == 0) || (!rte_is_power_of_2(qsize))) { - return -7; + return -8; } } @@ -347,7 +349,7 @@ rte_sched_port_check_params(struct rte_sched_port_params *params) if ((params->pipe_profiles == NULL) || (params->n_pipe_profiles == 0) || (params->n_pipe_profiles > RTE_SCHED_PIPE_PROFILES_PER_PORT)) { - return -8; + return -9; } for (i = 0; i < params->n_pipe_profiles; i ++) { @@ -355,39 +357,37 @@ rte_sched_port_check_params(struct rte_sched_port_params *params) /* TB rate: non-zero, not greater than port rate */ if ((p->tb_rate == 0) || (p->tb_rate > params->rate)) { - return -9; + return -10; } /* TB size: non-zero */ if (p->tb_size == 0) { - return -10; + return -11; } /* TC rate: non-zero, less than pipe rate */ for (j = 0; j < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; j ++) { if ((p->tc_rate[j] == 0) || (p->tc_rate[j] > p->tb_rate)) { - return -11; + return -12; } } /* TC period: non-zero */ if (p->tc_period == 0) { - return -12; + return -13; } #ifdef RTE_SCHED_SUBPORT_TC_OV - /* TC oversubscription weights: non-zero */ - for (j = 0; j < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; j ++) { - if (p->tc_ov_weight[j] == 0) { - return -13; - } + /* TC3 oversubscription weight: non-zero */ + if (p->tc_ov_weight == 0) { + return -14; } #endif /* Queue WRR weights: non-zero */ for (j = 0; j < RTE_SCHED_QUEUES_PER_PIPE; j ++) { if (p->wrr_weights[j] == 0) { - return -14; + return -15; } } } @@ -501,7 +501,8 @@ rte_sched_port_log_pipe_profile(struct rte_sched_port *port, uint32_t i) RTE_LOG(INFO, SCHED, "Low level config for pipe profile %u:\n" "\tToken bucket: period = %u, credits per period = %u, size = %u\n" - "\tTraffic classes: period = %u, credits per period = [%u, %u, %u, %u], ov weights = [%hhu, %hhu, %hhu, %hhu]\n" + "\tTraffic classes: period = %u, credits per period = [%u, %u, %u, %u]\n" + "\tTraffic class 3 oversubscription: weight = %hhu\n" "\tWRR cost: [%hhu, %hhu, %hhu, %hhu], [%hhu, %hhu, %hhu, %hhu], [%hhu, %hhu, %hhu, %hhu], [%hhu, %hhu, %hhu, %hhu]\n", i, @@ -516,10 +517,9 @@ rte_sched_port_log_pipe_profile(struct rte_sched_port *port, uint32_t i) p->tc_credits_per_period[1], p->tc_credits_per_period[2], p->tc_credits_per_period[3], - p->tc_ov_weight[0], - p->tc_ov_weight[1], - p->tc_ov_weight[2], - p->tc_ov_weight[3], + + /* Traffic class 3 oversubscription */ + p->tc_ov_weight, /* WRR */ p->wrr_cost[ 0], p->wrr_cost[ 1], p->wrr_cost[ 2], p->wrr_cost[ 3], @@ -564,9 +564,7 @@ rte_sched_port_config_pipe_profile_table(struct rte_sched_port *port, struct rte dst->tc_credits_per_period[j] = (uint32_t) rte_sched_time_ms_to_bytes(src->tc_period, src->tc_rate[j]); } #ifdef RTE_SCHED_SUBPORT_TC_OV - for (j = 0; j < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; j ++) { - dst->tc_ov_weight[j] = src->tc_ov_weight[j]; - } + dst->tc_ov_weight = src->tc_ov_weight; #endif /* WRR */ @@ -599,6 +597,16 @@ rte_sched_port_config_pipe_profile_table(struct rte_sched_port *port, struct rte rte_sched_port_log_pipe_profile(port, i); } + + port->pipe_tc3_rate_max = 0; + for (i = 0; i < port->n_pipe_profiles; i ++) { + struct rte_sched_pipe_params *src = params->pipe_profiles + i; + uint32_t pipe_tc3_rate = src->tc_rate[3]; + + if (port->pipe_tc3_rate_max < pipe_tc3_rate) { + port->pipe_tc3_rate_max = pipe_tc3_rate; + } + } } struct rte_sched_port * @@ -635,6 +643,7 @@ rte_sched_port_config(struct rte_sched_port_params *params) port->n_subports_per_port = params->n_subports_per_port; port->n_pipes_per_subport = params->n_pipes_per_subport; port->rate = params->rate; + port->mtu = params->mtu + params->frame_overhead; port->frame_overhead = params->frame_overhead; memcpy(port->qsize, params->qsize, sizeof(params->qsize)); port->n_pipe_profiles = params->n_pipe_profiles; @@ -719,7 +728,8 @@ rte_sched_port_log_subport_config(struct rte_sched_port *port, uint32_t i) RTE_LOG(INFO, SCHED, "Low level config for subport %u:\n" "\tToken bucket: period = %u, credits per period = %u, size = %u\n" - "\tTraffic classes: period = %u, credits per period = [%u, %u, %u, %u], ov period = %u\n", + "\tTraffic classes: period = %u, credits per period = [%u, %u, %u, %u]\n" + "\tTraffic class 3 oversubscription: wm min = %u, wm max = %u\n", i, /* Token bucket */ @@ -733,7 +743,10 @@ rte_sched_port_log_subport_config(struct rte_sched_port *port, uint32_t i) s->tc_credits_per_period[1], s->tc_credits_per_period[2], s->tc_credits_per_period[3], - s->tc_ov_period); + + /* Traffic class 3 oversubscription */ + s->tc_ov_wm_min, + s->tc_ov_wm_max); } int @@ -768,12 +781,6 @@ rte_sched_subport_config(struct rte_sched_port *port, if (params->tc_period == 0) { return -5; } - -#ifdef RTE_SCHED_SUBPORT_TC_OV - if ((params->tc_ov_period == 0) || (params->tc_ov_period > params->tc_period)) { - return -6; - } -#endif s = port->subport + subport_id; @@ -803,15 +810,13 @@ rte_sched_subport_config(struct rte_sched_port *port, #ifdef RTE_SCHED_SUBPORT_TC_OV /* TC oversubscription */ - s->tc_ov_period = (uint32_t) rte_sched_time_ms_to_bytes(params->tc_ov_period, port->rate); - s->tc_ov_time = port->time + s->tc_ov_period; + s->tc_ov_wm_min = port->mtu; + s->tc_ov_wm_max = (uint32_t) rte_sched_time_ms_to_bytes(params->tc_period, port->pipe_tc3_rate_max); + s->tc_ov_wm = s->tc_ov_wm_max; s->tc_ov_period_id = 0; - for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i ++) { - s->tc_ov[i] = 0; - s->tc_ov_n[i] = 0; - s->tc_ov_rate[i] = 0; - s->tc_ov_credits[i] = 0; - } + s->tc_ov = 0; + s->tc_ov_n = 0; + s->tc_ov_rate = 0; #endif rte_sched_port_log_subport_config(port, subport_id); @@ -853,11 +858,18 @@ rte_sched_pipe_config(struct rte_sched_port *port, params = port->pipe_profiles + p->profile; #ifdef RTE_SCHED_SUBPORT_TC_OV + double subport_tc3_rate = ((double) s->tc_credits_per_period[3]) / ((double) s->tc_period); + double pipe_tc3_rate = ((double) params->tc_credits_per_period[3]) / ((double) params->tc_period); + uint32_t tc3_ov = s->tc_ov; + /* Unplug pipe from its subport */ - for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i ++) { - s->tc_ov_n[i] -= params->tc_ov_weight[i]; - s->tc_ov_rate[i] -= ((double) params->tc_credits_per_period[i]) / ((double) params->tc_period); - s->tc_ov[i] = s->tc_ov_rate[i] > (((double) s->tc_credits_per_period[i]) / ((double) s->tc_period)); + s->tc_ov_n -= params->tc_ov_weight; + s->tc_ov_rate -= pipe_tc3_rate; + s->tc_ov = s->tc_ov_rate > subport_tc3_rate; + + if (s->tc_ov != tc3_ov) { + RTE_LOG(INFO, SCHED, "Subport %u TC3 oversubscription is OFF (%.4lf >= %.4lf)\n", + subport_id, subport_tc3_rate, s->tc_ov_rate); } #endif @@ -884,15 +896,22 @@ rte_sched_pipe_config(struct rte_sched_port *port, } #ifdef RTE_SCHED_SUBPORT_TC_OV - /* Subport TC oversubscription */ - for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i ++) { - s->tc_ov_n[i] += params->tc_ov_weight[i]; - s->tc_ov_rate[i] += ((double) params->tc_credits_per_period[i]) / ((double) params->tc_period); - s->tc_ov[i] = s->tc_ov_rate[i] > (((double) s->tc_credits_per_period[i]) / ((double) s->tc_period)); - } - p->tc_ov_period_id = s->tc_ov_period_id; - for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i ++) { - p->tc_ov_credits[i] = 0; + { + /* Subport TC3 oversubscription */ + double subport_tc3_rate = ((double) s->tc_credits_per_period[3]) / ((double) s->tc_period); + double pipe_tc3_rate = ((double) params->tc_credits_per_period[3]) / ((double) params->tc_period); + uint32_t tc3_ov = s->tc_ov; + + s->tc_ov_n += params->tc_ov_weight; + s->tc_ov_rate += pipe_tc3_rate; + s->tc_ov = s->tc_ov_rate > subport_tc3_rate; + + if (s->tc_ov != tc3_ov) { + RTE_LOG(INFO, SCHED, "Subport %u TC3 oversubscription is ON (%.4lf < %.4lf)\n", + subport_id, subport_tc3_rate, s->tc_ov_rate); + } + p->tc_ov_period_id = s->tc_ov_period_id; + p->tc_ov_credits = s->tc_ov_wm; } #endif @@ -906,7 +925,6 @@ rte_sched_subport_read_stats(struct rte_sched_port *port, uint32_t *tc_ov) { struct rte_sched_subport *s; - uint32_t mask, i; /* Check user parameters */ if ((port == NULL) || @@ -922,11 +940,7 @@ rte_sched_subport_read_stats(struct rte_sched_port *port, memset(&s->stats, 0, sizeof(struct rte_sched_subport_stats)); /* Subport TC ovesubscription status */ - mask = 0; - for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i ++) { - mask |= ((uint32_t) s->tc_ov[i]) << i; - } - *tc_ov = mask; + *tc_ov = s->tc_ov; return 0; } @@ -1260,11 +1274,11 @@ rte_sched_port_enqueue(struct rte_sched_port *port, struct rte_mbuf **pkts, uint * of prefetching the data structures. The naming convention is presented in the * diagram below: * - * p00 _______ p10 _______ p20 _______ p30 _______ + * p00 _______ p10 _______ p20 _______ p30 _______ * ----->| |----->| |----->| |----->| |-----> - * | 0 | | 1 | | 2 | | 3 | + * | 0 | | 1 | | 2 | | 3 | * ----->|_______|----->|_______|----->|_______|----->|_______|-----> - * p01 p11 p21 p31 + * p01 p11 p21 p31 * ***/ int @@ -1465,6 +1479,42 @@ grinder_credits_update(struct rte_sched_port *port, uint32_t pos) #else +static inline uint32_t +grinder_tc_ov_credits_update(struct rte_sched_port *port, uint32_t pos) +{ + struct rte_sched_grinder *grinder = port->grinder + pos; + struct rte_sched_subport *subport = grinder->subport; + uint32_t tc_ov_consumption[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; + uint32_t tc_ov_consumption_max; + uint32_t tc_ov_wm = subport->tc_ov_wm; + + if (subport->tc_ov == 0) { + return subport->tc_ov_wm_max; + } + + tc_ov_consumption[0] = subport->tc_credits_per_period[0] - subport->tc_credits[0]; + tc_ov_consumption[1] = subport->tc_credits_per_period[1] - subport->tc_credits[1]; + tc_ov_consumption[2] = subport->tc_credits_per_period[2] - subport->tc_credits[2]; + tc_ov_consumption[3] = subport->tc_credits_per_period[3] - subport->tc_credits[3]; + + tc_ov_consumption_max = subport->tc_credits_per_period[3] - + (tc_ov_consumption[0] + tc_ov_consumption[1] + tc_ov_consumption[2]); + + if (tc_ov_consumption[3] > (tc_ov_consumption_max - port->mtu)) { + tc_ov_wm -= tc_ov_wm >> 7; + if (tc_ov_wm < subport->tc_ov_wm_min) { + tc_ov_wm = subport->tc_ov_wm_min; + } + return tc_ov_wm; + } + + tc_ov_wm += (tc_ov_wm >> 7) + 1; + if (tc_ov_wm > subport->tc_ov_wm_max) { + tc_ov_wm = subport->tc_ov_wm_max; + } + return tc_ov_wm; +} + static inline void grinder_credits_update(struct rte_sched_port *port, uint32_t pos) { @@ -1487,29 +1537,18 @@ grinder_credits_update(struct rte_sched_port *port, uint32_t pos) pipe->tb_time += n_periods * params->tb_period; /* Subport TCs */ - if (unlikely(port->time >= subport->tc_ov_time)) { - uint64_t n_ov_periods; - - if (unlikely(port->time >= subport->tc_time)) { - subport->tc_credits[0] = subport->tc_credits_per_period[0]; - subport->tc_credits[1] = subport->tc_credits_per_period[1]; - subport->tc_credits[2] = subport->tc_credits_per_period[2]; - subport->tc_credits[3] = subport->tc_credits_per_period[3]; - - subport->tc_time = port->time + subport->tc_period; - } - - n_ov_periods = (subport->tc_time - port->time + subport->tc_ov_period - 1) / subport->tc_ov_period; - - subport->tc_ov_credits[0] = subport->tc_credits[0] / (n_ov_periods * subport->tc_ov_n[0]); - subport->tc_ov_credits[1] = subport->tc_credits[1] / (n_ov_periods * subport->tc_ov_n[1]); - subport->tc_ov_credits[2] = subport->tc_credits[2] / (n_ov_periods * subport->tc_ov_n[2]); - subport->tc_ov_credits[3] = subport->tc_credits[3] / (n_ov_periods * subport->tc_ov_n[3]); + if (unlikely(port->time >= subport->tc_time)) { + subport->tc_ov_wm = grinder_tc_ov_credits_update(port, pos); + + subport->tc_credits[0] = subport->tc_credits_per_period[0]; + subport->tc_credits[1] = subport->tc_credits_per_period[1]; + subport->tc_credits[2] = subport->tc_credits_per_period[2]; + subport->tc_credits[3] = subport->tc_credits_per_period[3]; - subport->tc_ov_time = port->time + subport->tc_ov_period; + subport->tc_time = port->time + subport->tc_period; subport->tc_ov_period_id ++; } - + /* Pipe TCs */ if (unlikely(port->time >= pipe->tc_time)) { pipe->tc_credits[0] = params->tc_credits_per_period[0]; @@ -1518,25 +1557,10 @@ grinder_credits_update(struct rte_sched_port *port, uint32_t pos) pipe->tc_credits[3] = params->tc_credits_per_period[3]; pipe->tc_time = port->time + params->tc_period; } + + /* Pipe TCs - Oversubscription */ if (unlikely(pipe->tc_ov_period_id != subport->tc_ov_period_id)) { - uint32_t pipe_tc_ov_credits[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; - uint32_t tc_mask[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; - uint32_t mask[] = {UINT32_MAX, 0}; - - tc_mask[0] = mask[subport->tc_ov[0]]; - tc_mask[1] = mask[subport->tc_ov[1]]; - tc_mask[2] = mask[subport->tc_ov[2]]; - tc_mask[3] = mask[subport->tc_ov[3]]; - - pipe_tc_ov_credits[0] = subport->tc_ov_credits[0] * params->tc_ov_weight[0]; - pipe_tc_ov_credits[1] = subport->tc_ov_credits[1] * params->tc_ov_weight[1]; - pipe_tc_ov_credits[2] = subport->tc_ov_credits[2] * params->tc_ov_weight[2]; - pipe_tc_ov_credits[3] = subport->tc_ov_credits[3] * params->tc_ov_weight[3]; - - pipe->tc_ov_credits[0] = (tc_mask[0] & pipe->tc_credits[0]) | ((~ tc_mask[0]) & pipe_tc_ov_credits[0]); - pipe->tc_ov_credits[1] = (tc_mask[1] & pipe->tc_credits[1]) | ((~ tc_mask[1]) & pipe_tc_ov_credits[1]); - pipe->tc_ov_credits[2] = (tc_mask[2] & pipe->tc_credits[2]) | ((~ tc_mask[2]) & pipe_tc_ov_credits[2]); - pipe->tc_ov_credits[3] = (tc_mask[3] & pipe->tc_credits[3]) | ((~ tc_mask[3]) & pipe_tc_ov_credits[3]); + pipe->tc_ov_credits = subport->tc_ov_wm * params->tc_ov_weight; pipe->tc_ov_period_id = subport->tc_ov_period_id; } @@ -1555,13 +1579,17 @@ grinder_credits_check(struct rte_sched_port *port, uint32_t pos) struct rte_mbuf *pkt = grinder->pkt; uint32_t tc_index = grinder->tc_index; uint32_t pkt_len = pkt->pkt.pkt_len + port->frame_overhead; + uint32_t subport_tb_credits = subport->tb_credits; + uint32_t subport_tc_credits = subport->tc_credits[tc_index]; + uint32_t pipe_tb_credits = pipe->tb_credits; + uint32_t pipe_tc_credits = pipe->tc_credits[tc_index]; int enough_credits; /* Check queue credits */ - enough_credits = (pkt_len <= subport->tb_credits) && - (pkt_len <= subport->tc_credits[tc_index]) && - (pkt_len <= pipe->tb_credits) && - (pkt_len <= pipe->tc_credits[tc_index]); + enough_credits = (pkt_len <= subport_tb_credits) && + (pkt_len <= subport_tc_credits) && + (pkt_len <= pipe_tb_credits) && + (pkt_len <= pipe_tc_credits); if (!enough_credits) { return 0; @@ -1591,7 +1619,9 @@ grinder_credits_check(struct rte_sched_port *port, uint32_t pos) uint32_t subport_tc_credits = subport->tc_credits[tc_index]; uint32_t pipe_tb_credits = pipe->tb_credits; uint32_t pipe_tc_credits = pipe->tc_credits[tc_index]; - uint32_t pipe_tc_ov_credits = pipe->tc_ov_credits[tc_index]; + uint32_t pipe_tc_ov_mask1[] = {UINT32_MAX, UINT32_MAX, UINT32_MAX, pipe->tc_ov_credits}; + uint32_t pipe_tc_ov_mask2[] = {0, 0, 0, UINT32_MAX}; + uint32_t pipe_tc_ov_credits = pipe_tc_ov_mask1[tc_index]; int enough_credits; /* Check pipe and subport credits */ @@ -1610,7 +1640,7 @@ grinder_credits_check(struct rte_sched_port *port, uint32_t pos) subport->tc_credits[tc_index] -= pkt_len; pipe->tb_credits -= pkt_len; pipe->tc_credits[tc_index] -= pkt_len; - pipe->tc_ov_credits[tc_index] -= pkt_len; + pipe->tc_ov_credits -= pipe_tc_ov_mask2[tc_index] & pkt_len; return 1; }