* [dpdk-dev] [PATCH 00/27] sched: feature enhancements @ 2019-05-28 12:05 Lukasz Krakowiak 2019-05-28 12:05 ` [dpdk-dev] [PATCH 01/27] sched: update macros for flexible config Lukasz Krakowiak ` (26 more replies) 0 siblings, 27 replies; 163+ messages in thread From: Lukasz Krakowiak @ 2019-05-28 12:05 UTC (permalink / raw) To: cristian.dumitrescu; +Cc: dev, Lukasz Krakowiak This patchset refactors the dpdk qos sched library to add following features to enhance the scheduler functionality. 1. flexibile configuration of the pipe traffic classes and queues; Currently, each pipe has 16 queues hardwired into 4 TCs scheduled with strict priority, and each TC has exactly with 4 queues that are scheduled with Weighted Fair Queuing (WFQ). Instead of hardwiring queues to traffic class within the specific pipe, the new implementation allows more flexible/configurable split of pipe queues between strict priority (SP) and best-effort (BE) traffic classes along with the support of more number of traffic classes i.e. max 16. All the high priority TCs (TC1, TC2, ...) have exactly 1 queue, while the lowest priority BE TC, has 1, 4 or 8 queues. This is justified by the fact that all the high priority TCs are fully provisioned (small to medium traffic rates), while most of the traffic fits into the BE class, which is typically oversubscribed. Furthermore, this change allows to use less than 16 queues per pipe when not all the 16 queues are needed. Therefore, no memory will be allocated to the queues that are not needed. 2. Subport level configuration of pipe nodes; Currently, all parameters for the pipe nodes (subscribers) configuration are part of the port level structure which forces all groups of subscribers (i.e. pipes) in different subports to have similar configurations in terms of their number, queue sizes, traffic-classes, etc. The new implementation moves pipe nodes configuration parameters from port level to subport level structure. Therefore, different subports of the same port can have different configuration for the pipe nodes (subscribers), for examples- number of pipes, queue sizes, queues to traffic-class mapping, etc. Jasvinder Singh (27): sched: update macros for flexible config sched: update subport and pipe data structures sched: update internal data structures sched: update port config api sched: update port free api sched: update subport config api sched: update pipe profile add api sched: update pipe config api sched: update pkt read and write api sched: update subport and tc queue stats sched: update port memory footprint api sched: update packet enqueue api sched: update grinder pipe and tc cache sched: update grinder next pipe and tc functions sched: update pipe and tc queues prefetch sched: update grinder wrr compute function sched: modify credits update function sched: update mbuf prefetch function sched: update grinder schedule function sched: update grinder handle function sched: update packet dequeue api sched: update sched queue stats api test/sched: update unit test net/softnic: update softnic tm function examples/qos_sched: update qos sched sample app examples/ip_pipeline: update ip pipeline sample app sched: code cleanup app/test/test_sched.c | 39 +- doc/guides/rel_notes/deprecation.rst | 6 - doc/guides/rel_notes/release_19_08.rst | 7 +- drivers/net/softnic/rte_eth_softnic.c | 131 ++ drivers/net/softnic/rte_eth_softnic_cli.c | 285 ++- .../net/softnic/rte_eth_softnic_internals.h | 4 +- drivers/net/softnic/rte_eth_softnic_tm.c | 89 +- examples/ip_pipeline/cli.c | 85 +- examples/ip_pipeline/tmgr.c | 21 +- examples/ip_pipeline/tmgr.h | 3 - examples/qos_sched/app_thread.c | 11 +- examples/qos_sched/cfg_file.c | 282 ++- examples/qos_sched/init.c | 110 +- examples/qos_sched/main.h | 6 +- examples/qos_sched/profile.cfg | 59 +- examples/qos_sched/profile_ov.cfg | 47 +- examples/qos_sched/stats.c | 152 +- lib/librte_pipeline/rte_table_action.c | 1 - lib/librte_pipeline/rte_table_action.h | 4 +- lib/librte_sched/Makefile | 2 +- lib/librte_sched/meson.build | 2 +- lib/librte_sched/rte_sched.c | 2015 ++++++++++------- lib/librte_sched/rte_sched.h | 147 +- lib/librte_sched/rte_sched_common.h | 33 + 24 files changed, 2314 insertions(+), 1227 deletions(-) -- 2.20.1 ^ permalink raw reply [flat|nested] 163+ messages in thread
* [dpdk-dev] [PATCH 01/27] sched: update macros for flexible config 2019-05-28 12:05 [dpdk-dev] [PATCH 00/27] sched: feature enhancements Lukasz Krakowiak @ 2019-05-28 12:05 ` Lukasz Krakowiak 2019-06-25 15:31 ` [dpdk-dev] [PATCH v2 00/28] sched: feature enhancements Jasvinder Singh 2019-05-28 12:05 ` [dpdk-dev] [PATCH 02/27] sched: update subport and pipe data structures Lukasz Krakowiak ` (25 subsequent siblings) 26 siblings, 1 reply; 163+ messages in thread From: Lukasz Krakowiak @ 2019-05-28 12:05 UTC (permalink / raw) To: cristian.dumitrescu; +Cc: dev, Jasvinder Singh, Abraham Tovar, Lukasz Krakowiak From: Jasvinder Singh <jasvinder.singh@intel.com> Update existing macros and add new one for best-effort traffic class queues to allow configuration flexiblity for pipe traffic classes and queues, and subport level configuration of the pipe parameters. Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com> Signed-off-by: Abraham Tovar <abrahamx.tovar@intel.com> Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com> --- doc/guides/rel_notes/deprecation.rst | 6 ----- doc/guides/rel_notes/release_19_08.rst | 7 ++++- lib/librte_sched/Makefile | 2 +- lib/librte_sched/meson.build | 2 +- lib/librte_sched/rte_sched.h | 37 +++++++++++++++++++------- 5 files changed, 35 insertions(+), 19 deletions(-) diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst index 098d24381..a408270f5 100644 --- a/doc/guides/rel_notes/deprecation.rst +++ b/doc/guides/rel_notes/deprecation.rst @@ -99,12 +99,6 @@ Deprecation Notices to one it means it represents IV, when is set to zero it means J0 is used directly, in this case 16 bytes of J0 need to be passed. -* sched: To allow more traffic classes, flexible mapping of pipe queues to - traffic classes, and subport level configuration of pipes and queues - changes will be made to macros, data structures and API functions defined - in "rte_sched.h". These changes are aligned to improvements suggested in the - RFC https://mails.dpdk.org/archives/dev/2018-November/120035.html. - * metrics: The function ``rte_metrics_init`` will have a non-void return in order to notify errors instead of calling ``rte_exit``. diff --git a/doc/guides/rel_notes/release_19_08.rst b/doc/guides/rel_notes/release_19_08.rst index b9510f93a..210f32e7f 100644 --- a/doc/guides/rel_notes/release_19_08.rst +++ b/doc/guides/rel_notes/release_19_08.rst @@ -83,6 +83,11 @@ API Changes Also, make sure to start the actual text at the margin. ========================================================= +* sched: To allow more traffic classes, flexible mapping of pipe queues to + traffic classes, and subport level configuration of pipes and queues + changes are made to public macros, data structures and API functions defined + in "rte_sched.h". + ABI Changes ----------- @@ -170,7 +175,7 @@ The libraries prepended with a plus sign were incremented in this version. librte_rcu.so.1 librte_reorder.so.1 librte_ring.so.2 - librte_sched.so.2 + + librte_sched.so.3 librte_security.so.2 librte_stack.so.1 librte_table.so.3 diff --git a/lib/librte_sched/Makefile b/lib/librte_sched/Makefile index 644fd9d15..3d7f410e1 100644 --- a/lib/librte_sched/Makefile +++ b/lib/librte_sched/Makefile @@ -18,7 +18,7 @@ LDLIBS += -lrte_timer EXPORT_MAP := rte_sched_version.map -LIBABIVER := 2 +LIBABIVER := 3 # # all source are stored in SRCS-y diff --git a/lib/librte_sched/meson.build b/lib/librte_sched/meson.build index 8e989e5f6..59d43c6d8 100644 --- a/lib/librte_sched/meson.build +++ b/lib/librte_sched/meson.build @@ -1,7 +1,7 @@ # SPDX-License-Identifier: BSD-3-Clause # Copyright(c) 2017 Intel Corporation -version = 2 +version = 3 sources = files('rte_sched.c', 'rte_red.c', 'rte_approx.c') headers = files('rte_sched.h', 'rte_sched_common.h', 'rte_red.h', 'rte_approx.h') diff --git a/lib/librte_sched/rte_sched.h b/lib/librte_sched/rte_sched.h index 9c55a787d..cf7695f27 100644 --- a/lib/librte_sched/rte_sched.h +++ b/lib/librte_sched/rte_sched.h @@ -52,7 +52,7 @@ extern "C" { * multiple connections of same traffic class belonging to * the same user; * - Weighted Round Robin (WRR) is used to service the - * queues within same pipe traffic class. + * queues within same pipe lowest priority (best-effort) traffic class. * */ @@ -66,26 +66,43 @@ extern "C" { #include "rte_red.h" #endif -/** Number of traffic classes per pipe (as well as subport). - * Cannot be changed. +/** Maximum number of queues per pipe. + * Note that the multiple queues (power of 2) can only be assigned to + * lowest priority (best-effort) traffic class. Other higher priority traffic + * classes can only have one queue. + * + * Can not change. + */ +#define RTE_SCHED_QUEUES_PER_PIPE 16 + +/** Number of WRR queues for lowest priority (best-effort) traffic class per + * pipe. */ -#define RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE 4 +#define RTE_SCHED_WRR_QUEUES_PER_PIPE 8 -/** Number of queues per pipe traffic class. Cannot be changed. */ +/** Number of traffic classes per pipe (as well as subport). */ #define RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS 4 +#define RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE \ +(RTE_SCHED_QUEUES_PER_PIPE - RTE_SCHED_WRR_QUEUES_PER_PIPE + 1) -/** Number of queues per pipe. */ -#define RTE_SCHED_QUEUES_PER_PIPE \ - (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE * \ - RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS) +/** Maximum number of subports that can be defined per port. + * Compile-time configurable. + */ +#ifndef RTE_SCHED_SUBPORTS_PER_PORT +#define RTE_SCHED_SUBPORTS_PER_PORT 256 +#endif -/** Maximum number of pipe profiles that can be defined per port. +/** Maximum number of pipe profiles that can be defined per subport. * Compile-time configurable. */ #ifndef RTE_SCHED_PIPE_PROFILES_PER_PORT #define RTE_SCHED_PIPE_PROFILES_PER_PORT 256 #endif +#ifndef RTE_SCHED_PIPE_PROFILES_PER_SUBPORT +#define RTE_SCHED_PIPE_PROFILES_PER_SUBPORT 256 +#endif + /* * Ethernet framing overhead. Overhead fields per Ethernet frame: * 1. Preamble: 7 bytes; -- 2.20.1 ^ permalink raw reply [flat|nested] 163+ messages in thread
* [dpdk-dev] [PATCH v2 00/28] sched: feature enhancements 2019-05-28 12:05 ` [dpdk-dev] [PATCH 01/27] sched: update macros for flexible config Lukasz Krakowiak @ 2019-06-25 15:31 ` Jasvinder Singh 2019-06-25 15:31 ` [dpdk-dev] [PATCH v2 01/28] sched: update macros for flexible config Jasvinder Singh ` (30 more replies) 0 siblings, 31 replies; 163+ messages in thread From: Jasvinder Singh @ 2019-06-25 15:31 UTC (permalink / raw) To: dev; +Cc: cristian.dumitrescu This patchset refactors the dpdk qos sched library to add following features to enhance the scheduler functionality. 1. flexibile configuration of the pipe traffic classes and queues; Currently, each pipe has 16 queues hardwired into 4 TCs scheduled with strict priority, and each TC has exactly with 4 queues that are scheduled with Weighted Fair Queuing (WFQ). Instead of hardwiring queues to traffic class within the specific pipe, the new implementation allows more flexible/configurable split of pipe queues between strict priority (SP) and best-effort (BE) traffic classes along with the support of more number of traffic classes i.e. max 16. All the high priority TCs (TC1, TC2, ...) have exactly 1 queue, while the lowest priority BE TC, has 1, 4 or 8 queues. This is justified by the fact that all the high priority TCs are fully provisioned (small to medium traffic rates), while most of the traffic fits into the BE class, which is typically oversubscribed. Furthermore, this change allows to use less than 16 queues per pipe when not all the 16 queues are needed. Therefore, no memory will be allocated to the queues that are not needed. 2. Subport level configuration of pipe nodes; Currently, all parameters for the pipe nodes (subscribers) configuration are part of the port level structure which forces all groups of subscribers (i.e. pipes) in different subports to have similar configurations in terms of their number, queue sizes, traffic-classes, etc. The new implementation moves pipe nodes configuration parameters from port level to subport level structure. Therefore, different subports of the same port can have different configuration for the pipe nodes (subscribers), for examples- number of pipes, queue sizes, queues to traffic-class mapping, etc. v2: - fix bug in subport parameters check - remove redundant RTE_SCHED_SUBPORT_PER_PORT macro - fix bug in grinder_scheduler function - improve doxygen comments - add error log information Jasvinder Singh (27): sched: update macros for flexible config sched: update subport and pipe data structures sched: update internal data structures sched: update port config API sched: update port free API sched: update subport config API sched: update pipe profile add API sched: update pipe config API sched: update pkt read and write API sched: update subport and tc queue stats sched: update port memory footprint API sched: update packet enqueue API sched: update grinder pipe and tc cache sched: update grinder next pipe and tc functions sched: update pipe and tc queues prefetch sched: update grinder wrr compute function sched: modify credits update function sched: update mbuf prefetch function sched: update grinder schedule function sched: update grinder handle function sched: update packet dequeue API sched: update sched queue stats API test/sched: update unit test net/softnic: update softnic tm function examples/qos_sched: update qos sched sample app examples/ip_pipeline: update ip pipeline sample app sched: code cleanup Lukasz Krakowiak (1): sched: add release note app/test/test_sched.c | 39 +- doc/guides/rel_notes/deprecation.rst | 6 - doc/guides/rel_notes/release_19_08.rst | 7 +- drivers/net/softnic/rte_eth_softnic.c | 131 + drivers/net/softnic/rte_eth_softnic_cli.c | 286 ++- .../net/softnic/rte_eth_softnic_internals.h | 8 +- drivers/net/softnic/rte_eth_softnic_tm.c | 89 +- examples/ip_pipeline/cli.c | 85 +- examples/ip_pipeline/tmgr.c | 22 +- examples/ip_pipeline/tmgr.h | 3 - examples/qos_sched/app_thread.c | 11 +- examples/qos_sched/cfg_file.c | 283 ++- examples/qos_sched/init.c | 111 +- examples/qos_sched/main.h | 7 +- examples/qos_sched/profile.cfg | 59 +- examples/qos_sched/profile_ov.cfg | 47 +- examples/qos_sched/stats.c | 483 ++-- lib/librte_pipeline/rte_table_action.c | 1 - lib/librte_pipeline/rte_table_action.h | 4 +- lib/librte_sched/Makefile | 2 +- lib/librte_sched/meson.build | 2 +- lib/librte_sched/rte_sched.c | 2133 ++++++++++------- lib/librte_sched/rte_sched.h | 229 +- lib/librte_sched/rte_sched_common.h | 41 + 24 files changed, 2634 insertions(+), 1455 deletions(-) -- 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* [dpdk-dev] [PATCH v2 01/28] sched: update macros for flexible config 2019-06-25 15:31 ` [dpdk-dev] [PATCH v2 00/28] sched: feature enhancements Jasvinder Singh @ 2019-06-25 15:31 ` Jasvinder Singh 2019-07-01 19:04 ` Dumitrescu, Cristian 2019-07-11 10:26 ` [dpdk-dev] [PATCH v3 00/11] sched: feature enhancements Jasvinder Singh 2019-06-25 15:31 ` [dpdk-dev] [PATCH v2 02/28] sched: update subport and pipe data structures Jasvinder Singh ` (29 subsequent siblings) 30 siblings, 2 replies; 163+ messages in thread From: Jasvinder Singh @ 2019-06-25 15:31 UTC (permalink / raw) To: dev; +Cc: cristian.dumitrescu, Abraham Tovar, Lukasz Krakowiak Update macros to allow configuration flexiblity for pipe traffic classes and queues, and subport level configuration of the pipe parameters. Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com> Signed-off-by: Abraham Tovar <abrahamx.tovar@intel.com> Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com> --- lib/librte_sched/rte_sched.h | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/lib/librte_sched/rte_sched.h b/lib/librte_sched/rte_sched.h index 9c55a787d..470a0036a 100644 --- a/lib/librte_sched/rte_sched.h +++ b/lib/librte_sched/rte_sched.h @@ -52,7 +52,7 @@ extern "C" { * multiple connections of same traffic class belonging to * the same user; * - Weighted Round Robin (WRR) is used to service the - * queues within same pipe traffic class. + * queues within same pipe lowest priority traffic class (best-effort). * */ @@ -66,20 +66,32 @@ extern "C" { #include "rte_red.h" #endif -/** Number of traffic classes per pipe (as well as subport). - * Cannot be changed. +/** Maximum number of queues per pipe. + * Note that the multiple queues (power of 2) can only be assigned to + * lowest priority (best-effort) traffic class. Other higher priority traffic + * classes can only have one queue. + * Can not change. + * + * @see struct rte_sched_subport_params */ -#define RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE 4 +#define RTE_SCHED_QUEUES_PER_PIPE 16 -/** Number of queues per pipe traffic class. Cannot be changed. */ -#define RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS 4 +/** Number of WRR queues for best-effort traffic class per pipe. + * + * @see struct rte_sched_pipe_params + */ +#define RTE_SCHED_BE_QUEUES_PER_PIPE 8 -/** Number of queues per pipe. */ -#define RTE_SCHED_QUEUES_PER_PIPE \ - (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE * \ - RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS) +#define RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS 4 +/** Number of traffic classes per pipe (as well as subport). + * + * @see struct rte_sched_subport_params + * @see struct rte_sched_pipe_params + */ +#define RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE \ +(RTE_SCHED_QUEUES_PER_PIPE - RTE_SCHED_BE_QUEUES_PER_PIPE + 1) -/** Maximum number of pipe profiles that can be defined per port. +/** Maximum number of pipe profiles that can be defined per subport. * Compile-time configurable. */ #ifndef RTE_SCHED_PIPE_PROFILES_PER_PORT @@ -95,6 +107,8 @@ extern "C" { * * The FCS is considered overhead only if not included in the packet * length (field pkt_len of struct rte_mbuf). + * + * @see struct rte_sched_port_params */ #ifndef RTE_SCHED_FRAME_OVERHEAD_DEFAULT #define RTE_SCHED_FRAME_OVERHEAD_DEFAULT 24 -- 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* Re: [dpdk-dev] [PATCH v2 01/28] sched: update macros for flexible config 2019-06-25 15:31 ` [dpdk-dev] [PATCH v2 01/28] sched: update macros for flexible config Jasvinder Singh @ 2019-07-01 19:04 ` Dumitrescu, Cristian 2019-07-02 13:26 ` Singh, Jasvinder 2019-07-11 10:26 ` [dpdk-dev] [PATCH v3 00/11] sched: feature enhancements Jasvinder Singh 1 sibling, 1 reply; 163+ messages in thread From: Dumitrescu, Cristian @ 2019-07-01 19:04 UTC (permalink / raw) To: Singh, Jasvinder, dev; +Cc: Tovar, AbrahamX, Krakowiak, LukaszX > -----Original Message----- > From: Singh, Jasvinder > Sent: Tuesday, June 25, 2019 4:32 PM > To: dev@dpdk.org > Cc: Dumitrescu, Cristian <cristian.dumitrescu@intel.com>; Tovar, AbrahamX > <abrahamx.tovar@intel.com>; Krakowiak, LukaszX > <lukaszx.krakowiak@intel.com> > Subject: [PATCH v2 01/28] sched: update macros for flexible config > > Update macros to allow configuration flexiblity for pipe traffic > classes and queues, and subport level configuration of the pipe > parameters. > > Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com> > Signed-off-by: Abraham Tovar <abrahamx.tovar@intel.com> > Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com> > --- > lib/librte_sched/rte_sched.h | 36 +++++++++++++++++++++++++----------- > 1 file changed, 25 insertions(+), 11 deletions(-) > > diff --git a/lib/librte_sched/rte_sched.h b/lib/librte_sched/rte_sched.h > index 9c55a787d..470a0036a 100644 > --- a/lib/librte_sched/rte_sched.h > +++ b/lib/librte_sched/rte_sched.h > @@ -52,7 +52,7 @@ extern "C" { > * multiple connections of same traffic class belonging to > * the same user; > * - Weighted Round Robin (WRR) is used to service the > - * queues within same pipe traffic class. > + * queues within same pipe lowest priority traffic class (best-effort). > * > */ > > @@ -66,20 +66,32 @@ extern "C" { > #include "rte_red.h" > #endif > > -/** Number of traffic classes per pipe (as well as subport). > - * Cannot be changed. > +/** Maximum number of queues per pipe. > + * Note that the multiple queues (power of 2) can only be assigned to > + * lowest priority (best-effort) traffic class. Other higher priority traffic > + * classes can only have one queue. > + * Can not change. > + * > + * @see struct rte_sched_subport_params > */ > -#define RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE 4 > +#define RTE_SCHED_QUEUES_PER_PIPE 16 > > -/** Number of queues per pipe traffic class. Cannot be changed. */ > -#define RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS 4 > +/** Number of WRR queues for best-effort traffic class per pipe. > + * > + * @see struct rte_sched_pipe_params > + */ > +#define RTE_SCHED_BE_QUEUES_PER_PIPE 8 Should we have this as 8 or 4? I think we should limit this to 4, as 4 allows quick vectorization, while 8 is problematic. We should also not have a run-time parameter for number of best effort queues, as this can be detected by checking the size of all best effort queues against 0. Of course, we should mandate that the enabled queues (with non-zero size) are contiguous. > > -/** Number of queues per pipe. */ > -#define RTE_SCHED_QUEUES_PER_PIPE \ > - (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE * \ > - RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS) > +#define RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS 4 > +/** Number of traffic classes per pipe (as well as subport). > + * > + * @see struct rte_sched_subport_params > + * @see struct rte_sched_pipe_params > + */ > +#define RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE \ > +(RTE_SCHED_QUEUES_PER_PIPE - RTE_SCHED_BE_QUEUES_PER_PIPE + 1) > > -/** Maximum number of pipe profiles that can be defined per port. > +/** Maximum number of pipe profiles that can be defined per subport. > * Compile-time configurable. > */ > #ifndef RTE_SCHED_PIPE_PROFILES_PER_PORT > @@ -95,6 +107,8 @@ extern "C" { > * > * The FCS is considered overhead only if not included in the packet > * length (field pkt_len of struct rte_mbuf). > + * > + * @see struct rte_sched_port_params > */ > #ifndef RTE_SCHED_FRAME_OVERHEAD_DEFAULT > #define RTE_SCHED_FRAME_OVERHEAD_DEFAULT 24 > -- > 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* Re: [dpdk-dev] [PATCH v2 01/28] sched: update macros for flexible config 2019-07-01 19:04 ` Dumitrescu, Cristian @ 2019-07-02 13:26 ` Singh, Jasvinder 0 siblings, 0 replies; 163+ messages in thread From: Singh, Jasvinder @ 2019-07-02 13:26 UTC (permalink / raw) To: Dumitrescu, Cristian, dev; +Cc: Tovar, AbrahamX, Krakowiak, LukaszX > -----Original Message----- > From: Dumitrescu, Cristian > Sent: Monday, July 1, 2019 8:05 PM > To: Singh, Jasvinder <jasvinder.singh@intel.com>; dev@dpdk.org > Cc: Tovar, AbrahamX <abrahamx.tovar@intel.com>; Krakowiak, LukaszX > <lukaszx.krakowiak@intel.com> > Subject: RE: [PATCH v2 01/28] sched: update macros for flexible config > > > > > -----Original Message----- > > From: Singh, Jasvinder > > Sent: Tuesday, June 25, 2019 4:32 PM > > To: dev@dpdk.org > > Cc: Dumitrescu, Cristian <cristian.dumitrescu@intel.com>; Tovar, > > AbrahamX <abrahamx.tovar@intel.com>; Krakowiak, LukaszX > > <lukaszx.krakowiak@intel.com> > > Subject: [PATCH v2 01/28] sched: update macros for flexible config > > > > Update macros to allow configuration flexiblity for pipe traffic > > classes and queues, and subport level configuration of the pipe > > parameters. > > > > Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com> > > Signed-off-by: Abraham Tovar <abrahamx.tovar@intel.com> > > Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com> > > --- > > lib/librte_sched/rte_sched.h | 36 > > +++++++++++++++++++++++++----------- > > 1 file changed, 25 insertions(+), 11 deletions(-) > > > > diff --git a/lib/librte_sched/rte_sched.h > > b/lib/librte_sched/rte_sched.h index 9c55a787d..470a0036a 100644 > > --- a/lib/librte_sched/rte_sched.h > > +++ b/lib/librte_sched/rte_sched.h > > @@ -52,7 +52,7 @@ extern "C" { > > * multiple connections of same traffic class belonging to > > * the same user; > > * - Weighted Round Robin (WRR) is used to service the > > - * queues within same pipe traffic class. > > + * queues within same pipe lowest priority traffic class (best-effort). > > * > > */ > > > > @@ -66,20 +66,32 @@ extern "C" { > > #include "rte_red.h" > > #endif > > > > -/** Number of traffic classes per pipe (as well as subport). > > - * Cannot be changed. > > +/** Maximum number of queues per pipe. > > + * Note that the multiple queues (power of 2) can only be assigned to > > + * lowest priority (best-effort) traffic class. Other higher priority > > +traffic > > + * classes can only have one queue. > > + * Can not change. > > + * > > + * @see struct rte_sched_subport_params > > */ > > -#define RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE 4 > > +#define RTE_SCHED_QUEUES_PER_PIPE 16 > > > > -/** Number of queues per pipe traffic class. Cannot be changed. */ > > -#define RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS 4 > > +/** Number of WRR queues for best-effort traffic class per pipe. > > + * > > + * @see struct rte_sched_pipe_params > > + */ > > +#define RTE_SCHED_BE_QUEUES_PER_PIPE 8 > > Should we have this as 8 or 4? I think we should limit this to 4, as 4 allows quick > vectorization, while 8 is problematic. The only reason to keep 8 queues for best effort TC is flexibility in reducing to 4 if needed, and moreover, it has very little impact on performance in out tests. > We should also not have a run-time parameter for number of best effort > queues, as this can be detected by checking the size of all best effort queues > against 0. Of course, we should mandate that the enabled queues (with non- > zero size) are contiguous. Yes, it is done that way without having any additional parameter in public structure. > > > > -/** Number of queues per pipe. */ > > -#define RTE_SCHED_QUEUES_PER_PIPE \ > > - (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE * \ > > - RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS) > > +#define RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS 4 > > +/** Number of traffic classes per pipe (as well as subport). > > + * > > + * @see struct rte_sched_subport_params > > + * @see struct rte_sched_pipe_params > > + */ > > +#define RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE \ > > +(RTE_SCHED_QUEUES_PER_PIPE - RTE_SCHED_BE_QUEUES_PER_PIPE + 1) > > > > -/** Maximum number of pipe profiles that can be defined per port. > > +/** Maximum number of pipe profiles that can be defined per subport. > > * Compile-time configurable. > > */ > > #ifndef RTE_SCHED_PIPE_PROFILES_PER_PORT @@ -95,6 +107,8 @@ > extern > > "C" { > > * > > * The FCS is considered overhead only if not included in the packet > > * length (field pkt_len of struct rte_mbuf). > > + * > > + * @see struct rte_sched_port_params > > */ > > #ifndef RTE_SCHED_FRAME_OVERHEAD_DEFAULT > > #define RTE_SCHED_FRAME_OVERHEAD_DEFAULT 24 > > -- > > 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* [dpdk-dev] [PATCH v3 00/11] sched: feature enhancements 2019-06-25 15:31 ` [dpdk-dev] [PATCH v2 01/28] sched: update macros for flexible config Jasvinder Singh 2019-07-01 19:04 ` Dumitrescu, Cristian @ 2019-07-11 10:26 ` Jasvinder Singh 2019-07-11 10:26 ` [dpdk-dev] [PATCH v3 01/11] sched: remove wrr from strict priority tc queues Jasvinder Singh ` (10 more replies) 1 sibling, 11 replies; 163+ messages in thread From: Jasvinder Singh @ 2019-07-11 10:26 UTC (permalink / raw) To: dev; +Cc: cristian.dumitrescu This patchset refactors the dpdk qos sched library to allow flexibile configuration of the pipe traffic classes and queue sizes. Currently, each pipe has 16 queues hardwired into 4 TCs scheduled with strict priority, and each TC has exactly with 4 queues that are scheduled with Weighted Fair Queuing (WFQ). Instead of hardwiring queues to traffic class within the specific pipe, the new implementation allows more flexible/configurable split of pipe queues between strict priority (SP) and best-effort (BE) traffic classes along with the support of more number of traffic classes i.e. max 16. All the high priority TCs (TC1, TC2, ...) have exactly 1 queue, while the lowest priority BE TC, has 1, 4 or 8 queues. This is justified by the fact that all the high priority TCs are fully provisioned (small to medium traffic rates), while most of the traffic fits into the BE class, which is typically oversubscribed. Furthermore, this change allows to use less than 16 queues per pipe when not all the 16 queues are needed. Therefore, no memory will be allocated to the queues that are not needed. v3: - remove code related to subport level configuration of the pipe - remove tc oversubscription flag from struct rte_sched_pipe_params - replace RTE_SCHED_PIPE_PROFILES_PER_PORT with port param field v2: - fix bug in subport parameters check - remove redundant RTE_SCHED_SUBPORT_PER_PORT macro - fix bug in grinder_scheduler function - improve doxygen comments - add error log information Jasvinder Singh (11): sched: remove wrr from strict priority tc queues sched: add config flexibility to tc queue sizes sched: add max pipe profiles config in run time sched: rename tc3 params to best-effort tc sched: improve error log messages sched: improve doxygen comments net/softnic: add config flexibility to softnic tm test_sched: modify tests for config flexibility examples/ip_pipeline: add config flexibility to tm function examples/qos_sched: add tc and queue config flexibility sched: remove redundant macros app/test/test_sched.c | 12 +- doc/guides/rel_notes/release_19_08.rst | 10 +- drivers/net/softnic/rte_eth_softnic.c | 131 +++ drivers/net/softnic/rte_eth_softnic_cli.c | 433 ++++++++- .../net/softnic/rte_eth_softnic_internals.h | 8 +- drivers/net/softnic/rte_eth_softnic_tm.c | 64 +- examples/ip_pipeline/cli.c | 45 +- examples/ip_pipeline/tmgr.c | 2 +- examples/ip_pipeline/tmgr.h | 4 +- examples/qos_sched/app_thread.c | 9 +- examples/qos_sched/cfg_file.c | 119 ++- examples/qos_sched/init.c | 65 +- examples/qos_sched/main.h | 4 + examples/qos_sched/profile.cfg | 66 +- examples/qos_sched/profile_ov.cfg | 54 +- examples/qos_sched/stats.c | 483 +++++----- lib/librte_pipeline/rte_table_action.c | 1 - lib/librte_pipeline/rte_table_action.h | 4 +- lib/librte_sched/Makefile | 2 +- lib/librte_sched/meson.build | 2 +- lib/librte_sched/rte_sched.c | 842 +++++++++++------- lib/librte_sched/rte_sched.h | 182 ++-- 22 files changed, 1786 insertions(+), 756 deletions(-) -- 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* [dpdk-dev] [PATCH v3 01/11] sched: remove wrr from strict priority tc queues 2019-07-11 10:26 ` [dpdk-dev] [PATCH v3 00/11] sched: feature enhancements Jasvinder Singh @ 2019-07-11 10:26 ` Jasvinder Singh 2019-07-12 9:57 ` [dpdk-dev] [PATCH v4 00/11] sched: feature enhancements Jasvinder Singh 2019-07-11 10:26 ` [dpdk-dev] [PATCH v3 02/11] sched: add config flexibility to tc queue sizes Jasvinder Singh ` (9 subsequent siblings) 10 siblings, 1 reply; 163+ messages in thread From: Jasvinder Singh @ 2019-07-11 10:26 UTC (permalink / raw) To: dev; +Cc: cristian.dumitrescu, Abraham Tovar, Lukasz Krakowiak All higher priority traffic classes contain only one queue, thus remove wrr function for them. The lowest priority best-effort traffic class conitnue to have multiple queues and packet are scheduled from its queues using wrr function. Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com> Signed-off-by: Abraham Tovar <abrahamx.tovar@intel.com> Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com> --- app/test/test_sched.c | 2 +- examples/qos_sched/init.c | 2 +- lib/librte_sched/Makefile | 2 +- lib/librte_sched/meson.build | 2 +- lib/librte_sched/rte_sched.c | 183 ++++++++++++++++++++--------------- lib/librte_sched/rte_sched.h | 23 +++-- 6 files changed, 125 insertions(+), 89 deletions(-) diff --git a/app/test/test_sched.c b/app/test/test_sched.c index 49bb9ea6f..36fa2d425 100644 --- a/app/test/test_sched.c +++ b/app/test/test_sched.c @@ -40,7 +40,7 @@ static struct rte_sched_pipe_params pipe_profile[] = { .tc_rate = {305175, 305175, 305175, 305175}, .tc_period = 40, - .wrr_weights = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, + .wrr_weights = {1, 1, 1, 1}, }, }; diff --git a/examples/qos_sched/init.c b/examples/qos_sched/init.c index 1209bd7ce..6b63d4e0e 100644 --- a/examples/qos_sched/init.c +++ b/examples/qos_sched/init.c @@ -186,7 +186,7 @@ static struct rte_sched_pipe_params pipe_profiles[RTE_SCHED_PIPE_PROFILES_PER_PO .tc_ov_weight = 1, #endif - .wrr_weights = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, + .wrr_weights = {1, 1, 1, 1}, }, }; diff --git a/lib/librte_sched/Makefile b/lib/librte_sched/Makefile index 644fd9d15..3d7f410e1 100644 --- a/lib/librte_sched/Makefile +++ b/lib/librte_sched/Makefile @@ -18,7 +18,7 @@ LDLIBS += -lrte_timer EXPORT_MAP := rte_sched_version.map -LIBABIVER := 2 +LIBABIVER := 3 # # all source are stored in SRCS-y diff --git a/lib/librte_sched/meson.build b/lib/librte_sched/meson.build index 8e989e5f6..59d43c6d8 100644 --- a/lib/librte_sched/meson.build +++ b/lib/librte_sched/meson.build @@ -1,7 +1,7 @@ # SPDX-License-Identifier: BSD-3-Clause # Copyright(c) 2017 Intel Corporation -version = 2 +version = 3 sources = files('rte_sched.c', 'rte_red.c', 'rte_approx.c') headers = files('rte_sched.h', 'rte_sched_common.h', 'rte_red.h', 'rte_approx.h') diff --git a/lib/librte_sched/rte_sched.c b/lib/librte_sched/rte_sched.c index bc06bc3f4..eac995680 100644 --- a/lib/librte_sched/rte_sched.c +++ b/lib/librte_sched/rte_sched.c @@ -37,6 +37,8 @@ #define RTE_SCHED_TB_RATE_CONFIG_ERR (1e-7) #define RTE_SCHED_WRR_SHIFT 3 +#define RTE_SCHED_TRAFFIC_CLASS_BE (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1) +#define RTE_SCHED_MAX_QUEUES_PER_TC RTE_SCHED_BE_QUEUES_PER_PIPE #define RTE_SCHED_GRINDER_PCACHE_SIZE (64 / RTE_SCHED_QUEUES_PER_PIPE) #define RTE_SCHED_PIPE_INVALID UINT32_MAX #define RTE_SCHED_BMP_POS_INVALID UINT32_MAX @@ -84,8 +86,9 @@ struct rte_sched_pipe_profile { uint32_t tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; uint8_t tc_ov_weight; - /* Pipe queues */ - uint8_t wrr_cost[RTE_SCHED_QUEUES_PER_PIPE]; + /* Pipe best-effort traffic class queues */ + uint8_t n_be_queues; + uint8_t wrr_cost[RTE_SCHED_BE_QUEUES_PER_PIPE]; }; struct rte_sched_pipe { @@ -100,8 +103,10 @@ struct rte_sched_pipe { uint64_t tc_time; /* time of next update */ uint32_t tc_credits[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; + uint8_t n_be_queues; /* Best effort traffic class queues */ + /* Weighted Round Robin (WRR) */ - uint8_t wrr_tokens[RTE_SCHED_QUEUES_PER_PIPE]; + uint8_t wrr_tokens[RTE_SCHED_BE_QUEUES_PER_PIPE]; /* TC oversubscription */ uint32_t tc_ov_credits; @@ -153,16 +158,16 @@ struct rte_sched_grinder { uint32_t tc_index; struct rte_sched_queue *queue[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; struct rte_mbuf **qbase[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; - uint32_t qindex[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; - uint16_t qsize; + uint32_t qindex[RTE_SCHED_MAX_QUEUES_PER_TC]; + uint16_t qsize[RTE_SCHED_MAX_QUEUES_PER_TC]; uint32_t qmask; uint32_t qpos; struct rte_mbuf *pkt; /* 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]; + uint16_t wrr_tokens[RTE_SCHED_BE_QUEUES_PER_PIPE]; + uint16_t wrr_mask[RTE_SCHED_BE_QUEUES_PER_PIPE]; + uint8_t wrr_cost[RTE_SCHED_BE_QUEUES_PER_PIPE]; }; struct rte_sched_port { @@ -301,7 +306,6 @@ pipe_profile_check(struct rte_sched_pipe_params *params, if (params->wrr_weights[i] == 0) return -16; } - return 0; } @@ -483,7 +487,7 @@ rte_sched_port_log_pipe_profile(struct rte_sched_port *port, uint32_t i) " Token bucket: period = %u, credits per period = %u, size = %u\n" " Traffic classes: period = %u, credits per period = [%u, %u, %u, %u]\n" " Traffic class 3 oversubscription: weight = %hhu\n" - " WRR cost: [%hhu, %hhu, %hhu, %hhu], [%hhu, %hhu, %hhu, %hhu], [%hhu, %hhu, %hhu, %hhu], [%hhu, %hhu, %hhu, %hhu]\n", + " WRR cost: [%hhu, %hhu, %hhu, %hhu]\n", i, /* Token bucket */ @@ -502,10 +506,7 @@ rte_sched_port_log_pipe_profile(struct rte_sched_port *port, uint32_t i) p->tc_ov_weight, /* WRR */ - p->wrr_cost[ 0], p->wrr_cost[ 1], p->wrr_cost[ 2], p->wrr_cost[ 3], - p->wrr_cost[ 4], p->wrr_cost[ 5], p->wrr_cost[ 6], p->wrr_cost[ 7], - p->wrr_cost[ 8], p->wrr_cost[ 9], p->wrr_cost[10], p->wrr_cost[11], - p->wrr_cost[12], p->wrr_cost[13], p->wrr_cost[14], p->wrr_cost[15]); + p->wrr_cost[0], p->wrr_cost[1], p->wrr_cost[2], p->wrr_cost[3]); } static inline uint64_t @@ -519,10 +520,12 @@ rte_sched_time_ms_to_bytes(uint32_t time_ms, uint32_t rate) } static void -rte_sched_pipe_profile_convert(struct rte_sched_pipe_params *src, +rte_sched_pipe_profile_convert(struct rte_sched_port *port, + struct rte_sched_pipe_params *src, struct rte_sched_pipe_profile *dst, uint32_t rate) { + uint32_t wrr_cost[RTE_SCHED_BE_QUEUES_PER_PIPE]; uint32_t i; /* Token Bucket */ @@ -553,18 +556,36 @@ rte_sched_pipe_profile_convert(struct rte_sched_pipe_params *src, dst->tc_ov_weight = src->tc_ov_weight; #endif - /* WRR */ - for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { - uint32_t wrr_cost[RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS]; - uint32_t lcd, lcd1, lcd2; - uint32_t qindex; + /* WRR queues */ + for (i = 0; i < RTE_SCHED_BE_QUEUES_PER_PIPE; i++) + if (port->qsize[i]) + dst->n_be_queues++; + + if (dst->n_be_queues == 1) + dst->wrr_cost[0] = src->wrr_weights[0]; + + if (dst->n_be_queues == 2) { + uint32_t lcd; + + wrr_cost[0] = src->wrr_weights[0]; + wrr_cost[1] = src->wrr_weights[1]; + + lcd = rte_get_lcd(wrr_cost[0], wrr_cost[1]); + + wrr_cost[0] = lcd / wrr_cost[0]; + wrr_cost[1] = lcd / wrr_cost[1]; - qindex = i * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; + dst->wrr_cost[0] = (uint8_t) wrr_cost[0]; + dst->wrr_cost[1] = (uint8_t) wrr_cost[1]; + } - wrr_cost[0] = src->wrr_weights[qindex]; - wrr_cost[1] = src->wrr_weights[qindex + 1]; - wrr_cost[2] = src->wrr_weights[qindex + 2]; - wrr_cost[3] = src->wrr_weights[qindex + 3]; + if (dst->n_be_queues == 4) { + uint32_t lcd1, lcd2, lcd; + + wrr_cost[0] = src->wrr_weights[0]; + wrr_cost[1] = src->wrr_weights[1]; + wrr_cost[2] = src->wrr_weights[2]; + wrr_cost[3] = src->wrr_weights[3]; lcd1 = rte_get_lcd(wrr_cost[0], wrr_cost[1]); lcd2 = rte_get_lcd(wrr_cost[2], wrr_cost[3]); @@ -575,10 +596,10 @@ rte_sched_pipe_profile_convert(struct rte_sched_pipe_params *src, wrr_cost[2] = lcd / wrr_cost[2]; wrr_cost[3] = lcd / wrr_cost[3]; - dst->wrr_cost[qindex] = (uint8_t) wrr_cost[0]; - dst->wrr_cost[qindex + 1] = (uint8_t) wrr_cost[1]; - dst->wrr_cost[qindex + 2] = (uint8_t) wrr_cost[2]; - dst->wrr_cost[qindex + 3] = (uint8_t) wrr_cost[3]; + dst->wrr_cost[0] = (uint8_t) wrr_cost[0]; + dst->wrr_cost[1] = (uint8_t) wrr_cost[1]; + dst->wrr_cost[2] = (uint8_t) wrr_cost[2]; + dst->wrr_cost[3] = (uint8_t) wrr_cost[3]; } } @@ -592,7 +613,7 @@ rte_sched_port_config_pipe_profile_table(struct rte_sched_port *port, struct rte_sched_pipe_params *src = params->pipe_profiles + i; struct rte_sched_pipe_profile *dst = port->pipe_profiles + i; - rte_sched_pipe_profile_convert(src, dst, params->rate); + rte_sched_pipe_profile_convert(port, src, dst, params->rate); rte_sched_port_log_pipe_profile(port, i); } @@ -976,7 +997,7 @@ rte_sched_port_pipe_profile_add(struct rte_sched_port *port, return status; pp = &port->pipe_profiles[port->n_pipe_profiles]; - rte_sched_pipe_profile_convert(params, pp, port->rate); + rte_sched_pipe_profile_convert(port, params, pp, port->rate); /* Pipe profile not exists */ for (i = 0; i < port->n_pipe_profiles; i++) @@ -1715,6 +1736,7 @@ grinder_schedule(struct rte_sched_port *port, uint32_t pos) struct rte_sched_queue *queue = grinder->queue[grinder->qpos]; struct rte_mbuf *pkt = grinder->pkt; uint32_t pkt_len = pkt->pkt_len + port->frame_overhead; + int be_tc_active; if (!grinder_credits_check(port, pos)) return 0; @@ -1725,13 +1747,18 @@ grinder_schedule(struct rte_sched_port *port, uint32_t pos) /* Send packet */ port->pkts_out[port->n_pkts_out++] = pkt; queue->qr++; - grinder->wrr_tokens[grinder->qpos] += pkt_len * grinder->wrr_cost[grinder->qpos]; + + be_tc_active = (grinder->tc_index == RTE_SCHED_TRAFFIC_CLASS_BE); + grinder->wrr_tokens[grinder->qpos] += + pkt_len * grinder->wrr_cost[grinder->qpos] * be_tc_active; + if (queue->qr == queue->qw) { uint32_t qindex = grinder->qindex[grinder->qpos]; rte_bitmap_clear(port->bmp, qindex); grinder->qmask &= ~(1 << grinder->qpos); - grinder->wrr_mask[grinder->qpos] = 0; + if (be_tc_active) + grinder->wrr_mask[grinder->qpos] = 0; rte_sched_port_set_queue_empty_timestamp(port, qindex); } @@ -1877,7 +1904,7 @@ grinder_next_tc(struct rte_sched_port *port, uint32_t pos) grinder->tc_index = (qindex >> 2) & 0x3; grinder->qmask = grinder->tccache_qmask[grinder->tccache_r]; - grinder->qsize = qsize; + grinder->qsize[grinder->tc_index] = qsize; grinder->qindex[0] = qindex; grinder->qindex[1] = qindex + 1; @@ -1962,26 +1989,16 @@ grinder_wrr_load(struct rte_sched_port *port, uint32_t pos) struct rte_sched_grinder *grinder = port->grinder + pos; struct rte_sched_pipe *pipe = grinder->pipe; struct rte_sched_pipe_profile *pipe_params = grinder->pipe_params; - uint32_t tc_index = grinder->tc_index; uint32_t qmask = grinder->qmask; - uint32_t qindex; - - qindex = tc_index * 4; - - grinder->wrr_tokens[0] = ((uint16_t) pipe->wrr_tokens[qindex]) << RTE_SCHED_WRR_SHIFT; - grinder->wrr_tokens[1] = ((uint16_t) pipe->wrr_tokens[qindex + 1]) << RTE_SCHED_WRR_SHIFT; - grinder->wrr_tokens[2] = ((uint16_t) pipe->wrr_tokens[qindex + 2]) << RTE_SCHED_WRR_SHIFT; - grinder->wrr_tokens[3] = ((uint16_t) pipe->wrr_tokens[qindex + 3]) << RTE_SCHED_WRR_SHIFT; - - grinder->wrr_mask[0] = (qmask & 0x1) * 0xFFFF; - grinder->wrr_mask[1] = ((qmask >> 1) & 0x1) * 0xFFFF; - grinder->wrr_mask[2] = ((qmask >> 2) & 0x1) * 0xFFFF; - grinder->wrr_mask[3] = ((qmask >> 3) & 0x1) * 0xFFFF; + uint32_t qindex = grinder->qindex[0]; + uint32_t i; - grinder->wrr_cost[0] = pipe_params->wrr_cost[qindex]; - grinder->wrr_cost[1] = pipe_params->wrr_cost[qindex + 1]; - grinder->wrr_cost[2] = pipe_params->wrr_cost[qindex + 2]; - grinder->wrr_cost[3] = pipe_params->wrr_cost[qindex + 3]; + for (i = 0; i < pipe->n_be_queues; i++) { + grinder->wrr_tokens[i] = + ((uint16_t) pipe->wrr_tokens[qindex + i]) << RTE_SCHED_WRR_SHIFT; + grinder->wrr_mask[i] = ((qmask >> i) & 0x1) * 0xFFFF; + grinder->wrr_cost[i] = pipe_params->wrr_cost[qindex + i]; + } } static inline void @@ -1989,19 +2006,12 @@ grinder_wrr_store(struct rte_sched_port *port, uint32_t pos) { struct rte_sched_grinder *grinder = port->grinder + pos; struct rte_sched_pipe *pipe = grinder->pipe; - uint32_t tc_index = grinder->tc_index; - uint32_t qindex; - - qindex = tc_index * 4; + uint32_t i; - pipe->wrr_tokens[qindex] = (grinder->wrr_tokens[0] & grinder->wrr_mask[0]) - >> RTE_SCHED_WRR_SHIFT; - pipe->wrr_tokens[qindex + 1] = (grinder->wrr_tokens[1] & grinder->wrr_mask[1]) - >> RTE_SCHED_WRR_SHIFT; - pipe->wrr_tokens[qindex + 2] = (grinder->wrr_tokens[2] & grinder->wrr_mask[2]) - >> RTE_SCHED_WRR_SHIFT; - pipe->wrr_tokens[qindex + 3] = (grinder->wrr_tokens[3] & grinder->wrr_mask[3]) - >> RTE_SCHED_WRR_SHIFT; + for (i = 0; i < pipe->n_be_queues; i++) + pipe->wrr_tokens[i] = + (grinder->wrr_tokens[i] & grinder->wrr_mask[i]) >> + RTE_SCHED_WRR_SHIFT; } static inline void @@ -2040,22 +2050,31 @@ static inline void grinder_prefetch_tc_queue_arrays(struct rte_sched_port *port, uint32_t pos) { struct rte_sched_grinder *grinder = port->grinder + pos; - uint16_t qsize, qr[4]; + struct rte_sched_pipe *pipe = grinder->pipe; + struct rte_sched_queue *queue; + uint32_t i; + uint16_t qsize, qr[RTE_SCHED_MAX_QUEUES_PER_TC]; - qsize = grinder->qsize; - qr[0] = grinder->queue[0]->qr & (qsize - 1); - qr[1] = grinder->queue[1]->qr & (qsize - 1); - qr[2] = grinder->queue[2]->qr & (qsize - 1); - qr[3] = grinder->queue[3]->qr & (qsize - 1); + grinder->qpos = 0; + if (grinder->tc_index < RTE_SCHED_TRAFFIC_CLASS_BE) { + queue = grinder->queue[0]; + qsize = grinder->qsize[0]; + qr[0] = queue->qr & (qsize - 1); - rte_prefetch0(grinder->qbase[0] + qr[0]); - rte_prefetch0(grinder->qbase[1] + qr[1]); + rte_prefetch0(grinder->qbase[0] + qr[0]); + return; + } + + for (i = 0; i < pipe->n_be_queues; i++) { + queue = grinder->queue[i]; + qsize = grinder->qsize[i]; + qr[i] = queue->qr & (qsize - 1); + + rte_prefetch0(grinder->qbase[i] + qr[i]); + } grinder_wrr_load(port, pos); grinder_wrr(port, pos); - - rte_prefetch0(grinder->qbase[2] + qr[2]); - rte_prefetch0(grinder->qbase[3] + qr[3]); } static inline void @@ -2064,7 +2083,7 @@ grinder_prefetch_mbuf(struct rte_sched_port *port, uint32_t pos) struct rte_sched_grinder *grinder = port->grinder + pos; uint32_t qpos = grinder->qpos; struct rte_mbuf **qbase = grinder->qbase[qpos]; - uint16_t qsize = grinder->qsize; + uint16_t qsize = grinder->qsize[qpos]; uint16_t qr = grinder->queue[qpos]->qr & (qsize - 1); grinder->pkt = qbase[qr]; @@ -2118,18 +2137,24 @@ grinder_handle(struct rte_sched_port *port, uint32_t pos) case e_GRINDER_READ_MBUF: { - uint32_t result = 0; + uint32_t wrr_active, result = 0; result = grinder_schedule(port, pos); + wrr_active = (grinder->tc_index == RTE_SCHED_TRAFFIC_CLASS_BE); + /* Look for next packet within the same TC */ if (result && grinder->qmask) { - grinder_wrr(port, pos); + if (wrr_active) + grinder_wrr(port, pos); + grinder_prefetch_mbuf(port, pos); return 1; } - grinder_wrr_store(port, pos); + + if (wrr_active) + grinder_wrr_store(port, pos); /* Look for another active TC within same pipe */ if (grinder_next_tc(port, pos)) { diff --git a/lib/librte_sched/rte_sched.h b/lib/librte_sched/rte_sched.h index d61dda9f5..2a935998a 100644 --- a/lib/librte_sched/rte_sched.h +++ b/lib/librte_sched/rte_sched.h @@ -66,6 +66,22 @@ extern "C" { #include "rte_red.h" #endif +/** Maximum number of queues per pipe. + * Note that the multiple queues (power of 2) can only be assigned to + * lowest priority (best-effort) traffic class. Other higher priority traffic + * classes can only have one queue. + * Can not change. + * + * @see struct rte_sched_port_params + */ +#define RTE_SCHED_QUEUES_PER_PIPE 16 + +/** Number of WRR queues for best-effort traffic class per pipe. + * + * @see struct rte_sched_pipe_params + */ +#define RTE_SCHED_BE_QUEUES_PER_PIPE 4 + /** Number of traffic classes per pipe (as well as subport). * Cannot be changed. */ @@ -74,11 +90,6 @@ extern "C" { /** Number of queues per pipe traffic class. Cannot be changed. */ #define RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS 4 -/** Number of queues per pipe. */ -#define RTE_SCHED_QUEUES_PER_PIPE \ - (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE * \ - RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS) - /** Maximum number of pipe profiles that can be defined per port. * Compile-time configurable. */ @@ -165,7 +176,7 @@ struct rte_sched_pipe_params { #endif /* Pipe queues */ - uint8_t wrr_weights[RTE_SCHED_QUEUES_PER_PIPE]; /**< WRR weights */ + uint8_t wrr_weights[RTE_SCHED_BE_QUEUES_PER_PIPE]; /**< WRR weights */ }; /** Queue statistics */ -- 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* [dpdk-dev] [PATCH v4 00/11] sched: feature enhancements 2019-07-11 10:26 ` [dpdk-dev] [PATCH v3 01/11] sched: remove wrr from strict priority tc queues Jasvinder Singh @ 2019-07-12 9:57 ` Jasvinder Singh 2019-07-12 9:57 ` [dpdk-dev] [PATCH v4 01/11] sched: remove wrr from strict priority tc queues Jasvinder Singh ` (10 more replies) 0 siblings, 11 replies; 163+ messages in thread From: Jasvinder Singh @ 2019-07-12 9:57 UTC (permalink / raw) To: dev; +Cc: cristian.dumitrescu This patchset refactors the dpdk qos sched library to allow flexibile configuration of the pipe traffic classes and queue sizes. Currently, each pipe has 16 queues hardwired into 4 TCs scheduled with strict priority, and each TC has exactly with 4 queues that are scheduled with Weighted Fair Queuing (WFQ). Instead of hardwiring queues to traffic class within the specific pipe, the new implementation allows more flexible/configurable split of pipe queues between strict priority (SP) and best-effort (BE) traffic classes along with the support of more number of traffic classes i.e. max 16. All the high priority TCs (TC1, TC2, ...) have exactly 1 queue, while the lowest priority BE TC, has 1, 4 or 8 queues. This is justified by the fact that all the high priority TCs are fully provisioned (small to medium traffic rates), while most of the traffic fits into the BE class, which is typically oversubscribed. Furthermore, this change allows to use less than 16 queues per pipe when not all the 16 queues are needed. Therefore, no memory will be allocated to the queues that are not needed. v4: - fix build errors - fix checkpatch errors v3: - remove code related to subport level configuration of the pipe - remove tc oversubscription flag from struct rte_sched_pipe_params - replace RTE_SCHED_PIPE_PROFILES_PER_PORT with port param field v2: - fix bug in subport parameters check - remove redundant RTE_SCHED_SUBPORT_PER_PORT macro - fix bug in grinder_scheduler function - improve doxygen comments - add error log information Jasvinder Singh (11): sched: remove wrr from strict priority tc queues sched: add config flexibility to tc queue sizes sched: add max pipe profiles config in run time sched: rename tc3 params to best-effort tc sched: improve error log messages sched: improve doxygen comments net/softnic: add config flexibility to softnic tm test_sched: modify tests for config flexibility examples/ip_pipeline: add config flexibility to tm function examples/qos_sched: add tc and queue config flexibility sched: remove redundant macros app/test/test_sched.c | 12 +- doc/guides/rel_notes/release_19_08.rst | 10 +- drivers/net/softnic/rte_eth_softnic.c | 131 +++ drivers/net/softnic/rte_eth_softnic_cli.c | 448 +++++++++- .../net/softnic/rte_eth_softnic_internals.h | 8 +- drivers/net/softnic/rte_eth_softnic_tm.c | 64 +- examples/ip_pipeline/cli.c | 45 +- examples/ip_pipeline/tmgr.c | 2 +- examples/ip_pipeline/tmgr.h | 4 +- examples/qos_sched/app_thread.c | 9 +- examples/qos_sched/cfg_file.c | 119 ++- examples/qos_sched/init.c | 65 +- examples/qos_sched/main.h | 4 + examples/qos_sched/profile.cfg | 66 +- examples/qos_sched/profile_ov.cfg | 54 +- examples/qos_sched/stats.c | 517 ++++++----- lib/librte_pipeline/rte_table_action.c | 1 - lib/librte_pipeline/rte_table_action.h | 4 +- lib/librte_sched/Makefile | 2 +- lib/librte_sched/meson.build | 2 +- lib/librte_sched/rte_sched.c | 840 +++++++++++------- lib/librte_sched/rte_sched.h | 182 ++-- 22 files changed, 1820 insertions(+), 769 deletions(-) -- 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* [dpdk-dev] [PATCH v4 01/11] sched: remove wrr from strict priority tc queues 2019-07-12 9:57 ` [dpdk-dev] [PATCH v4 00/11] sched: feature enhancements Jasvinder Singh @ 2019-07-12 9:57 ` Jasvinder Singh 2019-07-15 23:50 ` Dumitrescu, Cristian 2019-07-17 14:42 ` [dpdk-dev] [PATCH v5 00/11] sched: feature enhancements Jasvinder Singh 2019-07-12 9:57 ` [dpdk-dev] [PATCH v4 02/11] sched: add config flexibility to tc queue sizes Jasvinder Singh ` (9 subsequent siblings) 10 siblings, 2 replies; 163+ messages in thread From: Jasvinder Singh @ 2019-07-12 9:57 UTC (permalink / raw) To: dev; +Cc: cristian.dumitrescu, Abraham Tovar, Lukasz Krakowiak All higher priority traffic classes contain only one queue, thus remove wrr function for them. The lowest priority best-effort traffic class conitnue to have multiple queues and packet are scheduled from its queues using wrr function. Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com> Signed-off-by: Abraham Tovar <abrahamx.tovar@intel.com> Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com> --- app/test/test_sched.c | 2 +- examples/qos_sched/init.c | 2 +- lib/librte_sched/Makefile | 2 +- lib/librte_sched/meson.build | 2 +- lib/librte_sched/rte_sched.c | 182 ++++++++++++++++++++--------------- lib/librte_sched/rte_sched.h | 23 +++-- 6 files changed, 124 insertions(+), 89 deletions(-) diff --git a/app/test/test_sched.c b/app/test/test_sched.c index 49bb9ea6f..36fa2d425 100644 --- a/app/test/test_sched.c +++ b/app/test/test_sched.c @@ -40,7 +40,7 @@ static struct rte_sched_pipe_params pipe_profile[] = { .tc_rate = {305175, 305175, 305175, 305175}, .tc_period = 40, - .wrr_weights = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, + .wrr_weights = {1, 1, 1, 1}, }, }; diff --git a/examples/qos_sched/init.c b/examples/qos_sched/init.c index 1209bd7ce..6b63d4e0e 100644 --- a/examples/qos_sched/init.c +++ b/examples/qos_sched/init.c @@ -186,7 +186,7 @@ static struct rte_sched_pipe_params pipe_profiles[RTE_SCHED_PIPE_PROFILES_PER_PO .tc_ov_weight = 1, #endif - .wrr_weights = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, + .wrr_weights = {1, 1, 1, 1}, }, }; diff --git a/lib/librte_sched/Makefile b/lib/librte_sched/Makefile index 644fd9d15..3d7f410e1 100644 --- a/lib/librte_sched/Makefile +++ b/lib/librte_sched/Makefile @@ -18,7 +18,7 @@ LDLIBS += -lrte_timer EXPORT_MAP := rte_sched_version.map -LIBABIVER := 2 +LIBABIVER := 3 # # all source are stored in SRCS-y diff --git a/lib/librte_sched/meson.build b/lib/librte_sched/meson.build index 8e989e5f6..59d43c6d8 100644 --- a/lib/librte_sched/meson.build +++ b/lib/librte_sched/meson.build @@ -1,7 +1,7 @@ # SPDX-License-Identifier: BSD-3-Clause # Copyright(c) 2017 Intel Corporation -version = 2 +version = 3 sources = files('rte_sched.c', 'rte_red.c', 'rte_approx.c') headers = files('rte_sched.h', 'rte_sched_common.h', 'rte_red.h', 'rte_approx.h') diff --git a/lib/librte_sched/rte_sched.c b/lib/librte_sched/rte_sched.c index bc06bc3f4..b1f521794 100644 --- a/lib/librte_sched/rte_sched.c +++ b/lib/librte_sched/rte_sched.c @@ -37,6 +37,8 @@ #define RTE_SCHED_TB_RATE_CONFIG_ERR (1e-7) #define RTE_SCHED_WRR_SHIFT 3 +#define RTE_SCHED_TRAFFIC_CLASS_BE (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1) +#define RTE_SCHED_MAX_QUEUES_PER_TC RTE_SCHED_BE_QUEUES_PER_PIPE #define RTE_SCHED_GRINDER_PCACHE_SIZE (64 / RTE_SCHED_QUEUES_PER_PIPE) #define RTE_SCHED_PIPE_INVALID UINT32_MAX #define RTE_SCHED_BMP_POS_INVALID UINT32_MAX @@ -84,8 +86,9 @@ struct rte_sched_pipe_profile { uint32_t tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; uint8_t tc_ov_weight; - /* Pipe queues */ - uint8_t wrr_cost[RTE_SCHED_QUEUES_PER_PIPE]; + /* Pipe best-effort traffic class queues */ + uint8_t n_be_queues; + uint8_t wrr_cost[RTE_SCHED_BE_QUEUES_PER_PIPE]; }; struct rte_sched_pipe { @@ -100,8 +103,10 @@ struct rte_sched_pipe { uint64_t tc_time; /* time of next update */ uint32_t tc_credits[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; + uint8_t n_be_queues; /* Best effort traffic class queues */ + /* Weighted Round Robin (WRR) */ - uint8_t wrr_tokens[RTE_SCHED_QUEUES_PER_PIPE]; + uint8_t wrr_tokens[RTE_SCHED_BE_QUEUES_PER_PIPE]; /* TC oversubscription */ uint32_t tc_ov_credits; @@ -153,16 +158,16 @@ struct rte_sched_grinder { uint32_t tc_index; struct rte_sched_queue *queue[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; struct rte_mbuf **qbase[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; - uint32_t qindex[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; - uint16_t qsize; + uint32_t qindex[RTE_SCHED_MAX_QUEUES_PER_TC]; + uint16_t qsize[RTE_SCHED_MAX_QUEUES_PER_TC]; uint32_t qmask; uint32_t qpos; struct rte_mbuf *pkt; /* 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]; + uint16_t wrr_tokens[RTE_SCHED_BE_QUEUES_PER_PIPE]; + uint16_t wrr_mask[RTE_SCHED_BE_QUEUES_PER_PIPE]; + uint8_t wrr_cost[RTE_SCHED_BE_QUEUES_PER_PIPE]; }; struct rte_sched_port { @@ -301,7 +306,6 @@ pipe_profile_check(struct rte_sched_pipe_params *params, if (params->wrr_weights[i] == 0) return -16; } - return 0; } @@ -483,7 +487,7 @@ rte_sched_port_log_pipe_profile(struct rte_sched_port *port, uint32_t i) " Token bucket: period = %u, credits per period = %u, size = %u\n" " Traffic classes: period = %u, credits per period = [%u, %u, %u, %u]\n" " Traffic class 3 oversubscription: weight = %hhu\n" - " WRR cost: [%hhu, %hhu, %hhu, %hhu], [%hhu, %hhu, %hhu, %hhu], [%hhu, %hhu, %hhu, %hhu], [%hhu, %hhu, %hhu, %hhu]\n", + " WRR cost: [%hhu, %hhu, %hhu, %hhu]\n", i, /* Token bucket */ @@ -502,10 +506,7 @@ rte_sched_port_log_pipe_profile(struct rte_sched_port *port, uint32_t i) p->tc_ov_weight, /* WRR */ - p->wrr_cost[ 0], p->wrr_cost[ 1], p->wrr_cost[ 2], p->wrr_cost[ 3], - p->wrr_cost[ 4], p->wrr_cost[ 5], p->wrr_cost[ 6], p->wrr_cost[ 7], - p->wrr_cost[ 8], p->wrr_cost[ 9], p->wrr_cost[10], p->wrr_cost[11], - p->wrr_cost[12], p->wrr_cost[13], p->wrr_cost[14], p->wrr_cost[15]); + p->wrr_cost[0], p->wrr_cost[1], p->wrr_cost[2], p->wrr_cost[3]); } static inline uint64_t @@ -519,10 +520,12 @@ rte_sched_time_ms_to_bytes(uint32_t time_ms, uint32_t rate) } static void -rte_sched_pipe_profile_convert(struct rte_sched_pipe_params *src, +rte_sched_pipe_profile_convert(struct rte_sched_port *port, + struct rte_sched_pipe_params *src, struct rte_sched_pipe_profile *dst, uint32_t rate) { + uint32_t wrr_cost[RTE_SCHED_BE_QUEUES_PER_PIPE]; uint32_t i; /* Token Bucket */ @@ -553,18 +556,36 @@ rte_sched_pipe_profile_convert(struct rte_sched_pipe_params *src, dst->tc_ov_weight = src->tc_ov_weight; #endif - /* WRR */ - for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { - uint32_t wrr_cost[RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS]; - uint32_t lcd, lcd1, lcd2; - uint32_t qindex; + /* WRR queues */ + for (i = 0; i < RTE_SCHED_BE_QUEUES_PER_PIPE; i++) + if (port->qsize[i]) + dst->n_be_queues++; + + if (dst->n_be_queues == 1) + dst->wrr_cost[0] = src->wrr_weights[0]; + + if (dst->n_be_queues == 2) { + uint32_t lcd; + + wrr_cost[0] = src->wrr_weights[0]; + wrr_cost[1] = src->wrr_weights[1]; + + lcd = rte_get_lcd(wrr_cost[0], wrr_cost[1]); + + wrr_cost[0] = lcd / wrr_cost[0]; + wrr_cost[1] = lcd / wrr_cost[1]; - qindex = i * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; + dst->wrr_cost[0] = (uint8_t) wrr_cost[0]; + dst->wrr_cost[1] = (uint8_t) wrr_cost[1]; + } - wrr_cost[0] = src->wrr_weights[qindex]; - wrr_cost[1] = src->wrr_weights[qindex + 1]; - wrr_cost[2] = src->wrr_weights[qindex + 2]; - wrr_cost[3] = src->wrr_weights[qindex + 3]; + if (dst->n_be_queues == 4) { + uint32_t lcd1, lcd2, lcd; + + wrr_cost[0] = src->wrr_weights[0]; + wrr_cost[1] = src->wrr_weights[1]; + wrr_cost[2] = src->wrr_weights[2]; + wrr_cost[3] = src->wrr_weights[3]; lcd1 = rte_get_lcd(wrr_cost[0], wrr_cost[1]); lcd2 = rte_get_lcd(wrr_cost[2], wrr_cost[3]); @@ -575,10 +596,10 @@ rte_sched_pipe_profile_convert(struct rte_sched_pipe_params *src, wrr_cost[2] = lcd / wrr_cost[2]; wrr_cost[3] = lcd / wrr_cost[3]; - dst->wrr_cost[qindex] = (uint8_t) wrr_cost[0]; - dst->wrr_cost[qindex + 1] = (uint8_t) wrr_cost[1]; - dst->wrr_cost[qindex + 2] = (uint8_t) wrr_cost[2]; - dst->wrr_cost[qindex + 3] = (uint8_t) wrr_cost[3]; + dst->wrr_cost[0] = (uint8_t) wrr_cost[0]; + dst->wrr_cost[1] = (uint8_t) wrr_cost[1]; + dst->wrr_cost[2] = (uint8_t) wrr_cost[2]; + dst->wrr_cost[3] = (uint8_t) wrr_cost[3]; } } @@ -592,7 +613,7 @@ rte_sched_port_config_pipe_profile_table(struct rte_sched_port *port, struct rte_sched_pipe_params *src = params->pipe_profiles + i; struct rte_sched_pipe_profile *dst = port->pipe_profiles + i; - rte_sched_pipe_profile_convert(src, dst, params->rate); + rte_sched_pipe_profile_convert(port, src, dst, params->rate); rte_sched_port_log_pipe_profile(port, i); } @@ -976,7 +997,7 @@ rte_sched_port_pipe_profile_add(struct rte_sched_port *port, return status; pp = &port->pipe_profiles[port->n_pipe_profiles]; - rte_sched_pipe_profile_convert(params, pp, port->rate); + rte_sched_pipe_profile_convert(port, params, pp, port->rate); /* Pipe profile not exists */ for (i = 0; i < port->n_pipe_profiles; i++) @@ -1715,6 +1736,7 @@ grinder_schedule(struct rte_sched_port *port, uint32_t pos) struct rte_sched_queue *queue = grinder->queue[grinder->qpos]; struct rte_mbuf *pkt = grinder->pkt; uint32_t pkt_len = pkt->pkt_len + port->frame_overhead; + int be_tc_active; if (!grinder_credits_check(port, pos)) return 0; @@ -1725,13 +1747,18 @@ grinder_schedule(struct rte_sched_port *port, uint32_t pos) /* Send packet */ port->pkts_out[port->n_pkts_out++] = pkt; queue->qr++; - grinder->wrr_tokens[grinder->qpos] += pkt_len * grinder->wrr_cost[grinder->qpos]; + + be_tc_active = (grinder->tc_index == RTE_SCHED_TRAFFIC_CLASS_BE); + grinder->wrr_tokens[grinder->qpos] += + pkt_len * grinder->wrr_cost[grinder->qpos] * be_tc_active; + if (queue->qr == queue->qw) { uint32_t qindex = grinder->qindex[grinder->qpos]; rte_bitmap_clear(port->bmp, qindex); grinder->qmask &= ~(1 << grinder->qpos); - grinder->wrr_mask[grinder->qpos] = 0; + if (be_tc_active) + grinder->wrr_mask[grinder->qpos] = 0; rte_sched_port_set_queue_empty_timestamp(port, qindex); } @@ -1877,7 +1904,7 @@ grinder_next_tc(struct rte_sched_port *port, uint32_t pos) grinder->tc_index = (qindex >> 2) & 0x3; grinder->qmask = grinder->tccache_qmask[grinder->tccache_r]; - grinder->qsize = qsize; + grinder->qsize[grinder->tc_index] = qsize; grinder->qindex[0] = qindex; grinder->qindex[1] = qindex + 1; @@ -1962,26 +1989,15 @@ grinder_wrr_load(struct rte_sched_port *port, uint32_t pos) struct rte_sched_grinder *grinder = port->grinder + pos; struct rte_sched_pipe *pipe = grinder->pipe; struct rte_sched_pipe_profile *pipe_params = grinder->pipe_params; - uint32_t tc_index = grinder->tc_index; uint32_t qmask = grinder->qmask; - uint32_t qindex; - - qindex = tc_index * 4; - - grinder->wrr_tokens[0] = ((uint16_t) pipe->wrr_tokens[qindex]) << RTE_SCHED_WRR_SHIFT; - grinder->wrr_tokens[1] = ((uint16_t) pipe->wrr_tokens[qindex + 1]) << RTE_SCHED_WRR_SHIFT; - grinder->wrr_tokens[2] = ((uint16_t) pipe->wrr_tokens[qindex + 2]) << RTE_SCHED_WRR_SHIFT; - grinder->wrr_tokens[3] = ((uint16_t) pipe->wrr_tokens[qindex + 3]) << RTE_SCHED_WRR_SHIFT; - - grinder->wrr_mask[0] = (qmask & 0x1) * 0xFFFF; - grinder->wrr_mask[1] = ((qmask >> 1) & 0x1) * 0xFFFF; - grinder->wrr_mask[2] = ((qmask >> 2) & 0x1) * 0xFFFF; - grinder->wrr_mask[3] = ((qmask >> 3) & 0x1) * 0xFFFF; + uint32_t i; - grinder->wrr_cost[0] = pipe_params->wrr_cost[qindex]; - grinder->wrr_cost[1] = pipe_params->wrr_cost[qindex + 1]; - grinder->wrr_cost[2] = pipe_params->wrr_cost[qindex + 2]; - grinder->wrr_cost[3] = pipe_params->wrr_cost[qindex + 3]; + for (i = 0; i < pipe->n_be_queues; i++) { + grinder->wrr_tokens[i] = + ((uint16_t) pipe->wrr_tokens[i]) << RTE_SCHED_WRR_SHIFT; + grinder->wrr_mask[i] = ((qmask >> i) & 0x1) * 0xFFFF; + grinder->wrr_cost[i] = pipe_params->wrr_cost[i]; + } } static inline void @@ -1989,19 +2005,12 @@ grinder_wrr_store(struct rte_sched_port *port, uint32_t pos) { struct rte_sched_grinder *grinder = port->grinder + pos; struct rte_sched_pipe *pipe = grinder->pipe; - uint32_t tc_index = grinder->tc_index; - uint32_t qindex; - - qindex = tc_index * 4; + uint32_t i; - pipe->wrr_tokens[qindex] = (grinder->wrr_tokens[0] & grinder->wrr_mask[0]) - >> RTE_SCHED_WRR_SHIFT; - pipe->wrr_tokens[qindex + 1] = (grinder->wrr_tokens[1] & grinder->wrr_mask[1]) - >> RTE_SCHED_WRR_SHIFT; - pipe->wrr_tokens[qindex + 2] = (grinder->wrr_tokens[2] & grinder->wrr_mask[2]) - >> RTE_SCHED_WRR_SHIFT; - pipe->wrr_tokens[qindex + 3] = (grinder->wrr_tokens[3] & grinder->wrr_mask[3]) - >> RTE_SCHED_WRR_SHIFT; + for (i = 0; i < pipe->n_be_queues; i++) + pipe->wrr_tokens[i] = + (grinder->wrr_tokens[i] & grinder->wrr_mask[i]) >> + RTE_SCHED_WRR_SHIFT; } static inline void @@ -2040,22 +2049,31 @@ static inline void grinder_prefetch_tc_queue_arrays(struct rte_sched_port *port, uint32_t pos) { struct rte_sched_grinder *grinder = port->grinder + pos; - uint16_t qsize, qr[4]; + struct rte_sched_pipe *pipe = grinder->pipe; + struct rte_sched_queue *queue; + uint32_t i; + uint16_t qsize, qr[RTE_SCHED_MAX_QUEUES_PER_TC]; - qsize = grinder->qsize; - qr[0] = grinder->queue[0]->qr & (qsize - 1); - qr[1] = grinder->queue[1]->qr & (qsize - 1); - qr[2] = grinder->queue[2]->qr & (qsize - 1); - qr[3] = grinder->queue[3]->qr & (qsize - 1); + grinder->qpos = 0; + if (grinder->tc_index < RTE_SCHED_TRAFFIC_CLASS_BE) { + queue = grinder->queue[0]; + qsize = grinder->qsize[0]; + qr[0] = queue->qr & (qsize - 1); - rte_prefetch0(grinder->qbase[0] + qr[0]); - rte_prefetch0(grinder->qbase[1] + qr[1]); + rte_prefetch0(grinder->qbase[0] + qr[0]); + return; + } + + for (i = 0; i < pipe->n_be_queues; i++) { + queue = grinder->queue[i]; + qsize = grinder->qsize[i]; + qr[i] = queue->qr & (qsize - 1); + + rte_prefetch0(grinder->qbase[i] + qr[i]); + } grinder_wrr_load(port, pos); grinder_wrr(port, pos); - - rte_prefetch0(grinder->qbase[2] + qr[2]); - rte_prefetch0(grinder->qbase[3] + qr[3]); } static inline void @@ -2064,7 +2082,7 @@ grinder_prefetch_mbuf(struct rte_sched_port *port, uint32_t pos) struct rte_sched_grinder *grinder = port->grinder + pos; uint32_t qpos = grinder->qpos; struct rte_mbuf **qbase = grinder->qbase[qpos]; - uint16_t qsize = grinder->qsize; + uint16_t qsize = grinder->qsize[qpos]; uint16_t qr = grinder->queue[qpos]->qr & (qsize - 1); grinder->pkt = qbase[qr]; @@ -2118,18 +2136,24 @@ grinder_handle(struct rte_sched_port *port, uint32_t pos) case e_GRINDER_READ_MBUF: { - uint32_t result = 0; + uint32_t wrr_active, result = 0; result = grinder_schedule(port, pos); + wrr_active = (grinder->tc_index == RTE_SCHED_TRAFFIC_CLASS_BE); + /* Look for next packet within the same TC */ if (result && grinder->qmask) { - grinder_wrr(port, pos); + if (wrr_active) + grinder_wrr(port, pos); + grinder_prefetch_mbuf(port, pos); return 1; } - grinder_wrr_store(port, pos); + + if (wrr_active) + grinder_wrr_store(port, pos); /* Look for another active TC within same pipe */ if (grinder_next_tc(port, pos)) { diff --git a/lib/librte_sched/rte_sched.h b/lib/librte_sched/rte_sched.h index d61dda9f5..2a935998a 100644 --- a/lib/librte_sched/rte_sched.h +++ b/lib/librte_sched/rte_sched.h @@ -66,6 +66,22 @@ extern "C" { #include "rte_red.h" #endif +/** Maximum number of queues per pipe. + * Note that the multiple queues (power of 2) can only be assigned to + * lowest priority (best-effort) traffic class. Other higher priority traffic + * classes can only have one queue. + * Can not change. + * + * @see struct rte_sched_port_params + */ +#define RTE_SCHED_QUEUES_PER_PIPE 16 + +/** Number of WRR queues for best-effort traffic class per pipe. + * + * @see struct rte_sched_pipe_params + */ +#define RTE_SCHED_BE_QUEUES_PER_PIPE 4 + /** Number of traffic classes per pipe (as well as subport). * Cannot be changed. */ @@ -74,11 +90,6 @@ extern "C" { /** Number of queues per pipe traffic class. Cannot be changed. */ #define RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS 4 -/** Number of queues per pipe. */ -#define RTE_SCHED_QUEUES_PER_PIPE \ - (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE * \ - RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS) - /** Maximum number of pipe profiles that can be defined per port. * Compile-time configurable. */ @@ -165,7 +176,7 @@ struct rte_sched_pipe_params { #endif /* Pipe queues */ - uint8_t wrr_weights[RTE_SCHED_QUEUES_PER_PIPE]; /**< WRR weights */ + uint8_t wrr_weights[RTE_SCHED_BE_QUEUES_PER_PIPE]; /**< WRR weights */ }; /** Queue statistics */ -- 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* Re: [dpdk-dev] [PATCH v4 01/11] sched: remove wrr from strict priority tc queues 2019-07-12 9:57 ` [dpdk-dev] [PATCH v4 01/11] sched: remove wrr from strict priority tc queues Jasvinder Singh @ 2019-07-15 23:50 ` Dumitrescu, Cristian 2019-07-17 14:49 ` Singh, Jasvinder 2019-07-17 14:42 ` [dpdk-dev] [PATCH v5 00/11] sched: feature enhancements Jasvinder Singh 1 sibling, 1 reply; 163+ messages in thread From: Dumitrescu, Cristian @ 2019-07-15 23:50 UTC (permalink / raw) To: Singh, Jasvinder, dev; +Cc: Tovar, AbrahamX, Krakowiak, LukaszX > -----Original Message----- > From: Singh, Jasvinder > Sent: Friday, July 12, 2019 11:57 AM > To: dev@dpdk.org > Cc: Dumitrescu, Cristian <cristian.dumitrescu@intel.com>; Tovar, AbrahamX > <abrahamx.tovar@intel.com>; Krakowiak, LukaszX > <lukaszx.krakowiak@intel.com> > Subject: [PATCH v4 01/11] sched: remove wrr from strict priority tc queues > > All higher priority traffic classes contain only one queue, thus > remove wrr function for them. The lowest priority best-effort > traffic class conitnue to have multiple queues and packet are > scheduled from its queues using wrr function. > > Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com> > Signed-off-by: Abraham Tovar <abrahamx.tovar@intel.com> > Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com> > --- > app/test/test_sched.c | 2 +- > examples/qos_sched/init.c | 2 +- > lib/librte_sched/Makefile | 2 +- > lib/librte_sched/meson.build | 2 +- > lib/librte_sched/rte_sched.c | 182 ++++++++++++++++++++--------------- > lib/librte_sched/rte_sched.h | 23 +++-- > 6 files changed, 124 insertions(+), 89 deletions(-) > > diff --git a/app/test/test_sched.c b/app/test/test_sched.c > index 49bb9ea6f..36fa2d425 100644 > --- a/app/test/test_sched.c > +++ b/app/test/test_sched.c > @@ -40,7 +40,7 @@ static struct rte_sched_pipe_params pipe_profile[] = { > .tc_rate = {305175, 305175, 305175, 305175}, > .tc_period = 40, > > - .wrr_weights = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, > + .wrr_weights = {1, 1, 1, 1}, > }, > }; > > diff --git a/examples/qos_sched/init.c b/examples/qos_sched/init.c > index 1209bd7ce..6b63d4e0e 100644 > --- a/examples/qos_sched/init.c > +++ b/examples/qos_sched/init.c > @@ -186,7 +186,7 @@ static struct rte_sched_pipe_params > pipe_profiles[RTE_SCHED_PIPE_PROFILES_PER_PO > .tc_ov_weight = 1, > #endif > > - .wrr_weights = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, > + .wrr_weights = {1, 1, 1, 1}, > }, > }; > > diff --git a/lib/librte_sched/Makefile b/lib/librte_sched/Makefile > index 644fd9d15..3d7f410e1 100644 > --- a/lib/librte_sched/Makefile > +++ b/lib/librte_sched/Makefile > @@ -18,7 +18,7 @@ LDLIBS += -lrte_timer > > EXPORT_MAP := rte_sched_version.map > > -LIBABIVER := 2 > +LIBABIVER := 3 > > # > # all source are stored in SRCS-y > diff --git a/lib/librte_sched/meson.build b/lib/librte_sched/meson.build > index 8e989e5f6..59d43c6d8 100644 > --- a/lib/librte_sched/meson.build > +++ b/lib/librte_sched/meson.build > @@ -1,7 +1,7 @@ > # SPDX-License-Identifier: BSD-3-Clause > # Copyright(c) 2017 Intel Corporation > > -version = 2 > +version = 3 > sources = files('rte_sched.c', 'rte_red.c', 'rte_approx.c') > headers = files('rte_sched.h', 'rte_sched_common.h', > 'rte_red.h', 'rte_approx.h') > diff --git a/lib/librte_sched/rte_sched.c b/lib/librte_sched/rte_sched.c > index bc06bc3f4..b1f521794 100644 > --- a/lib/librte_sched/rte_sched.c > +++ b/lib/librte_sched/rte_sched.c > @@ -37,6 +37,8 @@ > > #define RTE_SCHED_TB_RATE_CONFIG_ERR (1e-7) > #define RTE_SCHED_WRR_SHIFT 3 > +#define RTE_SCHED_TRAFFIC_CLASS_BE > (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1) > +#define RTE_SCHED_MAX_QUEUES_PER_TC > RTE_SCHED_BE_QUEUES_PER_PIPE > #define RTE_SCHED_GRINDER_PCACHE_SIZE (64 / > RTE_SCHED_QUEUES_PER_PIPE) > #define RTE_SCHED_PIPE_INVALID UINT32_MAX > #define RTE_SCHED_BMP_POS_INVALID UINT32_MAX > @@ -84,8 +86,9 @@ struct rte_sched_pipe_profile { > uint32_t > tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; > uint8_t tc_ov_weight; > > - /* Pipe queues */ > - uint8_t wrr_cost[RTE_SCHED_QUEUES_PER_PIPE]; > + /* Pipe best-effort traffic class queues */ > + uint8_t n_be_queues; The n_be_queues is the same for all pipes within the same port, so it does not make sense to save this per-port value in each pipe profile. At the very least, let's move it to the port data structure, please. In fact, a better solution (that also simplifies the implementation) is to enforce the same queue size for all BE queues, as it does not make sense to have queues within the same traffic class of different size (see my comment in the other patch where you update the API). So n_be_queues should always be 4, therefore no need for this variable. > + uint8_t wrr_cost[RTE_SCHED_BE_QUEUES_PER_PIPE]; > }; > > struct rte_sched_pipe { > @@ -100,8 +103,10 @@ struct rte_sched_pipe { > uint64_t tc_time; /* time of next update */ > uint32_t tc_credits[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; > > + uint8_t n_be_queues; /* Best effort traffic class queues */ Same comment here, even more important, as we need to strive reducing the size of this struct for performance reasons. > + > /* Weighted Round Robin (WRR) */ > - uint8_t wrr_tokens[RTE_SCHED_QUEUES_PER_PIPE]; > + uint8_t wrr_tokens[RTE_SCHED_BE_QUEUES_PER_PIPE]; > > /* TC oversubscription */ > uint32_t tc_ov_credits; > @@ -153,16 +158,16 @@ struct rte_sched_grinder { > uint32_t tc_index; > struct rte_sched_queue > *queue[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; > struct rte_mbuf **qbase[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; > - uint32_t qindex[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; > - uint16_t qsize; > + uint32_t qindex[RTE_SCHED_MAX_QUEUES_PER_TC]; > + uint16_t qsize[RTE_SCHED_MAX_QUEUES_PER_TC]; > uint32_t qmask; > uint32_t qpos; > struct rte_mbuf *pkt; > > /* 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]; > + uint16_t wrr_tokens[RTE_SCHED_BE_QUEUES_PER_PIPE]; > + uint16_t wrr_mask[RTE_SCHED_BE_QUEUES_PER_PIPE]; > + uint8_t wrr_cost[RTE_SCHED_BE_QUEUES_PER_PIPE]; > }; > > struct rte_sched_port { > @@ -301,7 +306,6 @@ pipe_profile_check(struct rte_sched_pipe_params > *params, > if (params->wrr_weights[i] == 0) > return -16; > } > - > return 0; > } > > @@ -483,7 +487,7 @@ rte_sched_port_log_pipe_profile(struct > rte_sched_port *port, uint32_t i) > " Token bucket: period = %u, credits per period = %u, size = > %u\n" > " Traffic classes: period = %u, credits per period = [%u, %u, > %u, %u]\n" > " Traffic class 3 oversubscription: weight = %hhu\n" > - " WRR cost: [%hhu, %hhu, %hhu, %hhu], [%hhu, %hhu, > %hhu, %hhu], [%hhu, %hhu, %hhu, %hhu], [%hhu, %hhu, %hhu, %hhu]\n", > + " WRR cost: [%hhu, %hhu, %hhu, %hhu]\n", > i, > > /* Token bucket */ > @@ -502,10 +506,7 @@ rte_sched_port_log_pipe_profile(struct > rte_sched_port *port, uint32_t i) > p->tc_ov_weight, > > /* WRR */ > - p->wrr_cost[ 0], p->wrr_cost[ 1], p->wrr_cost[ 2], p- > >wrr_cost[ 3], > - p->wrr_cost[ 4], p->wrr_cost[ 5], p->wrr_cost[ 6], p- > >wrr_cost[ 7], > - p->wrr_cost[ 8], p->wrr_cost[ 9], p->wrr_cost[10], p- > >wrr_cost[11], > - p->wrr_cost[12], p->wrr_cost[13], p->wrr_cost[14], p- > >wrr_cost[15]); > + p->wrr_cost[0], p->wrr_cost[1], p->wrr_cost[2], p- > >wrr_cost[3]); > } > > static inline uint64_t > @@ -519,10 +520,12 @@ rte_sched_time_ms_to_bytes(uint32_t time_ms, > uint32_t rate) > } > > static void > -rte_sched_pipe_profile_convert(struct rte_sched_pipe_params *src, > +rte_sched_pipe_profile_convert(struct rte_sched_port *port, > + struct rte_sched_pipe_params *src, > struct rte_sched_pipe_profile *dst, > uint32_t rate) > { > + uint32_t wrr_cost[RTE_SCHED_BE_QUEUES_PER_PIPE]; > uint32_t i; > > /* Token Bucket */ > @@ -553,18 +556,36 @@ rte_sched_pipe_profile_convert(struct > rte_sched_pipe_params *src, > dst->tc_ov_weight = src->tc_ov_weight; > #endif > > - /* WRR */ > - for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { > - uint32_t > wrr_cost[RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS]; > - uint32_t lcd, lcd1, lcd2; > - uint32_t qindex; > + /* WRR queues */ > + for (i = 0; i < RTE_SCHED_BE_QUEUES_PER_PIPE; i++) > + if (port->qsize[i]) > + dst->n_be_queues++; > + > + if (dst->n_be_queues == 1) > + dst->wrr_cost[0] = src->wrr_weights[0]; > + > + if (dst->n_be_queues == 2) { > + uint32_t lcd; > + > + wrr_cost[0] = src->wrr_weights[0]; > + wrr_cost[1] = src->wrr_weights[1]; > + > + lcd = rte_get_lcd(wrr_cost[0], wrr_cost[1]); > + > + wrr_cost[0] = lcd / wrr_cost[0]; > + wrr_cost[1] = lcd / wrr_cost[1]; > > - qindex = i * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; > + dst->wrr_cost[0] = (uint8_t) wrr_cost[0]; > + dst->wrr_cost[1] = (uint8_t) wrr_cost[1]; > + } > > - wrr_cost[0] = src->wrr_weights[qindex]; > - wrr_cost[1] = src->wrr_weights[qindex + 1]; > - wrr_cost[2] = src->wrr_weights[qindex + 2]; > - wrr_cost[3] = src->wrr_weights[qindex + 3]; > + if (dst->n_be_queues == 4) { See the above comment, it is better and simpler to enforce n_be_queues == 4, which simplifies this code a loot, as it keeps only this branch and removes the need for the above two. > + uint32_t lcd1, lcd2, lcd; > + > + wrr_cost[0] = src->wrr_weights[0]; > + wrr_cost[1] = src->wrr_weights[1]; > + wrr_cost[2] = src->wrr_weights[2]; > + wrr_cost[3] = src->wrr_weights[3]; > > lcd1 = rte_get_lcd(wrr_cost[0], wrr_cost[1]); > lcd2 = rte_get_lcd(wrr_cost[2], wrr_cost[3]); > @@ -575,10 +596,10 @@ rte_sched_pipe_profile_convert(struct > rte_sched_pipe_params *src, > wrr_cost[2] = lcd / wrr_cost[2]; > wrr_cost[3] = lcd / wrr_cost[3]; > > - dst->wrr_cost[qindex] = (uint8_t) wrr_cost[0]; > - dst->wrr_cost[qindex + 1] = (uint8_t) wrr_cost[1]; > - dst->wrr_cost[qindex + 2] = (uint8_t) wrr_cost[2]; > - dst->wrr_cost[qindex + 3] = (uint8_t) wrr_cost[3]; > + dst->wrr_cost[0] = (uint8_t) wrr_cost[0]; > + dst->wrr_cost[1] = (uint8_t) wrr_cost[1]; > + dst->wrr_cost[2] = (uint8_t) wrr_cost[2]; > + dst->wrr_cost[3] = (uint8_t) wrr_cost[3]; > } > } > > @@ -592,7 +613,7 @@ rte_sched_port_config_pipe_profile_table(struct > rte_sched_port *port, > struct rte_sched_pipe_params *src = params->pipe_profiles > + i; > struct rte_sched_pipe_profile *dst = port->pipe_profiles + i; > > - rte_sched_pipe_profile_convert(src, dst, params->rate); > + rte_sched_pipe_profile_convert(port, src, dst, params- > >rate); > rte_sched_port_log_pipe_profile(port, i); > } > > @@ -976,7 +997,7 @@ rte_sched_port_pipe_profile_add(struct > rte_sched_port *port, > return status; > > pp = &port->pipe_profiles[port->n_pipe_profiles]; > - rte_sched_pipe_profile_convert(params, pp, port->rate); > + rte_sched_pipe_profile_convert(port, params, pp, port->rate); > > /* Pipe profile not exists */ > for (i = 0; i < port->n_pipe_profiles; i++) > @@ -1715,6 +1736,7 @@ grinder_schedule(struct rte_sched_port *port, > uint32_t pos) > struct rte_sched_queue *queue = grinder->queue[grinder->qpos]; > struct rte_mbuf *pkt = grinder->pkt; > uint32_t pkt_len = pkt->pkt_len + port->frame_overhead; > + int be_tc_active; > > if (!grinder_credits_check(port, pos)) > return 0; > @@ -1725,13 +1747,18 @@ grinder_schedule(struct rte_sched_port *port, > uint32_t pos) > /* Send packet */ > port->pkts_out[port->n_pkts_out++] = pkt; > queue->qr++; > - grinder->wrr_tokens[grinder->qpos] += pkt_len * grinder- > >wrr_cost[grinder->qpos]; > + > + be_tc_active = (grinder->tc_index == > RTE_SCHED_TRAFFIC_CLASS_BE); > + grinder->wrr_tokens[grinder->qpos] += > + pkt_len * grinder->wrr_cost[grinder->qpos] * be_tc_active; > + Integer multiplication is very expensive, you can easily avoid it by doing bitwise-and with a mask whose values are either 0 or all-ones. > if (queue->qr == queue->qw) { > uint32_t qindex = grinder->qindex[grinder->qpos]; > > rte_bitmap_clear(port->bmp, qindex); > grinder->qmask &= ~(1 << grinder->qpos); > - grinder->wrr_mask[grinder->qpos] = 0; > + if (be_tc_active) > + grinder->wrr_mask[grinder->qpos] = 0; > rte_sched_port_set_queue_empty_timestamp(port, > qindex); > } > > @@ -1877,7 +1904,7 @@ grinder_next_tc(struct rte_sched_port *port, > uint32_t pos) > > grinder->tc_index = (qindex >> 2) & 0x3; > grinder->qmask = grinder->tccache_qmask[grinder->tccache_r]; > - grinder->qsize = qsize; > + grinder->qsize[grinder->tc_index] = qsize; > > grinder->qindex[0] = qindex; > grinder->qindex[1] = qindex + 1; > @@ -1962,26 +1989,15 @@ grinder_wrr_load(struct rte_sched_port *port, > uint32_t pos) > struct rte_sched_grinder *grinder = port->grinder + pos; > struct rte_sched_pipe *pipe = grinder->pipe; > struct rte_sched_pipe_profile *pipe_params = grinder- > >pipe_params; > - uint32_t tc_index = grinder->tc_index; > uint32_t qmask = grinder->qmask; > - uint32_t qindex; > - > - qindex = tc_index * 4; > - > - grinder->wrr_tokens[0] = ((uint16_t) pipe->wrr_tokens[qindex]) << > RTE_SCHED_WRR_SHIFT; > - grinder->wrr_tokens[1] = ((uint16_t) pipe->wrr_tokens[qindex + 1]) > << RTE_SCHED_WRR_SHIFT; > - grinder->wrr_tokens[2] = ((uint16_t) pipe->wrr_tokens[qindex + 2]) > << RTE_SCHED_WRR_SHIFT; > - grinder->wrr_tokens[3] = ((uint16_t) pipe->wrr_tokens[qindex + 3]) > << RTE_SCHED_WRR_SHIFT; > - > - grinder->wrr_mask[0] = (qmask & 0x1) * 0xFFFF; > - grinder->wrr_mask[1] = ((qmask >> 1) & 0x1) * 0xFFFF; > - grinder->wrr_mask[2] = ((qmask >> 2) & 0x1) * 0xFFFF; > - grinder->wrr_mask[3] = ((qmask >> 3) & 0x1) * 0xFFFF; > + uint32_t i; > > - grinder->wrr_cost[0] = pipe_params->wrr_cost[qindex]; > - grinder->wrr_cost[1] = pipe_params->wrr_cost[qindex + 1]; > - grinder->wrr_cost[2] = pipe_params->wrr_cost[qindex + 2]; > - grinder->wrr_cost[3] = pipe_params->wrr_cost[qindex + 3]; > + for (i = 0; i < pipe->n_be_queues; i++) { > + grinder->wrr_tokens[i] = > + ((uint16_t) pipe->wrr_tokens[i]) << > RTE_SCHED_WRR_SHIFT; > + grinder->wrr_mask[i] = ((qmask >> i) & 0x1) * 0xFFFF; > + grinder->wrr_cost[i] = pipe_params->wrr_cost[i]; > + } > } > > static inline void > @@ -1989,19 +2005,12 @@ grinder_wrr_store(struct rte_sched_port *port, > uint32_t pos) > { > struct rte_sched_grinder *grinder = port->grinder + pos; > struct rte_sched_pipe *pipe = grinder->pipe; > - uint32_t tc_index = grinder->tc_index; > - uint32_t qindex; > - > - qindex = tc_index * 4; > + uint32_t i; > > - pipe->wrr_tokens[qindex] = (grinder->wrr_tokens[0] & grinder- > >wrr_mask[0]) > - >> RTE_SCHED_WRR_SHIFT; > - pipe->wrr_tokens[qindex + 1] = (grinder->wrr_tokens[1] & grinder- > >wrr_mask[1]) > - >> RTE_SCHED_WRR_SHIFT; > - pipe->wrr_tokens[qindex + 2] = (grinder->wrr_tokens[2] & grinder- > >wrr_mask[2]) > - >> RTE_SCHED_WRR_SHIFT; > - pipe->wrr_tokens[qindex + 3] = (grinder->wrr_tokens[3] & grinder- > >wrr_mask[3]) > - >> RTE_SCHED_WRR_SHIFT; > + for (i = 0; i < pipe->n_be_queues; i++) > + pipe->wrr_tokens[i] = > + (grinder->wrr_tokens[i] & grinder->wrr_mask[i]) >> > + RTE_SCHED_WRR_SHIFT; > } > > static inline void > @@ -2040,22 +2049,31 @@ static inline void > grinder_prefetch_tc_queue_arrays(struct rte_sched_port *port, uint32_t > pos) > { > struct rte_sched_grinder *grinder = port->grinder + pos; > - uint16_t qsize, qr[4]; > + struct rte_sched_pipe *pipe = grinder->pipe; > + struct rte_sched_queue *queue; > + uint32_t i; > + uint16_t qsize, qr[RTE_SCHED_MAX_QUEUES_PER_TC]; > > - qsize = grinder->qsize; > - qr[0] = grinder->queue[0]->qr & (qsize - 1); > - qr[1] = grinder->queue[1]->qr & (qsize - 1); > - qr[2] = grinder->queue[2]->qr & (qsize - 1); > - qr[3] = grinder->queue[3]->qr & (qsize - 1); > + grinder->qpos = 0; > + if (grinder->tc_index < RTE_SCHED_TRAFFIC_CLASS_BE) { > + queue = grinder->queue[0]; > + qsize = grinder->qsize[0]; > + qr[0] = queue->qr & (qsize - 1); > > - rte_prefetch0(grinder->qbase[0] + qr[0]); > - rte_prefetch0(grinder->qbase[1] + qr[1]); > + rte_prefetch0(grinder->qbase[0] + qr[0]); > + return; > + } > + > + for (i = 0; i < pipe->n_be_queues; i++) { > + queue = grinder->queue[i]; > + qsize = grinder->qsize[i]; > + qr[i] = queue->qr & (qsize - 1); > + > + rte_prefetch0(grinder->qbase[i] + qr[i]); > + } > > grinder_wrr_load(port, pos); > grinder_wrr(port, pos); > - > - rte_prefetch0(grinder->qbase[2] + qr[2]); > - rte_prefetch0(grinder->qbase[3] + qr[3]); > } > > static inline void > @@ -2064,7 +2082,7 @@ grinder_prefetch_mbuf(struct rte_sched_port > *port, uint32_t pos) > struct rte_sched_grinder *grinder = port->grinder + pos; > uint32_t qpos = grinder->qpos; > struct rte_mbuf **qbase = grinder->qbase[qpos]; > - uint16_t qsize = grinder->qsize; > + uint16_t qsize = grinder->qsize[qpos]; > uint16_t qr = grinder->queue[qpos]->qr & (qsize - 1); > > grinder->pkt = qbase[qr]; > @@ -2118,18 +2136,24 @@ grinder_handle(struct rte_sched_port *port, > uint32_t pos) > > case e_GRINDER_READ_MBUF: > { > - uint32_t result = 0; > + uint32_t wrr_active, result = 0; > > result = grinder_schedule(port, pos); > > + wrr_active = (grinder->tc_index == > RTE_SCHED_TRAFFIC_CLASS_BE); > + > /* Look for next packet within the same TC */ > if (result && grinder->qmask) { > - grinder_wrr(port, pos); > + if (wrr_active) > + grinder_wrr(port, pos); > + > grinder_prefetch_mbuf(port, pos); > > return 1; > } > - grinder_wrr_store(port, pos); > + > + if (wrr_active) > + grinder_wrr_store(port, pos); > > /* Look for another active TC within same pipe */ > if (grinder_next_tc(port, pos)) { > diff --git a/lib/librte_sched/rte_sched.h b/lib/librte_sched/rte_sched.h > index d61dda9f5..2a935998a 100644 > --- a/lib/librte_sched/rte_sched.h > +++ b/lib/librte_sched/rte_sched.h > @@ -66,6 +66,22 @@ extern "C" { > #include "rte_red.h" > #endif > > +/** Maximum number of queues per pipe. > + * Note that the multiple queues (power of 2) can only be assigned to > + * lowest priority (best-effort) traffic class. Other higher priority traffic > + * classes can only have one queue. > + * Can not change. > + * > + * @see struct rte_sched_port_params > + */ > +#define RTE_SCHED_QUEUES_PER_PIPE 16 > + > +/** Number of WRR queues for best-effort traffic class per pipe. > + * > + * @see struct rte_sched_pipe_params > + */ > +#define RTE_SCHED_BE_QUEUES_PER_PIPE 4 > + > /** Number of traffic classes per pipe (as well as subport). > * Cannot be changed. > */ > @@ -74,11 +90,6 @@ extern "C" { > /** Number of queues per pipe traffic class. Cannot be changed. */ > #define RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS 4 > > -/** Number of queues per pipe. */ > -#define RTE_SCHED_QUEUES_PER_PIPE \ > - (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE * \ > - RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS) > - > /** Maximum number of pipe profiles that can be defined per port. > * Compile-time configurable. > */ > @@ -165,7 +176,7 @@ struct rte_sched_pipe_params { > #endif > > /* Pipe queues */ > - uint8_t wrr_weights[RTE_SCHED_QUEUES_PER_PIPE]; /**< WRR > weights */ > + uint8_t wrr_weights[RTE_SCHED_BE_QUEUES_PER_PIPE]; /**< > WRR weights */ > }; > > /** Queue statistics */ > -- > 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* Re: [dpdk-dev] [PATCH v4 01/11] sched: remove wrr from strict priority tc queues 2019-07-15 23:50 ` Dumitrescu, Cristian @ 2019-07-17 14:49 ` Singh, Jasvinder 0 siblings, 0 replies; 163+ messages in thread From: Singh, Jasvinder @ 2019-07-17 14:49 UTC (permalink / raw) To: Dumitrescu, Cristian, dev; +Cc: Tovar, AbrahamX, Krakowiak, LukaszX <snip> > > +version = 3 > > sources = files('rte_sched.c', 'rte_red.c', 'rte_approx.c') headers > > = files('rte_sched.h', 'rte_sched_common.h', > > 'rte_red.h', 'rte_approx.h') > > diff --git a/lib/librte_sched/rte_sched.c > > b/lib/librte_sched/rte_sched.c index bc06bc3f4..b1f521794 100644 > > --- a/lib/librte_sched/rte_sched.c > > +++ b/lib/librte_sched/rte_sched.c > > @@ -37,6 +37,8 @@ > > > > #define RTE_SCHED_TB_RATE_CONFIG_ERR (1e-7) > > #define RTE_SCHED_WRR_SHIFT 3 > > +#define RTE_SCHED_TRAFFIC_CLASS_BE > > (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1) > > +#define RTE_SCHED_MAX_QUEUES_PER_TC > > RTE_SCHED_BE_QUEUES_PER_PIPE > > #define RTE_SCHED_GRINDER_PCACHE_SIZE (64 / > > RTE_SCHED_QUEUES_PER_PIPE) > > #define RTE_SCHED_PIPE_INVALID UINT32_MAX > > #define RTE_SCHED_BMP_POS_INVALID UINT32_MAX > > @@ -84,8 +86,9 @@ struct rte_sched_pipe_profile { > > uint32_t > > tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; > > uint8_t tc_ov_weight; > > > > - /* Pipe queues */ > > - uint8_t wrr_cost[RTE_SCHED_QUEUES_PER_PIPE]; > > + /* Pipe best-effort traffic class queues */ > > + uint8_t n_be_queues; > > The n_be_queues is the same for all pipes within the same port, so it does not > make sense to save this per-port value in each pipe profile. At the very least, > let's move it to the port data structure, please. > > In fact, a better solution (that also simplifies the implementation) is to enforce > the same queue size for all BE queues, as it does not make sense to have > queues within the same traffic class of different size (see my comment in the > other patch where you update the API). So n_be_queues should always be 4, > therefore no need for this variable. > Thanks for your time and comments. I have removed n_be_queues in v5. > > + uint8_t wrr_cost[RTE_SCHED_BE_QUEUES_PER_PIPE]; > > }; > > > > struct rte_sched_pipe { > > @@ -100,8 +103,10 @@ struct rte_sched_pipe { > > uint64_t tc_time; /* time of next update */ > > uint32_t tc_credits[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; > > > > + uint8_t n_be_queues; /* Best effort traffic class queues */ > > Same comment here, even more important, as we need to strive reducing the > size of this struct for performance reasons. > > > + > > /* Weighted Round Robin (WRR) */ > > - uint8_t wrr_tokens[RTE_SCHED_QUEUES_PER_PIPE]; > > + uint8_t wrr_tokens[RTE_SCHED_BE_QUEUES_PER_PIPE]; > > > > /* TC oversubscription */ > > uint32_t tc_ov_credits; > > @@ -153,16 +158,16 @@ struct rte_sched_grinder { > > uint32_t tc_index; > > struct rte_sched_queue > > *queue[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; > > struct rte_mbuf **qbase[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; > > - uint32_t qindex[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; > > - uint16_t qsize; > > + uint32_t qindex[RTE_SCHED_MAX_QUEUES_PER_TC]; > > + uint16_t qsize[RTE_SCHED_MAX_QUEUES_PER_TC]; > > uint32_t qmask; > > uint32_t qpos; > > struct rte_mbuf *pkt; > > > > /* 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]; > > + uint16_t wrr_tokens[RTE_SCHED_BE_QUEUES_PER_PIPE]; > > + uint16_t wrr_mask[RTE_SCHED_BE_QUEUES_PER_PIPE]; > > + uint8_t wrr_cost[RTE_SCHED_BE_QUEUES_PER_PIPE]; > > }; > > > > struct rte_sched_port { > > @@ -301,7 +306,6 @@ pipe_profile_check(struct rte_sched_pipe_params > > *params, > > if (params->wrr_weights[i] == 0) > > return -16; > > } > > - > > return 0; > > } > > > > @@ -483,7 +487,7 @@ rte_sched_port_log_pipe_profile(struct > > rte_sched_port *port, uint32_t i) > > " Token bucket: period = %u, credits per period = %u, size = > > %u\n" > > " Traffic classes: period = %u, credits per period = [%u, %u, > > %u, %u]\n" > > " Traffic class 3 oversubscription: weight = %hhu\n" > > - " WRR cost: [%hhu, %hhu, %hhu, %hhu], [%hhu, %hhu, > > %hhu, %hhu], [%hhu, %hhu, %hhu, %hhu], [%hhu, %hhu, %hhu, %hhu]\n", > > + " WRR cost: [%hhu, %hhu, %hhu, %hhu]\n", > > i, > > > > /* Token bucket */ > > @@ -502,10 +506,7 @@ rte_sched_port_log_pipe_profile(struct > > rte_sched_port *port, uint32_t i) > > p->tc_ov_weight, > > > > /* WRR */ > > - p->wrr_cost[ 0], p->wrr_cost[ 1], p->wrr_cost[ 2], p- > > >wrr_cost[ 3], > > - p->wrr_cost[ 4], p->wrr_cost[ 5], p->wrr_cost[ 6], p- > > >wrr_cost[ 7], > > - p->wrr_cost[ 8], p->wrr_cost[ 9], p->wrr_cost[10], p- > > >wrr_cost[11], > > - p->wrr_cost[12], p->wrr_cost[13], p->wrr_cost[14], p- > > >wrr_cost[15]); > > + p->wrr_cost[0], p->wrr_cost[1], p->wrr_cost[2], p- > > >wrr_cost[3]); > > } > > > > static inline uint64_t > > @@ -519,10 +520,12 @@ rte_sched_time_ms_to_bytes(uint32_t time_ms, > > uint32_t rate) } > > > > static void > > -rte_sched_pipe_profile_convert(struct rte_sched_pipe_params *src, > > +rte_sched_pipe_profile_convert(struct rte_sched_port *port, > > + struct rte_sched_pipe_params *src, > > struct rte_sched_pipe_profile *dst, > > uint32_t rate) > > { > > + uint32_t wrr_cost[RTE_SCHED_BE_QUEUES_PER_PIPE]; > > uint32_t i; > > > > /* Token Bucket */ > > @@ -553,18 +556,36 @@ rte_sched_pipe_profile_convert(struct > > rte_sched_pipe_params *src, > > dst->tc_ov_weight = src->tc_ov_weight; #endif > > > > - /* WRR */ > > - for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { > > - uint32_t > > wrr_cost[RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS]; > > - uint32_t lcd, lcd1, lcd2; > > - uint32_t qindex; > > + /* WRR queues */ > > + for (i = 0; i < RTE_SCHED_BE_QUEUES_PER_PIPE; i++) > > + if (port->qsize[i]) > > + dst->n_be_queues++; > > + > > + if (dst->n_be_queues == 1) > > + dst->wrr_cost[0] = src->wrr_weights[0]; > > + > > + if (dst->n_be_queues == 2) { > > + uint32_t lcd; > > + > > + wrr_cost[0] = src->wrr_weights[0]; > > + wrr_cost[1] = src->wrr_weights[1]; > > + > > + lcd = rte_get_lcd(wrr_cost[0], wrr_cost[1]); > > + > > + wrr_cost[0] = lcd / wrr_cost[0]; > > + wrr_cost[1] = lcd / wrr_cost[1]; > > > > - qindex = i * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; > > + dst->wrr_cost[0] = (uint8_t) wrr_cost[0]; > > + dst->wrr_cost[1] = (uint8_t) wrr_cost[1]; > > + } > > > > - wrr_cost[0] = src->wrr_weights[qindex]; > > - wrr_cost[1] = src->wrr_weights[qindex + 1]; > > - wrr_cost[2] = src->wrr_weights[qindex + 2]; > > - wrr_cost[3] = src->wrr_weights[qindex + 3]; > > + if (dst->n_be_queues == 4) { > > See the above comment, it is better and simpler to enforce n_be_queues == 4, > which simplifies this code a loot, as it keeps only this branch and removes the > need for the above two. > Fixed in v5. > > + uint32_t lcd1, lcd2, lcd; > > + > > + wrr_cost[0] = src->wrr_weights[0]; > > + wrr_cost[1] = src->wrr_weights[1]; > > + wrr_cost[2] = src->wrr_weights[2]; > > + wrr_cost[3] = src->wrr_weights[3]; > > > > lcd1 = rte_get_lcd(wrr_cost[0], wrr_cost[1]); > > lcd2 = rte_get_lcd(wrr_cost[2], wrr_cost[3]); @@ -575,10 > +596,10 @@ > > rte_sched_pipe_profile_convert(struct > > rte_sched_pipe_params *src, > > wrr_cost[2] = lcd / wrr_cost[2]; > > wrr_cost[3] = lcd / wrr_cost[3]; > > > > - dst->wrr_cost[qindex] = (uint8_t) wrr_cost[0]; > > - dst->wrr_cost[qindex + 1] = (uint8_t) wrr_cost[1]; > > - dst->wrr_cost[qindex + 2] = (uint8_t) wrr_cost[2]; > > - dst->wrr_cost[qindex + 3] = (uint8_t) wrr_cost[3]; > > + dst->wrr_cost[0] = (uint8_t) wrr_cost[0]; > > + dst->wrr_cost[1] = (uint8_t) wrr_cost[1]; > > + dst->wrr_cost[2] = (uint8_t) wrr_cost[2]; > > + dst->wrr_cost[3] = (uint8_t) wrr_cost[3]; > > } > > } > > > > @@ -592,7 +613,7 @@ rte_sched_port_config_pipe_profile_table(struct > > rte_sched_port *port, > > struct rte_sched_pipe_params *src = params->pipe_profiles > > + i; > > struct rte_sched_pipe_profile *dst = port->pipe_profiles + i; > > > > - rte_sched_pipe_profile_convert(src, dst, params->rate); > > + rte_sched_pipe_profile_convert(port, src, dst, params- > > >rate); > > rte_sched_port_log_pipe_profile(port, i); > > } > > > > @@ -976,7 +997,7 @@ rte_sched_port_pipe_profile_add(struct > > rte_sched_port *port, > > return status; > > > > pp = &port->pipe_profiles[port->n_pipe_profiles]; > > - rte_sched_pipe_profile_convert(params, pp, port->rate); > > + rte_sched_pipe_profile_convert(port, params, pp, port->rate); > > > > /* Pipe profile not exists */ > > for (i = 0; i < port->n_pipe_profiles; i++) @@ -1715,6 +1736,7 @@ > > grinder_schedule(struct rte_sched_port *port, uint32_t pos) > > struct rte_sched_queue *queue = grinder->queue[grinder->qpos]; > > struct rte_mbuf *pkt = grinder->pkt; > > uint32_t pkt_len = pkt->pkt_len + port->frame_overhead; > > + int be_tc_active; > > > > if (!grinder_credits_check(port, pos)) > > return 0; > > @@ -1725,13 +1747,18 @@ grinder_schedule(struct rte_sched_port *port, > > uint32_t pos) > > /* Send packet */ > > port->pkts_out[port->n_pkts_out++] = pkt; > > queue->qr++; > > - grinder->wrr_tokens[grinder->qpos] += pkt_len * grinder- > > >wrr_cost[grinder->qpos]; > > + > > + be_tc_active = (grinder->tc_index == > > RTE_SCHED_TRAFFIC_CLASS_BE); > > + grinder->wrr_tokens[grinder->qpos] += > > + pkt_len * grinder->wrr_cost[grinder->qpos] * be_tc_active; > > + > > Integer multiplication is very expensive, you can easily avoid it by doing > bitwise-and with a mask whose values are either 0 or all-ones. > Replace multiplication with bitwise & operation in v5. > > if (queue->qr == queue->qw) { > > uint32_t qindex = grinder->qindex[grinder->qpos]; > > > > rte_bitmap_clear(port->bmp, qindex); > > grinder->qmask &= ~(1 << grinder->qpos); > > - grinder->wrr_mask[grinder->qpos] = 0; > > + if (be_tc_active) > > + grinder->wrr_mask[grinder->qpos] = 0; > > rte_sched_port_set_queue_empty_timestamp(port, > > qindex); > > } > > > > @@ -1877,7 +1904,7 @@ grinder_next_tc(struct rte_sched_port *port, > > uint32_t pos) > > > > grinder->tc_index = (qindex >> 2) & 0x3; > > grinder->qmask = grinder->tccache_qmask[grinder->tccache_r]; > > - grinder->qsize = qsize; > > + grinder->qsize[grinder->tc_index] = qsize; > > > > grinder->qindex[0] = qindex; > > grinder->qindex[1] = qindex + 1; > > @@ -1962,26 +1989,15 @@ grinder_wrr_load(struct rte_sched_port *port, > > uint32_t pos) > > struct rte_sched_grinder *grinder = port->grinder + pos; > > struct rte_sched_pipe *pipe = grinder->pipe; > > struct rte_sched_pipe_profile *pipe_params = grinder- > > >pipe_params; > > - uint32_t tc_index = grinder->tc_index; > > uint32_t qmask = grinder->qmask; > > - uint32_t qindex; > > - > > - qindex = tc_index * 4; > > - > > - grinder->wrr_tokens[0] = ((uint16_t) pipe->wrr_tokens[qindex]) << > > RTE_SCHED_WRR_SHIFT; > > - grinder->wrr_tokens[1] = ((uint16_t) pipe->wrr_tokens[qindex + 1]) > > << RTE_SCHED_WRR_SHIFT; > > - grinder->wrr_tokens[2] = ((uint16_t) pipe->wrr_tokens[qindex + 2]) > > << RTE_SCHED_WRR_SHIFT; > > - grinder->wrr_tokens[3] = ((uint16_t) pipe->wrr_tokens[qindex + 3]) > > << RTE_SCHED_WRR_SHIFT; > > - > > - grinder->wrr_mask[0] = (qmask & 0x1) * 0xFFFF; > > - grinder->wrr_mask[1] = ((qmask >> 1) & 0x1) * 0xFFFF; > > - grinder->wrr_mask[2] = ((qmask >> 2) & 0x1) * 0xFFFF; > > - grinder->wrr_mask[3] = ((qmask >> 3) & 0x1) * 0xFFFF; > > + uint32_t i; > > > > - grinder->wrr_cost[0] = pipe_params->wrr_cost[qindex]; > > - grinder->wrr_cost[1] = pipe_params->wrr_cost[qindex + 1]; > > - grinder->wrr_cost[2] = pipe_params->wrr_cost[qindex + 2]; > > - grinder->wrr_cost[3] = pipe_params->wrr_cost[qindex + 3]; > > + for (i = 0; i < pipe->n_be_queues; i++) { > > + grinder->wrr_tokens[i] = > > + ((uint16_t) pipe->wrr_tokens[i]) << > > RTE_SCHED_WRR_SHIFT; > > + grinder->wrr_mask[i] = ((qmask >> i) & 0x1) * 0xFFFF; > > + grinder->wrr_cost[i] = pipe_params->wrr_cost[i]; > > + } > > } > > > > static inline void > > @@ -1989,19 +2005,12 @@ grinder_wrr_store(struct rte_sched_port *port, > > uint32_t pos) { > > struct rte_sched_grinder *grinder = port->grinder + pos; > > struct rte_sched_pipe *pipe = grinder->pipe; > > - uint32_t tc_index = grinder->tc_index; > > - uint32_t qindex; > > - > > - qindex = tc_index * 4; > > + uint32_t i; > > > > - pipe->wrr_tokens[qindex] = (grinder->wrr_tokens[0] & grinder- > > >wrr_mask[0]) > > - >> RTE_SCHED_WRR_SHIFT; > > - pipe->wrr_tokens[qindex + 1] = (grinder->wrr_tokens[1] & grinder- > > >wrr_mask[1]) > > - >> RTE_SCHED_WRR_SHIFT; > > - pipe->wrr_tokens[qindex + 2] = (grinder->wrr_tokens[2] & grinder- > > >wrr_mask[2]) > > - >> RTE_SCHED_WRR_SHIFT; > > - pipe->wrr_tokens[qindex + 3] = (grinder->wrr_tokens[3] & grinder- > > >wrr_mask[3]) > > - >> RTE_SCHED_WRR_SHIFT; > > + for (i = 0; i < pipe->n_be_queues; i++) > > + pipe->wrr_tokens[i] = > > + (grinder->wrr_tokens[i] & grinder->wrr_mask[i]) >> > > + RTE_SCHED_WRR_SHIFT; > > } > > > > static inline void > > @@ -2040,22 +2049,31 @@ static inline void > > grinder_prefetch_tc_queue_arrays(struct rte_sched_port *port, uint32_t > > pos) > > { > > struct rte_sched_grinder *grinder = port->grinder + pos; > > - uint16_t qsize, qr[4]; > > + struct rte_sched_pipe *pipe = grinder->pipe; > > + struct rte_sched_queue *queue; > > + uint32_t i; > > + uint16_t qsize, qr[RTE_SCHED_MAX_QUEUES_PER_TC]; > > > > - qsize = grinder->qsize; > > - qr[0] = grinder->queue[0]->qr & (qsize - 1); > > - qr[1] = grinder->queue[1]->qr & (qsize - 1); > > - qr[2] = grinder->queue[2]->qr & (qsize - 1); > > - qr[3] = grinder->queue[3]->qr & (qsize - 1); > > + grinder->qpos = 0; > > + if (grinder->tc_index < RTE_SCHED_TRAFFIC_CLASS_BE) { > > + queue = grinder->queue[0]; > > + qsize = grinder->qsize[0]; > > + qr[0] = queue->qr & (qsize - 1); > > > > - rte_prefetch0(grinder->qbase[0] + qr[0]); > > - rte_prefetch0(grinder->qbase[1] + qr[1]); > > + rte_prefetch0(grinder->qbase[0] + qr[0]); > > + return; > > + } > > + > > + for (i = 0; i < pipe->n_be_queues; i++) { > > + queue = grinder->queue[i]; > > + qsize = grinder->qsize[i]; > > + qr[i] = queue->qr & (qsize - 1); > > + > > + rte_prefetch0(grinder->qbase[i] + qr[i]); > > + } > > > > grinder_wrr_load(port, pos); > > grinder_wrr(port, pos); > > - > > - rte_prefetch0(grinder->qbase[2] + qr[2]); > > - rte_prefetch0(grinder->qbase[3] + qr[3]); > > } > > > > static inline void > > @@ -2064,7 +2082,7 @@ grinder_prefetch_mbuf(struct rte_sched_port > > *port, uint32_t pos) > > struct rte_sched_grinder *grinder = port->grinder + pos; > > uint32_t qpos = grinder->qpos; > > struct rte_mbuf **qbase = grinder->qbase[qpos]; > > - uint16_t qsize = grinder->qsize; > > + uint16_t qsize = grinder->qsize[qpos]; > > uint16_t qr = grinder->queue[qpos]->qr & (qsize - 1); > > > > grinder->pkt = qbase[qr]; > > @@ -2118,18 +2136,24 @@ grinder_handle(struct rte_sched_port *port, > > uint32_t pos) > > > > case e_GRINDER_READ_MBUF: > > { > > - uint32_t result = 0; > > + uint32_t wrr_active, result = 0; > > > > result = grinder_schedule(port, pos); > > > > + wrr_active = (grinder->tc_index == > > RTE_SCHED_TRAFFIC_CLASS_BE); > > + > > /* Look for next packet within the same TC */ > > if (result && grinder->qmask) { > > - grinder_wrr(port, pos); > > + if (wrr_active) > > + grinder_wrr(port, pos); > > + > > grinder_prefetch_mbuf(port, pos); > > > > return 1; > > } > > - grinder_wrr_store(port, pos); > > + > > + if (wrr_active) > > + grinder_wrr_store(port, pos); > > > > /* Look for another active TC within same pipe */ > > if (grinder_next_tc(port, pos)) { > > diff --git a/lib/librte_sched/rte_sched.h > > b/lib/librte_sched/rte_sched.h index d61dda9f5..2a935998a 100644 > > --- a/lib/librte_sched/rte_sched.h > > +++ b/lib/librte_sched/rte_sched.h > > @@ -66,6 +66,22 @@ extern "C" { > > #include "rte_red.h" > > #endif > > > > +/** Maximum number of queues per pipe. > > + * Note that the multiple queues (power of 2) can only be assigned to > > + * lowest priority (best-effort) traffic class. Other higher priority > > +traffic > > + * classes can only have one queue. > > + * Can not change. > > + * > > + * @see struct rte_sched_port_params > > + */ > > +#define RTE_SCHED_QUEUES_PER_PIPE 16 > > + > > +/** Number of WRR queues for best-effort traffic class per pipe. > > + * > > + * @see struct rte_sched_pipe_params > > + */ > > +#define RTE_SCHED_BE_QUEUES_PER_PIPE 4 > > + > > /** Number of traffic classes per pipe (as well as subport). > > * Cannot be changed. > > */ > > @@ -74,11 +90,6 @@ extern "C" { > > /** Number of queues per pipe traffic class. Cannot be changed. */ > > #define RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS 4 > > > > -/** Number of queues per pipe. */ > > -#define RTE_SCHED_QUEUES_PER_PIPE \ > > - (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE * \ > > - RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS) > > - > > /** Maximum number of pipe profiles that can be defined per port. > > * Compile-time configurable. > > */ > > @@ -165,7 +176,7 @@ struct rte_sched_pipe_params { #endif > > > > /* Pipe queues */ > > - uint8_t wrr_weights[RTE_SCHED_QUEUES_PER_PIPE]; /**< WRR > > weights */ > > + uint8_t wrr_weights[RTE_SCHED_BE_QUEUES_PER_PIPE]; /**< > > WRR weights */ > > }; > > > > /** Queue statistics */ > > -- > > 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* [dpdk-dev] [PATCH v5 00/11] sched: feature enhancements 2019-07-12 9:57 ` [dpdk-dev] [PATCH v4 01/11] sched: remove wrr from strict priority tc queues Jasvinder Singh 2019-07-15 23:50 ` Dumitrescu, Cristian @ 2019-07-17 14:42 ` Jasvinder Singh 2019-07-17 14:42 ` [dpdk-dev] [PATCH v5 01/11] sched: remove wrr from strict priority tc queues Jasvinder Singh ` (11 more replies) 1 sibling, 12 replies; 163+ messages in thread From: Jasvinder Singh @ 2019-07-17 14:42 UTC (permalink / raw) To: dev; +Cc: cristian.dumitrescu This patchset refactors the dpdk qos sched library to allow flexibile configuration of the pipe traffic classes and queue sizes. Currently, each pipe has 16 queues hardwired into 4 TCs scheduled with strict priority, and each TC has exactly with 4 queues that are scheduled with Weighted Fair Queuing (WFQ). Instead of hardwiring queues to traffic class within the specific pipe, the new implementation allows more flexible/configurable split of pipe queues between strict priority (SP) and best-effort (BE) traffic classes along with the support of more number of traffic classes i.e. max 16. All the high priority TCs (TC1, TC2, ...) have exactly 1 queue, while the lowest priority BE TC, has 1, 4 or 8 queues. This is justified by the fact that all the high priority TCs are fully provisioned (small to medium traffic rates), while most of the traffic fits into the BE class, which is typically oversubscribed. Furthermore, this change allows to use less than 16 queues per pipe when not all the 16 queues are needed. Therefore, no memory will be allocated to the queues that are not needed. v5: - fix traffic class and queue mapping in api function - remove n_be_queues parameter from internal pipe profile and pipe struct - replace int multiplication in grinder_schedule func with bitwise & operation - remove TC_OV logic flag from all the configuration/initialization code - fix traffic qsize per traffic class instead of individual queue of the pipe v4: - fix build errors - fix checkpatch errors v3: - remove code related to subport level configuration of the pipe - remove tc oversubscription flag from struct rte_sched_pipe_params - replace RTE_SCHED_PIPE_PROFILES_PER_PORT with port param field v2: - fix bug in subport parameters check - remove redundant RTE_SCHED_SUBPORT_PER_PORT macro - fix bug in grinder_scheduler function - improve doxygen comments - add error log information Jasvinder Singh (11): sched: remove wrr from strict priority tc queues sched: add config flexibility to tc queue sizes sched: add max pipe profiles config in run time sched: rename tc3 params to best-effort tc sched: improve error log messages sched: improve doxygen comments net/softnic: add config flexibility to softnic tm test_sched: modify tests for config flexibility examples/ip_pipeline: add config flexibility to tm function examples/qos_sched: add tc and queue config flexibility sched: remove redundant macros app/test/test_sched.c | 15 +- doc/guides/rel_notes/release_19_08.rst | 10 +- drivers/net/softnic/rte_eth_softnic.c | 98 ++ drivers/net/softnic/rte_eth_softnic_cli.c | 448 +++++++++- .../net/softnic/rte_eth_softnic_internals.h | 6 +- drivers/net/softnic/rte_eth_softnic_tm.c | 121 ++- examples/ip_pipeline/cli.c | 43 +- examples/ip_pipeline/tmgr.h | 4 +- examples/qos_sched/app_thread.c | 11 +- examples/qos_sched/cfg_file.c | 130 ++- examples/qos_sched/init.c | 65 +- examples/qos_sched/main.h | 4 + examples/qos_sched/profile.cfg | 67 +- examples/qos_sched/profile_ov.cfg | 54 +- examples/qos_sched/stats.c | 517 ++++++----- lib/librte_pipeline/rte_table_action.c | 1 - lib/librte_pipeline/rte_table_action.h | 4 +- lib/librte_sched/Makefile | 2 +- lib/librte_sched/meson.build | 2 +- lib/librte_sched/rte_sched.c | 835 +++++++++++------- lib/librte_sched/rte_sched.h | 183 ++-- 21 files changed, 1847 insertions(+), 773 deletions(-) -- 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* [dpdk-dev] [PATCH v5 01/11] sched: remove wrr from strict priority tc queues 2019-07-17 14:42 ` [dpdk-dev] [PATCH v5 00/11] sched: feature enhancements Jasvinder Singh @ 2019-07-17 14:42 ` Jasvinder Singh 2019-07-19 14:18 ` [dpdk-dev] [PATCH v6 00/11] sched: feature enhancements Jasvinder Singh 2019-07-17 14:42 ` [dpdk-dev] [PATCH v5 02/11] sched: add config flexibility to tc queue sizes Jasvinder Singh ` (10 subsequent siblings) 11 siblings, 1 reply; 163+ messages in thread From: Jasvinder Singh @ 2019-07-17 14:42 UTC (permalink / raw) To: dev; +Cc: cristian.dumitrescu, Abraham Tovar, Lukasz Krakowiak All higher priority traffic classes contain only one queue, thus remove wrr function for them. The lowest priority best-effort traffic class conitnue to have multiple queues and packet are scheduled from its queues using wrr function. Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com> Signed-off-by: Abraham Tovar <abrahamx.tovar@intel.com> Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com> --- app/test/test_sched.c | 2 +- examples/qos_sched/init.c | 2 +- lib/librte_sched/Makefile | 2 +- lib/librte_sched/meson.build | 2 +- lib/librte_sched/rte_sched.c | 152 +++++++++++++++++++---------------- lib/librte_sched/rte_sched.h | 22 +++-- 6 files changed, 104 insertions(+), 78 deletions(-) diff --git a/app/test/test_sched.c b/app/test/test_sched.c index 49bb9ea6f..36fa2d425 100644 --- a/app/test/test_sched.c +++ b/app/test/test_sched.c @@ -40,7 +40,7 @@ static struct rte_sched_pipe_params pipe_profile[] = { .tc_rate = {305175, 305175, 305175, 305175}, .tc_period = 40, - .wrr_weights = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, + .wrr_weights = {1, 1, 1, 1}, }, }; diff --git a/examples/qos_sched/init.c b/examples/qos_sched/init.c index 1209bd7ce..6b63d4e0e 100644 --- a/examples/qos_sched/init.c +++ b/examples/qos_sched/init.c @@ -186,7 +186,7 @@ static struct rte_sched_pipe_params pipe_profiles[RTE_SCHED_PIPE_PROFILES_PER_PO .tc_ov_weight = 1, #endif - .wrr_weights = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, + .wrr_weights = {1, 1, 1, 1}, }, }; diff --git a/lib/librte_sched/Makefile b/lib/librte_sched/Makefile index 644fd9d15..3d7f410e1 100644 --- a/lib/librte_sched/Makefile +++ b/lib/librte_sched/Makefile @@ -18,7 +18,7 @@ LDLIBS += -lrte_timer EXPORT_MAP := rte_sched_version.map -LIBABIVER := 2 +LIBABIVER := 3 # # all source are stored in SRCS-y diff --git a/lib/librte_sched/meson.build b/lib/librte_sched/meson.build index 8e989e5f6..59d43c6d8 100644 --- a/lib/librte_sched/meson.build +++ b/lib/librte_sched/meson.build @@ -1,7 +1,7 @@ # SPDX-License-Identifier: BSD-3-Clause # Copyright(c) 2017 Intel Corporation -version = 2 +version = 3 sources = files('rte_sched.c', 'rte_red.c', 'rte_approx.c') headers = files('rte_sched.h', 'rte_sched_common.h', 'rte_red.h', 'rte_approx.h') diff --git a/lib/librte_sched/rte_sched.c b/lib/librte_sched/rte_sched.c index bc06bc3f4..f7c218ef0 100644 --- a/lib/librte_sched/rte_sched.c +++ b/lib/librte_sched/rte_sched.c @@ -37,6 +37,8 @@ #define RTE_SCHED_TB_RATE_CONFIG_ERR (1e-7) #define RTE_SCHED_WRR_SHIFT 3 +#define RTE_SCHED_TRAFFIC_CLASS_BE (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1) +#define RTE_SCHED_MAX_QUEUES_PER_TC RTE_SCHED_BE_QUEUES_PER_PIPE #define RTE_SCHED_GRINDER_PCACHE_SIZE (64 / RTE_SCHED_QUEUES_PER_PIPE) #define RTE_SCHED_PIPE_INVALID UINT32_MAX #define RTE_SCHED_BMP_POS_INVALID UINT32_MAX @@ -84,8 +86,8 @@ struct rte_sched_pipe_profile { uint32_t tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; uint8_t tc_ov_weight; - /* Pipe queues */ - uint8_t wrr_cost[RTE_SCHED_QUEUES_PER_PIPE]; + /* Pipe best-effort traffic class queues */ + uint8_t wrr_cost[RTE_SCHED_BE_QUEUES_PER_PIPE]; }; struct rte_sched_pipe { @@ -101,7 +103,7 @@ struct rte_sched_pipe { uint32_t tc_credits[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; /* Weighted Round Robin (WRR) */ - uint8_t wrr_tokens[RTE_SCHED_QUEUES_PER_PIPE]; + uint8_t wrr_tokens[RTE_SCHED_BE_QUEUES_PER_PIPE]; /* TC oversubscription */ uint32_t tc_ov_credits; @@ -153,16 +155,16 @@ struct rte_sched_grinder { uint32_t tc_index; struct rte_sched_queue *queue[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; struct rte_mbuf **qbase[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; - uint32_t qindex[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; + uint32_t qindex[RTE_SCHED_MAX_QUEUES_PER_TC]; uint16_t qsize; uint32_t qmask; uint32_t qpos; struct rte_mbuf *pkt; /* 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]; + uint16_t wrr_tokens[RTE_SCHED_BE_QUEUES_PER_PIPE]; + uint16_t wrr_mask[RTE_SCHED_BE_QUEUES_PER_PIPE]; + uint8_t wrr_cost[RTE_SCHED_BE_QUEUES_PER_PIPE]; }; struct rte_sched_port { @@ -483,7 +485,7 @@ rte_sched_port_log_pipe_profile(struct rte_sched_port *port, uint32_t i) " Token bucket: period = %u, credits per period = %u, size = %u\n" " Traffic classes: period = %u, credits per period = [%u, %u, %u, %u]\n" " Traffic class 3 oversubscription: weight = %hhu\n" - " WRR cost: [%hhu, %hhu, %hhu, %hhu], [%hhu, %hhu, %hhu, %hhu], [%hhu, %hhu, %hhu, %hhu], [%hhu, %hhu, %hhu, %hhu]\n", + " WRR cost: [%hhu, %hhu, %hhu, %hhu]\n", i, /* Token bucket */ @@ -502,10 +504,7 @@ rte_sched_port_log_pipe_profile(struct rte_sched_port *port, uint32_t i) p->tc_ov_weight, /* WRR */ - p->wrr_cost[ 0], p->wrr_cost[ 1], p->wrr_cost[ 2], p->wrr_cost[ 3], - p->wrr_cost[ 4], p->wrr_cost[ 5], p->wrr_cost[ 6], p->wrr_cost[ 7], - p->wrr_cost[ 8], p->wrr_cost[ 9], p->wrr_cost[10], p->wrr_cost[11], - p->wrr_cost[12], p->wrr_cost[13], p->wrr_cost[14], p->wrr_cost[15]); + p->wrr_cost[0], p->wrr_cost[1], p->wrr_cost[2], p->wrr_cost[3]); } static inline uint64_t @@ -523,6 +522,8 @@ rte_sched_pipe_profile_convert(struct rte_sched_pipe_params *src, struct rte_sched_pipe_profile *dst, uint32_t rate) { + uint32_t wrr_cost[RTE_SCHED_BE_QUEUES_PER_PIPE]; + uint32_t lcd1, lcd2, lcd; uint32_t i; /* Token Bucket */ @@ -553,33 +554,25 @@ rte_sched_pipe_profile_convert(struct rte_sched_pipe_params *src, dst->tc_ov_weight = src->tc_ov_weight; #endif - /* WRR */ - for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { - uint32_t wrr_cost[RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS]; - uint32_t lcd, lcd1, lcd2; - uint32_t qindex; - - qindex = i * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; - - wrr_cost[0] = src->wrr_weights[qindex]; - wrr_cost[1] = src->wrr_weights[qindex + 1]; - wrr_cost[2] = src->wrr_weights[qindex + 2]; - wrr_cost[3] = src->wrr_weights[qindex + 3]; - - lcd1 = rte_get_lcd(wrr_cost[0], wrr_cost[1]); - lcd2 = rte_get_lcd(wrr_cost[2], wrr_cost[3]); - lcd = rte_get_lcd(lcd1, lcd2); - - wrr_cost[0] = lcd / wrr_cost[0]; - wrr_cost[1] = lcd / wrr_cost[1]; - wrr_cost[2] = lcd / wrr_cost[2]; - wrr_cost[3] = lcd / wrr_cost[3]; - - dst->wrr_cost[qindex] = (uint8_t) wrr_cost[0]; - dst->wrr_cost[qindex + 1] = (uint8_t) wrr_cost[1]; - dst->wrr_cost[qindex + 2] = (uint8_t) wrr_cost[2]; - dst->wrr_cost[qindex + 3] = (uint8_t) wrr_cost[3]; - } + /* WRR queues */ + wrr_cost[0] = src->wrr_weights[0]; + wrr_cost[1] = src->wrr_weights[1]; + wrr_cost[2] = src->wrr_weights[2]; + wrr_cost[3] = src->wrr_weights[3]; + + lcd1 = rte_get_lcd(wrr_cost[0], wrr_cost[1]); + lcd2 = rte_get_lcd(wrr_cost[2], wrr_cost[3]); + lcd = rte_get_lcd(lcd1, lcd2); + + wrr_cost[0] = lcd / wrr_cost[0]; + wrr_cost[1] = lcd / wrr_cost[1]; + wrr_cost[2] = lcd / wrr_cost[2]; + wrr_cost[3] = lcd / wrr_cost[3]; + + dst->wrr_cost[0] = (uint8_t) wrr_cost[0]; + dst->wrr_cost[1] = (uint8_t) wrr_cost[1]; + dst->wrr_cost[2] = (uint8_t) wrr_cost[2]; + dst->wrr_cost[3] = (uint8_t) wrr_cost[3]; } static void @@ -1715,6 +1708,7 @@ grinder_schedule(struct rte_sched_port *port, uint32_t pos) struct rte_sched_queue *queue = grinder->queue[grinder->qpos]; struct rte_mbuf *pkt = grinder->pkt; uint32_t pkt_len = pkt->pkt_len + port->frame_overhead; + uint32_t be_tc_active; if (!grinder_credits_check(port, pos)) return 0; @@ -1725,13 +1719,18 @@ grinder_schedule(struct rte_sched_port *port, uint32_t pos) /* Send packet */ port->pkts_out[port->n_pkts_out++] = pkt; queue->qr++; - grinder->wrr_tokens[grinder->qpos] += pkt_len * grinder->wrr_cost[grinder->qpos]; + + be_tc_active = (grinder->tc_index == RTE_SCHED_TRAFFIC_CLASS_BE) ? ~0x0 : 0x0; + grinder->wrr_tokens[grinder->qpos] += + (pkt_len * grinder->wrr_cost[grinder->qpos]) & be_tc_active; + if (queue->qr == queue->qw) { uint32_t qindex = grinder->qindex[grinder->qpos]; rte_bitmap_clear(port->bmp, qindex); grinder->qmask &= ~(1 << grinder->qpos); - grinder->wrr_mask[grinder->qpos] = 0; + if (be_tc_active) + grinder->wrr_mask[grinder->qpos] = 0; rte_sched_port_set_queue_empty_timestamp(port, qindex); } @@ -1962,26 +1961,26 @@ grinder_wrr_load(struct rte_sched_port *port, uint32_t pos) struct rte_sched_grinder *grinder = port->grinder + pos; struct rte_sched_pipe *pipe = grinder->pipe; struct rte_sched_pipe_profile *pipe_params = grinder->pipe_params; - uint32_t tc_index = grinder->tc_index; uint32_t qmask = grinder->qmask; - uint32_t qindex; - - qindex = tc_index * 4; - grinder->wrr_tokens[0] = ((uint16_t) pipe->wrr_tokens[qindex]) << RTE_SCHED_WRR_SHIFT; - grinder->wrr_tokens[1] = ((uint16_t) pipe->wrr_tokens[qindex + 1]) << RTE_SCHED_WRR_SHIFT; - grinder->wrr_tokens[2] = ((uint16_t) pipe->wrr_tokens[qindex + 2]) << RTE_SCHED_WRR_SHIFT; - grinder->wrr_tokens[3] = ((uint16_t) pipe->wrr_tokens[qindex + 3]) << RTE_SCHED_WRR_SHIFT; + grinder->wrr_tokens[0] = + ((uint16_t) pipe->wrr_tokens[0]) << RTE_SCHED_WRR_SHIFT; + grinder->wrr_tokens[1] = + ((uint16_t) pipe->wrr_tokens[1]) << RTE_SCHED_WRR_SHIFT; + grinder->wrr_tokens[2] = + ((uint16_t) pipe->wrr_tokens[2]) << RTE_SCHED_WRR_SHIFT; + grinder->wrr_tokens[3] = + ((uint16_t) pipe->wrr_tokens[3]) << RTE_SCHED_WRR_SHIFT; grinder->wrr_mask[0] = (qmask & 0x1) * 0xFFFF; grinder->wrr_mask[1] = ((qmask >> 1) & 0x1) * 0xFFFF; grinder->wrr_mask[2] = ((qmask >> 2) & 0x1) * 0xFFFF; grinder->wrr_mask[3] = ((qmask >> 3) & 0x1) * 0xFFFF; - grinder->wrr_cost[0] = pipe_params->wrr_cost[qindex]; - grinder->wrr_cost[1] = pipe_params->wrr_cost[qindex + 1]; - grinder->wrr_cost[2] = pipe_params->wrr_cost[qindex + 2]; - grinder->wrr_cost[3] = pipe_params->wrr_cost[qindex + 3]; + grinder->wrr_cost[0] = pipe_params->wrr_cost[0]; + grinder->wrr_cost[1] = pipe_params->wrr_cost[1]; + grinder->wrr_cost[2] = pipe_params->wrr_cost[2]; + grinder->wrr_cost[3] = pipe_params->wrr_cost[3]; } static inline void @@ -1989,19 +1988,19 @@ grinder_wrr_store(struct rte_sched_port *port, uint32_t pos) { struct rte_sched_grinder *grinder = port->grinder + pos; struct rte_sched_pipe *pipe = grinder->pipe; - uint32_t tc_index = grinder->tc_index; - uint32_t qindex; - qindex = tc_index * 4; - - pipe->wrr_tokens[qindex] = (grinder->wrr_tokens[0] & grinder->wrr_mask[0]) - >> RTE_SCHED_WRR_SHIFT; - pipe->wrr_tokens[qindex + 1] = (grinder->wrr_tokens[1] & grinder->wrr_mask[1]) - >> RTE_SCHED_WRR_SHIFT; - pipe->wrr_tokens[qindex + 2] = (grinder->wrr_tokens[2] & grinder->wrr_mask[2]) - >> RTE_SCHED_WRR_SHIFT; - pipe->wrr_tokens[qindex + 3] = (grinder->wrr_tokens[3] & grinder->wrr_mask[3]) - >> RTE_SCHED_WRR_SHIFT; + pipe->wrr_tokens[0] = + (grinder->wrr_tokens[0] & grinder->wrr_mask[0]) >> + RTE_SCHED_WRR_SHIFT; + pipe->wrr_tokens[1] = + (grinder->wrr_tokens[1] & grinder->wrr_mask[1]) >> + RTE_SCHED_WRR_SHIFT; + pipe->wrr_tokens[2] = + (grinder->wrr_tokens[2] & grinder->wrr_mask[2]) >> + RTE_SCHED_WRR_SHIFT; + pipe->wrr_tokens[3] = + (grinder->wrr_tokens[3] & grinder->wrr_mask[3]) >> + RTE_SCHED_WRR_SHIFT; } static inline void @@ -2040,9 +2039,18 @@ static inline void grinder_prefetch_tc_queue_arrays(struct rte_sched_port *port, uint32_t pos) { struct rte_sched_grinder *grinder = port->grinder + pos; - uint16_t qsize, qr[4]; + uint16_t qsize, qr[RTE_SCHED_MAX_QUEUES_PER_TC]; qsize = grinder->qsize; + grinder->qpos = 0; + + if (grinder->tc_index < RTE_SCHED_TRAFFIC_CLASS_BE) { + qr[0] = grinder->queue[0]->qr & (qsize - 1); + + rte_prefetch0(grinder->qbase[0] + qr[0]); + return; + } + qr[0] = grinder->queue[0]->qr & (qsize - 1); qr[1] = grinder->queue[1]->qr & (qsize - 1); qr[2] = grinder->queue[2]->qr & (qsize - 1); @@ -2118,18 +2126,24 @@ grinder_handle(struct rte_sched_port *port, uint32_t pos) case e_GRINDER_READ_MBUF: { - uint32_t result = 0; + uint32_t wrr_active, result = 0; result = grinder_schedule(port, pos); + wrr_active = (grinder->tc_index == RTE_SCHED_TRAFFIC_CLASS_BE); + /* Look for next packet within the same TC */ if (result && grinder->qmask) { - grinder_wrr(port, pos); + if (wrr_active) + grinder_wrr(port, pos); + grinder_prefetch_mbuf(port, pos); return 1; } - grinder_wrr_store(port, pos); + + if (wrr_active) + grinder_wrr_store(port, pos); /* Look for another active TC within same pipe */ if (grinder_next_tc(port, pos)) { diff --git a/lib/librte_sched/rte_sched.h b/lib/librte_sched/rte_sched.h index d61dda9f5..f9947c4cd 100644 --- a/lib/librte_sched/rte_sched.h +++ b/lib/librte_sched/rte_sched.h @@ -66,6 +66,22 @@ extern "C" { #include "rte_red.h" #endif +/** Maximum number of queues per pipe. + * Note that the multiple queues (power of 2) can only be assigned to + * lowest priority (best-effort) traffic class. Other higher priority traffic + * classes can only have one queue. + * Can not change. + * + * @see struct rte_sched_port_params + */ +#define RTE_SCHED_QUEUES_PER_PIPE 16 + +/** Number of WRR queues for best-effort traffic class per pipe. + * + * @see struct rte_sched_pipe_params + */ +#define RTE_SCHED_BE_QUEUES_PER_PIPE 4 + /** Number of traffic classes per pipe (as well as subport). * Cannot be changed. */ @@ -74,10 +90,6 @@ extern "C" { /** Number of queues per pipe traffic class. Cannot be changed. */ #define RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS 4 -/** Number of queues per pipe. */ -#define RTE_SCHED_QUEUES_PER_PIPE \ - (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE * \ - RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS) /** Maximum number of pipe profiles that can be defined per port. * Compile-time configurable. @@ -165,7 +177,7 @@ struct rte_sched_pipe_params { #endif /* Pipe queues */ - uint8_t wrr_weights[RTE_SCHED_QUEUES_PER_PIPE]; /**< WRR weights */ + uint8_t wrr_weights[RTE_SCHED_BE_QUEUES_PER_PIPE]; /**< WRR weights */ }; /** Queue statistics */ -- 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* [dpdk-dev] [PATCH v6 00/11] sched: feature enhancements 2019-07-17 14:42 ` [dpdk-dev] [PATCH v5 01/11] sched: remove wrr from strict priority tc queues Jasvinder Singh @ 2019-07-19 14:18 ` Jasvinder Singh 2019-07-19 14:18 ` [dpdk-dev] [PATCH v6 01/11] sched: remove wrr from strict priority tc queues Jasvinder Singh ` (12 more replies) 0 siblings, 13 replies; 163+ messages in thread From: Jasvinder Singh @ 2019-07-19 14:18 UTC (permalink / raw) To: dev; +Cc: cristian.dumitrescu This patchset refactors the dpdk qos sched library to allow flexibile configuration of the pipe traffic classes and queue sizes. Currently, each pipe has 16 queues hardwired into 4 TCs scheduled with strict priority, and each TC has exactly with 4 queues that are scheduled with Weighted Fair Queuing (WFQ). Instead of hardwiring queues to traffic class within the specific pipe, the new implementation allows more flexible/configurable split of pipe queues between strict priority (SP) and best-effort (BE) traffic classes along with the support of more number of traffic classes i.e. max 16. All the high priority TCs (TC1, TC2, ...) have exactly 1 queue, while the lowest priority best-effort traffic class can have 1, 4 or 8 queues. This is justified by the fact that all the high priority TCs are fully provisioned (small to medium traffic rates), while most of the traffic fits into the BE class, which is typically oversubscribed. Furthermore, this change allows to use less than 16 queues per pipe when not all the 16 queues are needed. Therefore, no memory will be allocated to the queues that are not needed. v6: - add functions to access port internal struct fields (e.g. pipe queues and tc) - Move definition of RTE_SCHED_TRAFFIC_CLASS_BE to rte_sched.h - fix doxygen comments v5: - fix traffic class and queue mapping in api function - remove n_be_queues parameter from internal pipe profile and pipe struct - replace int multiplication in grinder_schedule func with bitwise & operation - remove TC_OV logic flag from all the configuration/initialization code - fix traffic qsize per traffic class instead of individual queue of the pipe v4: - fix build errors - fix checkpatch errors v3: - remove code related to subport level configuration of the pipe - remove tc oversubscription flag from struct rte_sched_pipe_params - replace RTE_SCHED_PIPE_PROFILES_PER_PORT with port param field v2: - fix bug in subport parameters check - remove redundant RTE_SCHED_SUBPORT_PER_PORT macro - fix bug in grinder_scheduler function - improve doxygen comments - add error log information Jasvinder Singh (11): sched: remove wrr from strict priority tc queues sched: add config flexibility to tc queue sizes sched: add max pipe profiles config in run time sched: rename tc3 params to best-effort tc sched: improve error log messages sched: improve doxygen comments net/softnic: add config flexibility to softnic tm test_sched: modify tests for config flexibility examples/ip_pipeline: add config flexibility to tm function examples/qos_sched: add tc and queue config flexibility sched: remove redundant macros app/test/test_sched.c | 15 +- doc/guides/rel_notes/release_19_08.rst | 10 +- drivers/net/softnic/rte_eth_softnic.c | 98 ++ drivers/net/softnic/rte_eth_softnic_cli.c | 448 ++++++++- .../net/softnic/rte_eth_softnic_internals.h | 6 +- drivers/net/softnic/rte_eth_softnic_tm.c | 121 ++- examples/ip_pipeline/cli.c | 43 +- examples/ip_pipeline/tmgr.h | 4 +- examples/qos_sched/app_thread.c | 11 +- examples/qos_sched/cfg_file.c | 130 ++- examples/qos_sched/init.c | 65 +- examples/qos_sched/main.h | 4 + examples/qos_sched/profile.cfg | 67 +- examples/qos_sched/profile_ov.cfg | 54 +- examples/qos_sched/stats.c | 517 ++++++----- lib/librte_pipeline/rte_table_action.c | 1 - lib/librte_pipeline/rte_table_action.h | 4 +- lib/librte_sched/Makefile | 2 +- lib/librte_sched/meson.build | 2 +- lib/librte_sched/rte_sched.c | 857 ++++++++++++------ lib/librte_sched/rte_sched.h | 187 ++-- 21 files changed, 1874 insertions(+), 772 deletions(-) -- 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* [dpdk-dev] [PATCH v6 01/11] sched: remove wrr from strict priority tc queues 2019-07-19 14:18 ` [dpdk-dev] [PATCH v6 00/11] sched: feature enhancements Jasvinder Singh @ 2019-07-19 14:18 ` Jasvinder Singh 2019-07-22 11:01 ` [dpdk-dev] [PATCH v7 00/11] sched: feature enhancements Jasvinder Singh 2019-07-19 14:18 ` [dpdk-dev] [PATCH v6 02/11] sched: add config flexibility to tc queue sizes Jasvinder Singh ` (11 subsequent siblings) 12 siblings, 1 reply; 163+ messages in thread From: Jasvinder Singh @ 2019-07-19 14:18 UTC (permalink / raw) To: dev; +Cc: cristian.dumitrescu, Abraham Tovar, Lukasz Krakowiak All higher priority traffic classes contain only one queue, thus remove wrr function for them. The lowest priority best-effort traffic class conitnue to have multiple queues and packet are scheduled from its queues using wrr function. Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com> Signed-off-by: Abraham Tovar <abrahamx.tovar@intel.com> Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com> --- app/test/test_sched.c | 2 +- examples/qos_sched/init.c | 2 +- lib/librte_sched/Makefile | 2 +- lib/librte_sched/meson.build | 2 +- lib/librte_sched/rte_sched.c | 151 +++++++++++++++++++---------------- lib/librte_sched/rte_sched.h | 27 +++++-- 6 files changed, 108 insertions(+), 78 deletions(-) diff --git a/app/test/test_sched.c b/app/test/test_sched.c index 49bb9ea6f..36fa2d425 100644 --- a/app/test/test_sched.c +++ b/app/test/test_sched.c @@ -40,7 +40,7 @@ static struct rte_sched_pipe_params pipe_profile[] = { .tc_rate = {305175, 305175, 305175, 305175}, .tc_period = 40, - .wrr_weights = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, + .wrr_weights = {1, 1, 1, 1}, }, }; diff --git a/examples/qos_sched/init.c b/examples/qos_sched/init.c index 1209bd7ce..6b63d4e0e 100644 --- a/examples/qos_sched/init.c +++ b/examples/qos_sched/init.c @@ -186,7 +186,7 @@ static struct rte_sched_pipe_params pipe_profiles[RTE_SCHED_PIPE_PROFILES_PER_PO .tc_ov_weight = 1, #endif - .wrr_weights = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, + .wrr_weights = {1, 1, 1, 1}, }, }; diff --git a/lib/librte_sched/Makefile b/lib/librte_sched/Makefile index 644fd9d15..3d7f410e1 100644 --- a/lib/librte_sched/Makefile +++ b/lib/librte_sched/Makefile @@ -18,7 +18,7 @@ LDLIBS += -lrte_timer EXPORT_MAP := rte_sched_version.map -LIBABIVER := 2 +LIBABIVER := 3 # # all source are stored in SRCS-y diff --git a/lib/librte_sched/meson.build b/lib/librte_sched/meson.build index 8e989e5f6..59d43c6d8 100644 --- a/lib/librte_sched/meson.build +++ b/lib/librte_sched/meson.build @@ -1,7 +1,7 @@ # SPDX-License-Identifier: BSD-3-Clause # Copyright(c) 2017 Intel Corporation -version = 2 +version = 3 sources = files('rte_sched.c', 'rte_red.c', 'rte_approx.c') headers = files('rte_sched.h', 'rte_sched_common.h', 'rte_red.h', 'rte_approx.h') diff --git a/lib/librte_sched/rte_sched.c b/lib/librte_sched/rte_sched.c index bc06bc3f4..1592c804b 100644 --- a/lib/librte_sched/rte_sched.c +++ b/lib/librte_sched/rte_sched.c @@ -37,6 +37,7 @@ #define RTE_SCHED_TB_RATE_CONFIG_ERR (1e-7) #define RTE_SCHED_WRR_SHIFT 3 +#define RTE_SCHED_MAX_QUEUES_PER_TC RTE_SCHED_BE_QUEUES_PER_PIPE #define RTE_SCHED_GRINDER_PCACHE_SIZE (64 / RTE_SCHED_QUEUES_PER_PIPE) #define RTE_SCHED_PIPE_INVALID UINT32_MAX #define RTE_SCHED_BMP_POS_INVALID UINT32_MAX @@ -84,8 +85,8 @@ struct rte_sched_pipe_profile { uint32_t tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; uint8_t tc_ov_weight; - /* Pipe queues */ - uint8_t wrr_cost[RTE_SCHED_QUEUES_PER_PIPE]; + /* Pipe best-effort traffic class queues */ + uint8_t wrr_cost[RTE_SCHED_BE_QUEUES_PER_PIPE]; }; struct rte_sched_pipe { @@ -101,7 +102,7 @@ struct rte_sched_pipe { uint32_t tc_credits[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; /* Weighted Round Robin (WRR) */ - uint8_t wrr_tokens[RTE_SCHED_QUEUES_PER_PIPE]; + uint8_t wrr_tokens[RTE_SCHED_BE_QUEUES_PER_PIPE]; /* TC oversubscription */ uint32_t tc_ov_credits; @@ -153,16 +154,16 @@ struct rte_sched_grinder { uint32_t tc_index; struct rte_sched_queue *queue[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; struct rte_mbuf **qbase[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; - uint32_t qindex[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; + uint32_t qindex[RTE_SCHED_MAX_QUEUES_PER_TC]; uint16_t qsize; uint32_t qmask; uint32_t qpos; struct rte_mbuf *pkt; /* 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]; + uint16_t wrr_tokens[RTE_SCHED_BE_QUEUES_PER_PIPE]; + uint16_t wrr_mask[RTE_SCHED_BE_QUEUES_PER_PIPE]; + uint8_t wrr_cost[RTE_SCHED_BE_QUEUES_PER_PIPE]; }; struct rte_sched_port { @@ -483,7 +484,7 @@ rte_sched_port_log_pipe_profile(struct rte_sched_port *port, uint32_t i) " Token bucket: period = %u, credits per period = %u, size = %u\n" " Traffic classes: period = %u, credits per period = [%u, %u, %u, %u]\n" " Traffic class 3 oversubscription: weight = %hhu\n" - " WRR cost: [%hhu, %hhu, %hhu, %hhu], [%hhu, %hhu, %hhu, %hhu], [%hhu, %hhu, %hhu, %hhu], [%hhu, %hhu, %hhu, %hhu]\n", + " WRR cost: [%hhu, %hhu, %hhu, %hhu]\n", i, /* Token bucket */ @@ -502,10 +503,7 @@ rte_sched_port_log_pipe_profile(struct rte_sched_port *port, uint32_t i) p->tc_ov_weight, /* WRR */ - p->wrr_cost[ 0], p->wrr_cost[ 1], p->wrr_cost[ 2], p->wrr_cost[ 3], - p->wrr_cost[ 4], p->wrr_cost[ 5], p->wrr_cost[ 6], p->wrr_cost[ 7], - p->wrr_cost[ 8], p->wrr_cost[ 9], p->wrr_cost[10], p->wrr_cost[11], - p->wrr_cost[12], p->wrr_cost[13], p->wrr_cost[14], p->wrr_cost[15]); + p->wrr_cost[0], p->wrr_cost[1], p->wrr_cost[2], p->wrr_cost[3]); } static inline uint64_t @@ -523,6 +521,8 @@ rte_sched_pipe_profile_convert(struct rte_sched_pipe_params *src, struct rte_sched_pipe_profile *dst, uint32_t rate) { + uint32_t wrr_cost[RTE_SCHED_BE_QUEUES_PER_PIPE]; + uint32_t lcd1, lcd2, lcd; uint32_t i; /* Token Bucket */ @@ -553,33 +553,25 @@ rte_sched_pipe_profile_convert(struct rte_sched_pipe_params *src, dst->tc_ov_weight = src->tc_ov_weight; #endif - /* WRR */ - for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { - uint32_t wrr_cost[RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS]; - uint32_t lcd, lcd1, lcd2; - uint32_t qindex; - - qindex = i * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; - - wrr_cost[0] = src->wrr_weights[qindex]; - wrr_cost[1] = src->wrr_weights[qindex + 1]; - wrr_cost[2] = src->wrr_weights[qindex + 2]; - wrr_cost[3] = src->wrr_weights[qindex + 3]; - - lcd1 = rte_get_lcd(wrr_cost[0], wrr_cost[1]); - lcd2 = rte_get_lcd(wrr_cost[2], wrr_cost[3]); - lcd = rte_get_lcd(lcd1, lcd2); - - wrr_cost[0] = lcd / wrr_cost[0]; - wrr_cost[1] = lcd / wrr_cost[1]; - wrr_cost[2] = lcd / wrr_cost[2]; - wrr_cost[3] = lcd / wrr_cost[3]; - - dst->wrr_cost[qindex] = (uint8_t) wrr_cost[0]; - dst->wrr_cost[qindex + 1] = (uint8_t) wrr_cost[1]; - dst->wrr_cost[qindex + 2] = (uint8_t) wrr_cost[2]; - dst->wrr_cost[qindex + 3] = (uint8_t) wrr_cost[3]; - } + /* WRR queues */ + wrr_cost[0] = src->wrr_weights[0]; + wrr_cost[1] = src->wrr_weights[1]; + wrr_cost[2] = src->wrr_weights[2]; + wrr_cost[3] = src->wrr_weights[3]; + + lcd1 = rte_get_lcd(wrr_cost[0], wrr_cost[1]); + lcd2 = rte_get_lcd(wrr_cost[2], wrr_cost[3]); + lcd = rte_get_lcd(lcd1, lcd2); + + wrr_cost[0] = lcd / wrr_cost[0]; + wrr_cost[1] = lcd / wrr_cost[1]; + wrr_cost[2] = lcd / wrr_cost[2]; + wrr_cost[3] = lcd / wrr_cost[3]; + + dst->wrr_cost[0] = (uint8_t) wrr_cost[0]; + dst->wrr_cost[1] = (uint8_t) wrr_cost[1]; + dst->wrr_cost[2] = (uint8_t) wrr_cost[2]; + dst->wrr_cost[3] = (uint8_t) wrr_cost[3]; } static void @@ -1715,6 +1707,7 @@ grinder_schedule(struct rte_sched_port *port, uint32_t pos) struct rte_sched_queue *queue = grinder->queue[grinder->qpos]; struct rte_mbuf *pkt = grinder->pkt; uint32_t pkt_len = pkt->pkt_len + port->frame_overhead; + uint32_t be_tc_active; if (!grinder_credits_check(port, pos)) return 0; @@ -1725,13 +1718,18 @@ grinder_schedule(struct rte_sched_port *port, uint32_t pos) /* Send packet */ port->pkts_out[port->n_pkts_out++] = pkt; queue->qr++; - grinder->wrr_tokens[grinder->qpos] += pkt_len * grinder->wrr_cost[grinder->qpos]; + + be_tc_active = (grinder->tc_index == RTE_SCHED_TRAFFIC_CLASS_BE) ? ~0x0 : 0x0; + grinder->wrr_tokens[grinder->qpos] += + (pkt_len * grinder->wrr_cost[grinder->qpos]) & be_tc_active; + if (queue->qr == queue->qw) { uint32_t qindex = grinder->qindex[grinder->qpos]; rte_bitmap_clear(port->bmp, qindex); grinder->qmask &= ~(1 << grinder->qpos); - grinder->wrr_mask[grinder->qpos] = 0; + if (be_tc_active) + grinder->wrr_mask[grinder->qpos] = 0; rte_sched_port_set_queue_empty_timestamp(port, qindex); } @@ -1962,26 +1960,26 @@ grinder_wrr_load(struct rte_sched_port *port, uint32_t pos) struct rte_sched_grinder *grinder = port->grinder + pos; struct rte_sched_pipe *pipe = grinder->pipe; struct rte_sched_pipe_profile *pipe_params = grinder->pipe_params; - uint32_t tc_index = grinder->tc_index; uint32_t qmask = grinder->qmask; - uint32_t qindex; - - qindex = tc_index * 4; - grinder->wrr_tokens[0] = ((uint16_t) pipe->wrr_tokens[qindex]) << RTE_SCHED_WRR_SHIFT; - grinder->wrr_tokens[1] = ((uint16_t) pipe->wrr_tokens[qindex + 1]) << RTE_SCHED_WRR_SHIFT; - grinder->wrr_tokens[2] = ((uint16_t) pipe->wrr_tokens[qindex + 2]) << RTE_SCHED_WRR_SHIFT; - grinder->wrr_tokens[3] = ((uint16_t) pipe->wrr_tokens[qindex + 3]) << RTE_SCHED_WRR_SHIFT; + grinder->wrr_tokens[0] = + ((uint16_t) pipe->wrr_tokens[0]) << RTE_SCHED_WRR_SHIFT; + grinder->wrr_tokens[1] = + ((uint16_t) pipe->wrr_tokens[1]) << RTE_SCHED_WRR_SHIFT; + grinder->wrr_tokens[2] = + ((uint16_t) pipe->wrr_tokens[2]) << RTE_SCHED_WRR_SHIFT; + grinder->wrr_tokens[3] = + ((uint16_t) pipe->wrr_tokens[3]) << RTE_SCHED_WRR_SHIFT; grinder->wrr_mask[0] = (qmask & 0x1) * 0xFFFF; grinder->wrr_mask[1] = ((qmask >> 1) & 0x1) * 0xFFFF; grinder->wrr_mask[2] = ((qmask >> 2) & 0x1) * 0xFFFF; grinder->wrr_mask[3] = ((qmask >> 3) & 0x1) * 0xFFFF; - grinder->wrr_cost[0] = pipe_params->wrr_cost[qindex]; - grinder->wrr_cost[1] = pipe_params->wrr_cost[qindex + 1]; - grinder->wrr_cost[2] = pipe_params->wrr_cost[qindex + 2]; - grinder->wrr_cost[3] = pipe_params->wrr_cost[qindex + 3]; + grinder->wrr_cost[0] = pipe_params->wrr_cost[0]; + grinder->wrr_cost[1] = pipe_params->wrr_cost[1]; + grinder->wrr_cost[2] = pipe_params->wrr_cost[2]; + grinder->wrr_cost[3] = pipe_params->wrr_cost[3]; } static inline void @@ -1989,19 +1987,19 @@ grinder_wrr_store(struct rte_sched_port *port, uint32_t pos) { struct rte_sched_grinder *grinder = port->grinder + pos; struct rte_sched_pipe *pipe = grinder->pipe; - uint32_t tc_index = grinder->tc_index; - uint32_t qindex; - qindex = tc_index * 4; - - pipe->wrr_tokens[qindex] = (grinder->wrr_tokens[0] & grinder->wrr_mask[0]) - >> RTE_SCHED_WRR_SHIFT; - pipe->wrr_tokens[qindex + 1] = (grinder->wrr_tokens[1] & grinder->wrr_mask[1]) - >> RTE_SCHED_WRR_SHIFT; - pipe->wrr_tokens[qindex + 2] = (grinder->wrr_tokens[2] & grinder->wrr_mask[2]) - >> RTE_SCHED_WRR_SHIFT; - pipe->wrr_tokens[qindex + 3] = (grinder->wrr_tokens[3] & grinder->wrr_mask[3]) - >> RTE_SCHED_WRR_SHIFT; + pipe->wrr_tokens[0] = + (grinder->wrr_tokens[0] & grinder->wrr_mask[0]) >> + RTE_SCHED_WRR_SHIFT; + pipe->wrr_tokens[1] = + (grinder->wrr_tokens[1] & grinder->wrr_mask[1]) >> + RTE_SCHED_WRR_SHIFT; + pipe->wrr_tokens[2] = + (grinder->wrr_tokens[2] & grinder->wrr_mask[2]) >> + RTE_SCHED_WRR_SHIFT; + pipe->wrr_tokens[3] = + (grinder->wrr_tokens[3] & grinder->wrr_mask[3]) >> + RTE_SCHED_WRR_SHIFT; } static inline void @@ -2040,9 +2038,18 @@ static inline void grinder_prefetch_tc_queue_arrays(struct rte_sched_port *port, uint32_t pos) { struct rte_sched_grinder *grinder = port->grinder + pos; - uint16_t qsize, qr[4]; + uint16_t qsize, qr[RTE_SCHED_MAX_QUEUES_PER_TC]; qsize = grinder->qsize; + grinder->qpos = 0; + + if (grinder->tc_index < RTE_SCHED_TRAFFIC_CLASS_BE) { + qr[0] = grinder->queue[0]->qr & (qsize - 1); + + rte_prefetch0(grinder->qbase[0] + qr[0]); + return; + } + qr[0] = grinder->queue[0]->qr & (qsize - 1); qr[1] = grinder->queue[1]->qr & (qsize - 1); qr[2] = grinder->queue[2]->qr & (qsize - 1); @@ -2118,18 +2125,24 @@ grinder_handle(struct rte_sched_port *port, uint32_t pos) case e_GRINDER_READ_MBUF: { - uint32_t result = 0; + uint32_t wrr_active, result = 0; result = grinder_schedule(port, pos); + wrr_active = (grinder->tc_index == RTE_SCHED_TRAFFIC_CLASS_BE); + /* Look for next packet within the same TC */ if (result && grinder->qmask) { - grinder_wrr(port, pos); + if (wrr_active) + grinder_wrr(port, pos); + grinder_prefetch_mbuf(port, pos); return 1; } - grinder_wrr_store(port, pos); + + if (wrr_active) + grinder_wrr_store(port, pos); /* Look for another active TC within same pipe */ if (grinder_next_tc(port, pos)) { diff --git a/lib/librte_sched/rte_sched.h b/lib/librte_sched/rte_sched.h index d61dda9f5..662c3a057 100644 --- a/lib/librte_sched/rte_sched.h +++ b/lib/librte_sched/rte_sched.h @@ -66,18 +66,35 @@ extern "C" { #include "rte_red.h" #endif +/** Maximum number of queues per pipe. + * Note that the multiple queues (power of 2) can only be assigned to + * lowest priority (best-effort) traffic class. Other higher priority traffic + * classes can only have one queue. + * Can not change. + * + * @see struct rte_sched_port_params + */ +#define RTE_SCHED_QUEUES_PER_PIPE 16 + +/** Number of WRR queues for best-effort traffic class per pipe. + * + * @see struct rte_sched_pipe_params + */ +#define RTE_SCHED_BE_QUEUES_PER_PIPE 4 + /** Number of traffic classes per pipe (as well as subport). * Cannot be changed. */ #define RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE 4 +/** Best-effort traffic class ID + * Can not change. + */ +#define RTE_SCHED_TRAFFIC_CLASS_BE (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1) + /** Number of queues per pipe traffic class. Cannot be changed. */ #define RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS 4 -/** Number of queues per pipe. */ -#define RTE_SCHED_QUEUES_PER_PIPE \ - (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE * \ - RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS) /** Maximum number of pipe profiles that can be defined per port. * Compile-time configurable. @@ -165,7 +182,7 @@ struct rte_sched_pipe_params { #endif /* Pipe queues */ - uint8_t wrr_weights[RTE_SCHED_QUEUES_PER_PIPE]; /**< WRR weights */ + uint8_t wrr_weights[RTE_SCHED_BE_QUEUES_PER_PIPE]; /**< WRR weights */ }; /** Queue statistics */ -- 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* [dpdk-dev] [PATCH v7 00/11] sched: feature enhancements 2019-07-19 14:18 ` [dpdk-dev] [PATCH v6 01/11] sched: remove wrr from strict priority tc queues Jasvinder Singh @ 2019-07-22 11:01 ` Jasvinder Singh 2019-07-22 11:01 ` [dpdk-dev] [PATCH v7 01/11] sched: remove wrr from strict priority tc queues Jasvinder Singh ` (11 more replies) 0 siblings, 12 replies; 163+ messages in thread From: Jasvinder Singh @ 2019-07-22 11:01 UTC (permalink / raw) To: dev; +Cc: cristian.dumitrescu This patchset refactors the dpdk qos sched library to allow flexibile configuration of the pipe traffic classes and queue sizes. Currently, each pipe has 16 queues hardwired into 4 TCs scheduled with strict priority, and each TC has exactly with 4 queues that are scheduled with Weighted Fair Queuing (WFQ). Instead of hardwiring queues to traffic class within the specific pipe, the new implementation allows more flexible/configurable split of pipe queues between strict priority (SP) and best-effort (BE) traffic classes along with the support of more number of traffic classes i.e. max 16. All the high priority TCs (TC1, TC2, ...) have exactly 1 queue, while the lowest priority best-effort traffic class can have 1, 4 or 8 queues. This is justified by the fact that all the high priority TCs are fully provisioned (small to medium traffic rates), while most of the traffic fits into the BE class, which is typically oversubscribed. Furthermore, this change allows to use less than 16 queues per pipe when not all the 16 queues are needed. Therefore, no memory will be allocated to the queues that are not needed. v7: - fix checkpatch warinings v6: - add functions to access port internal struct fields (e.g. pipe queues and tc) - Move definition of RTE_SCHED_TRAFFIC_CLASS_BE to rte_sched.h - fix doxygen comments v5: - fix traffic class and queue mapping in api function - remove n_be_queues parameter from internal pipe profile and pipe struct - replace int multiplication in grinder_schedule func with bitwise & operation - remove TC_OV logic flag from all the configuration/initialization code - fix traffic qsize per traffic class instead of individual queue of the pipe v4: - fix build errors - fix checkpatch errors v3: - remove code related to subport level configuration of the pipe - remove tc oversubscription flag from struct rte_sched_pipe_params - replace RTE_SCHED_PIPE_PROFILES_PER_PORT with port param field v2: - fix bug in subport parameters check - remove redundant RTE_SCHED_SUBPORT_PER_PORT macro - fix bug in grinder_scheduler function - improve doxygen comments - add error log information Jasvinder Singh (11): sched: remove wrr from strict priority tc queues sched: add config flexibility to tc queue sizes sched: add max pipe profiles config in run time sched: rename tc3 params to best-effort tc sched: improve error log messages sched: improve doxygen comments net/softnic: add config flexibility to softnic tm test_sched: modify tests for config flexibility examples/ip_pipeline: add config flexibility to tm function examples/qos_sched: add tc and queue config flexibility sched: remove redundant macros app/test/test_sched.c | 15 +- doc/guides/rel_notes/release_19_08.rst | 10 +- drivers/net/softnic/rte_eth_softnic.c | 98 ++ drivers/net/softnic/rte_eth_softnic_cli.c | 449 ++++++++- .../net/softnic/rte_eth_softnic_internals.h | 6 +- drivers/net/softnic/rte_eth_softnic_tm.c | 121 ++- examples/ip_pipeline/cli.c | 43 +- examples/ip_pipeline/tmgr.h | 4 +- examples/qos_sched/app_thread.c | 13 +- examples/qos_sched/cfg_file.c | 130 ++- examples/qos_sched/init.c | 65 +- examples/qos_sched/main.h | 4 + examples/qos_sched/profile.cfg | 67 +- examples/qos_sched/profile_ov.cfg | 54 +- examples/qos_sched/stats.c | 526 ++++++----- lib/librte_pipeline/rte_table_action.c | 1 - lib/librte_pipeline/rte_table_action.h | 4 +- lib/librte_sched/Makefile | 2 +- lib/librte_sched/meson.build | 2 +- lib/librte_sched/rte_sched.c | 859 ++++++++++++------ lib/librte_sched/rte_sched.h | 187 ++-- 21 files changed, 1888 insertions(+), 772 deletions(-) -- 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* [dpdk-dev] [PATCH v7 01/11] sched: remove wrr from strict priority tc queues 2019-07-22 11:01 ` [dpdk-dev] [PATCH v7 00/11] sched: feature enhancements Jasvinder Singh @ 2019-07-22 11:01 ` Jasvinder Singh 2019-07-22 11:01 ` [dpdk-dev] [PATCH v7 02/11] sched: add config flexibility to tc queue sizes Jasvinder Singh ` (10 subsequent siblings) 11 siblings, 0 replies; 163+ messages in thread From: Jasvinder Singh @ 2019-07-22 11:01 UTC (permalink / raw) To: dev; +Cc: cristian.dumitrescu, Abraham Tovar, Lukasz Krakowiak All higher priority traffic classes contain only one queue, thus remove wrr function for them. The lowest priority best-effort traffic class conitnue to have multiple queues and packet are scheduled from its queues using wrr function. Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com> Signed-off-by: Abraham Tovar <abrahamx.tovar@intel.com> Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com> --- app/test/test_sched.c | 2 +- examples/qos_sched/init.c | 2 +- lib/librte_sched/Makefile | 2 +- lib/librte_sched/meson.build | 2 +- lib/librte_sched/rte_sched.c | 151 +++++++++++++++++++---------------- lib/librte_sched/rte_sched.h | 27 +++++-- 6 files changed, 108 insertions(+), 78 deletions(-) diff --git a/app/test/test_sched.c b/app/test/test_sched.c index 49bb9ea6f..36fa2d425 100644 --- a/app/test/test_sched.c +++ b/app/test/test_sched.c @@ -40,7 +40,7 @@ static struct rte_sched_pipe_params pipe_profile[] = { .tc_rate = {305175, 305175, 305175, 305175}, .tc_period = 40, - .wrr_weights = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, + .wrr_weights = {1, 1, 1, 1}, }, }; diff --git a/examples/qos_sched/init.c b/examples/qos_sched/init.c index 1209bd7ce..6b63d4e0e 100644 --- a/examples/qos_sched/init.c +++ b/examples/qos_sched/init.c @@ -186,7 +186,7 @@ static struct rte_sched_pipe_params pipe_profiles[RTE_SCHED_PIPE_PROFILES_PER_PO .tc_ov_weight = 1, #endif - .wrr_weights = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, + .wrr_weights = {1, 1, 1, 1}, }, }; diff --git a/lib/librte_sched/Makefile b/lib/librte_sched/Makefile index 644fd9d15..3d7f410e1 100644 --- a/lib/librte_sched/Makefile +++ b/lib/librte_sched/Makefile @@ -18,7 +18,7 @@ LDLIBS += -lrte_timer EXPORT_MAP := rte_sched_version.map -LIBABIVER := 2 +LIBABIVER := 3 # # all source are stored in SRCS-y diff --git a/lib/librte_sched/meson.build b/lib/librte_sched/meson.build index 8e989e5f6..59d43c6d8 100644 --- a/lib/librte_sched/meson.build +++ b/lib/librte_sched/meson.build @@ -1,7 +1,7 @@ # SPDX-License-Identifier: BSD-3-Clause # Copyright(c) 2017 Intel Corporation -version = 2 +version = 3 sources = files('rte_sched.c', 'rte_red.c', 'rte_approx.c') headers = files('rte_sched.h', 'rte_sched_common.h', 'rte_red.h', 'rte_approx.h') diff --git a/lib/librte_sched/rte_sched.c b/lib/librte_sched/rte_sched.c index bc06bc3f4..1592c804b 100644 --- a/lib/librte_sched/rte_sched.c +++ b/lib/librte_sched/rte_sched.c @@ -37,6 +37,7 @@ #define RTE_SCHED_TB_RATE_CONFIG_ERR (1e-7) #define RTE_SCHED_WRR_SHIFT 3 +#define RTE_SCHED_MAX_QUEUES_PER_TC RTE_SCHED_BE_QUEUES_PER_PIPE #define RTE_SCHED_GRINDER_PCACHE_SIZE (64 / RTE_SCHED_QUEUES_PER_PIPE) #define RTE_SCHED_PIPE_INVALID UINT32_MAX #define RTE_SCHED_BMP_POS_INVALID UINT32_MAX @@ -84,8 +85,8 @@ struct rte_sched_pipe_profile { uint32_t tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; uint8_t tc_ov_weight; - /* Pipe queues */ - uint8_t wrr_cost[RTE_SCHED_QUEUES_PER_PIPE]; + /* Pipe best-effort traffic class queues */ + uint8_t wrr_cost[RTE_SCHED_BE_QUEUES_PER_PIPE]; }; struct rte_sched_pipe { @@ -101,7 +102,7 @@ struct rte_sched_pipe { uint32_t tc_credits[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; /* Weighted Round Robin (WRR) */ - uint8_t wrr_tokens[RTE_SCHED_QUEUES_PER_PIPE]; + uint8_t wrr_tokens[RTE_SCHED_BE_QUEUES_PER_PIPE]; /* TC oversubscription */ uint32_t tc_ov_credits; @@ -153,16 +154,16 @@ struct rte_sched_grinder { uint32_t tc_index; struct rte_sched_queue *queue[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; struct rte_mbuf **qbase[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; - uint32_t qindex[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; + uint32_t qindex[RTE_SCHED_MAX_QUEUES_PER_TC]; uint16_t qsize; uint32_t qmask; uint32_t qpos; struct rte_mbuf *pkt; /* 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]; + uint16_t wrr_tokens[RTE_SCHED_BE_QUEUES_PER_PIPE]; + uint16_t wrr_mask[RTE_SCHED_BE_QUEUES_PER_PIPE]; + uint8_t wrr_cost[RTE_SCHED_BE_QUEUES_PER_PIPE]; }; struct rte_sched_port { @@ -483,7 +484,7 @@ rte_sched_port_log_pipe_profile(struct rte_sched_port *port, uint32_t i) " Token bucket: period = %u, credits per period = %u, size = %u\n" " Traffic classes: period = %u, credits per period = [%u, %u, %u, %u]\n" " Traffic class 3 oversubscription: weight = %hhu\n" - " WRR cost: [%hhu, %hhu, %hhu, %hhu], [%hhu, %hhu, %hhu, %hhu], [%hhu, %hhu, %hhu, %hhu], [%hhu, %hhu, %hhu, %hhu]\n", + " WRR cost: [%hhu, %hhu, %hhu, %hhu]\n", i, /* Token bucket */ @@ -502,10 +503,7 @@ rte_sched_port_log_pipe_profile(struct rte_sched_port *port, uint32_t i) p->tc_ov_weight, /* WRR */ - p->wrr_cost[ 0], p->wrr_cost[ 1], p->wrr_cost[ 2], p->wrr_cost[ 3], - p->wrr_cost[ 4], p->wrr_cost[ 5], p->wrr_cost[ 6], p->wrr_cost[ 7], - p->wrr_cost[ 8], p->wrr_cost[ 9], p->wrr_cost[10], p->wrr_cost[11], - p->wrr_cost[12], p->wrr_cost[13], p->wrr_cost[14], p->wrr_cost[15]); + p->wrr_cost[0], p->wrr_cost[1], p->wrr_cost[2], p->wrr_cost[3]); } static inline uint64_t @@ -523,6 +521,8 @@ rte_sched_pipe_profile_convert(struct rte_sched_pipe_params *src, struct rte_sched_pipe_profile *dst, uint32_t rate) { + uint32_t wrr_cost[RTE_SCHED_BE_QUEUES_PER_PIPE]; + uint32_t lcd1, lcd2, lcd; uint32_t i; /* Token Bucket */ @@ -553,33 +553,25 @@ rte_sched_pipe_profile_convert(struct rte_sched_pipe_params *src, dst->tc_ov_weight = src->tc_ov_weight; #endif - /* WRR */ - for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { - uint32_t wrr_cost[RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS]; - uint32_t lcd, lcd1, lcd2; - uint32_t qindex; - - qindex = i * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; - - wrr_cost[0] = src->wrr_weights[qindex]; - wrr_cost[1] = src->wrr_weights[qindex + 1]; - wrr_cost[2] = src->wrr_weights[qindex + 2]; - wrr_cost[3] = src->wrr_weights[qindex + 3]; - - lcd1 = rte_get_lcd(wrr_cost[0], wrr_cost[1]); - lcd2 = rte_get_lcd(wrr_cost[2], wrr_cost[3]); - lcd = rte_get_lcd(lcd1, lcd2); - - wrr_cost[0] = lcd / wrr_cost[0]; - wrr_cost[1] = lcd / wrr_cost[1]; - wrr_cost[2] = lcd / wrr_cost[2]; - wrr_cost[3] = lcd / wrr_cost[3]; - - dst->wrr_cost[qindex] = (uint8_t) wrr_cost[0]; - dst->wrr_cost[qindex + 1] = (uint8_t) wrr_cost[1]; - dst->wrr_cost[qindex + 2] = (uint8_t) wrr_cost[2]; - dst->wrr_cost[qindex + 3] = (uint8_t) wrr_cost[3]; - } + /* WRR queues */ + wrr_cost[0] = src->wrr_weights[0]; + wrr_cost[1] = src->wrr_weights[1]; + wrr_cost[2] = src->wrr_weights[2]; + wrr_cost[3] = src->wrr_weights[3]; + + lcd1 = rte_get_lcd(wrr_cost[0], wrr_cost[1]); + lcd2 = rte_get_lcd(wrr_cost[2], wrr_cost[3]); + lcd = rte_get_lcd(lcd1, lcd2); + + wrr_cost[0] = lcd / wrr_cost[0]; + wrr_cost[1] = lcd / wrr_cost[1]; + wrr_cost[2] = lcd / wrr_cost[2]; + wrr_cost[3] = lcd / wrr_cost[3]; + + dst->wrr_cost[0] = (uint8_t) wrr_cost[0]; + dst->wrr_cost[1] = (uint8_t) wrr_cost[1]; + dst->wrr_cost[2] = (uint8_t) wrr_cost[2]; + dst->wrr_cost[3] = (uint8_t) wrr_cost[3]; } static void @@ -1715,6 +1707,7 @@ grinder_schedule(struct rte_sched_port *port, uint32_t pos) struct rte_sched_queue *queue = grinder->queue[grinder->qpos]; struct rte_mbuf *pkt = grinder->pkt; uint32_t pkt_len = pkt->pkt_len + port->frame_overhead; + uint32_t be_tc_active; if (!grinder_credits_check(port, pos)) return 0; @@ -1725,13 +1718,18 @@ grinder_schedule(struct rte_sched_port *port, uint32_t pos) /* Send packet */ port->pkts_out[port->n_pkts_out++] = pkt; queue->qr++; - grinder->wrr_tokens[grinder->qpos] += pkt_len * grinder->wrr_cost[grinder->qpos]; + + be_tc_active = (grinder->tc_index == RTE_SCHED_TRAFFIC_CLASS_BE) ? ~0x0 : 0x0; + grinder->wrr_tokens[grinder->qpos] += + (pkt_len * grinder->wrr_cost[grinder->qpos]) & be_tc_active; + if (queue->qr == queue->qw) { uint32_t qindex = grinder->qindex[grinder->qpos]; rte_bitmap_clear(port->bmp, qindex); grinder->qmask &= ~(1 << grinder->qpos); - grinder->wrr_mask[grinder->qpos] = 0; + if (be_tc_active) + grinder->wrr_mask[grinder->qpos] = 0; rte_sched_port_set_queue_empty_timestamp(port, qindex); } @@ -1962,26 +1960,26 @@ grinder_wrr_load(struct rte_sched_port *port, uint32_t pos) struct rte_sched_grinder *grinder = port->grinder + pos; struct rte_sched_pipe *pipe = grinder->pipe; struct rte_sched_pipe_profile *pipe_params = grinder->pipe_params; - uint32_t tc_index = grinder->tc_index; uint32_t qmask = grinder->qmask; - uint32_t qindex; - - qindex = tc_index * 4; - grinder->wrr_tokens[0] = ((uint16_t) pipe->wrr_tokens[qindex]) << RTE_SCHED_WRR_SHIFT; - grinder->wrr_tokens[1] = ((uint16_t) pipe->wrr_tokens[qindex + 1]) << RTE_SCHED_WRR_SHIFT; - grinder->wrr_tokens[2] = ((uint16_t) pipe->wrr_tokens[qindex + 2]) << RTE_SCHED_WRR_SHIFT; - grinder->wrr_tokens[3] = ((uint16_t) pipe->wrr_tokens[qindex + 3]) << RTE_SCHED_WRR_SHIFT; + grinder->wrr_tokens[0] = + ((uint16_t) pipe->wrr_tokens[0]) << RTE_SCHED_WRR_SHIFT; + grinder->wrr_tokens[1] = + ((uint16_t) pipe->wrr_tokens[1]) << RTE_SCHED_WRR_SHIFT; + grinder->wrr_tokens[2] = + ((uint16_t) pipe->wrr_tokens[2]) << RTE_SCHED_WRR_SHIFT; + grinder->wrr_tokens[3] = + ((uint16_t) pipe->wrr_tokens[3]) << RTE_SCHED_WRR_SHIFT; grinder->wrr_mask[0] = (qmask & 0x1) * 0xFFFF; grinder->wrr_mask[1] = ((qmask >> 1) & 0x1) * 0xFFFF; grinder->wrr_mask[2] = ((qmask >> 2) & 0x1) * 0xFFFF; grinder->wrr_mask[3] = ((qmask >> 3) & 0x1) * 0xFFFF; - grinder->wrr_cost[0] = pipe_params->wrr_cost[qindex]; - grinder->wrr_cost[1] = pipe_params->wrr_cost[qindex + 1]; - grinder->wrr_cost[2] = pipe_params->wrr_cost[qindex + 2]; - grinder->wrr_cost[3] = pipe_params->wrr_cost[qindex + 3]; + grinder->wrr_cost[0] = pipe_params->wrr_cost[0]; + grinder->wrr_cost[1] = pipe_params->wrr_cost[1]; + grinder->wrr_cost[2] = pipe_params->wrr_cost[2]; + grinder->wrr_cost[3] = pipe_params->wrr_cost[3]; } static inline void @@ -1989,19 +1987,19 @@ grinder_wrr_store(struct rte_sched_port *port, uint32_t pos) { struct rte_sched_grinder *grinder = port->grinder + pos; struct rte_sched_pipe *pipe = grinder->pipe; - uint32_t tc_index = grinder->tc_index; - uint32_t qindex; - qindex = tc_index * 4; - - pipe->wrr_tokens[qindex] = (grinder->wrr_tokens[0] & grinder->wrr_mask[0]) - >> RTE_SCHED_WRR_SHIFT; - pipe->wrr_tokens[qindex + 1] = (grinder->wrr_tokens[1] & grinder->wrr_mask[1]) - >> RTE_SCHED_WRR_SHIFT; - pipe->wrr_tokens[qindex + 2] = (grinder->wrr_tokens[2] & grinder->wrr_mask[2]) - >> RTE_SCHED_WRR_SHIFT; - pipe->wrr_tokens[qindex + 3] = (grinder->wrr_tokens[3] & grinder->wrr_mask[3]) - >> RTE_SCHED_WRR_SHIFT; + pipe->wrr_tokens[0] = + (grinder->wrr_tokens[0] & grinder->wrr_mask[0]) >> + RTE_SCHED_WRR_SHIFT; + pipe->wrr_tokens[1] = + (grinder->wrr_tokens[1] & grinder->wrr_mask[1]) >> + RTE_SCHED_WRR_SHIFT; + pipe->wrr_tokens[2] = + (grinder->wrr_tokens[2] & grinder->wrr_mask[2]) >> + RTE_SCHED_WRR_SHIFT; + pipe->wrr_tokens[3] = + (grinder->wrr_tokens[3] & grinder->wrr_mask[3]) >> + RTE_SCHED_WRR_SHIFT; } static inline void @@ -2040,9 +2038,18 @@ static inline void grinder_prefetch_tc_queue_arrays(struct rte_sched_port *port, uint32_t pos) { struct rte_sched_grinder *grinder = port->grinder + pos; - uint16_t qsize, qr[4]; + uint16_t qsize, qr[RTE_SCHED_MAX_QUEUES_PER_TC]; qsize = grinder->qsize; + grinder->qpos = 0; + + if (grinder->tc_index < RTE_SCHED_TRAFFIC_CLASS_BE) { + qr[0] = grinder->queue[0]->qr & (qsize - 1); + + rte_prefetch0(grinder->qbase[0] + qr[0]); + return; + } + qr[0] = grinder->queue[0]->qr & (qsize - 1); qr[1] = grinder->queue[1]->qr & (qsize - 1); qr[2] = grinder->queue[2]->qr & (qsize - 1); @@ -2118,18 +2125,24 @@ grinder_handle(struct rte_sched_port *port, uint32_t pos) case e_GRINDER_READ_MBUF: { - uint32_t result = 0; + uint32_t wrr_active, result = 0; result = grinder_schedule(port, pos); + wrr_active = (grinder->tc_index == RTE_SCHED_TRAFFIC_CLASS_BE); + /* Look for next packet within the same TC */ if (result && grinder->qmask) { - grinder_wrr(port, pos); + if (wrr_active) + grinder_wrr(port, pos); + grinder_prefetch_mbuf(port, pos); return 1; } - grinder_wrr_store(port, pos); + + if (wrr_active) + grinder_wrr_store(port, pos); /* Look for another active TC within same pipe */ if (grinder_next_tc(port, pos)) { diff --git a/lib/librte_sched/rte_sched.h b/lib/librte_sched/rte_sched.h index d61dda9f5..662c3a057 100644 --- a/lib/librte_sched/rte_sched.h +++ b/lib/librte_sched/rte_sched.h @@ -66,18 +66,35 @@ extern "C" { #include "rte_red.h" #endif +/** Maximum number of queues per pipe. + * Note that the multiple queues (power of 2) can only be assigned to + * lowest priority (best-effort) traffic class. Other higher priority traffic + * classes can only have one queue. + * Can not change. + * + * @see struct rte_sched_port_params + */ +#define RTE_SCHED_QUEUES_PER_PIPE 16 + +/** Number of WRR queues for best-effort traffic class per pipe. + * + * @see struct rte_sched_pipe_params + */ +#define RTE_SCHED_BE_QUEUES_PER_PIPE 4 + /** Number of traffic classes per pipe (as well as subport). * Cannot be changed. */ #define RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE 4 +/** Best-effort traffic class ID + * Can not change. + */ +#define RTE_SCHED_TRAFFIC_CLASS_BE (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1) + /** Number of queues per pipe traffic class. Cannot be changed. */ #define RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS 4 -/** Number of queues per pipe. */ -#define RTE_SCHED_QUEUES_PER_PIPE \ - (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE * \ - RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS) /** Maximum number of pipe profiles that can be defined per port. * Compile-time configurable. @@ -165,7 +182,7 @@ struct rte_sched_pipe_params { #endif /* Pipe queues */ - uint8_t wrr_weights[RTE_SCHED_QUEUES_PER_PIPE]; /**< WRR weights */ + uint8_t wrr_weights[RTE_SCHED_BE_QUEUES_PER_PIPE]; /**< WRR weights */ }; /** Queue statistics */ -- 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* [dpdk-dev] [PATCH v7 02/11] sched: add config flexibility to tc queue sizes 2019-07-22 11:01 ` [dpdk-dev] [PATCH v7 00/11] sched: feature enhancements Jasvinder Singh 2019-07-22 11:01 ` [dpdk-dev] [PATCH v7 01/11] sched: remove wrr from strict priority tc queues Jasvinder Singh @ 2019-07-22 11:01 ` Jasvinder Singh 2019-07-22 11:01 ` [dpdk-dev] [PATCH v7 03/11] sched: add max pipe profiles config in run time Jasvinder Singh ` (9 subsequent siblings) 11 siblings, 0 replies; 163+ messages in thread From: Jasvinder Singh @ 2019-07-22 11:01 UTC (permalink / raw) To: dev; +Cc: cristian.dumitrescu, Abraham Tovar, Lukasz Krakowiak Add support for zero queue sizes of the traffic classes. The queues which are not used can be set to zero size. This helps in reducing memory footprint of the hierarchical scheduler. Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com> Signed-off-by: Abraham Tovar <abrahamx.tovar@intel.com> Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com> --- lib/librte_sched/rte_sched.c | 381 ++++++++++++++++++++++------------- lib/librte_sched/rte_sched.h | 5 +- 2 files changed, 238 insertions(+), 148 deletions(-) diff --git a/lib/librte_sched/rte_sched.c b/lib/librte_sched/rte_sched.c index 1592c804b..a4eaa7a68 100644 --- a/lib/librte_sched/rte_sched.c +++ b/lib/librte_sched/rte_sched.c @@ -145,15 +145,15 @@ struct rte_sched_grinder { struct rte_sched_pipe_profile *pipe_params; /* TC cache */ - uint8_t tccache_qmask[4]; - uint32_t tccache_qindex[4]; + uint8_t tccache_qmask[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; + uint32_t tccache_qindex[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; uint32_t tccache_w; uint32_t tccache_r; /* Current TC */ uint32_t tc_index; - struct rte_sched_queue *queue[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; - struct rte_mbuf **qbase[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; + struct rte_sched_queue *queue[RTE_SCHED_MAX_QUEUES_PER_TC]; + struct rte_mbuf **qbase[RTE_SCHED_MAX_QUEUES_PER_TC]; uint32_t qindex[RTE_SCHED_MAX_QUEUES_PER_TC]; uint16_t qsize; uint32_t qmask; @@ -171,6 +171,9 @@ struct rte_sched_port { uint32_t n_subports_per_port; uint32_t n_pipes_per_subport; uint32_t n_pipes_per_subport_log2; + 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 rate; uint32_t mtu; uint32_t frame_overhead; @@ -256,14 +259,38 @@ rte_sched_port_qbase(struct rte_sched_port *port, uint32_t qindex) static inline uint16_t rte_sched_port_qsize(struct rte_sched_port *port, uint32_t qindex) { - uint32_t tc = (qindex >> 2) & 0x3; + uint32_t tc = port->pipe_tc[qindex & (RTE_SCHED_QUEUES_PER_PIPE - 1)]; return port->qsize[tc]; } +static inline uint16_t +rte_sched_port_pipe_queue(struct rte_sched_port *port, uint32_t traffic_class) +{ + uint16_t pipe_queue = port->pipe_queue[traffic_class]; + + return pipe_queue; +} + +static inline uint8_t +rte_sched_port_pipe_tc(struct rte_sched_port *port, uint32_t qindex) +{ + uint8_t pipe_tc = port->pipe_tc[qindex & (RTE_SCHED_QUEUES_PER_PIPE - 1)]; + + return pipe_tc; +} + +static inline uint8_t +rte_sched_port_tc_queue(struct rte_sched_port *port, uint32_t qindex) +{ + uint8_t tc_queue = port->tc_queue[qindex & (RTE_SCHED_QUEUES_PER_PIPE - 1)]; + + return tc_queue; +} + static int pipe_profile_check(struct rte_sched_pipe_params *params, - uint32_t rate) + uint32_t rate, uint16_t *qsize) { uint32_t i; @@ -280,25 +307,27 @@ pipe_profile_check(struct rte_sched_pipe_params *params, if (params->tb_size == 0) return -12; - /* TC rate: non-zero, less than pipe rate */ + /* TC rate: non-zero if qsize non-zero, less than pipe rate */ for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { - if (params->tc_rate[i] == 0 || - params->tc_rate[i] > params->tb_rate) + if ((qsize[i] == 0 && params->tc_rate[i] != 0) || + (qsize[i] != 0 && (params->tc_rate[i] == 0 || + params->tc_rate[i] > params->tb_rate))) return -13; } + if (params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE] == 0 || + qsize[RTE_SCHED_TRAFFIC_CLASS_BE] == 0) + return -13; /* TC period: non-zero */ if (params->tc_period == 0) return -14; -#ifdef RTE_SCHED_SUBPORT_TC_OV /* TC3 oversubscription weight: non-zero */ if (params->tc_ov_weight == 0) return -15; -#endif /* Queue WRR weights: non-zero */ - for (i = 0; i < RTE_SCHED_QUEUES_PER_PIPE; i++) { + for (i = 0; i < RTE_SCHED_BE_QUEUES_PER_PIPE; i++) { if (params->wrr_weights[i] == 0) return -16; } @@ -343,7 +372,8 @@ rte_sched_port_check_params(struct rte_sched_port_params *params) for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { uint16_t qsize = params->qsize[i]; - if (qsize == 0 || !rte_is_power_of_2(qsize)) + if ((qsize != 0 && !rte_is_power_of_2(qsize)) || + ((i == RTE_SCHED_TRAFFIC_CLASS_BE) && (qsize == 0))) return -8; } @@ -357,7 +387,7 @@ rte_sched_port_check_params(struct rte_sched_port_params *params) struct rte_sched_pipe_params *p = params->pipe_profiles + i; int status; - status = pipe_profile_check(p, params->rate); + status = pipe_profile_check(p, params->rate, ¶ms->qsize[0]); if (status != 0) return status; } @@ -387,8 +417,12 @@ rte_sched_port_get_array_base(struct rte_sched_port_params *params, enum rte_sch size_per_pipe_queue_array = 0; for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { - size_per_pipe_queue_array += RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS - * params->qsize[i] * sizeof(struct rte_mbuf *); + if (i < RTE_SCHED_TRAFFIC_CLASS_BE) + size_per_pipe_queue_array += + params->qsize[i] * sizeof(struct rte_mbuf *); + else + size_per_pipe_queue_array += RTE_SCHED_MAX_QUEUES_PER_TC * + params->qsize[i] * sizeof(struct rte_mbuf *); } size_queue_array = n_pipes_per_port * size_per_pipe_queue_array; @@ -448,31 +482,27 @@ rte_sched_port_get_memory_footprint(struct rte_sched_port_params *params) static void rte_sched_port_config_qsize(struct rte_sched_port *port) { - /* TC 0 */ + uint32_t i; + port->qsize_add[0] = 0; - port->qsize_add[1] = port->qsize_add[0] + port->qsize[0]; - port->qsize_add[2] = port->qsize_add[1] + port->qsize[0]; - port->qsize_add[3] = port->qsize_add[2] + port->qsize[0]; - - /* TC 1 */ - port->qsize_add[4] = port->qsize_add[3] + port->qsize[0]; - port->qsize_add[5] = port->qsize_add[4] + port->qsize[1]; - port->qsize_add[6] = port->qsize_add[5] + port->qsize[1]; - port->qsize_add[7] = port->qsize_add[6] + port->qsize[1]; - - /* TC 2 */ - port->qsize_add[8] = port->qsize_add[7] + port->qsize[1]; - port->qsize_add[9] = port->qsize_add[8] + port->qsize[2]; - port->qsize_add[10] = port->qsize_add[9] + port->qsize[2]; - port->qsize_add[11] = port->qsize_add[10] + port->qsize[2]; - - /* TC 3 */ - port->qsize_add[12] = port->qsize_add[11] + port->qsize[2]; - port->qsize_add[13] = port->qsize_add[12] + port->qsize[3]; - port->qsize_add[14] = port->qsize_add[13] + port->qsize[3]; - port->qsize_add[15] = port->qsize_add[14] + port->qsize[3]; - - port->qsize_sum = port->qsize_add[15] + port->qsize[3]; + + /* Strict prority traffic class */ + for (i = 1; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) + port->qsize_add[i] = port->qsize_add[i-1] + port->qsize[i-1]; + + /* Best-effort traffic class */ + port->qsize_add[RTE_SCHED_TRAFFIC_CLASS_BE + 1] = + port->qsize_add[RTE_SCHED_TRAFFIC_CLASS_BE] + + port->qsize[RTE_SCHED_TRAFFIC_CLASS_BE]; + port->qsize_add[RTE_SCHED_TRAFFIC_CLASS_BE + 2] = + port->qsize_add[RTE_SCHED_TRAFFIC_CLASS_BE + 1] + + port->qsize[RTE_SCHED_TRAFFIC_CLASS_BE]; + port->qsize_add[RTE_SCHED_TRAFFIC_CLASS_BE + 3] = + port->qsize_add[RTE_SCHED_TRAFFIC_CLASS_BE + 2] + + port->qsize[RTE_SCHED_TRAFFIC_CLASS_BE]; + + port->qsize_sum = port->qsize_add[RTE_SCHED_TRAFFIC_CLASS_BE + 3] + + port->qsize[RTE_SCHED_TRAFFIC_CLASS_BE]; } static void @@ -481,10 +511,11 @@ rte_sched_port_log_pipe_profile(struct rte_sched_port *port, uint32_t i) struct rte_sched_pipe_profile *p = port->pipe_profiles + i; RTE_LOG(DEBUG, SCHED, "Low level config for pipe profile %u:\n" - " Token bucket: period = %u, credits per period = %u, size = %u\n" - " Traffic classes: period = %u, credits per period = [%u, %u, %u, %u]\n" - " Traffic class 3 oversubscription: weight = %hhu\n" - " WRR cost: [%hhu, %hhu, %hhu, %hhu]\n", + " Token bucket: period = %u, credits per period = %u, size = %u\n" + " Traffic classes: period = %u,\n" + " credits per period = [%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u]\n" + " Best-effort traffic class oversubscription: weight = %hhu\n" + " WRR cost: [%hhu, %hhu, %hhu, %hhu]\n", i, /* Token bucket */ @@ -498,6 +529,15 @@ 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_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], /* Traffic class 3 oversubscription */ p->tc_ov_weight, @@ -517,7 +557,8 @@ rte_sched_time_ms_to_bytes(uint32_t time_ms, uint32_t rate) } static void -rte_sched_pipe_profile_convert(struct rte_sched_pipe_params *src, +rte_sched_pipe_profile_convert(struct rte_sched_port *port, + struct rte_sched_pipe_params *src, struct rte_sched_pipe_profile *dst, uint32_t rate) { @@ -545,13 +586,12 @@ rte_sched_pipe_profile_convert(struct rte_sched_pipe_params *src, 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]); + if (port->qsize[i]) + dst->tc_credits_per_period[i] + = rte_sched_time_ms_to_bytes(src->tc_period, + src->tc_rate[i]); -#ifdef RTE_SCHED_SUBPORT_TC_OV dst->tc_ov_weight = src->tc_ov_weight; -#endif /* WRR queues */ wrr_cost[0] = src->wrr_weights[0]; @@ -584,14 +624,14 @@ rte_sched_port_config_pipe_profile_table(struct rte_sched_port *port, struct rte_sched_pipe_params *src = params->pipe_profiles + i; struct rte_sched_pipe_profile *dst = port->pipe_profiles + i; - rte_sched_pipe_profile_convert(src, dst, params->rate); + rte_sched_pipe_profile_convert(port, src, dst, params->rate); 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]; + uint32_t pipe_tc3_rate = src->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE]; if (port->pipe_tc3_rate_max < pipe_tc3_rate) port->pipe_tc3_rate_max = pipe_tc3_rate; @@ -602,7 +642,7 @@ struct rte_sched_port * rte_sched_port_config(struct rte_sched_port_params *params) { struct rte_sched_port *port = NULL; - uint32_t mem_size, bmp_mem_size, n_queues_per_port, i, cycles_per_byte; + uint32_t mem_size, bmp_mem_size, n_queues_per_port, i, j, cycles_per_byte; /* Check user parameters. Determine the amount of memory to allocate */ mem_size = rte_sched_port_get_memory_footprint(params); @@ -624,6 +664,23 @@ rte_sched_port_config(struct rte_sched_port_params *params) port->n_pipes_per_subport = params->n_pipes_per_subport; port->n_pipes_per_subport_log2 = __builtin_ctz(params->n_pipes_per_subport); + + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) + port->pipe_queue[i] = i; + + for (i = 0, j = 0; i < RTE_SCHED_QUEUES_PER_PIPE; i++) { + port->pipe_tc[i] = j; + + if (j < RTE_SCHED_TRAFFIC_CLASS_BE) + j++; + } + + for (i = 0, j = 0; i < RTE_SCHED_QUEUES_PER_PIPE; i++) { + port->tc_queue[i] = j; + + if (i >= RTE_SCHED_TRAFFIC_CLASS_BE) + j++; + } port->rate = params->rate; port->mtu = params->mtu + params->frame_overhead; port->frame_overhead = params->frame_overhead; @@ -733,12 +790,14 @@ rte_sched_port_free(struct rte_sched_port *port) for (qindex = 0; qindex < n_queues_per_port; qindex++) { struct rte_mbuf **mbufs = rte_sched_port_qbase(port, qindex); uint16_t qsize = rte_sched_port_qsize(port, qindex); - struct rte_sched_queue *queue = port->queue + qindex; - uint16_t qr = queue->qr & (qsize - 1); - uint16_t qw = queue->qw & (qsize - 1); + if (qsize != 0) { + struct rte_sched_queue *queue = port->queue + qindex; + uint16_t qr = queue->qr & (qsize - 1); + uint16_t qw = queue->qw & (qsize - 1); - for (; qr != qw; qr = (qr + 1) & (qsize - 1)) - rte_pktmbuf_free(mbufs[qr]); + for (; qr != qw; qr = (qr + 1) & (qsize - 1)) + rte_pktmbuf_free(mbufs[qr]); + } } rte_bitmap_free(port->bmp); @@ -751,9 +810,10 @@ rte_sched_port_log_subport_config(struct rte_sched_port *port, uint32_t i) struct rte_sched_subport *s = port->subport + i; RTE_LOG(DEBUG, SCHED, "Low level config for subport %u:\n" - " Token bucket: period = %u, credits per period = %u, size = %u\n" - " Traffic classes: period = %u, credits per period = [%u, %u, %u, %u]\n" - " Traffic class 3 oversubscription: wm min = %u, wm max = %u\n", + " Token bucket: period = %u, credits per period = %u, size = %u\n" + " Traffic classes: period = %u\n" + " credits per period = [%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u]\n" + " Best effort traffic class oversubscription: wm min = %u, wm max = %u\n", i, /* Token bucket */ @@ -767,6 +827,15 @@ 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_credits_per_period[4], + s->tc_credits_per_period[5], + s->tc_credits_per_period[6], + s->tc_credits_per_period[7], + s->tc_credits_per_period[8], + s->tc_credits_per_period[9], + s->tc_credits_per_period[10], + s->tc_credits_per_period[11], + s->tc_credits_per_period[12], /* Traffic class 3 oversubscription */ s->tc_ov_wm_min, @@ -794,11 +863,19 @@ rte_sched_subport_config(struct rte_sched_port *port, return -3; for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { - if (params->tc_rate[i] == 0 || - params->tc_rate[i] > params->tb_rate) + uint32_t tc_rate = params->tc_rate[i]; + uint16_t qsize = port->qsize[i]; + + if ((qsize == 0 && tc_rate != 0) || + (qsize != 0 && tc_rate == 0) || + (tc_rate > params->tb_rate)) return -4; } + if (port->qsize[RTE_SCHED_TRAFFIC_CLASS_BE] == 0 || + params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE] == 0) + return -4; + if (params->tc_period == 0) return -5; @@ -822,15 +899,17 @@ rte_sched_subport_config(struct rte_sched_port *port, /* Traffic Classes (TCs) */ s->tc_period = rte_sched_time_ms_to_bytes(params->tc_period, port->rate); for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { - s->tc_credits_per_period[i] - = rte_sched_time_ms_to_bytes(params->tc_period, - params->tc_rate[i]); + if (port->qsize[i]) + s->tc_credits_per_period[i] + = rte_sched_time_ms_to_bytes(params->tc_period, + params->tc_rate[i]); + } s->tc_time = port->time + s->tc_period; for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) - s->tc_credits[i] = s->tc_credits_per_period[i]; + if (port->qsize[i]) + s->tc_credits[i] = s->tc_credits_per_period[i]; -#ifdef RTE_SCHED_SUBPORT_TC_OV /* TC oversubscription */ s->tc_ov_wm_min = port->mtu; s->tc_ov_wm_max = rte_sched_time_ms_to_bytes(params->tc_period, @@ -840,7 +919,6 @@ rte_sched_subport_config(struct rte_sched_port *port, s->tc_ov = 0; s->tc_ov_n = 0; s->tc_ov_rate = 0; -#endif rte_sched_port_log_subport_config(port, subport_id); @@ -880,10 +958,11 @@ rte_sched_pipe_config(struct rte_sched_port *port, if (p->tb_time) { params = port->pipe_profiles + p->profile; -#ifdef RTE_SCHED_SUBPORT_TC_OV - double subport_tc3_rate = (double) s->tc_credits_per_period[3] + double subport_tc3_rate = + (double) s->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] / (double) s->tc_period; - double pipe_tc3_rate = (double) params->tc_credits_per_period[3] + double pipe_tc3_rate = + (double) params->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] / (double) params->tc_period; uint32_t tc3_ov = s->tc_ov; @@ -897,7 +976,6 @@ rte_sched_pipe_config(struct rte_sched_port *port, "Subport %u TC3 oversubscription is OFF (%.4lf >= %.4lf)\n", subport_id, subport_tc3_rate, s->tc_ov_rate); } -#endif /* Reset the pipe */ memset(p, 0, sizeof(struct rte_sched_pipe)); @@ -916,15 +994,18 @@ rte_sched_pipe_config(struct rte_sched_port *port, /* Traffic Classes (TCs) */ p->tc_time = port->time + params->tc_period; + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) - p->tc_credits[i] = params->tc_credits_per_period[i]; + if (port->qsize[i]) + p->tc_credits[i] = params->tc_credits_per_period[i]; -#ifdef RTE_SCHED_SUBPORT_TC_OV { /* Subport TC3 oversubscription */ - double subport_tc3_rate = (double) s->tc_credits_per_period[3] + double subport_tc3_rate = + (double) s->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] / (double) s->tc_period; - double pipe_tc3_rate = (double) params->tc_credits_per_period[3] + double pipe_tc3_rate = + (double) params->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] / (double) params->tc_period; uint32_t tc3_ov = s->tc_ov; @@ -940,7 +1021,6 @@ rte_sched_pipe_config(struct rte_sched_port *port, p->tc_ov_period_id = s->tc_ov_period_id; p->tc_ov_credits = s->tc_ov_wm; } -#endif return 0; } @@ -963,12 +1043,12 @@ rte_sched_port_pipe_profile_add(struct rte_sched_port *port, return -2; /* Pipe params */ - status = pipe_profile_check(params, port->rate); + status = pipe_profile_check(params, port->rate, &port->qsize[0]); if (status != 0) return status; pp = &port->pipe_profiles[port->n_pipe_profiles]; - rte_sched_pipe_profile_convert(params, pp, port->rate); + rte_sched_pipe_profile_convert(port, params, pp, port->rate); /* Pipe profile not exists */ for (i = 0; i < port->n_pipe_profiles; i++) @@ -979,8 +1059,8 @@ rte_sched_port_pipe_profile_add(struct rte_sched_port *port, *pipe_profile_id = port->n_pipe_profiles; port->n_pipe_profiles++; - if (port->pipe_tc3_rate_max < params->tc_rate[3]) - port->pipe_tc3_rate_max = params->tc_rate[3]; + if (port->pipe_tc3_rate_max < params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE]) + port->pipe_tc3_rate_max = params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE]; rte_sched_port_log_pipe_profile(port, *pipe_profile_id); @@ -997,9 +1077,8 @@ rte_sched_port_qindex(struct rte_sched_port *port, return ((subport & (port->n_subports_per_port - 1)) << (port->n_pipes_per_subport_log2 + 4)) | ((pipe & (port->n_pipes_per_subport - 1)) << 4) | - ((traffic_class & - (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1)) << 2) | - (queue & (RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS - 1)); + ((rte_sched_port_pipe_queue(port, traffic_class) + queue) & + (RTE_SCHED_QUEUES_PER_PIPE - 1)); } void @@ -1009,8 +1088,9 @@ rte_sched_port_pkt_write(struct rte_sched_port *port, uint32_t traffic_class, uint32_t queue, enum rte_color color) { - uint32_t queue_id = rte_sched_port_qindex(port, subport, pipe, - traffic_class, queue); + uint32_t queue_id = + rte_sched_port_qindex(port, subport, pipe, traffic_class, queue); + rte_mbuf_sched_set(pkt, queue_id, traffic_class, (uint8_t)color); } @@ -1024,9 +1104,8 @@ rte_sched_port_pkt_read_tree_path(struct rte_sched_port *port, *subport = queue_id >> (port->n_pipes_per_subport_log2 + 4); *pipe = (queue_id >> 4) & (port->n_pipes_per_subport - 1); - *traffic_class = (queue_id >> 2) & - (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1); - *queue = queue_id & (RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS - 1); + *traffic_class = rte_sched_port_pipe_tc(port, queue_id); + *queue = rte_sched_port_tc_queue(port, queue_id); } enum rte_color @@ -1107,7 +1186,7 @@ static inline void rte_sched_port_update_subport_stats(struct rte_sched_port *port, uint32_t qindex, struct rte_mbuf *pkt) { struct rte_sched_subport *s = port->subport + (qindex / rte_sched_port_queues_per_subport(port)); - uint32_t tc_index = (qindex >> 2) & 0x3; + uint32_t tc_index = rte_sched_port_pipe_tc(port, qindex); uint32_t pkt_len = pkt->pkt_len; s->stats.n_pkts_tc[tc_index] += 1; @@ -1127,7 +1206,7 @@ rte_sched_port_update_subport_stats_on_drop(struct rte_sched_port *port, #endif { struct rte_sched_subport *s = port->subport + (qindex / rte_sched_port_queues_per_subport(port)); - uint32_t tc_index = (qindex >> 2) & 0x3; + uint32_t tc_index = rte_sched_port_pipe_tc(port, qindex); uint32_t pkt_len = pkt->pkt_len; s->stats.n_pkts_tc_dropped[tc_index] += 1; @@ -1182,7 +1261,7 @@ rte_sched_port_red_drop(struct rte_sched_port *port, struct rte_mbuf *pkt, uint3 uint32_t tc_index; enum rte_color color; - tc_index = (qindex >> 2) & 0x3; + tc_index = rte_sched_port_pipe_tc(port, qindex); color = rte_sched_port_pkt_read_color(pkt); red_cfg = &port->red_config[tc_index][color]; @@ -1499,6 +1578,7 @@ grinder_credits_update(struct rte_sched_port *port, uint32_t pos) struct rte_sched_pipe *pipe = grinder->pipe; struct rte_sched_pipe_profile *params = grinder->pipe_params; uint64_t n_periods; + uint32_t i; /* Subport TB */ n_periods = (port->time - subport->tb_time) / subport->tb_period; @@ -1514,19 +1594,17 @@ grinder_credits_update(struct rte_sched_port *port, uint32_t pos) /* Subport TCs */ 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]; + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) + subport->tc_credits[i] = subport->tc_credits_per_period[i]; + subport->tc_time = port->time + subport->tc_period; } /* Pipe TCs */ if (unlikely(port->time >= pipe->tc_time)) { - pipe->tc_credits[0] = params->tc_credits_per_period[0]; - pipe->tc_credits[1] = params->tc_credits_per_period[1]; - pipe->tc_credits[2] = params->tc_credits_per_period[2]; - pipe->tc_credits[3] = params->tc_credits_per_period[3]; + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) + pipe->tc_credits[i] = params->tc_credits_per_period[i]; + pipe->tc_time = port->time + params->tc_period; } } @@ -1539,21 +1617,29 @@ 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_consumption = 0, tc_ov_consumption_max; uint32_t tc_ov_wm = subport->tc_ov_wm; + uint32_t i; 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]; + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASS_BE; i++) { + tc_ov_consumption[i] = + subport->tc_credits_per_period[i] - subport->tc_credits[i]; + tc_consumption += tc_ov_consumption[i]; + } + + tc_ov_consumption[RTE_SCHED_TRAFFIC_CLASS_BE] = + subport->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] - + subport->tc_credits[RTE_SCHED_TRAFFIC_CLASS_BE]; - tc_ov_consumption_max = subport->tc_credits_per_period[3] - - (tc_ov_consumption[0] + tc_ov_consumption[1] + tc_ov_consumption[2]); + tc_ov_consumption_max = + subport->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] - + tc_consumption; - if (tc_ov_consumption[3] > (tc_ov_consumption_max - port->mtu)) { + if (tc_ov_consumption[RTE_SCHED_TRAFFIC_CLASS_BE] > + (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; @@ -1576,6 +1662,7 @@ grinder_credits_update(struct rte_sched_port *port, uint32_t pos) struct rte_sched_pipe *pipe = grinder->pipe; struct rte_sched_pipe_profile *params = grinder->pipe_params; uint64_t n_periods; + uint32_t i; /* Subport TB */ n_periods = (port->time - subport->tb_time) / subport->tb_period; @@ -1593,10 +1680,8 @@ grinder_credits_update(struct rte_sched_port *port, uint32_t pos) 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]; + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) + subport->tc_credits[i] = subport->tc_credits_per_period[i]; subport->tc_time = port->time + subport->tc_period; subport->tc_ov_period_id++; @@ -1604,10 +1689,8 @@ grinder_credits_update(struct rte_sched_port *port, uint32_t pos) /* Pipe TCs */ if (unlikely(port->time >= pipe->tc_time)) { - pipe->tc_credits[0] = params->tc_credits_per_period[0]; - pipe->tc_credits[1] = params->tc_credits_per_period[1]; - pipe->tc_credits[2] = params->tc_credits_per_period[2]; - pipe->tc_credits[3] = params->tc_credits_per_period[3]; + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) + pipe->tc_credits[i] = params->tc_credits_per_period[i]; pipe->tc_time = port->time + params->tc_period; } @@ -1672,11 +1755,18 @@ 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_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]; + uint32_t pipe_tc_ov_mask1[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; + uint32_t pipe_tc_ov_mask2[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE] = {0}; + uint32_t pipe_tc_ov_credits, i; int enough_credits; + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) + pipe_tc_ov_mask1[i] = UINT32_MAX; + + pipe_tc_ov_mask1[RTE_SCHED_TRAFFIC_CLASS_BE] = pipe->tc_ov_credits; + pipe_tc_ov_mask2[RTE_SCHED_TRAFFIC_CLASS_BE] = UINT32_MAX; + pipe_tc_ov_credits = pipe_tc_ov_mask1[tc_index]; + /* Check pipe and subport credits */ enough_credits = (pkt_len <= subport_tb_credits) && (pkt_len <= subport_tc_credits) && @@ -1831,31 +1921,23 @@ static inline void grinder_tccache_populate(struct rte_sched_port *port, uint32_t pos, uint32_t qindex, uint16_t qmask) { struct rte_sched_grinder *grinder = port->grinder + pos; - uint8_t b[4]; + uint8_t b, i; grinder->tccache_w = 0; grinder->tccache_r = 0; - b[0] = (uint8_t) (qmask & 0xF); - b[1] = (uint8_t) ((qmask >> 4) & 0xF); - b[2] = (uint8_t) ((qmask >> 8) & 0xF); - b[3] = (uint8_t) ((qmask >> 12) & 0xF); - - grinder->tccache_qmask[grinder->tccache_w] = b[0]; - grinder->tccache_qindex[grinder->tccache_w] = qindex; - grinder->tccache_w += (b[0] != 0); - - grinder->tccache_qmask[grinder->tccache_w] = b[1]; - grinder->tccache_qindex[grinder->tccache_w] = qindex + 4; - grinder->tccache_w += (b[1] != 0); - - grinder->tccache_qmask[grinder->tccache_w] = b[2]; - grinder->tccache_qindex[grinder->tccache_w] = qindex + 8; - grinder->tccache_w += (b[2] != 0); + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASS_BE; i++) { + b = (uint8_t) ((qmask >> i) & 0x1); + grinder->tccache_qmask[grinder->tccache_w] = b; + grinder->tccache_qindex[grinder->tccache_w] = qindex + i; + grinder->tccache_w += (b != 0); + } - grinder->tccache_qmask[grinder->tccache_w] = b[3]; - grinder->tccache_qindex[grinder->tccache_w] = qindex + 12; - grinder->tccache_w += (b[3] != 0); + b = (uint8_t) (qmask >> (RTE_SCHED_TRAFFIC_CLASS_BE)); + grinder->tccache_qmask[grinder->tccache_w] = b; + grinder->tccache_qindex[grinder->tccache_w] = qindex + + RTE_SCHED_TRAFFIC_CLASS_BE; + grinder->tccache_w += (b != 0); } static inline int @@ -1873,14 +1955,18 @@ grinder_next_tc(struct rte_sched_port *port, uint32_t pos) qbase = rte_sched_port_qbase(port, qindex); qsize = rte_sched_port_qsize(port, qindex); - grinder->tc_index = (qindex >> 2) & 0x3; + grinder->tc_index = rte_sched_port_pipe_tc(port, qindex); grinder->qmask = grinder->tccache_qmask[grinder->tccache_r]; grinder->qsize = qsize; - grinder->qindex[0] = qindex; - grinder->qindex[1] = qindex + 1; - grinder->qindex[2] = qindex + 2; - grinder->qindex[3] = qindex + 3; + if (grinder->tc_index < RTE_SCHED_TRAFFIC_CLASS_BE) { + grinder->queue[0] = port->queue + qindex; + grinder->qbase[0] = qbase; + grinder->qindex[0] = qindex; + grinder->tccache_r++; + + return 1; + } grinder->queue[0] = port->queue + qindex; grinder->queue[1] = port->queue + qindex + 1; @@ -1892,6 +1978,11 @@ grinder_next_tc(struct rte_sched_port *port, uint32_t pos) grinder->qbase[2] = qbase + 2 * qsize; grinder->qbase[3] = qbase + 3 * qsize; + grinder->qindex[0] = qindex; + grinder->qindex[1] = qindex + 1; + grinder->qindex[2] = qindex + 2; + grinder->qindex[3] = qindex + 3; + grinder->tccache_r++; return 1; } diff --git a/lib/librte_sched/rte_sched.h b/lib/librte_sched/rte_sched.h index 662c3a057..2b65420d1 100644 --- a/lib/librte_sched/rte_sched.h +++ b/lib/librte_sched/rte_sched.h @@ -85,7 +85,8 @@ extern "C" { /** Number of traffic classes per pipe (as well as subport). * Cannot be changed. */ -#define RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE 4 +#define RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE \ +(RTE_SCHED_QUEUES_PER_PIPE - RTE_SCHED_BE_QUEUES_PER_PIPE + 1) /** Best-effort traffic class ID * Can not change. @@ -177,9 +178,7 @@ struct rte_sched_pipe_params { /**< Traffic class rates (measured in bytes per second) */ uint32_t tc_period; /**< Enforcement period (measured in milliseconds) */ -#ifdef RTE_SCHED_SUBPORT_TC_OV uint8_t tc_ov_weight; /**< Weight Traffic class 3 oversubscription */ -#endif /* Pipe queues */ uint8_t wrr_weights[RTE_SCHED_BE_QUEUES_PER_PIPE]; /**< WRR weights */ -- 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* [dpdk-dev] [PATCH v7 03/11] sched: add max pipe profiles config in run time 2019-07-22 11:01 ` [dpdk-dev] [PATCH v7 00/11] sched: feature enhancements Jasvinder Singh 2019-07-22 11:01 ` [dpdk-dev] [PATCH v7 01/11] sched: remove wrr from strict priority tc queues Jasvinder Singh 2019-07-22 11:01 ` [dpdk-dev] [PATCH v7 02/11] sched: add config flexibility to tc queue sizes Jasvinder Singh @ 2019-07-22 11:01 ` Jasvinder Singh 2019-07-22 11:01 ` [dpdk-dev] [PATCH v7 04/11] sched: rename tc3 params to best-effort tc Jasvinder Singh ` (8 subsequent siblings) 11 siblings, 0 replies; 163+ messages in thread From: Jasvinder Singh @ 2019-07-22 11:01 UTC (permalink / raw) To: dev; +Cc: cristian.dumitrescu, Abraham Tovar, Lukasz Krakowiak Allow setting the maximum number of pipe profiles in run time. Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com> Signed-off-by: Abraham Tovar <abrahamx.tovar@intel.com> Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com> --- lib/librte_sched/rte_sched.c | 8 +++++--- lib/librte_sched/rte_sched.h | 2 ++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/librte_sched/rte_sched.c b/lib/librte_sched/rte_sched.c index a4eaa7a68..ac315d60b 100644 --- a/lib/librte_sched/rte_sched.c +++ b/lib/librte_sched/rte_sched.c @@ -179,6 +179,7 @@ struct rte_sched_port { uint32_t frame_overhead; uint16_t qsize[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; uint32_t n_pipe_profiles; + uint32_t n_max_pipe_profiles; uint32_t pipe_tc3_rate_max; #ifdef RTE_SCHED_RED struct rte_red_config red_config[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE][RTE_COLORS]; @@ -380,7 +381,7 @@ rte_sched_port_check_params(struct rte_sched_port_params *params) /* pipe_profiles and n_pipe_profiles */ if (params->pipe_profiles == NULL || params->n_pipe_profiles == 0 || - params->n_pipe_profiles > RTE_SCHED_PIPE_PROFILES_PER_PORT) + params->n_pipe_profiles > params->n_max_pipe_profiles) return -9; for (i = 0; i < params->n_pipe_profiles; i++) { @@ -409,7 +410,7 @@ rte_sched_port_get_array_base(struct rte_sched_port_params *params, enum rte_sch uint32_t size_queue_extra = n_queues_per_port * sizeof(struct rte_sched_queue_extra); uint32_t size_pipe_profiles - = RTE_SCHED_PIPE_PROFILES_PER_PORT * sizeof(struct rte_sched_pipe_profile); + = params->n_max_pipe_profiles * sizeof(struct rte_sched_pipe_profile); uint32_t size_bmp_array = rte_bitmap_get_memory_footprint(n_queues_per_port); uint32_t size_per_pipe_queue_array, size_queue_array; @@ -686,6 +687,7 @@ rte_sched_port_config(struct rte_sched_port_params *params) port->frame_overhead = params->frame_overhead; memcpy(port->qsize, params->qsize, sizeof(params->qsize)); port->n_pipe_profiles = params->n_pipe_profiles; + port->n_max_pipe_profiles = params->n_max_pipe_profiles; #ifdef RTE_SCHED_RED for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { @@ -1039,7 +1041,7 @@ rte_sched_port_pipe_profile_add(struct rte_sched_port *port, return -1; /* Pipe profiles not exceeds the max limit */ - if (port->n_pipe_profiles >= RTE_SCHED_PIPE_PROFILES_PER_PORT) + if (port->n_pipe_profiles >= port->n_max_pipe_profiles) return -2; /* Pipe params */ diff --git a/lib/librte_sched/rte_sched.h b/lib/librte_sched/rte_sched.h index 2b65420d1..d7d4f1767 100644 --- a/lib/librte_sched/rte_sched.h +++ b/lib/librte_sched/rte_sched.h @@ -220,6 +220,8 @@ struct rte_sched_port_params { /**< Pipe profile table. * Every pipe is configured using one of the profiles from this table. */ uint32_t n_pipe_profiles; /**< Profiles in the pipe profile table */ + uint32_t n_max_pipe_profiles; + /**< Max profiles allowed in the pipe profile table */ #ifdef RTE_SCHED_RED struct rte_red_params red_params[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE][RTE_COLORS]; /**< RED parameters */ #endif -- 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* [dpdk-dev] [PATCH v7 04/11] sched: rename tc3 params to best-effort tc 2019-07-22 11:01 ` [dpdk-dev] [PATCH v7 00/11] sched: feature enhancements Jasvinder Singh ` (2 preceding siblings ...) 2019-07-22 11:01 ` [dpdk-dev] [PATCH v7 03/11] sched: add max pipe profiles config in run time Jasvinder Singh @ 2019-07-22 11:01 ` Jasvinder Singh 2019-07-22 11:01 ` [dpdk-dev] [PATCH v7 05/11] sched: improve error log messages Jasvinder Singh ` (7 subsequent siblings) 11 siblings, 0 replies; 163+ messages in thread From: Jasvinder Singh @ 2019-07-22 11:01 UTC (permalink / raw) To: dev; +Cc: cristian.dumitrescu, Abraham Tovar, Lukasz Krakowiak Change the traffic class 3 related params name to best-effort(be) traffic class. Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com> Signed-off-by: Abraham Tovar <abrahamx.tovar@intel.com> Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com> --- lib/librte_sched/rte_sched.c | 56 ++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/lib/librte_sched/rte_sched.c b/lib/librte_sched/rte_sched.c index ac315d60b..2e7086555 100644 --- a/lib/librte_sched/rte_sched.c +++ b/lib/librte_sched/rte_sched.c @@ -180,7 +180,7 @@ struct rte_sched_port { uint16_t qsize[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; uint32_t n_pipe_profiles; uint32_t n_max_pipe_profiles; - uint32_t pipe_tc3_rate_max; + uint32_t pipe_tc_be_rate_max; #ifdef RTE_SCHED_RED struct rte_red_config red_config[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE][RTE_COLORS]; #endif @@ -323,7 +323,7 @@ pipe_profile_check(struct rte_sched_pipe_params *params, if (params->tc_period == 0) return -14; - /* TC3 oversubscription weight: non-zero */ + /* Best effort tc oversubscription weight: non-zero */ if (params->tc_ov_weight == 0) return -15; @@ -540,7 +540,7 @@ rte_sched_port_log_pipe_profile(struct rte_sched_port *port, uint32_t i) p->tc_credits_per_period[11], p->tc_credits_per_period[12], - /* Traffic class 3 oversubscription */ + /* Best-effort traffic class oversubscription */ p->tc_ov_weight, /* WRR */ @@ -629,13 +629,13 @@ rte_sched_port_config_pipe_profile_table(struct rte_sched_port *port, rte_sched_port_log_pipe_profile(port, i); } - port->pipe_tc3_rate_max = 0; + port->pipe_tc_be_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[RTE_SCHED_TRAFFIC_CLASS_BE]; + uint32_t pipe_tc_be_rate = src->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE]; - if (port->pipe_tc3_rate_max < pipe_tc3_rate) - port->pipe_tc3_rate_max = pipe_tc3_rate; + if (port->pipe_tc_be_rate_max < pipe_tc_be_rate) + port->pipe_tc_be_rate_max = pipe_tc_be_rate; } } @@ -839,7 +839,7 @@ rte_sched_port_log_subport_config(struct rte_sched_port *port, uint32_t i) s->tc_credits_per_period[11], s->tc_credits_per_period[12], - /* Traffic class 3 oversubscription */ + /* Best effort traffic class oversubscription */ s->tc_ov_wm_min, s->tc_ov_wm_max); } @@ -915,7 +915,7 @@ rte_sched_subport_config(struct rte_sched_port *port, /* TC oversubscription */ s->tc_ov_wm_min = port->mtu; s->tc_ov_wm_max = rte_sched_time_ms_to_bytes(params->tc_period, - port->pipe_tc3_rate_max); + port->pipe_tc_be_rate_max); s->tc_ov_wm = s->tc_ov_wm_max; s->tc_ov_period_id = 0; s->tc_ov = 0; @@ -960,23 +960,23 @@ rte_sched_pipe_config(struct rte_sched_port *port, if (p->tb_time) { params = port->pipe_profiles + p->profile; - double subport_tc3_rate = + double subport_tc_be_rate = (double) s->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] / (double) s->tc_period; - double pipe_tc3_rate = + double pipe_tc_be_rate = (double) params->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] / (double) params->tc_period; - uint32_t tc3_ov = s->tc_ov; + uint32_t tc_be_ov = s->tc_ov; /* Unplug pipe from its subport */ 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; + s->tc_ov_rate -= pipe_tc_be_rate; + s->tc_ov = s->tc_ov_rate > subport_tc_be_rate; - if (s->tc_ov != tc3_ov) { + if (s->tc_ov != tc_be_ov) { RTE_LOG(DEBUG, SCHED, - "Subport %u TC3 oversubscription is OFF (%.4lf >= %.4lf)\n", - subport_id, subport_tc3_rate, s->tc_ov_rate); + "Subport %u Best-effort TC oversubscription is OFF (%.4lf >= %.4lf)\n", + subport_id, subport_tc_be_rate, s->tc_ov_rate); } /* Reset the pipe */ @@ -1002,23 +1002,23 @@ rte_sched_pipe_config(struct rte_sched_port *port, p->tc_credits[i] = params->tc_credits_per_period[i]; { - /* Subport TC3 oversubscription */ - double subport_tc3_rate = + /* Subport best effort tc oversubscription */ + double subport_tc_be_rate = (double) s->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] / (double) s->tc_period; - double pipe_tc3_rate = + double pipe_tc_be_rate = (double) params->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] / (double) params->tc_period; - uint32_t tc3_ov = s->tc_ov; + uint32_t tc_be_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; + s->tc_ov_rate += pipe_tc_be_rate; + s->tc_ov = s->tc_ov_rate > subport_tc_be_rate; - if (s->tc_ov != tc3_ov) { + if (s->tc_ov != tc_be_ov) { RTE_LOG(DEBUG, SCHED, - "Subport %u TC3 oversubscription is ON (%.4lf < %.4lf)\n", - subport_id, subport_tc3_rate, s->tc_ov_rate); + "Subport %u Best effort TC oversubscription is ON (%.4lf < %.4lf)\n", + subport_id, subport_tc_be_rate, s->tc_ov_rate); } p->tc_ov_period_id = s->tc_ov_period_id; p->tc_ov_credits = s->tc_ov_wm; @@ -1061,8 +1061,8 @@ rte_sched_port_pipe_profile_add(struct rte_sched_port *port, *pipe_profile_id = port->n_pipe_profiles; port->n_pipe_profiles++; - if (port->pipe_tc3_rate_max < params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE]) - port->pipe_tc3_rate_max = params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE]; + if (port->pipe_tc_be_rate_max < params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE]) + port->pipe_tc_be_rate_max = params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE]; rte_sched_port_log_pipe_profile(port, *pipe_profile_id); -- 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* [dpdk-dev] [PATCH v7 05/11] sched: improve error log messages 2019-07-22 11:01 ` [dpdk-dev] [PATCH v7 00/11] sched: feature enhancements Jasvinder Singh ` (3 preceding siblings ...) 2019-07-22 11:01 ` [dpdk-dev] [PATCH v7 04/11] sched: rename tc3 params to best-effort tc Jasvinder Singh @ 2019-07-22 11:01 ` Jasvinder Singh 2019-07-22 11:01 ` [dpdk-dev] [PATCH v7 06/11] sched: improve doxygen comments Jasvinder Singh ` (6 subsequent siblings) 11 siblings, 0 replies; 163+ messages in thread From: Jasvinder Singh @ 2019-07-22 11:01 UTC (permalink / raw) To: dev; +Cc: cristian.dumitrescu, Abraham Tovar, Lukasz Krakowiak Replace hard-coded numbers for reporting errors with error messages. Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com> Signed-off-by: Abraham Tovar <abrahamx.tovar@intel.com> Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com> --- lib/librte_sched/rte_sched.c | 293 ++++++++++++++++++++++++++--------- 1 file changed, 221 insertions(+), 72 deletions(-) diff --git a/lib/librte_sched/rte_sched.c b/lib/librte_sched/rte_sched.c index 2e7086555..d8ab21d64 100644 --- a/lib/librte_sched/rte_sched.c +++ b/lib/librte_sched/rte_sched.c @@ -296,41 +296,66 @@ pipe_profile_check(struct rte_sched_pipe_params *params, uint32_t i; /* Pipe parameters */ - if (params == NULL) - return -10; + if (params == NULL) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for parameter params\n", __func__); + return -EINVAL; + } /* TB rate: non-zero, not greater than port rate */ if (params->tb_rate == 0 || - params->tb_rate > rate) - return -11; + params->tb_rate > rate) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for tb rate\n", __func__); + return -EINVAL; + } /* TB size: non-zero */ - if (params->tb_size == 0) - return -12; + if (params->tb_size == 0) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for tb size\n", __func__); + return -EINVAL; + } /* TC rate: non-zero if qsize non-zero, less than pipe rate */ for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { if ((qsize[i] == 0 && params->tc_rate[i] != 0) || (qsize[i] != 0 && (params->tc_rate[i] == 0 || - params->tc_rate[i] > params->tb_rate))) - return -13; + params->tc_rate[i] > params->tb_rate))) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for qsize or tc_rate\n", __func__); + return -EINVAL; + } } + if (params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE] == 0 || - qsize[RTE_SCHED_TRAFFIC_CLASS_BE] == 0) - return -13; + qsize[RTE_SCHED_TRAFFIC_CLASS_BE] == 0) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for be traffic class rate\n", __func__); + return -EINVAL; + } /* TC period: non-zero */ - if (params->tc_period == 0) - return -14; + if (params->tc_period == 0) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for tc period\n", __func__); + return -EINVAL; + } /* Best effort tc oversubscription weight: non-zero */ - if (params->tc_ov_weight == 0) - return -15; + if (params->tc_ov_weight == 0) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for tc ov weight\n", __func__); + return -EINVAL; + } /* Queue WRR weights: non-zero */ for (i = 0; i < RTE_SCHED_BE_QUEUES_PER_PIPE; i++) { - if (params->wrr_weights[i] == 0) - return -16; + if (params->wrr_weights[i] == 0) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for wrr weight\n", __func__); + return -EINVAL; + } } return 0; @@ -341,56 +366,83 @@ rte_sched_port_check_params(struct rte_sched_port_params *params) { uint32_t i; - if (params == NULL) - return -1; + if (params == NULL) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for parameter params\n", __func__); + return -EINVAL; + } /* socket */ - if (params->socket < 0) - return -3; + if (params->socket < 0) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for socket id\n", __func__); + return -EINVAL; + } /* rate */ - if (params->rate == 0) - return -4; + if (params->rate == 0) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for rate\n", __func__); + return -EINVAL; + } /* mtu */ - if (params->mtu == 0) - return -5; + if (params->mtu == 0) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for mtu\n", __func__); + return -EINVAL; + } /* n_subports_per_port: non-zero, limited to 16 bits, power of 2 */ if (params->n_subports_per_port == 0 || params->n_subports_per_port > 1u << 16 || - !rte_is_power_of_2(params->n_subports_per_port)) - return -6; + !rte_is_power_of_2(params->n_subports_per_port)) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for number of subports\n", __func__); + return -EINVAL; + } /* 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 -7; + !rte_is_power_of_2(params->n_pipes_per_subport)) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for pipes number\n", __func__); + return -EINVAL; + } - /* qsize: non-zero, power of 2, + /* qsize: if non-zero, power of 2, * no bigger than 32K (due to 16-bit read/write pointers) */ for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { uint16_t qsize = params->qsize[i]; if ((qsize != 0 && !rte_is_power_of_2(qsize)) || - ((i == RTE_SCHED_TRAFFIC_CLASS_BE) && (qsize == 0))) - return -8; + ((i == RTE_SCHED_TRAFFIC_CLASS_BE) && (qsize == 0))) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for tc rate\n", __func__); + return -EINVAL; + } } /* pipe_profiles and n_pipe_profiles */ if (params->pipe_profiles == NULL || params->n_pipe_profiles == 0 || - params->n_pipe_profiles > params->n_max_pipe_profiles) - return -9; + params->n_pipe_profiles > params->n_max_pipe_profiles) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for number of pipe profiles\n", __func__); + return -EINVAL; + } for (i = 0; i < params->n_pipe_profiles; i++) { struct rte_sched_pipe_params *p = params->pipe_profiles + i; int status; status = pipe_profile_check(p, params->rate, ¶ms->qsize[0]); - if (status != 0) - return status; + if (status != 0) { + RTE_LOG(ERR, SCHED, + "%s: Pipe profile check failed(%d)\n", __func__, status); + return -EINVAL; + } } return 0; @@ -853,16 +905,35 @@ rte_sched_subport_config(struct rte_sched_port *port, uint32_t i; /* Check user parameters */ - if (port == NULL || - subport_id >= port->n_subports_per_port || - params == NULL) - return -1; + if (port == NULL) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for parameter port\n", __func__); + return -EINVAL; + } - if (params->tb_rate == 0 || params->tb_rate > port->rate) - return -2; + if (subport_id >= port->n_subports_per_port) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for subport id\n", __func__); + return -EINVAL; + } - if (params->tb_size == 0) - return -3; + 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 > port->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++) { uint32_t tc_rate = params->tc_rate[i]; @@ -870,16 +941,25 @@ rte_sched_subport_config(struct rte_sched_port *port, if ((qsize == 0 && tc_rate != 0) || (qsize != 0 && tc_rate == 0) || - (tc_rate > params->tb_rate)) - return -4; + (tc_rate > params->tb_rate)) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for tc rate\n", __func__); + return -EINVAL; + } } if (port->qsize[RTE_SCHED_TRAFFIC_CLASS_BE] == 0 || - params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE] == 0) - return -4; + params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE] == 0) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for tc rate(best effort)\n", __func__); + return -EINVAL; + } - if (params->tc_period == 0) - return -5; + if (params->tc_period == 0) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for tc period\n", __func__); + return -EINVAL; + } s = port->subport + subport_id; @@ -942,17 +1022,37 @@ rte_sched_pipe_config(struct rte_sched_port *port, profile = (uint32_t) pipe_profile; deactivate = (pipe_profile < 0); - if (port == NULL || - subport_id >= port->n_subports_per_port || - pipe_id >= port->n_pipes_per_subport || - (!deactivate && profile >= port->n_pipe_profiles)) - return -1; + if (port == NULL) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for parameter port\n", __func__); + return -EINVAL; + } + + if (subport_id >= port->n_subports_per_port) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for parameter subport id\n", __func__); + return -EINVAL; + } + if (pipe_id >= port->n_pipes_per_subport) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for parameter pipe id\n", __func__); + return -EINVAL; + } + + if (!deactivate && profile >= port->n_pipe_profiles) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for parameter pipe profile\n", __func__); + return -EINVAL; + } /* Check that subport configuration is valid */ s = port->subport + subport_id; - if (s->tb_period == 0) - return -2; + if (s->tb_period == 0) { + RTE_LOG(ERR, SCHED, + "%s: Subport configuration invalid\n", __func__); + return -EINVAL; + } p = port->pipe + (subport_id * port->n_pipes_per_subport + pipe_id); @@ -1037,25 +1137,37 @@ rte_sched_port_pipe_profile_add(struct rte_sched_port *port, int status; /* Port */ - if (port == NULL) - return -1; + if (port == NULL) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for parameter port\n", __func__); + return -EINVAL; + } /* Pipe profiles not exceeds the max limit */ - if (port->n_pipe_profiles >= port->n_max_pipe_profiles) - return -2; + if (port->n_pipe_profiles >= port->n_max_pipe_profiles) { + RTE_LOG(ERR, SCHED, + "%s: Number of pipe profiles exceeds the max limit\n", __func__); + return -EINVAL; + } /* Pipe params */ status = pipe_profile_check(params, port->rate, &port->qsize[0]); - if (status != 0) - return status; + if (status != 0) { + RTE_LOG(ERR, SCHED, + "%s: Pipe profile check failed(%d)\n", __func__, status); + return -EINVAL; + } pp = &port->pipe_profiles[port->n_pipe_profiles]; rte_sched_pipe_profile_convert(port, params, pp, port->rate); /* Pipe profile not exists */ for (i = 0; i < port->n_pipe_profiles; i++) - if (memcmp(port->pipe_profiles + i, pp, sizeof(*pp)) == 0) - return -3; + if (memcmp(port->pipe_profiles + i, pp, sizeof(*pp)) == 0) { + RTE_LOG(ERR, SCHED, + "%s: Pipe profile doesn't exist\n", __func__); + return -EINVAL; + } /* Pipe profile commit */ *pipe_profile_id = port->n_pipe_profiles; @@ -1125,9 +1237,29 @@ rte_sched_subport_read_stats(struct rte_sched_port *port, struct rte_sched_subport *s; /* Check user parameters */ - if (port == NULL || subport_id >= port->n_subports_per_port || - stats == NULL || tc_ov == NULL) - return -1; + if (port == NULL) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for parameter port\n", __func__); + return -EINVAL; + } + + if (subport_id >= port->n_subports_per_port) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for subport id\n", __func__); + return -EINVAL; + } + + if (stats == NULL) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for parameter stats\n", __func__); + return -EINVAL; + } + + if (tc_ov == NULL) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for tc_ov\n", __func__); + return -EINVAL; + } s = port->subport + subport_id; @@ -1151,11 +1283,28 @@ rte_sched_queue_read_stats(struct rte_sched_port *port, struct rte_sched_queue_extra *qe; /* Check user parameters */ - if ((port == NULL) || - (queue_id >= rte_sched_port_queues_per_port(port)) || - (stats == NULL) || - (qlen == NULL)) { - return -1; + if (port == NULL) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for parameter port\n", __func__); + return -EINVAL; + } + + if (queue_id >= rte_sched_port_queues_per_port(port)) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for queue id\n", __func__); + return -EINVAL; + } + + if (stats == NULL) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for parameter stats\n", __func__); + return -EINVAL; + } + + if (qlen == NULL) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for parameter qlen\n", __func__); + return -EINVAL; } q = port->queue + queue_id; qe = port->queue_extra + queue_id; -- 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* [dpdk-dev] [PATCH v7 06/11] sched: improve doxygen comments 2019-07-22 11:01 ` [dpdk-dev] [PATCH v7 00/11] sched: feature enhancements Jasvinder Singh ` (4 preceding siblings ...) 2019-07-22 11:01 ` [dpdk-dev] [PATCH v7 05/11] sched: improve error log messages Jasvinder Singh @ 2019-07-22 11:01 ` Jasvinder Singh 2019-07-22 11:01 ` [dpdk-dev] [PATCH v7 07/11] net/softnic: add config flexibility to softnic tm Jasvinder Singh ` (5 subsequent siblings) 11 siblings, 0 replies; 163+ messages in thread From: Jasvinder Singh @ 2019-07-22 11:01 UTC (permalink / raw) To: dev; +Cc: cristian.dumitrescu, Abraham Tovar, Lukasz Krakowiak Improve doxygen comments. Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com> Signed-off-by: Abraham Tovar <abrahamx.tovar@intel.com> Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com> --- lib/librte_sched/rte_sched.h | 152 ++++++++++++++++++++++------------- 1 file changed, 94 insertions(+), 58 deletions(-) diff --git a/lib/librte_sched/rte_sched.h b/lib/librte_sched/rte_sched.h index d7d4f1767..fffbad696 100644 --- a/lib/librte_sched/rte_sched.h +++ b/lib/librte_sched/rte_sched.h @@ -52,7 +52,7 @@ extern "C" { * multiple connections of same traffic class belonging to * the same user; * - Weighted Round Robin (WRR) is used to service the - * queues within same pipe traffic class. + * queues within same pipe lowest priority traffic class (best-effort). * */ @@ -83,7 +83,8 @@ extern "C" { #define RTE_SCHED_BE_QUEUES_PER_PIPE 4 /** Number of traffic classes per pipe (as well as subport). - * Cannot be changed. + * @see struct rte_sched_subport_params + * @see struct rte_sched_pipe_params */ #define RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE \ (RTE_SCHED_QUEUES_PER_PIPE - RTE_SCHED_BE_QUEUES_PER_PIPE + 1) @@ -113,6 +114,8 @@ extern "C" { * * The FCS is considered overhead only if not included in the packet * length (field pkt_len of struct rte_mbuf). + * + * @see struct rte_sched_port_params */ #ifndef RTE_SCHED_FRAME_OVERHEAD_DEFAULT #define RTE_SCHED_FRAME_OVERHEAD_DEFAULT 24 @@ -128,34 +131,36 @@ extern "C" { * byte. */ struct rte_sched_subport_params { - /* Subport token bucket */ - uint32_t tb_rate; /**< Rate (measured in bytes per second) */ - uint32_t tb_size; /**< Size (measured in credits) */ + /** Token bucket rate (measured in bytes per second) */ + uint32_t tb_rate; + + /** Token bucket size (measured in credits) */ + uint32_t tb_size; - /* Subport traffic classes */ + /** Traffic class rates (measured in bytes per second) */ uint32_t tc_rate[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; - /**< Traffic class rates (measured in bytes per second) */ + + /** Enforcement period for rates (measured in milliseconds) */ uint32_t tc_period; - /**< Enforcement period for rates (measured in milliseconds) */ }; /** Subport statistics */ struct rte_sched_subport_stats { - /* Packets */ + /** Number of packets successfully written */ uint32_t n_pkts_tc[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; - /**< Number of packets successfully written */ + + /** Number of packets dropped */ uint32_t n_pkts_tc_dropped[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; - /**< Number of packets dropped */ - /* Bytes */ + /** Number of bytes successfully written for each traffic class */ uint32_t n_bytes_tc[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; - /**< Number of bytes successfully written for each traffic class */ + + /** Number of bytes dropped for each traffic class */ uint32_t n_bytes_tc_dropped[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; - /**< Number of bytes dropped for each traffic class */ #ifdef RTE_SCHED_RED + /** Number of packets dropped by red */ uint32_t n_pkts_red_dropped[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; - /**< Number of packets dropped by red */ #endif }; @@ -169,61 +174,90 @@ struct rte_sched_subport_stats { * byte. */ struct rte_sched_pipe_params { - /* Pipe token bucket */ - uint32_t tb_rate; /**< Rate (measured in bytes per second) */ - uint32_t tb_size; /**< Size (measured in credits) */ + /** Token bucket rate (measured in bytes per second) */ + uint32_t tb_rate; - /* Pipe traffic classes */ + /** Token bucket size (measured in credits) */ + uint32_t tb_size; + + /** Traffic class rates (measured in bytes per second) */ uint32_t tc_rate[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; - /**< Traffic class rates (measured in bytes per second) */ + + /** Enforcement period (measured in milliseconds) */ uint32_t tc_period; - /**< Enforcement period (measured in milliseconds) */ - uint8_t tc_ov_weight; /**< Weight Traffic class 3 oversubscription */ - /* Pipe queues */ - uint8_t wrr_weights[RTE_SCHED_BE_QUEUES_PER_PIPE]; /**< WRR weights */ + /** Best-effort traffic class oversubscription weight */ + uint8_t tc_ov_weight; + + /** WRR weights of best-effort traffic class queues */ + uint8_t wrr_weights[RTE_SCHED_BE_QUEUES_PER_PIPE]; }; /** Queue statistics */ struct rte_sched_queue_stats { - /* Packets */ - uint32_t n_pkts; /**< Packets successfully written */ - uint32_t n_pkts_dropped; /**< Packets dropped */ + /** Packets successfully written */ + uint32_t n_pkts; + + /** Packets dropped */ + uint32_t n_pkts_dropped; + #ifdef RTE_SCHED_RED - uint32_t n_pkts_red_dropped; /**< Packets dropped by RED */ + /** Packets dropped by RED */ + uint32_t n_pkts_red_dropped; #endif - /* Bytes */ - uint32_t n_bytes; /**< Bytes successfully written */ - uint32_t n_bytes_dropped; /**< Bytes dropped */ + /** Bytes successfully written */ + uint32_t n_bytes; + + /** Bytes dropped */ + uint32_t n_bytes_dropped; }; /** Port configuration parameters. */ struct rte_sched_port_params { - const char *name; /**< String to be associated */ - int socket; /**< CPU socket ID */ - uint32_t rate; /**< Output port rate - * (measured in bytes per second) */ - uint32_t mtu; /**< Maximum Ethernet frame size - * (measured in bytes). - * Should not include the framing overhead. */ - uint32_t frame_overhead; /**< Framing overhead per packet - * (measured in bytes) */ - uint32_t n_subports_per_port; /**< Number of subports */ - uint32_t n_pipes_per_subport; /**< Number of pipes per subport */ + /** Name of the port to be associated */ + const char *name; + + /** CPU socket ID */ + int socket; + + /** Output port rate (measured in bytes per second) */ + uint32_t rate; + + /** Maximum Ethernet frame size (measured in bytes). + * Should not include the framing overhead. + */ + uint32_t mtu; + + /** Framing overhead per packet (measured in bytes) */ + uint32_t frame_overhead; + + /** Number of subports */ + uint32_t n_subports_per_port; + + /** Number of subport_pipes */ + uint32_t n_pipes_per_subport; + + /** Packet queue size for each traffic class. + * All the pipes within the same subport share the similar + * configuration for the queues. + */ uint16_t qsize[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; - /**< Packet queue size for each traffic class. - * All queues within the same pipe traffic class have the same - * size. Queues from different pipes serving the same traffic - * class have the same size. */ + + /** Pipe profile table. + * Every pipe is configured using one of the profiles from this table. + */ struct rte_sched_pipe_params *pipe_profiles; - /**< Pipe profile table. - * Every pipe is configured using one of the profiles from this table. */ - uint32_t n_pipe_profiles; /**< Profiles in the pipe profile table */ + + /** Profiles in the pipe profile table */ + uint32_t n_pipe_profiles; + + /** Max profiles allowed in the pipe profile table */ uint32_t n_max_pipe_profiles; - /**< Max profiles allowed in the pipe profile table */ + #ifdef RTE_SCHED_RED - struct rte_red_params red_params[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE][RTE_COLORS]; /**< RED parameters */ + /** RED parameters */ + struct rte_red_params red_params[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE][RTE_COLORS]; #endif }; @@ -337,8 +371,9 @@ rte_sched_port_get_memory_footprint(struct rte_sched_port_params *params); * Pointer to pre-allocated subport statistics structure where the statistics * counters should be stored * @param tc_ov - * Pointer to pre-allocated 4-entry array where the oversubscription status for - * each of the 4 subport traffic classes should be stored. + * Pointer to pre-allocated RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE-entry array + * where the oversubscription status for each of the subport traffic classes + * should be stored. * @return * 0 upon success, error code otherwise */ @@ -383,9 +418,10 @@ rte_sched_queue_read_stats(struct rte_sched_port *port, * @param pipe * Pipe ID within subport * @param traffic_class - * Traffic class ID within pipe (0 .. 3) + * Traffic class ID within pipe (0 .. RTE_SCHED_TRAFFIC_CLASS_BE) * @param queue - * Queue ID within pipe traffic class (0 .. 3) + * Queue ID within pipe traffic class, 0 for high priority TCs, and + * 0 .. (RTE_SCHED_BE_QUEUES_PER_PIPE - 1) for best-effort TC * @param color * Packet color set */ @@ -410,10 +446,10 @@ rte_sched_port_pkt_write(struct rte_sched_port *port, * @param pipe * Pipe ID within subport * @param traffic_class - * Traffic class ID within pipe (0 .. 3) + * Traffic class ID within pipe (0 .. RTE_SCHED_TRAFFIC_CLASS_BE) * @param queue - * Queue ID within pipe traffic class (0 .. 3) - * + * Queue ID within pipe traffic class, 0 for high priority TCs, and + * 0 .. (RTE_SCHED_BE_QUEUES_PER_PIPE - 1) for best-effort TC */ void rte_sched_port_pkt_read_tree_path(struct rte_sched_port *port, -- 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* [dpdk-dev] [PATCH v7 07/11] net/softnic: add config flexibility to softnic tm 2019-07-22 11:01 ` [dpdk-dev] [PATCH v7 00/11] sched: feature enhancements Jasvinder Singh ` (5 preceding siblings ...) 2019-07-22 11:01 ` [dpdk-dev] [PATCH v7 06/11] sched: improve doxygen comments Jasvinder Singh @ 2019-07-22 11:01 ` Jasvinder Singh 2019-07-22 11:01 ` [dpdk-dev] [PATCH v7 08/11] test_sched: modify tests for config flexibility Jasvinder Singh ` (4 subsequent siblings) 11 siblings, 0 replies; 163+ messages in thread From: Jasvinder Singh @ 2019-07-22 11:01 UTC (permalink / raw) To: dev; +Cc: cristian.dumitrescu, Abraham Tovar, Lukasz Krakowiak Update softnic tm function for configuration flexiblity of pipe traffic classes and queues size. Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com> Signed-off-by: Abraham Tovar <abrahamx.tovar@intel.com> Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com> --- drivers/net/softnic/rte_eth_softnic.c | 98 ++++ drivers/net/softnic/rte_eth_softnic_cli.c | 449 ++++++++++++++++-- .../net/softnic/rte_eth_softnic_internals.h | 6 +- drivers/net/softnic/rte_eth_softnic_tm.c | 121 +++-- 4 files changed, 605 insertions(+), 69 deletions(-) diff --git a/drivers/net/softnic/rte_eth_softnic.c b/drivers/net/softnic/rte_eth_softnic.c index 4bda2f2b0..e3ad24161 100644 --- a/drivers/net/softnic/rte_eth_softnic.c +++ b/drivers/net/softnic/rte_eth_softnic.c @@ -28,6 +28,16 @@ #define PMD_PARAM_TM_QSIZE1 "tm_qsize1" #define PMD_PARAM_TM_QSIZE2 "tm_qsize2" #define PMD_PARAM_TM_QSIZE3 "tm_qsize3" +#define PMD_PARAM_TM_QSIZE4 "tm_qsize4" +#define PMD_PARAM_TM_QSIZE5 "tm_qsize5" +#define PMD_PARAM_TM_QSIZE6 "tm_qsize6" +#define PMD_PARAM_TM_QSIZE7 "tm_qsize7" +#define PMD_PARAM_TM_QSIZE8 "tm_qsize8" +#define PMD_PARAM_TM_QSIZE9 "tm_qsize9" +#define PMD_PARAM_TM_QSIZE10 "tm_qsize10" +#define PMD_PARAM_TM_QSIZE11 "tm_qsize11" +#define PMD_PARAM_TM_QSIZE12 "tm_qsize12" + static const char * const pmd_valid_args[] = { PMD_PARAM_FIRMWARE, @@ -39,6 +49,15 @@ static const char * const pmd_valid_args[] = { PMD_PARAM_TM_QSIZE1, PMD_PARAM_TM_QSIZE2, PMD_PARAM_TM_QSIZE3, + PMD_PARAM_TM_QSIZE4, + PMD_PARAM_TM_QSIZE5, + PMD_PARAM_TM_QSIZE6, + PMD_PARAM_TM_QSIZE7, + PMD_PARAM_TM_QSIZE8, + PMD_PARAM_TM_QSIZE9, + PMD_PARAM_TM_QSIZE10, + PMD_PARAM_TM_QSIZE11, + PMD_PARAM_TM_QSIZE12, NULL }; @@ -434,6 +453,15 @@ pmd_parse_args(struct pmd_params *p, const char *params) p->tm.qsize[1] = SOFTNIC_TM_QUEUE_SIZE; p->tm.qsize[2] = SOFTNIC_TM_QUEUE_SIZE; p->tm.qsize[3] = SOFTNIC_TM_QUEUE_SIZE; + p->tm.qsize[4] = SOFTNIC_TM_QUEUE_SIZE; + p->tm.qsize[5] = SOFTNIC_TM_QUEUE_SIZE; + p->tm.qsize[6] = SOFTNIC_TM_QUEUE_SIZE; + p->tm.qsize[7] = SOFTNIC_TM_QUEUE_SIZE; + p->tm.qsize[8] = SOFTNIC_TM_QUEUE_SIZE; + p->tm.qsize[9] = SOFTNIC_TM_QUEUE_SIZE; + p->tm.qsize[10] = SOFTNIC_TM_QUEUE_SIZE; + p->tm.qsize[11] = SOFTNIC_TM_QUEUE_SIZE; + p->tm.qsize[12] = SOFTNIC_TM_QUEUE_SIZE; /* Firmware script (optional) */ if (rte_kvargs_count(kvlist, PMD_PARAM_FIRMWARE) == 1) { @@ -504,6 +532,67 @@ pmd_parse_args(struct pmd_params *p, const char *params) goto out_free; } + if (rte_kvargs_count(kvlist, PMD_PARAM_TM_QSIZE4) == 1) { + ret = rte_kvargs_process(kvlist, PMD_PARAM_TM_QSIZE4, + &get_uint32, &p->tm.qsize[4]); + if (ret < 0) + goto out_free; + } + + if (rte_kvargs_count(kvlist, PMD_PARAM_TM_QSIZE5) == 1) { + ret = rte_kvargs_process(kvlist, PMD_PARAM_TM_QSIZE5, + &get_uint32, &p->tm.qsize[5]); + if (ret < 0) + goto out_free; + } + + if (rte_kvargs_count(kvlist, PMD_PARAM_TM_QSIZE6) == 1) { + ret = rte_kvargs_process(kvlist, PMD_PARAM_TM_QSIZE6, + &get_uint32, &p->tm.qsize[6]); + if (ret < 0) + goto out_free; + } + + if (rte_kvargs_count(kvlist, PMD_PARAM_TM_QSIZE7) == 1) { + ret = rte_kvargs_process(kvlist, PMD_PARAM_TM_QSIZE7, + &get_uint32, &p->tm.qsize[7]); + if (ret < 0) + goto out_free; + } + if (rte_kvargs_count(kvlist, PMD_PARAM_TM_QSIZE8) == 1) { + ret = rte_kvargs_process(kvlist, PMD_PARAM_TM_QSIZE8, + &get_uint32, &p->tm.qsize[8]); + if (ret < 0) + goto out_free; + } + if (rte_kvargs_count(kvlist, PMD_PARAM_TM_QSIZE9) == 1) { + ret = rte_kvargs_process(kvlist, PMD_PARAM_TM_QSIZE9, + &get_uint32, &p->tm.qsize[9]); + if (ret < 0) + goto out_free; + } + + if (rte_kvargs_count(kvlist, PMD_PARAM_TM_QSIZE10) == 1) { + ret = rte_kvargs_process(kvlist, PMD_PARAM_TM_QSIZE10, + &get_uint32, &p->tm.qsize[10]); + if (ret < 0) + goto out_free; + } + + if (rte_kvargs_count(kvlist, PMD_PARAM_TM_QSIZE11) == 1) { + ret = rte_kvargs_process(kvlist, PMD_PARAM_TM_QSIZE11, + &get_uint32, &p->tm.qsize[11]); + if (ret < 0) + goto out_free; + } + + if (rte_kvargs_count(kvlist, PMD_PARAM_TM_QSIZE12) == 1) { + ret = rte_kvargs_process(kvlist, PMD_PARAM_TM_QSIZE12, + &get_uint32, &p->tm.qsize[12]); + if (ret < 0) + goto out_free; + } + out_free: rte_kvargs_free(kvlist); return ret; @@ -588,6 +677,15 @@ RTE_PMD_REGISTER_PARAM_STRING(net_softnic, PMD_PARAM_TM_QSIZE1 "=<uint32> " PMD_PARAM_TM_QSIZE2 "=<uint32> " PMD_PARAM_TM_QSIZE3 "=<uint32>" + PMD_PARAM_TM_QSIZE4 "=<uint32> " + PMD_PARAM_TM_QSIZE5 "=<uint32> " + PMD_PARAM_TM_QSIZE6 "=<uint32> " + PMD_PARAM_TM_QSIZE7 "=<uint32> " + PMD_PARAM_TM_QSIZE8 "=<uint32> " + PMD_PARAM_TM_QSIZE9 "=<uint32> " + PMD_PARAM_TM_QSIZE10 "=<uint32> " + PMD_PARAM_TM_QSIZE11 "=<uint32>" + PMD_PARAM_TM_QSIZE12 "=<uint32>" ); diff --git a/drivers/net/softnic/rte_eth_softnic_cli.c b/drivers/net/softnic/rte_eth_softnic_cli.c index 88e0a848e..bc95f1643 100644 --- a/drivers/net/softnic/rte_eth_softnic_cli.c +++ b/drivers/net/softnic/rte_eth_softnic_cli.c @@ -566,8 +566,7 @@ queue_node_id(uint32_t n_spp __rte_unused, uint32_t tc_id, uint32_t queue_id) { - return queue_id + - tc_id * RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE + + return queue_id + tc_id + (pipe_id + subport_id * n_pps) * RTE_SCHED_QUEUES_PER_PIPE; } @@ -617,10 +616,20 @@ tmgr_hierarchy_default(struct pmd_internals *softnic, }, }; + uint32_t *shared_shaper_id = + (uint32_t *)calloc(RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE, + sizeof(uint32_t)); + + if (shared_shaper_id == NULL) + return -1; + + memcpy(shared_shaper_id, params->shared_shaper_id.tc, + sizeof(params->shared_shaper_id.tc)); + struct rte_tm_node_params tc_node_params[] = { [0] = { .shaper_profile_id = params->shaper_profile_id.tc[0], - .shared_shaper_id = ¶ms->shared_shaper_id.tc[0], + .shared_shaper_id = &shared_shaper_id[0], .n_shared_shapers = (¶ms->shared_shaper_id.tc_valid[0]) ? 1 : 0, .nonleaf = { @@ -630,7 +639,7 @@ tmgr_hierarchy_default(struct pmd_internals *softnic, [1] = { .shaper_profile_id = params->shaper_profile_id.tc[1], - .shared_shaper_id = ¶ms->shared_shaper_id.tc[1], + .shared_shaper_id = &shared_shaper_id[1], .n_shared_shapers = (¶ms->shared_shaper_id.tc_valid[1]) ? 1 : 0, .nonleaf = { @@ -640,7 +649,7 @@ tmgr_hierarchy_default(struct pmd_internals *softnic, [2] = { .shaper_profile_id = params->shaper_profile_id.tc[2], - .shared_shaper_id = ¶ms->shared_shaper_id.tc[2], + .shared_shaper_id = &shared_shaper_id[2], .n_shared_shapers = (¶ms->shared_shaper_id.tc_valid[2]) ? 1 : 0, .nonleaf = { @@ -650,13 +659,103 @@ tmgr_hierarchy_default(struct pmd_internals *softnic, [3] = { .shaper_profile_id = params->shaper_profile_id.tc[3], - .shared_shaper_id = ¶ms->shared_shaper_id.tc[3], + .shared_shaper_id = &shared_shaper_id[3], .n_shared_shapers = (¶ms->shared_shaper_id.tc_valid[3]) ? 1 : 0, .nonleaf = { .n_sp_priorities = 1, }, }, + + [4] = { + .shaper_profile_id = params->shaper_profile_id.tc[4], + .shared_shaper_id = &shared_shaper_id[4], + .n_shared_shapers = + (¶ms->shared_shaper_id.tc_valid[4]) ? 1 : 0, + .nonleaf = { + .n_sp_priorities = 1, + }, + }, + + [5] = { + .shaper_profile_id = params->shaper_profile_id.tc[5], + .shared_shaper_id = &shared_shaper_id[5], + .n_shared_shapers = + (¶ms->shared_shaper_id.tc_valid[5]) ? 1 : 0, + .nonleaf = { + .n_sp_priorities = 1, + }, + }, + + [6] = { + .shaper_profile_id = params->shaper_profile_id.tc[6], + .shared_shaper_id = &shared_shaper_id[6], + .n_shared_shapers = + (¶ms->shared_shaper_id.tc_valid[6]) ? 1 : 0, + .nonleaf = { + .n_sp_priorities = 1, + }, + }, + + [7] = { + .shaper_profile_id = params->shaper_profile_id.tc[7], + .shared_shaper_id = &shared_shaper_id[7], + .n_shared_shapers = + (¶ms->shared_shaper_id.tc_valid[7]) ? 1 : 0, + .nonleaf = { + .n_sp_priorities = 1, + }, + }, + + [8] = { + .shaper_profile_id = params->shaper_profile_id.tc[8], + .shared_shaper_id = &shared_shaper_id[8], + .n_shared_shapers = + (¶ms->shared_shaper_id.tc_valid[8]) ? 1 : 0, + .nonleaf = { + .n_sp_priorities = 1, + }, + }, + + [9] = { + .shaper_profile_id = params->shaper_profile_id.tc[9], + .shared_shaper_id = &shared_shaper_id[9], + .n_shared_shapers = + (¶ms->shared_shaper_id.tc_valid[9]) ? 1 : 0, + .nonleaf = { + .n_sp_priorities = 1, + }, + }, + + [10] = { + .shaper_profile_id = params->shaper_profile_id.tc[10], + .shared_shaper_id = &shared_shaper_id[10], + .n_shared_shapers = + (¶ms->shared_shaper_id.tc_valid[10]) ? 1 : 0, + .nonleaf = { + .n_sp_priorities = 1, + }, + }, + + [11] = { + .shaper_profile_id = params->shaper_profile_id.tc[11], + .shared_shaper_id = &shared_shaper_id[11], + .n_shared_shapers = + (¶ms->shared_shaper_id.tc_valid[11]) ? 1 : 0, + .nonleaf = { + .n_sp_priorities = 1, + }, + }, + + [12] = { + .shaper_profile_id = params->shaper_profile_id.tc[12], + .shared_shaper_id = &shared_shaper_id[12], + .n_shared_shapers = + (¶ms->shared_shaper_id.tc_valid[12]) ? 1 : 0, + .nonleaf = { + .n_sp_priorities = 1, + }, + }, }; struct rte_tm_node_params queue_node_params = { @@ -730,7 +829,24 @@ tmgr_hierarchy_default(struct pmd_internals *softnic, return -1; /* Hierarchy level 4: Queue nodes */ - for (q = 0; q < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; q++) { + if (t < RTE_SCHED_TRAFFIC_CLASS_BE) { + /* Strict-priority traffic class queues */ + q = 0; + status = rte_tm_node_add(port_id, + queue_node_id(n_spp, n_pps, s, p, t, q), + tc_node_id(n_spp, n_pps, s, p, t), + 0, + params->weight.queue[q], + RTE_TM_NODE_LEVEL_ID_ANY, + &queue_node_params, + &error); + if (status) + return -1; + + continue; + } + /* Best-effort traffic class queues */ + for (q = 0; q < RTE_SCHED_BE_QUEUES_PER_PIPE; q++) { status = rte_tm_node_add(port_id, queue_node_id(n_spp, n_pps, s, p, t, q), tc_node_id(n_spp, n_pps, s, p, t), @@ -741,7 +857,7 @@ tmgr_hierarchy_default(struct pmd_internals *softnic, &error); if (status) return -1; - } /* Queue */ + } } /* TC */ } /* Pipe */ } /* Subport */ @@ -762,13 +878,31 @@ tmgr_hierarchy_default(struct pmd_internals *softnic, * tc1 <profile_id> * tc2 <profile_id> * tc3 <profile_id> + * tc4 <profile_id> + * tc5 <profile_id> + * tc6 <profile_id> + * tc7 <profile_id> + * tc8 <profile_id> + * tc9 <profile_id> + * tc10 <profile_id> + * tc11 <profile_id> + * tc12 <profile_id> * shared shaper * tc0 <id | none> * tc1 <id | none> * tc2 <id | none> * tc3 <id | none> + * tc4 <id | none> + * tc5 <id | none> + * tc6 <id | none> + * tc7 <id | none> + * tc8 <id | none> + * tc9 <id | none> + * tc10 <id | none> + * tc11 <id | none> + * tc12 <id | none> * weight - * queue <q0> ... <q15> + * queue <q12> ... <q15> */ static void cmd_tmgr_hierarchy_default(struct pmd_internals *softnic, @@ -778,11 +912,11 @@ cmd_tmgr_hierarchy_default(struct pmd_internals *softnic, size_t out_size) { struct tmgr_hierarchy_default_params p; - int i, status; + int i, j, status; memset(&p, 0, sizeof(p)); - if (n_tokens != 50) { + if (n_tokens != 74) { snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); return; } @@ -894,27 +1028,118 @@ cmd_tmgr_hierarchy_default(struct pmd_internals *softnic, return; } + if (strcmp(tokens[22], "tc4") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc4"); + return; + } + + if (softnic_parser_read_uint32(&p.shaper_profile_id.tc[4], tokens[23]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "tc4 profile id"); + return; + } + + if (strcmp(tokens[24], "tc5") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc5"); + return; + } + + if (softnic_parser_read_uint32(&p.shaper_profile_id.tc[5], tokens[25]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "tc5 profile id"); + return; + } + + if (strcmp(tokens[26], "tc6") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc6"); + return; + } + + if (softnic_parser_read_uint32(&p.shaper_profile_id.tc[6], tokens[27]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "tc6 profile id"); + return; + } + + if (strcmp(tokens[28], "tc7") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc7"); + return; + } + + if (softnic_parser_read_uint32(&p.shaper_profile_id.tc[7], tokens[29]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "tc7 profile id"); + return; + } + + if (strcmp(tokens[30], "tc8") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc8"); + return; + } + + if (softnic_parser_read_uint32(&p.shaper_profile_id.tc[8], tokens[31]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "tc8 profile id"); + return; + } + + if (strcmp(tokens[32], "tc9") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc9"); + return; + } + + if (softnic_parser_read_uint32(&p.shaper_profile_id.tc[9], tokens[33]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "tc9 profile id"); + return; + } + + if (strcmp(tokens[34], "tc10") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc10"); + return; + } + + if (softnic_parser_read_uint32(&p.shaper_profile_id.tc[10], tokens[35]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "tc10 profile id"); + return; + } + + if (strcmp(tokens[36], "tc11") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc11"); + return; + } + + if (softnic_parser_read_uint32(&p.shaper_profile_id.tc[11], tokens[37]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "tc11 profile id"); + return; + } + + if (strcmp(tokens[38], "tc12") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc12"); + return; + } + + if (softnic_parser_read_uint32(&p.shaper_profile_id.tc[12], tokens[39]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "tc12 profile id"); + return; + } + /* Shared shaper */ - if (strcmp(tokens[22], "shared") != 0) { + if (strcmp(tokens[40], "shared") != 0) { snprintf(out, out_size, MSG_ARG_NOT_FOUND, "shared"); return; } - if (strcmp(tokens[23], "shaper") != 0) { + if (strcmp(tokens[41], "shaper") != 0) { snprintf(out, out_size, MSG_ARG_NOT_FOUND, "shaper"); return; } - if (strcmp(tokens[24], "tc0") != 0) { + if (strcmp(tokens[42], "tc0") != 0) { snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc0"); return; } - if (strcmp(tokens[25], "none") == 0) + if (strcmp(tokens[43], "none") == 0) p.shared_shaper_id.tc_valid[0] = 0; else { - if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[0], tokens[25]) != 0) { + if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[0], + tokens[43]) != 0) { snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc0"); return; } @@ -922,15 +1147,16 @@ cmd_tmgr_hierarchy_default(struct pmd_internals *softnic, p.shared_shaper_id.tc_valid[0] = 1; } - if (strcmp(tokens[26], "tc1") != 0) { + if (strcmp(tokens[44], "tc1") != 0) { snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc1"); return; } - if (strcmp(tokens[27], "none") == 0) + if (strcmp(tokens[45], "none") == 0) p.shared_shaper_id.tc_valid[1] = 0; else { - if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[1], tokens[27]) != 0) { + if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[1], + tokens[45]) != 0) { snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc1"); return; } @@ -938,15 +1164,16 @@ cmd_tmgr_hierarchy_default(struct pmd_internals *softnic, p.shared_shaper_id.tc_valid[1] = 1; } - if (strcmp(tokens[28], "tc2") != 0) { + if (strcmp(tokens[46], "tc2") != 0) { snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc2"); return; } - if (strcmp(tokens[29], "none") == 0) + if (strcmp(tokens[47], "none") == 0) p.shared_shaper_id.tc_valid[2] = 0; else { - if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[2], tokens[29]) != 0) { + if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[2], + tokens[47]) != 0) { snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc2"); return; } @@ -954,15 +1181,16 @@ cmd_tmgr_hierarchy_default(struct pmd_internals *softnic, p.shared_shaper_id.tc_valid[2] = 1; } - if (strcmp(tokens[30], "tc3") != 0) { + if (strcmp(tokens[48], "tc3") != 0) { snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc3"); return; } - if (strcmp(tokens[31], "none") == 0) + if (strcmp(tokens[49], "none") == 0) p.shared_shaper_id.tc_valid[3] = 0; else { - if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[3], tokens[31]) != 0) { + if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[3], + tokens[49]) != 0) { snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc3"); return; } @@ -970,22 +1198,181 @@ cmd_tmgr_hierarchy_default(struct pmd_internals *softnic, p.shared_shaper_id.tc_valid[3] = 1; } + if (strcmp(tokens[50], "tc4") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc4"); + return; + } + + if (strcmp(tokens[51], "none") == 0) { + p.shared_shaper_id.tc_valid[4] = 0; + } else { + if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[4], + tokens[51]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc4"); + return; + } + + p.shared_shaper_id.tc_valid[4] = 1; + } + + if (strcmp(tokens[52], "tc5") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc5"); + return; + } + + if (strcmp(tokens[53], "none") == 0) { + p.shared_shaper_id.tc_valid[5] = 0; + } else { + if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[5], + tokens[53]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc5"); + return; + } + + p.shared_shaper_id.tc_valid[5] = 1; + } + + if (strcmp(tokens[54], "tc6") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc6"); + return; + } + + if (strcmp(tokens[55], "none") == 0) { + p.shared_shaper_id.tc_valid[6] = 0; + } else { + if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[6], + tokens[55]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc6"); + return; + } + + p.shared_shaper_id.tc_valid[6] = 1; + } + + if (strcmp(tokens[56], "tc7") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc7"); + return; + } + + if (strcmp(tokens[57], "none") == 0) { + p.shared_shaper_id.tc_valid[7] = 0; + } else { + if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[7], + tokens[57]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc7"); + return; + } + + p.shared_shaper_id.tc_valid[7] = 1; + } + + if (strcmp(tokens[58], "tc8") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc8"); + return; + } + + if (strcmp(tokens[59], "none") == 0) { + p.shared_shaper_id.tc_valid[8] = 0; + } else { + if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[8], + tokens[59]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc8"); + return; + } + + p.shared_shaper_id.tc_valid[8] = 1; + } + + if (strcmp(tokens[60], "tc9") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc9"); + return; + } + + if (strcmp(tokens[61], "none") == 0) { + p.shared_shaper_id.tc_valid[9] = 0; + } else { + if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[9], + tokens[61]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc9"); + return; + } + + p.shared_shaper_id.tc_valid[9] = 1; + } + + if (strcmp(tokens[62], "tc10") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc10"); + return; + } + + if (strcmp(tokens[63], "none") == 0) { + p.shared_shaper_id.tc_valid[10] = 0; + } else { + if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[10], + tokens[63]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc10"); + return; + } + + p.shared_shaper_id.tc_valid[10] = 1; + } + + if (strcmp(tokens[64], "tc11") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc11"); + return; + } + + if (strcmp(tokens[65], "none") == 0) { + p.shared_shaper_id.tc_valid[11] = 0; + } else { + if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[11], + tokens[65]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc11"); + return; + } + + p.shared_shaper_id.tc_valid[11] = 1; + } + + if (strcmp(tokens[66], "tc12") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc12"); + return; + } + + if (strcmp(tokens[67], "none") == 0) { + p.shared_shaper_id.tc_valid[12] = 0; + } else { + if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[12], + tokens[67]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc12"); + return; + } + + p.shared_shaper_id.tc_valid[12] = 1; + } + /* Weight */ - if (strcmp(tokens[32], "weight") != 0) { + if (strcmp(tokens[68], "weight") != 0) { snprintf(out, out_size, MSG_ARG_NOT_FOUND, "weight"); return; } - if (strcmp(tokens[33], "queue") != 0) { + if (strcmp(tokens[69], "queue") != 0) { snprintf(out, out_size, MSG_ARG_NOT_FOUND, "queue"); return; } - for (i = 0; i < 16; i++) { - if (softnic_parser_read_uint32(&p.weight.queue[i], tokens[34 + i]) != 0) { - snprintf(out, out_size, MSG_ARG_INVALID, "weight queue"); - return; + for (i = 0, j = 0; i < 16; i++) { + if (i < RTE_SCHED_TRAFFIC_CLASS_BE) { + p.weight.queue[i] = 1; + } else { + if (softnic_parser_read_uint32(&p.weight.queue[i], + tokens[70 + j]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "weight queue"); + return; + } + j++; } } diff --git a/drivers/net/softnic/rte_eth_softnic_internals.h b/drivers/net/softnic/rte_eth_softnic_internals.h index 08bc66051..6eec43b22 100644 --- a/drivers/net/softnic/rte_eth_softnic_internals.h +++ b/drivers/net/softnic/rte_eth_softnic_internals.h @@ -161,13 +161,15 @@ TAILQ_HEAD(softnic_link_list, softnic_link); #define TM_MAX_PIPES_PER_SUBPORT 4096 #endif +#ifndef TM_MAX_PIPE_PROFILE +#define TM_MAX_PIPE_PROFILE 256 +#endif struct tm_params { struct rte_sched_port_params port_params; struct rte_sched_subport_params subport_params[TM_MAX_SUBPORTS]; - struct rte_sched_pipe_params - pipe_profiles[RTE_SCHED_PIPE_PROFILES_PER_PORT]; + struct rte_sched_pipe_params pipe_profiles[TM_MAX_PIPE_PROFILE]; uint32_t n_pipe_profiles; uint32_t pipe_to_profile[TM_MAX_SUBPORTS * TM_MAX_PIPES_PER_SUBPORT]; }; diff --git a/drivers/net/softnic/rte_eth_softnic_tm.c b/drivers/net/softnic/rte_eth_softnic_tm.c index 58744a9eb..61c3adc82 100644 --- a/drivers/net/softnic/rte_eth_softnic_tm.c +++ b/drivers/net/softnic/rte_eth_softnic_tm.c @@ -367,7 +367,9 @@ tm_level_get_max_nodes(struct rte_eth_dev *dev, enum tm_node_level level) { struct pmd_internals *p = dev->data->dev_private; uint32_t n_queues_max = p->params.tm.n_queues; - uint32_t n_tc_max = n_queues_max / RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; + uint32_t n_tc_max = + (n_queues_max * RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE) + / RTE_SCHED_QUEUES_PER_PIPE; uint32_t n_pipes_max = n_tc_max / RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; uint32_t n_subports_max = n_pipes_max; uint32_t n_root_max = 1; @@ -625,10 +627,10 @@ static const struct rte_tm_level_capabilities tm_level_cap[] = { .shaper_shared_n_max = 1, .sched_n_children_max = - RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS, + RTE_SCHED_BE_QUEUES_PER_PIPE, .sched_sp_n_priorities_max = 1, .sched_wfq_n_children_per_group_max = - RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS, + RTE_SCHED_BE_QUEUES_PER_PIPE, .sched_wfq_n_groups_max = 1, .sched_wfq_weight_max = UINT32_MAX, @@ -793,10 +795,10 @@ static const struct rte_tm_node_capabilities tm_node_cap[] = { {.nonleaf = { .sched_n_children_max = - RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS, + RTE_SCHED_BE_QUEUES_PER_PIPE, .sched_sp_n_priorities_max = 1, .sched_wfq_n_children_per_group_max = - RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS, + RTE_SCHED_BE_QUEUES_PER_PIPE, .sched_wfq_n_groups_max = 1, .sched_wfq_weight_max = UINT32_MAX, } }, @@ -2027,9 +2029,7 @@ pipe_profile_build(struct rte_eth_dev *dev, /* Traffic Class (TC) */ pp->tc_period = PIPE_TC_PERIOD; -#ifdef RTE_SCHED_SUBPORT_TC_OV pp->tc_ov_weight = np->weight; -#endif TAILQ_FOREACH(nt, nl, node) { uint32_t queue_id = 0; @@ -2043,15 +2043,13 @@ pipe_profile_build(struct rte_eth_dev *dev, /* Queue */ TAILQ_FOREACH(nq, nl, node) { - uint32_t pipe_queue_id; if (nq->level != TM_NODE_LEVEL_QUEUE || nq->parent_node_id != nt->node_id) continue; - pipe_queue_id = nt->priority * - RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS + queue_id; - pp->wrr_weights[pipe_queue_id] = nq->weight; + if (nt->priority == RTE_SCHED_TRAFFIC_CLASS_BE) + pp->wrr_weights[queue_id] = nq->weight; queue_id++; } @@ -2065,7 +2063,7 @@ pipe_profile_free_exists(struct rte_eth_dev *dev, struct pmd_internals *p = dev->data->dev_private; struct tm_params *t = &p->soft.tm.params; - if (t->n_pipe_profiles < RTE_SCHED_PIPE_PROFILES_PER_PORT) { + if (t->n_pipe_profiles < TM_MAX_PIPE_PROFILE) { *pipe_profile_id = t->n_pipe_profiles; return 1; } @@ -2217,6 +2215,7 @@ wred_profiles_set(struct rte_eth_dev *dev) { struct pmd_internals *p = dev->data->dev_private; struct rte_sched_port_params *pp = &p->soft.tm.params.port_params; + uint32_t tc_id; enum rte_color color; @@ -2332,7 +2331,7 @@ hierarchy_commit_check(struct rte_eth_dev *dev, struct rte_tm_error *error) rte_strerror(EINVAL)); } - /* Each pipe has exactly 4 TCs, with exactly one TC for each priority */ + /* Each pipe has exactly 13 TCs, with exactly one TC for each priority */ TAILQ_FOREACH(np, nl, node) { uint32_t mask = 0, mask_expected = RTE_LEN2MASK(RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE, @@ -2364,12 +2363,14 @@ hierarchy_commit_check(struct rte_eth_dev *dev, struct rte_tm_error *error) rte_strerror(EINVAL)); } - /* Each TC has exactly 4 packet queues. */ + /** Each Strict priority TC has exactly 1 packet queues while + * lowest priority TC (Best-effort) has 4 queues. + */ TAILQ_FOREACH(nt, nl, node) { if (nt->level != TM_NODE_LEVEL_TC) continue; - if (nt->n_children != RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS) + if (nt->n_children != 1 && nt->n_children != RTE_SCHED_BE_QUEUES_PER_PIPE) return -rte_tm_error_set(error, EINVAL, RTE_TM_ERROR_TYPE_UNSPECIFIED, @@ -2531,9 +2532,19 @@ hierarchy_blueprints_create(struct rte_eth_dev *dev) p->params.tm.qsize[1], p->params.tm.qsize[2], p->params.tm.qsize[3], + p->params.tm.qsize[4], + p->params.tm.qsize[5], + p->params.tm.qsize[6], + p->params.tm.qsize[7], + p->params.tm.qsize[8], + p->params.tm.qsize[9], + p->params.tm.qsize[10], + p->params.tm.qsize[11], + p->params.tm.qsize[12], }, .pipe_profiles = t->pipe_profiles, .n_pipe_profiles = t->n_pipe_profiles, + .n_max_pipe_profiles = TM_MAX_PIPE_PROFILE, }; wred_profiles_set(dev); @@ -2566,8 +2577,17 @@ hierarchy_blueprints_create(struct rte_eth_dev *dev) tc_rate[1], tc_rate[2], tc_rate[3], - }, - .tc_period = SUBPORT_TC_PERIOD, + tc_rate[4], + tc_rate[5], + tc_rate[6], + tc_rate[7], + tc_rate[8], + tc_rate[9], + tc_rate[10], + tc_rate[11], + tc_rate[12], + }, + .tc_period = SUBPORT_TC_PERIOD, }; subport_id++; @@ -2657,7 +2677,6 @@ update_queue_weight(struct rte_eth_dev *dev, uint32_t queue_id = tm_node_queue_id(dev, nq); struct tm_node *nt = nq->parent_node; - uint32_t tc_id = tm_node_tc_id(dev, nt); struct tm_node *np = nt->parent_node; uint32_t pipe_id = tm_node_pipe_id(dev, np); @@ -2665,8 +2684,8 @@ update_queue_weight(struct rte_eth_dev *dev, struct tm_node *ns = np->parent_node; uint32_t subport_id = tm_node_subport_id(dev, ns); - uint32_t pipe_queue_id = - tc_id * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS + queue_id; + uint32_t pipe_be_queue_id = + queue_id - RTE_SCHED_TRAFFIC_CLASS_BE; struct rte_sched_pipe_params *profile0 = pipe_profile_get(dev, np); struct rte_sched_pipe_params profile1; @@ -2674,7 +2693,7 @@ update_queue_weight(struct rte_eth_dev *dev, /* Derive new pipe profile. */ memcpy(&profile1, profile0, sizeof(profile1)); - profile1.wrr_weights[pipe_queue_id] = (uint8_t)weight; + profile1.wrr_weights[pipe_be_queue_id] = (uint8_t)weight; /* Since implementation does not allow adding more pipe profiles after * port configuration, the pipe configuration can be successfully @@ -3020,10 +3039,9 @@ tm_port_queue_id(struct rte_eth_dev *dev, uint32_t port_pipe_id = port_subport_id * n_pipes_per_subport + subport_pipe_id; - uint32_t port_tc_id = - port_pipe_id * RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE + pipe_tc_id; + uint32_t port_queue_id = - port_tc_id * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS + tc_queue_id; + port_pipe_id * RTE_SCHED_QUEUES_PER_PIPE + pipe_tc_id + tc_queue_id; return port_queue_id; } @@ -3138,7 +3156,7 @@ read_pipe_stats(struct rte_eth_dev *dev, struct tm_node *ns = np->parent_node; uint32_t subport_id = tm_node_subport_id(dev, ns); - + uint32_t tc_id, queue_id; uint32_t i; /* Stats read */ @@ -3146,11 +3164,19 @@ read_pipe_stats(struct rte_eth_dev *dev, struct rte_sched_queue_stats s; uint16_t qlen; + if (i < RTE_SCHED_TRAFFIC_CLASS_BE) { + tc_id = i; + queue_id = i; + } else { + tc_id = RTE_SCHED_TRAFFIC_CLASS_BE; + queue_id = i - tc_id; + } + uint32_t qid = tm_port_queue_id(dev, subport_id, pipe_id, - i / RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS, - i % RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS); + tc_id, + queue_id); int status = rte_sched_queue_read_stats(SCHED(p), qid, @@ -3198,21 +3224,20 @@ read_tc_stats(struct rte_eth_dev *dev, struct tm_node *ns = np->parent_node; uint32_t subport_id = tm_node_subport_id(dev, ns); - - uint32_t i; + struct rte_sched_queue_stats s; + uint32_t qid, i; + uint16_t qlen; + int status; /* Stats read */ - for (i = 0; i < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; i++) { - struct rte_sched_queue_stats s; - uint16_t qlen; - - uint32_t qid = tm_port_queue_id(dev, + if (tc_id < RTE_SCHED_TRAFFIC_CLASS_BE) { + qid = tm_port_queue_id(dev, subport_id, pipe_id, tc_id, - i); + 0); - int status = rte_sched_queue_read_stats(SCHED(p), + status = rte_sched_queue_read_stats(SCHED(p), qid, &s, &qlen); @@ -3226,6 +3251,30 @@ read_tc_stats(struct rte_eth_dev *dev, nt->stats.leaf.n_bytes_dropped[RTE_COLOR_GREEN] += s.n_bytes_dropped; nt->stats.leaf.n_pkts_queued = qlen; + } else { + for (i = 0; i < RTE_SCHED_BE_QUEUES_PER_PIPE; i++) { + qid = tm_port_queue_id(dev, + subport_id, + pipe_id, + tc_id, + i); + + status = rte_sched_queue_read_stats(SCHED(p), + qid, + &s, + &qlen); + if (status) + return status; + + /* Stats accumulate */ + nt->stats.n_pkts += s.n_pkts - s.n_pkts_dropped; + nt->stats.n_bytes += s.n_bytes - s.n_bytes_dropped; + nt->stats.leaf.n_pkts_dropped[RTE_COLOR_GREEN] += + s.n_pkts_dropped; + nt->stats.leaf.n_bytes_dropped[RTE_COLOR_GREEN] += + s.n_bytes_dropped; + nt->stats.leaf.n_pkts_queued = qlen; + } } /* Stats copy */ -- 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* [dpdk-dev] [PATCH v7 08/11] test_sched: modify tests for config flexibility 2019-07-22 11:01 ` [dpdk-dev] [PATCH v7 00/11] sched: feature enhancements Jasvinder Singh ` (6 preceding siblings ...) 2019-07-22 11:01 ` [dpdk-dev] [PATCH v7 07/11] net/softnic: add config flexibility to softnic tm Jasvinder Singh @ 2019-07-22 11:01 ` Jasvinder Singh 2019-07-22 11:01 ` [dpdk-dev] [PATCH v7 09/11] examples/ip_pipeline: add config flexibility to tm function Jasvinder Singh ` (3 subsequent siblings) 11 siblings, 0 replies; 163+ messages in thread From: Jasvinder Singh @ 2019-07-22 11:01 UTC (permalink / raw) To: dev; +Cc: cristian.dumitrescu, Abraham Tovar, Lukasz Krakowiak update unit tests for configuration flexibility of pipe traffic classes and queues size. Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com> Signed-off-by: Abraham Tovar <abrahamx.tovar@intel.com> Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com> --- app/test/test_sched.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/app/test/test_sched.c b/app/test/test_sched.c index 36fa2d425..afe0b0765 100644 --- a/app/test/test_sched.c +++ b/app/test/test_sched.c @@ -20,14 +20,16 @@ #define SUBPORT 0 #define PIPE 1 #define TC 2 -#define QUEUE 3 +#define QUEUE 0 static struct rte_sched_subport_params subport_param[] = { { .tb_rate = 1250000000, .tb_size = 1000000, - .tc_rate = {1250000000, 1250000000, 1250000000, 1250000000}, + .tc_rate = {1250000000, 1250000000, 1250000000, 1250000000, + 1250000000, 1250000000, 1250000000, 1250000000, 1250000000, + 1250000000, 1250000000, 1250000000, 1250000000}, .tc_period = 10, }, }; @@ -37,8 +39,10 @@ static struct rte_sched_pipe_params pipe_profile[] = { .tb_rate = 305175, .tb_size = 1000000, - .tc_rate = {305175, 305175, 305175, 305175}, + .tc_rate = {305175, 305175, 305175, 305175, 305175, 305175, + 305175, 305175, 305175, 305175, 305175, 305175, 305175}, .tc_period = 40, + .tc_ov_weight = 1, .wrr_weights = {1, 1, 1, 1}, }, @@ -51,9 +55,10 @@ static struct rte_sched_port_params port_param = { .frame_overhead = RTE_SCHED_FRAME_OVERHEAD_DEFAULT, .n_subports_per_port = 1, .n_pipes_per_subport = 1024, - .qsize = {32, 32, 32, 32}, + .qsize = {32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32}, .pipe_profiles = pipe_profile, .n_pipe_profiles = 1, + .n_max_pipe_profiles = 1, }; #define NB_MBUF 32 -- 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* [dpdk-dev] [PATCH v7 09/11] examples/ip_pipeline: add config flexibility to tm function 2019-07-22 11:01 ` [dpdk-dev] [PATCH v7 00/11] sched: feature enhancements Jasvinder Singh ` (7 preceding siblings ...) 2019-07-22 11:01 ` [dpdk-dev] [PATCH v7 08/11] test_sched: modify tests for config flexibility Jasvinder Singh @ 2019-07-22 11:01 ` Jasvinder Singh 2019-07-22 11:01 ` [dpdk-dev] [PATCH v7 10/11] examples/qos_sched: add tc and queue config flexibility Jasvinder Singh ` (2 subsequent siblings) 11 siblings, 0 replies; 163+ messages in thread From: Jasvinder Singh @ 2019-07-22 11:01 UTC (permalink / raw) To: dev; +Cc: cristian.dumitrescu, Abraham Tovar, Lukasz Krakowiak Update ip pipeline sample app for configuration flexiblity of pipe traffic classes and queues. Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com> Signed-off-by: Abraham Tovar <abrahamx.tovar@intel.com> Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com> --- examples/ip_pipeline/cli.c | 43 +++++++++++++++----------- examples/ip_pipeline/tmgr.h | 4 +-- lib/librte_pipeline/rte_table_action.c | 1 - lib/librte_pipeline/rte_table_action.h | 4 +-- 4 files changed, 29 insertions(+), 23 deletions(-) diff --git a/examples/ip_pipeline/cli.c b/examples/ip_pipeline/cli.c index 770b3bcd4..f4c2be8b8 100644 --- a/examples/ip_pipeline/cli.c +++ b/examples/ip_pipeline/cli.c @@ -377,7 +377,9 @@ cmd_swq(char **tokens, static const char cmd_tmgr_subport_profile_help[] = "tmgr subport profile\n" " <tb_rate> <tb_size>\n" -" <tc0_rate> <tc1_rate> <tc2_rate> <tc3_rate>\n" +" <tc0_rate> <tc1_rate> <tc2_rate> <tc3_rate> <tc4_rate>" +" <tc5_rate> <tc6_rate> <tc7_rate> <tc8_rate>" +" <tc9_rate> <tc10_rate> <tc11_rate> <tc12_rate>\n" " <tc_period>\n"; static void @@ -389,7 +391,7 @@ cmd_tmgr_subport_profile(char **tokens, struct rte_sched_subport_params p; int status, i; - if (n_tokens != 10) { + if (n_tokens != 19) { snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); return; } @@ -410,7 +412,7 @@ cmd_tmgr_subport_profile(char **tokens, return; } - if (parser_read_uint32(&p.tc_period, tokens[9]) != 0) { + if (parser_read_uint32(&p.tc_period, tokens[18]) != 0) { snprintf(out, out_size, MSG_ARG_INVALID, "tc_period"); return; } @@ -425,10 +427,12 @@ cmd_tmgr_subport_profile(char **tokens, static const char cmd_tmgr_pipe_profile_help[] = "tmgr pipe profile\n" " <tb_rate> <tb_size>\n" -" <tc0_rate> <tc1_rate> <tc2_rate> <tc3_rate>\n" +" <tc0_rate> <tc1_rate> <tc2_rate> <tc3_rate> <tc4_rate>" +" <tc5_rate> <tc6_rate> <tc7_rate> <tc8_rate>" +" <tc9_rate> <tc10_rate> <tc11_rate> <tc12_rate>\n" " <tc_period>\n" " <tc_ov_weight>\n" -" <wrr_weight0..15>\n"; +" <wrr_weight0..3>\n"; static void cmd_tmgr_pipe_profile(char **tokens, @@ -439,7 +443,7 @@ cmd_tmgr_pipe_profile(char **tokens, struct rte_sched_pipe_params p; int status, i; - if (n_tokens != 27) { + if (n_tokens != 24) { snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); return; } @@ -460,20 +464,20 @@ cmd_tmgr_pipe_profile(char **tokens, return; } - if (parser_read_uint32(&p.tc_period, tokens[9]) != 0) { + if (parser_read_uint32(&p.tc_period, tokens[18]) != 0) { snprintf(out, out_size, MSG_ARG_INVALID, "tc_period"); return; } #ifdef RTE_SCHED_SUBPORT_TC_OV - if (parser_read_uint8(&p.tc_ov_weight, tokens[10]) != 0) { + if (parser_read_uint8(&p.tc_ov_weight, tokens[19]) != 0) { snprintf(out, out_size, MSG_ARG_INVALID, "tc_ov_weight"); return; } #endif - for (i = 0; i < RTE_SCHED_QUEUES_PER_PIPE; i++) - if (parser_read_uint8(&p.wrr_weights[i], tokens[11 + i]) != 0) { + for (i = 0; i < RTE_SCHED_BE_QUEUES_PER_PIPE; i++) + if (parser_read_uint8(&p.wrr_weights[i], tokens[20 + i]) != 0) { snprintf(out, out_size, MSG_ARG_INVALID, "wrr_weights"); return; } @@ -490,7 +494,10 @@ static const char cmd_tmgr_help[] = " rate <rate>\n" " spp <n_subports_per_port>\n" " pps <n_pipes_per_subport>\n" -" qsize <qsize_tc0> <qsize_tc1> <qsize_tc2> <qsize_tc3>\n" +" qsize <qsize_tc0> <qsize_tc1> <qsize_tc2>" +" <qsize_tc3> <qsize_tc4> <qsize_tc5> <qsize_tc6>" +" <qsize_tc7> <qsize_tc8> <qsize_tc9> <qsize_tc10>" +" <qsize_tc11> <qsize_tc12>\n" " fo <frame_overhead>\n" " mtu <mtu>\n" " cpu <cpu_id>\n"; @@ -506,7 +513,7 @@ cmd_tmgr(char **tokens, struct tmgr_port *tmgr_port; int i; - if (n_tokens != 19) { + if (n_tokens != 28) { snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); return; } @@ -554,32 +561,32 @@ cmd_tmgr(char **tokens, return; } - if (strcmp(tokens[13], "fo") != 0) { + if (strcmp(tokens[22], "fo") != 0) { snprintf(out, out_size, MSG_ARG_NOT_FOUND, "fo"); return; } - if (parser_read_uint32(&p.frame_overhead, tokens[14]) != 0) { + if (parser_read_uint32(&p.frame_overhead, tokens[23]) != 0) { snprintf(out, out_size, MSG_ARG_INVALID, "frame_overhead"); return; } - if (strcmp(tokens[15], "mtu") != 0) { + if (strcmp(tokens[24], "mtu") != 0) { snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mtu"); return; } - if (parser_read_uint32(&p.mtu, tokens[16]) != 0) { + if (parser_read_uint32(&p.mtu, tokens[25]) != 0) { snprintf(out, out_size, MSG_ARG_INVALID, "mtu"); return; } - if (strcmp(tokens[17], "cpu") != 0) { + if (strcmp(tokens[26], "cpu") != 0) { snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cpu"); return; } - if (parser_read_uint32(&p.cpu_id, tokens[18]) != 0) { + if (parser_read_uint32(&p.cpu_id, tokens[27]) != 0) { snprintf(out, out_size, MSG_ARG_INVALID, "cpu_id"); return; } diff --git a/examples/ip_pipeline/tmgr.h b/examples/ip_pipeline/tmgr.h index 0b497e795..8703a2e00 100644 --- a/examples/ip_pipeline/tmgr.h +++ b/examples/ip_pipeline/tmgr.h @@ -39,11 +39,11 @@ tmgr_port_find(const char *name); struct tmgr_port_params { uint32_t rate; uint32_t n_subports_per_port; - uint32_t n_pipes_per_subport; - uint16_t qsize[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; uint32_t frame_overhead; uint32_t mtu; uint32_t cpu_id; + uint32_t n_pipes_per_subport; + uint16_t qsize[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; }; int diff --git a/lib/librte_pipeline/rte_table_action.c b/lib/librte_pipeline/rte_table_action.c index a54ec46bc..47d7efbc1 100644 --- a/lib/librte_pipeline/rte_table_action.c +++ b/lib/librte_pipeline/rte_table_action.c @@ -401,7 +401,6 @@ pkt_work_tm(struct rte_mbuf *mbuf, { struct dscp_table_entry_data *dscp_entry = &dscp_table->entry[dscp]; uint32_t queue_id = data->queue_id | - (dscp_entry->tc << 2) | dscp_entry->tc_queue; rte_mbuf_sched_set(mbuf, queue_id, dscp_entry->tc, (uint8_t)dscp_entry->color); diff --git a/lib/librte_pipeline/rte_table_action.h b/lib/librte_pipeline/rte_table_action.h index 44041b5c9..82bc9d9ac 100644 --- a/lib/librte_pipeline/rte_table_action.h +++ b/lib/librte_pipeline/rte_table_action.h @@ -181,10 +181,10 @@ struct rte_table_action_lb_params { * RTE_TABLE_ACTION_MTR */ /** Max number of traffic classes (TCs). */ -#define RTE_TABLE_ACTION_TC_MAX 4 +#define RTE_TABLE_ACTION_TC_MAX 16 /** Max number of queues per traffic class. */ -#define RTE_TABLE_ACTION_TC_QUEUE_MAX 4 +#define RTE_TABLE_ACTION_TC_QUEUE_MAX 16 /** Differentiated Services Code Point (DSCP) translation table entry. */ struct rte_table_action_dscp_table_entry { -- 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* [dpdk-dev] [PATCH v7 10/11] examples/qos_sched: add tc and queue config flexibility 2019-07-22 11:01 ` [dpdk-dev] [PATCH v7 00/11] sched: feature enhancements Jasvinder Singh ` (8 preceding siblings ...) 2019-07-22 11:01 ` [dpdk-dev] [PATCH v7 09/11] examples/ip_pipeline: add config flexibility to tm function Jasvinder Singh @ 2019-07-22 11:01 ` Jasvinder Singh 2019-07-22 11:01 ` [dpdk-dev] [PATCH v7 11/11] sched: remove redundant macros Jasvinder Singh 2019-07-22 13:15 ` [dpdk-dev] [PATCH v7 00/11] sched: feature enhancements Thomas Monjalon 11 siblings, 0 replies; 163+ messages in thread From: Jasvinder Singh @ 2019-07-22 11:01 UTC (permalink / raw) To: dev; +Cc: cristian.dumitrescu, Abraham Tovar, Lukasz Krakowiak Update qos sched sample app for configuration flexibility of pipe traffic classes and queues. Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com> Signed-off-by: Abraham Tovar <abrahamx.tovar@intel.com> Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com> --- examples/qos_sched/app_thread.c | 13 +- examples/qos_sched/cfg_file.c | 130 +++++--- examples/qos_sched/init.c | 63 +++- examples/qos_sched/main.h | 4 + examples/qos_sched/profile.cfg | 67 +++- examples/qos_sched/profile_ov.cfg | 54 ++- examples/qos_sched/stats.c | 526 +++++++++++++++++------------- 7 files changed, 560 insertions(+), 297 deletions(-) diff --git a/examples/qos_sched/app_thread.c b/examples/qos_sched/app_thread.c index e14b275e3..18b734a14 100644 --- a/examples/qos_sched/app_thread.c +++ b/examples/qos_sched/app_thread.c @@ -20,13 +20,11 @@ * QoS parameters are encoded as follows: * Outer VLAN ID defines subport * Inner VLAN ID defines pipe - * Destination IP 0.0.XXX.0 defines traffic class * Destination IP host (0.0.0.XXX) defines queue * Values below define offset to each field from start of frame */ #define SUBPORT_OFFSET 7 #define PIPE_OFFSET 9 -#define TC_OFFSET 20 #define QUEUE_OFFSET 20 #define COLOR_OFFSET 19 @@ -35,16 +33,17 @@ get_pkt_sched(struct rte_mbuf *m, uint32_t *subport, uint32_t *pipe, uint32_t *traffic_class, uint32_t *queue, uint32_t *color) { uint16_t *pdata = rte_pktmbuf_mtod(m, uint16_t *); + uint16_t pipe_queue; *subport = (rte_be_to_cpu_16(pdata[SUBPORT_OFFSET]) & 0x0FFF) & (port_params.n_subports_per_port - 1); /* Outer VLAN ID*/ *pipe = (rte_be_to_cpu_16(pdata[PIPE_OFFSET]) & 0x0FFF) & (port_params.n_pipes_per_subport - 1); /* Inner VLAN ID */ - *traffic_class = (pdata[QUEUE_OFFSET] & 0x0F) & - (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1); /* Destination IP */ - *queue = ((pdata[QUEUE_OFFSET] >> 8) & 0x0F) & - (RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS - 1) ; /* Destination IP */ - *color = pdata[COLOR_OFFSET] & 0x03; /* Destination IP */ + pipe_queue = active_queues[(pdata[QUEUE_OFFSET] >> 8) % n_active_queues]; + *traffic_class = pipe_queue > RTE_SCHED_TRAFFIC_CLASS_BE ? + RTE_SCHED_TRAFFIC_CLASS_BE : pipe_queue; /* Destination IP */ + *queue = pipe_queue - *traffic_class; /* Destination IP */ + *color = pdata[COLOR_OFFSET] & 0x03; /* Destination IP */ return 0; } diff --git a/examples/qos_sched/cfg_file.c b/examples/qos_sched/cfg_file.c index 76ffffc4b..45bf599e4 100644 --- a/examples/qos_sched/cfg_file.c +++ b/examples/qos_sched/cfg_file.c @@ -29,6 +29,9 @@ cfg_load_port(struct rte_cfgfile *cfg, struct rte_sched_port_params *port_params if (!cfg || !port_params) return -1; + memset(active_queues, 0, sizeof(active_queues)); + n_active_queues = 0; + entry = rte_cfgfile_get_entry(cfg, "port", "frame overhead"); if (entry) port_params->frame_overhead = (uint32_t)atoi(entry); @@ -45,12 +48,25 @@ cfg_load_port(struct rte_cfgfile *cfg, struct rte_sched_port_params *port_params if (entry) { char *next; - for(j = 0; j < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; j++) { + for (j = 0; j < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; j++) { port_params->qsize[j] = (uint16_t)strtol(entry, &next, 10); if (next == NULL) break; entry = next; } + + for (j = 0; j < RTE_SCHED_TRAFFIC_CLASS_BE; j++) + if (port_params->qsize[j]) { + active_queues[n_active_queues] = j; + n_active_queues++; + } + + if (port_params->qsize[RTE_SCHED_TRAFFIC_CLASS_BE]) + for (j = 0; j < RTE_SCHED_BE_QUEUES_PER_PIPE; j++) { + active_queues[n_active_queues] = + RTE_SCHED_TRAFFIC_CLASS_BE + j; + n_active_queues++; + } } #ifdef RTE_SCHED_RED @@ -173,46 +189,50 @@ cfg_load_pipe(struct rte_cfgfile *cfg, struct rte_sched_pipe_params *pipe_params if (entry) pipe_params[j].tc_rate[3] = (uint32_t)atoi(entry); -#ifdef RTE_SCHED_SUBPORT_TC_OV - entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 3 oversubscription weight"); + entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 4 rate"); + if (entry) + pipe_params[j].tc_rate[4] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 5 rate"); + if (entry) + pipe_params[j].tc_rate[5] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 6 rate"); + if (entry) + pipe_params[j].tc_rate[6] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 7 rate"); + if (entry) + pipe_params[j].tc_rate[7] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 8 rate"); + if (entry) + pipe_params[j].tc_rate[8] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 9 rate"); + if (entry) + pipe_params[j].tc_rate[9] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 10 rate"); + if (entry) + pipe_params[j].tc_rate[10] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 11 rate"); + if (entry) + pipe_params[j].tc_rate[11] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 12 rate"); + if (entry) + pipe_params[j].tc_rate[12] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 12 oversubscription weight"); if (entry) pipe_params[j].tc_ov_weight = (uint8_t)atoi(entry); -#endif - entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 0 wrr weights"); - if (entry) { - for(i = 0; i < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; i++) { - pipe_params[j].wrr_weights[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE*0 + i] = - (uint8_t)strtol(entry, &next, 10); - if (next == NULL) - break; - entry = next; - } - } - entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 1 wrr weights"); - if (entry) { - for(i = 0; i < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; i++) { - pipe_params[j].wrr_weights[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE*1 + i] = - (uint8_t)strtol(entry, &next, 10); - if (next == NULL) - break; - entry = next; - } - } - entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 2 wrr weights"); - if (entry) { - for(i = 0; i < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; i++) { - pipe_params[j].wrr_weights[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE*2 + i] = - (uint8_t)strtol(entry, &next, 10); - if (next == NULL) - break; - entry = next; - } - } - entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 3 wrr weights"); + entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 12 wrr weights"); if (entry) { - for(i = 0; i < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; i++) { - pipe_params[j].wrr_weights[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE*3 + i] = + for (i = 0; i < RTE_SCHED_BE_QUEUES_PER_PIPE; i++) { + pipe_params[j].wrr_weights[i] = (uint8_t)strtol(entry, &next, 10); if (next == NULL) break; @@ -267,6 +287,42 @@ cfg_load_subport(struct rte_cfgfile *cfg, struct rte_sched_subport_params *subpo if (entry) subport_params[i].tc_rate[3] = (uint32_t)atoi(entry); + entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 4 rate"); + if (entry) + subport_params[i].tc_rate[4] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 5 rate"); + if (entry) + subport_params[i].tc_rate[5] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 6 rate"); + if (entry) + subport_params[i].tc_rate[6] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 7 rate"); + if (entry) + subport_params[i].tc_rate[7] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 8 rate"); + if (entry) + subport_params[i].tc_rate[8] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 9 rate"); + if (entry) + subport_params[i].tc_rate[9] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 10 rate"); + if (entry) + subport_params[i].tc_rate[10] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 11 rate"); + if (entry) + subport_params[i].tc_rate[11] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 12 rate"); + if (entry) + subport_params[i].tc_rate[12] = (uint32_t)atoi(entry); + int n_entries = rte_cfgfile_section_num_entries(cfg, sec_name); struct rte_cfgfile_entry entries[n_entries]; diff --git a/examples/qos_sched/init.c b/examples/qos_sched/init.c index 6b63d4e0e..b05206d5a 100644 --- a/examples/qos_sched/init.c +++ b/examples/qos_sched/init.c @@ -170,17 +170,20 @@ static struct rte_sched_subport_params subport_params[MAX_SCHED_SUBPORTS] = { .tb_rate = 1250000000, .tb_size = 1000000, - .tc_rate = {1250000000, 1250000000, 1250000000, 1250000000}, + .tc_rate = {1250000000, 1250000000, 1250000000, 1250000000, + 1250000000, 1250000000, 1250000000, 1250000000, 1250000000, + 1250000000, 1250000000, 1250000000, 1250000000}, .tc_period = 10, }, }; -static struct rte_sched_pipe_params pipe_profiles[RTE_SCHED_PIPE_PROFILES_PER_PORT] = { +static struct rte_sched_pipe_params pipe_profiles[MAX_SCHED_PIPE_PROFILES] = { { /* Profile #0 */ .tb_rate = 305175, .tb_size = 1000000, - .tc_rate = {305175, 305175, 305175, 305175}, + .tc_rate = {305175, 305175, 305175, 305175, 305175, 305175, + 305175, 305175, 305175, 305175, 305175, 305175, 305175}, .tc_period = 40, #ifdef RTE_SCHED_SUBPORT_TC_OV .tc_ov_weight = 1, @@ -198,9 +201,10 @@ struct rte_sched_port_params port_params = { .frame_overhead = RTE_SCHED_FRAME_OVERHEAD_DEFAULT, .n_subports_per_port = 1, .n_pipes_per_subport = 4096, - .qsize = {64, 64, 64, 64}, + .qsize = {64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64}, .pipe_profiles = pipe_profiles, .n_pipe_profiles = sizeof(pipe_profiles) / sizeof(struct rte_sched_pipe_params), + .n_max_pipe_profiles = MAX_SCHED_PIPE_PROFILES, #ifdef RTE_SCHED_RED .red_params = { @@ -222,8 +226,53 @@ struct rte_sched_port_params port_params = { /* Traffic Class 3 - Colors Green / Yellow / Red */ [3][0] = {.min_th = 48, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, [3][1] = {.min_th = 40, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, - [3][2] = {.min_th = 32, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9} - } + [3][2] = {.min_th = 32, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + + /* Traffic Class 4 - Colors Green / Yellow / Red */ + [4][0] = {.min_th = 48, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [4][1] = {.min_th = 40, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [4][2] = {.min_th = 32, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + + /* Traffic Class 5 - Colors Green / Yellow / Red */ + [5][0] = {.min_th = 48, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [5][1] = {.min_th = 40, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [5][2] = {.min_th = 32, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + + /* Traffic Class 6 - Colors Green / Yellow / Red */ + [6][0] = {.min_th = 48, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [6][1] = {.min_th = 40, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [6][2] = {.min_th = 32, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + + /* Traffic Class 7 - Colors Green / Yellow / Red */ + [7][0] = {.min_th = 48, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [7][1] = {.min_th = 40, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [7][2] = {.min_th = 32, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + + /* Traffic Class 8 - Colors Green / Yellow / Red */ + [8][0] = {.min_th = 48, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [8][1] = {.min_th = 40, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [8][2] = {.min_th = 32, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + + /* Traffic Class 9 - Colors Green / Yellow / Red */ + [9][0] = {.min_th = 48, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [9][1] = {.min_th = 40, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [9][2] = {.min_th = 32, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + + /* Traffic Class 10 - Colors Green / Yellow / Red */ + [10][0] = {.min_th = 48, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [10][1] = {.min_th = 40, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [10][2] = {.min_th = 32, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + + /* Traffic Class 11 - Colors Green / Yellow / Red */ + [11][0] = {.min_th = 48, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [11][1] = {.min_th = 40, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [11][2] = {.min_th = 32, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + + /* Traffic Class 12 - Colors Green / Yellow / Red */ + [12][0] = {.min_th = 48, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [12][1] = {.min_th = 40, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [12][2] = {.min_th = 32, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + }, #endif /* RTE_SCHED_RED */ }; @@ -255,7 +304,7 @@ app_init_sched_port(uint32_t portid, uint32_t socketid) subport, err); } - for (pipe = 0; pipe < port_params.n_pipes_per_subport; pipe ++) { + for (pipe = 0; pipe < port_params.n_pipes_per_subport; pipe++) { if (app_pipe_to_profile[subport][pipe] != -1) { err = rte_sched_pipe_config(port, subport, pipe, app_pipe_to_profile[subport][pipe]); diff --git a/examples/qos_sched/main.h b/examples/qos_sched/main.h index 8a2741c58..d8f890b64 100644 --- a/examples/qos_sched/main.h +++ b/examples/qos_sched/main.h @@ -50,6 +50,7 @@ extern "C" { #define MAX_DATA_STREAMS (APP_MAX_LCORE/2) #define MAX_SCHED_SUBPORTS 8 #define MAX_SCHED_PIPES 4096 +#define MAX_SCHED_PIPE_PROFILES 256 #ifndef APP_COLLECT_STAT #define APP_COLLECT_STAT 1 @@ -147,6 +148,9 @@ extern struct burst_conf burst_conf; extern struct ring_thresh rx_thresh; extern struct ring_thresh tx_thresh; +uint32_t active_queues[RTE_SCHED_QUEUES_PER_PIPE]; +uint32_t n_active_queues; + extern struct rte_sched_port_params port_params; int app_parse_args(int argc, char **argv); diff --git a/examples/qos_sched/profile.cfg b/examples/qos_sched/profile.cfg index f5b704cc6..df7c6d1d8 100644 --- a/examples/qos_sched/profile.cfg +++ b/examples/qos_sched/profile.cfg @@ -1,6 +1,6 @@ ; BSD LICENSE ; -; Copyright(c) 2010-2014 Intel Corporation. All rights reserved. +; Copyright(c) 2010-2019 Intel Corporation. All rights reserved. ; All rights reserved. ; ; Redistribution and use in source and binary forms, with or without @@ -33,12 +33,13 @@ ; 10GbE output port: ; * Single subport (subport 0): ; - Subport rate set to 100% of port rate -; - Each of the 4 traffic classes has rate set to 100% of port rate +; - Each of the 13 traffic classes has rate set to 100% of port rate ; * 4K pipes per subport 0 (pipes 0 .. 4095) with identical configuration: ; - Pipe rate set to 1/4K of port rate -; - Each of the 4 traffic classes has rate set to 100% of pipe rate -; - Within each traffic class, the byte-level WRR weights for the 4 queues -; are set to 1:1:1:1 +; - Each of the 13 traffic classes has rate set to 100% of pipe rate +; - Within lowest priority traffic class (best-effort), the byte-level +; WRR weights for the 4 queues of best effort traffic class are set +; to 1:1:1:1 ; ; For more details, please refer to chapter "Quality of Service (QoS) Framework" ; of Data Plane Development Kit (DPDK) Programmer's Guide. @@ -48,7 +49,7 @@ frame overhead = 24 number of subports per port = 1 number of pipes per subport = 4096 -queue sizes = 64 64 64 64 +queue sizes = 64 64 64 64 64 64 64 64 64 64 64 64 64 ; Subport configuration [subport 0] @@ -59,6 +60,16 @@ tc 0 rate = 1250000000 ; Bytes per second tc 1 rate = 1250000000 ; Bytes per second tc 2 rate = 1250000000 ; Bytes per second tc 3 rate = 1250000000 ; Bytes per second +tc 4 rate = 1250000000 ; Bytes per second +tc 5 rate = 1250000000 ; Bytes per second +tc 6 rate = 1250000000 ; Bytes per second +tc 7 rate = 1250000000 ; Bytes per second +tc 8 rate = 1250000000 ; Bytes per second +tc 9 rate = 1250000000 ; Bytes per second +tc 10 rate = 1250000000 ; Bytes per second +tc 11 rate = 1250000000 ; Bytes per second +tc 12 rate = 1250000000 ; Bytes per second + tc period = 10 ; Milliseconds pipe 0-4095 = 0 ; These pipes are configured with pipe profile 0 @@ -72,14 +83,21 @@ tc 0 rate = 305175 ; Bytes per second tc 1 rate = 305175 ; Bytes per second tc 2 rate = 305175 ; Bytes per second tc 3 rate = 305175 ; Bytes per second -tc period = 40 ; Milliseconds +tc 4 rate = 305175 ; Bytes per second +tc 5 rate = 305175 ; Bytes per second +tc 6 rate = 305175 ; Bytes per second +tc 7 rate = 305175 ; Bytes per second +tc 8 rate = 305175 ; Bytes per second +tc 9 rate = 305175 ; Bytes per second +tc 10 rate = 305175 ; Bytes per second +tc 11 rate = 305175 ; Bytes per second +tc 12 rate = 305175 ; Bytes per second + +tc period = 40 ; Milliseconds -tc 3 oversubscription weight = 1 +tc 12 oversubscription weight = 1 -tc 0 wrr weights = 1 1 1 1 -tc 1 wrr weights = 1 1 1 1 -tc 2 wrr weights = 1 1 1 1 -tc 3 wrr weights = 1 1 1 1 +tc 12 wrr weights = 1 1 1 1 ; RED params per traffic class and color (Green / Yellow / Red) [red] @@ -102,3 +120,28 @@ tc 3 wred min = 48 40 32 tc 3 wred max = 64 64 64 tc 3 wred inv prob = 10 10 10 tc 3 wred weight = 9 9 9 + +tc 4 wred min = 48 40 32 +tc 4 wred max = 64 64 64 +tc 4 wred inv prob = 10 10 10 +tc 4 wred weight = 9 9 9 + +tc 5 wred min = 48 40 32 +tc 5 wred max = 64 64 64 +tc 5 wred inv prob = 10 10 10 +tc 5 wred weight = 9 9 9 + +tc 6 wred min = 48 40 32 +tc 6 wred max = 64 64 64 +tc 6 wred inv prob = 10 10 10 +tc 6 wred weight = 9 9 9 + +tc 7 wred min = 48 40 32 +tc 7 wred max = 64 64 64 +tc 7 wred inv prob = 10 10 10 +tc 7 wred weight = 9 9 9 + +tc 8 wred min = 48 40 32 +tc 8 wred max = 64 64 64 +tc 8 wred inv prob = 10 10 10 +tc 8 wred weight = 9 9 9 diff --git a/examples/qos_sched/profile_ov.cfg b/examples/qos_sched/profile_ov.cfg index 33000df9e..c0b7b3c3d 100644 --- a/examples/qos_sched/profile_ov.cfg +++ b/examples/qos_sched/profile_ov.cfg @@ -1,6 +1,6 @@ ; BSD LICENSE ; -; Copyright(c) 2010-2014 Intel Corporation. All rights reserved. +; Copyright(c) 2010-2019 Intel Corporation. All rights reserved. ; All rights reserved. ; ; Redistribution and use in source and binary forms, with or without @@ -34,7 +34,7 @@ frame overhead = 24 number of subports per port = 1 number of pipes per subport = 32 -queue sizes = 64 64 64 64 +queue sizes = 64 64 64 64 64 64 64 64 64 64 64 64 64 ; Subport configuration [subport 0] @@ -45,6 +45,15 @@ tc 0 rate = 8400000 ; Bytes per second tc 1 rate = 8400000 ; Bytes per second tc 2 rate = 8400000 ; Bytes per second tc 3 rate = 8400000 ; Bytes per second +tc 4 rate = 8400000 ; Bytes per second +tc 5 rate = 8400000 ; Bytes per second +tc 6 rate = 8400000 ; Bytes per second +tc 7 rate = 8400000 ; Bytes per second +tc 8 rate = 8400000 ; Bytes per second +tc 9 rate = 8400000 ; Bytes per second +tc 10 rate = 8400000 ; Bytes per second +tc 11 rate = 8400000 ; Bytes per second +tc 12 rate = 8400000 ; Bytes per second tc period = 10 ; Milliseconds pipe 0-31 = 0 ; These pipes are configured with pipe profile 0 @@ -58,14 +67,20 @@ tc 0 rate = 16800000 ; Bytes per second tc 1 rate = 16800000 ; Bytes per second tc 2 rate = 16800000 ; Bytes per second tc 3 rate = 16800000 ; Bytes per second +tc 4 rate = 16800000 ; Bytes per second +tc 5 rate = 16800000 ; Bytes per second +tc 6 rate = 16800000 ; Bytes per second +tc 7 rate = 16800000 ; Bytes per second +tc 8 rate = 16800000 ; Bytes per second +tc 9 rate = 16800000 ; Bytes per second +tc 10 rate = 16800000 ; Bytes per second +tc 11 rate = 16800000 ; Bytes per second +tc 12 rate = 16800000 ; Bytes per second tc period = 28 ; Milliseconds -tc 3 oversubscription weight = 1 +tc 12 oversubscription weight = 1 -tc 0 wrr weights = 1 1 1 1 -tc 1 wrr weights = 1 1 1 1 -tc 2 wrr weights = 1 1 1 1 -tc 3 wrr weights = 1 1 1 1 +tc 12 wrr weights = 1 1 1 1 ; RED params per traffic class and color (Green / Yellow / Red) [red] @@ -88,3 +103,28 @@ tc 3 wred min = 48 40 32 tc 3 wred max = 64 64 64 tc 3 wred inv prob = 10 10 10 tc 3 wred weight = 9 9 9 + +tc 4 wred min = 48 40 32 +tc 4 wred max = 64 64 64 +tc 4 wred inv prob = 10 10 10 +tc 4 wred weight = 9 9 9 + +tc 5 wred min = 48 40 32 +tc 5 wred max = 64 64 64 +tc 5 wred inv prob = 10 10 10 +tc 5 wred weight = 9 9 9 + +tc 6 wred min = 48 40 32 +tc 6 wred max = 64 64 64 +tc 6 wred inv prob = 10 10 10 +tc 6 wred weight = 9 9 9 + +tc 7 wred min = 48 40 32 +tc 7 wred max = 64 64 64 +tc 7 wred inv prob = 10 10 10 +tc 7 wred weight = 9 9 9 + +tc 8 wred min = 48 40 32 +tc 8 wred max = 64 64 64 +tc 8 wred inv prob = 10 10 10 +tc 8 wred weight = 9 9 9 diff --git a/examples/qos_sched/stats.c b/examples/qos_sched/stats.c index 8193d964c..e62e4a2f6 100644 --- a/examples/qos_sched/stats.c +++ b/examples/qos_sched/stats.c @@ -11,278 +11,350 @@ int qavg_q(uint16_t port_id, uint32_t subport_id, uint32_t pipe_id, uint8_t tc, uint8_t q) { - struct rte_sched_queue_stats stats; - struct rte_sched_port *port; - uint16_t qlen; - uint32_t queue_id, count, i; - uint32_t average; - - for (i = 0; i < nb_pfc; i++) { - if (qos_conf[i].tx_port == port_id) - break; - } - if (i == nb_pfc || subport_id >= port_params.n_subports_per_port || pipe_id >= port_params.n_pipes_per_subport - || tc >= RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE || q >= RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS) - return -1; - - port = qos_conf[i].sched_port; - - queue_id = RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS * (subport_id * port_params.n_pipes_per_subport + pipe_id); - queue_id = queue_id + (tc * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS + q); - - average = 0; - - for (count = 0; count < qavg_ntimes; count++) { - rte_sched_queue_read_stats(port, queue_id, &stats, &qlen); - average += qlen; - usleep(qavg_period); - } - - average /= qavg_ntimes; - - printf("\nAverage queue size: %" PRIu32 " bytes.\n\n", average); - - return 0; + struct rte_sched_queue_stats stats; + struct rte_sched_port *port; + uint16_t qlen; + uint32_t count, i, queue_id = 0; + uint32_t average; + + for (i = 0; i < nb_pfc; i++) { + if (qos_conf[i].tx_port == port_id) + break; + } + + if (i == nb_pfc || + subport_id >= port_params.n_subports_per_port || + pipe_id >= port_params.n_pipes_per_subport || + tc >= RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE || + q >= RTE_SCHED_BE_QUEUES_PER_PIPE || + (tc < RTE_SCHED_TRAFFIC_CLASS_BE && q > 0)) + return -1; + + port = qos_conf[i].sched_port; + for (i = 0; i < subport_id; i++) + queue_id += port_params.n_pipes_per_subport * + RTE_SCHED_QUEUES_PER_PIPE; + if (tc < RTE_SCHED_TRAFFIC_CLASS_BE) + queue_id += pipe_id * RTE_SCHED_QUEUES_PER_PIPE + tc; + else + queue_id += pipe_id * RTE_SCHED_QUEUES_PER_PIPE + tc + q; + + average = 0; + for (count = 0; count < qavg_ntimes; count++) { + rte_sched_queue_read_stats(port, queue_id, &stats, &qlen); + average += qlen; + usleep(qavg_period); + } + + average /= qavg_ntimes; + + printf("\nAverage queue size: %" PRIu32 " bytes.\n\n", average); + + return 0; } int qavg_tcpipe(uint16_t port_id, uint32_t subport_id, uint32_t pipe_id, - uint8_t tc) + uint8_t tc) { - struct rte_sched_queue_stats stats; - struct rte_sched_port *port; - uint16_t qlen; - uint32_t queue_id, count, i; - uint32_t average, part_average; - - for (i = 0; i < nb_pfc; i++) { - if (qos_conf[i].tx_port == port_id) - break; - } - if (i == nb_pfc || subport_id >= port_params.n_subports_per_port || pipe_id >= port_params.n_pipes_per_subport - || tc >= RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE) - return -1; - - port = qos_conf[i].sched_port; - - queue_id = RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS * (subport_id * port_params.n_pipes_per_subport + pipe_id); - - average = 0; - - for (count = 0; count < qavg_ntimes; count++) { - part_average = 0; - for (i = 0; i < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; i++) { - rte_sched_queue_read_stats(port, queue_id + (tc * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS + i), &stats, &qlen); - part_average += qlen; - } - average += part_average / RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; - usleep(qavg_period); - } - - average /= qavg_ntimes; - - printf("\nAverage queue size: %" PRIu32 " bytes.\n\n", average); - - return 0; + struct rte_sched_queue_stats stats; + struct rte_sched_port *port; + uint16_t qlen; + uint32_t count, i, queue_id = 0; + uint32_t average, part_average; + + for (i = 0; i < nb_pfc; i++) { + if (qos_conf[i].tx_port == port_id) + break; + } + + if (i == nb_pfc || subport_id >= port_params.n_subports_per_port || + pipe_id >= port_params.n_pipes_per_subport || + tc >= RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE) + return -1; + + port = qos_conf[i].sched_port; + + for (i = 0; i < subport_id; i++) + queue_id += port_params.n_pipes_per_subport * RTE_SCHED_QUEUES_PER_PIPE; + + queue_id += pipe_id * RTE_SCHED_QUEUES_PER_PIPE + tc; + + average = 0; + + for (count = 0; count < qavg_ntimes; count++) { + part_average = 0; + + if (tc < RTE_SCHED_TRAFFIC_CLASS_BE) { + rte_sched_queue_read_stats(port, queue_id, + &stats, &qlen); + part_average += qlen; + } else { + for (i = 0; i < RTE_SCHED_BE_QUEUES_PER_PIPE; i++) { + rte_sched_queue_read_stats(port, queue_id + i, + &stats, &qlen); + part_average += qlen; + } + average += part_average / RTE_SCHED_BE_QUEUES_PER_PIPE; + } + usleep(qavg_period); + } + + average /= qavg_ntimes; + + printf("\nAverage queue size: %" PRIu32 " bytes.\n\n", average); + + return 0; } int qavg_pipe(uint16_t port_id, uint32_t subport_id, uint32_t pipe_id) { - struct rte_sched_queue_stats stats; - struct rte_sched_port *port; - uint16_t qlen; - uint32_t queue_id, count, i; - uint32_t average, part_average; + struct rte_sched_queue_stats stats; + struct rte_sched_port *port; + uint16_t qlen; + uint32_t count, i, queue_id = 0; + uint32_t average, part_average; + + for (i = 0; i < nb_pfc; i++) { + if (qos_conf[i].tx_port == port_id) + break; + } - for (i = 0; i < nb_pfc; i++) { - if (qos_conf[i].tx_port == port_id) - break; - } - if (i == nb_pfc || subport_id >= port_params.n_subports_per_port || pipe_id >= port_params.n_pipes_per_subport) - return -1; + if (i == nb_pfc || + subport_id >= port_params.n_subports_per_port || + pipe_id >= port_params.n_pipes_per_subport) + return -1; - port = qos_conf[i].sched_port; + port = qos_conf[i].sched_port; - queue_id = RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS * (subport_id * port_params.n_pipes_per_subport + pipe_id); + for (i = 0; i < subport_id; i++) + queue_id += port_params.n_pipes_per_subport * + RTE_SCHED_QUEUES_PER_PIPE; - average = 0; + queue_id += pipe_id * RTE_SCHED_QUEUES_PER_PIPE; - for (count = 0; count < qavg_ntimes; count++) { - part_average = 0; - for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; i++) { - rte_sched_queue_read_stats(port, queue_id + i, &stats, &qlen); - part_average += qlen; - } - average += part_average / (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS); - usleep(qavg_period); - } + average = 0; - average /= qavg_ntimes; + for (count = 0; count < qavg_ntimes; count++) { + part_average = 0; + for (i = 0; i < RTE_SCHED_QUEUES_PER_PIPE; i++) { + rte_sched_queue_read_stats(port, queue_id + i, + &stats, &qlen); + part_average += qlen; + } + average += part_average / RTE_SCHED_QUEUES_PER_PIPE; + usleep(qavg_period); + } - printf("\nAverage queue size: %" PRIu32 " bytes.\n\n", average); + average /= qavg_ntimes; - return 0; + printf("\nAverage queue size: %" PRIu32 " bytes.\n\n", average); + + return 0; } int qavg_tcsubport(uint16_t port_id, uint32_t subport_id, uint8_t tc) { - struct rte_sched_queue_stats stats; - struct rte_sched_port *port; - uint16_t qlen; - uint32_t queue_id, count, i, j; - uint32_t average, part_average; - - for (i = 0; i < nb_pfc; i++) { - if (qos_conf[i].tx_port == port_id) - break; - } - if (i == nb_pfc || subport_id >= port_params.n_subports_per_port || tc >= RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE) - return -1; - - port = qos_conf[i].sched_port; - - average = 0; - - for (count = 0; count < qavg_ntimes; count++) { - part_average = 0; - for (i = 0; i < port_params.n_pipes_per_subport; i++) { - queue_id = RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS * (subport_id * port_params.n_pipes_per_subport + i); - - for (j = 0; j < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; j++) { - rte_sched_queue_read_stats(port, queue_id + (tc * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS + j), &stats, &qlen); - part_average += qlen; - } - } - - average += part_average / (port_params.n_pipes_per_subport * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS); - usleep(qavg_period); - } - - average /= qavg_ntimes; - - printf("\nAverage queue size: %" PRIu32 " bytes.\n\n", average); - - return 0; + struct rte_sched_queue_stats stats; + struct rte_sched_port *port; + uint16_t qlen; + uint32_t queue_id, count, i, j, subport_queue_id = 0; + uint32_t average, part_average; + + for (i = 0; i < nb_pfc; i++) { + if (qos_conf[i].tx_port == port_id) + break; + } + + if (i == nb_pfc || + subport_id >= port_params.n_subports_per_port || + tc >= RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE) + return -1; + + port = qos_conf[i].sched_port; + + for (i = 0; i < subport_id; i++) + subport_queue_id += + port_params.n_pipes_per_subport * RTE_SCHED_QUEUES_PER_PIPE; + + average = 0; + + for (count = 0; count < qavg_ntimes; count++) { + part_average = 0; + for (i = 0; i < port_params.n_pipes_per_subport; i++) { + if (tc < RTE_SCHED_TRAFFIC_CLASS_BE) { + queue_id = subport_queue_id + + i * RTE_SCHED_QUEUES_PER_PIPE + tc; + rte_sched_queue_read_stats(port, queue_id, + &stats, &qlen); + part_average += qlen; + } else { + for (j = 0; j < RTE_SCHED_BE_QUEUES_PER_PIPE; j++) { + queue_id = subport_queue_id + + i * RTE_SCHED_QUEUES_PER_PIPE + + tc + j; + rte_sched_queue_read_stats(port, queue_id, + &stats, &qlen); + part_average += qlen; + } + } + } + + if (tc < RTE_SCHED_TRAFFIC_CLASS_BE) + average += part_average / (port_params.n_pipes_per_subport); + else + average += + part_average / (port_params.n_pipes_per_subport) * + RTE_SCHED_BE_QUEUES_PER_PIPE; + + usleep(qavg_period); + } + + average /= qavg_ntimes; + + printf("\nAverage queue size: %" PRIu32 " bytes.\n\n", average); + + return 0; } int qavg_subport(uint16_t port_id, uint32_t subport_id) { - struct rte_sched_queue_stats stats; - struct rte_sched_port *port; - uint16_t qlen; - uint32_t queue_id, count, i, j; - uint32_t average, part_average; + struct rte_sched_queue_stats stats; + struct rte_sched_port *port; + uint16_t qlen; + uint32_t queue_id, count, i, j, subport_queue_id = 0; + uint32_t average, part_average; + + for (i = 0; i < nb_pfc; i++) { + if (qos_conf[i].tx_port == port_id) + break; + } + + if (i == nb_pfc || + subport_id >= port_params.n_subports_per_port) + return -1; - for (i = 0; i < nb_pfc; i++) { - if (qos_conf[i].tx_port == port_id) - break; - } - if (i == nb_pfc || subport_id >= port_params.n_subports_per_port) - return -1; + port = qos_conf[i].sched_port; - port = qos_conf[i].sched_port; + for (i = 0; i < subport_id; i++) + subport_queue_id += port_params.n_pipes_per_subport * + RTE_SCHED_QUEUES_PER_PIPE; - average = 0; + average = 0; - for (count = 0; count < qavg_ntimes; count++) { - part_average = 0; - for (i = 0; i < port_params.n_pipes_per_subport; i++) { - queue_id = RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS * (subport_id * port_params.n_pipes_per_subport + i); + for (count = 0; count < qavg_ntimes; count++) { + part_average = 0; + for (i = 0; i < port_params.n_pipes_per_subport; i++) { + queue_id = subport_queue_id + i * RTE_SCHED_QUEUES_PER_PIPE; - for (j = 0; j < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; j++) { - rte_sched_queue_read_stats(port, queue_id + j, &stats, &qlen); - part_average += qlen; - } - } + for (j = 0; j < RTE_SCHED_QUEUES_PER_PIPE; j++) { + rte_sched_queue_read_stats(port, queue_id + j, + &stats, &qlen); + part_average += qlen; + } + } - average += part_average / (port_params.n_pipes_per_subport * RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS); - usleep(qavg_period); - } + average += part_average / + (port_params.n_pipes_per_subport * RTE_SCHED_QUEUES_PER_PIPE); + usleep(qavg_period); + } - average /= qavg_ntimes; + average /= qavg_ntimes; - printf("\nAverage queue size: %" PRIu32 " bytes.\n\n", average); + printf("\nAverage queue size: %" PRIu32 " bytes.\n\n", average); - return 0; + return 0; } int subport_stat(uint16_t port_id, uint32_t subport_id) { - struct rte_sched_subport_stats stats; - struct rte_sched_port *port; - uint32_t tc_ov[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; - uint8_t i; - - for (i = 0; i < nb_pfc; i++) { - if (qos_conf[i].tx_port == port_id) - break; - } - if (i == nb_pfc || subport_id >= port_params.n_subports_per_port) - return -1; - - port = qos_conf[i].sched_port; - memset (tc_ov, 0, sizeof(tc_ov)); - - rte_sched_subport_read_stats(port, subport_id, &stats, tc_ov); - - printf("\n"); - printf("+----+-------------+-------------+-------------+-------------+-------------+\n"); - printf("| TC | Pkts OK |Pkts Dropped | Bytes OK |Bytes Dropped| OV Status |\n"); - printf("+----+-------------+-------------+-------------+-------------+-------------+\n"); - - for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { - printf("| %d | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " |\n", i, - stats.n_pkts_tc[i], stats.n_pkts_tc_dropped[i], - stats.n_bytes_tc[i], stats.n_bytes_tc_dropped[i], tc_ov[i]); - printf("+----+-------------+-------------+-------------+-------------+-------------+\n"); - } - printf("\n"); - - return 0; + struct rte_sched_subport_stats stats; + struct rte_sched_port *port; + uint32_t tc_ov[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; + uint8_t i; + + for (i = 0; i < nb_pfc; i++) { + if (qos_conf[i].tx_port == port_id) + break; + } + + if (i == nb_pfc || subport_id >= port_params.n_subports_per_port) + return -1; + + port = qos_conf[i].sched_port; + memset(tc_ov, 0, sizeof(tc_ov)); + + rte_sched_subport_read_stats(port, subport_id, &stats, tc_ov); + + printf("\n"); + printf("+----+-------------+-------------+-------------+-------------+-------------+\n"); + printf("| TC | Pkts OK |Pkts Dropped | Bytes OK |Bytes Dropped| OV Status |\n"); + printf("+----+-------------+-------------+-------------+-------------+-------------+\n"); + + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { + printf("| %d | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " |\n", + i, stats.n_pkts_tc[i], stats.n_pkts_tc_dropped[i], + stats.n_bytes_tc[i], stats.n_bytes_tc_dropped[i], tc_ov[i]); + printf("+----+-------------+-------------+-------------+-------------+-------------+\n"); + } + printf("\n"); + + return 0; } int pipe_stat(uint16_t port_id, uint32_t subport_id, uint32_t pipe_id) { - struct rte_sched_queue_stats stats; - struct rte_sched_port *port; - uint16_t qlen; - uint8_t i, j; - uint32_t queue_id; - - for (i = 0; i < nb_pfc; i++) { - if (qos_conf[i].tx_port == port_id) - break; - } - if (i == nb_pfc || subport_id >= port_params.n_subports_per_port || pipe_id >= port_params.n_pipes_per_subport) - return -1; - - port = qos_conf[i].sched_port; - - queue_id = RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS * (subport_id * port_params.n_pipes_per_subport + pipe_id); - - printf("\n"); - printf("+----+-------+-------------+-------------+-------------+-------------+-------------+\n"); - printf("| TC | Queue | Pkts OK |Pkts Dropped | Bytes OK |Bytes Dropped| Length |\n"); - printf("+----+-------+-------------+-------------+-------------+-------------+-------------+\n"); - - for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { - for (j = 0; j < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; j++) { - - rte_sched_queue_read_stats(port, queue_id + (i * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS + j), &stats, &qlen); - - printf("| %d | %d | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " | %11i |\n", i, j, - stats.n_pkts, stats.n_pkts_dropped, stats.n_bytes, stats.n_bytes_dropped, qlen); - printf("+----+-------+-------------+-------------+-------------+-------------+-------------+\n"); - } - if (i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1) - printf("+----+-------+-------------+-------------+-------------+-------------+-------------+\n"); - } - printf("\n"); - - return 0; + struct rte_sched_queue_stats stats; + struct rte_sched_port *port; + uint16_t qlen; + uint8_t i, j; + uint32_t queue_id = 0; + + for (i = 0; i < nb_pfc; i++) { + if (qos_conf[i].tx_port == port_id) + break; + } + + if (i == nb_pfc || + subport_id >= port_params.n_subports_per_port || + pipe_id >= port_params.n_pipes_per_subport) + return -1; + + port = qos_conf[i].sched_port; + for (i = 0; i < subport_id; i++) + queue_id += port_params.n_pipes_per_subport * RTE_SCHED_QUEUES_PER_PIPE; + + queue_id += pipe_id * RTE_SCHED_QUEUES_PER_PIPE; + + printf("\n"); + printf("+----+-------+-------------+-------------+-------------+-------------+-------------+\n"); + printf("| TC | Queue | Pkts OK |Pkts Dropped | Bytes OK |Bytes Dropped| Length |\n"); + printf("+----+-------+-------------+-------------+-------------+-------------+-------------+\n"); + + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { + if (i < RTE_SCHED_TRAFFIC_CLASS_BE) { + rte_sched_queue_read_stats(port, queue_id + i, &stats, &qlen); + printf("| %d | %d | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " | %11i |\n", + i, 0, stats.n_pkts, stats.n_pkts_dropped, stats.n_bytes, + stats.n_bytes_dropped, qlen); + printf("+----+-------+-------------+-------------+-------------+-------------+-------------+\n"); + } else { + for (j = 0; j < RTE_SCHED_BE_QUEUES_PER_PIPE; j++) { + rte_sched_queue_read_stats(port, queue_id + i + j, + &stats, &qlen); + printf("| %d | %d | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " | %11i |\n", + i, j, stats.n_pkts, stats.n_pkts_dropped, stats.n_bytes, + stats.n_bytes_dropped, qlen); + printf("+----+-------+-------------+-------------+-------------+-------------+-------------+\n"); + } + } + } + printf("\n"); + + return 0; } -- 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* [dpdk-dev] [PATCH v7 11/11] sched: remove redundant macros 2019-07-22 11:01 ` [dpdk-dev] [PATCH v7 00/11] sched: feature enhancements Jasvinder Singh ` (9 preceding siblings ...) 2019-07-22 11:01 ` [dpdk-dev] [PATCH v7 10/11] examples/qos_sched: add tc and queue config flexibility Jasvinder Singh @ 2019-07-22 11:01 ` Jasvinder Singh 2019-07-22 13:15 ` [dpdk-dev] [PATCH v7 00/11] sched: feature enhancements Thomas Monjalon 11 siblings, 0 replies; 163+ messages in thread From: Jasvinder Singh @ 2019-07-22 11:01 UTC (permalink / raw) To: dev; +Cc: cristian.dumitrescu, Abraham Tovar, Lukasz Krakowiak Remove unused macros from the library, and update release notes. Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com> Signed-off-by: Abraham Tovar <abrahamx.tovar@intel.com> Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com> --- doc/guides/rel_notes/release_19_08.rst | 10 +++++++++- lib/librte_sched/rte_sched.h | 11 ----------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/doc/guides/rel_notes/release_19_08.rst b/doc/guides/rel_notes/release_19_08.rst index 0a3f84065..bb271a2d4 100644 --- a/doc/guides/rel_notes/release_19_08.rst +++ b/doc/guides/rel_notes/release_19_08.rst @@ -255,6 +255,14 @@ API Changes * malloc: The function ``rte_malloc_set_limit`` was never implemented is deprecated and will be removed in a future release. +* sched: Macros ``RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS`` and + ``RTE_SCHED_PIPE_PROFILES_PER_PORT`` are removed for flexible configuration + of pipe traffic classes and their queues size, and for runtime configuration + of maximum number of pipe profiles, respectively. In addtion, wrr_weights + field of struct ``rte_sched_pipe_params`` is modifed to be used only for + best-effort tc, and qsize field of struct ``rte_sched_port_params`` is + changed to allow different size of the each queue. + * cryptodev: the ``uint8_t *data`` member of ``key`` structure in the xforms structure (``rte_crypto_cipher_xform``, ``rte_crypto_auth_xform``, and ``rte_crypto_aead_xform``) have been changed to ``const uint8_t *data``. @@ -393,7 +401,7 @@ The libraries prepended with a plus sign were incremented in this version. librte_rcu.so.1 librte_reorder.so.1 librte_ring.so.2 - librte_sched.so.2 + + librte_sched.so.3 librte_security.so.2 librte_stack.so.1 librte_table.so.3 diff --git a/lib/librte_sched/rte_sched.h b/lib/librte_sched/rte_sched.h index fffbad696..eac6db274 100644 --- a/lib/librte_sched/rte_sched.h +++ b/lib/librte_sched/rte_sched.h @@ -94,17 +94,6 @@ extern "C" { */ #define RTE_SCHED_TRAFFIC_CLASS_BE (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1) -/** Number of queues per pipe traffic class. Cannot be changed. */ -#define RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS 4 - - -/** Maximum number of pipe profiles that can be defined per port. - * Compile-time configurable. - */ -#ifndef RTE_SCHED_PIPE_PROFILES_PER_PORT -#define RTE_SCHED_PIPE_PROFILES_PER_PORT 256 -#endif - /* * Ethernet framing overhead. Overhead fields per Ethernet frame: * 1. Preamble: 7 bytes; -- 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* Re: [dpdk-dev] [PATCH v7 00/11] sched: feature enhancements 2019-07-22 11:01 ` [dpdk-dev] [PATCH v7 00/11] sched: feature enhancements Jasvinder Singh ` (10 preceding siblings ...) 2019-07-22 11:01 ` [dpdk-dev] [PATCH v7 11/11] sched: remove redundant macros Jasvinder Singh @ 2019-07-22 13:15 ` Thomas Monjalon 2019-07-22 13:22 ` Singh, Jasvinder 11 siblings, 1 reply; 163+ messages in thread From: Thomas Monjalon @ 2019-07-22 13:15 UTC (permalink / raw) To: Jasvinder Singh; +Cc: dev, cristian.dumitrescu > Jasvinder Singh (11): > sched: remove wrr from strict priority tc queues > sched: add config flexibility to tc queue sizes > sched: add max pipe profiles config in run time > sched: rename tc3 params to best-effort tc > sched: improve error log messages > sched: improve doxygen comments > net/softnic: add config flexibility to softnic tm > test_sched: modify tests for config flexibility > examples/ip_pipeline: add config flexibility to tm function > examples/qos_sched: add tc and queue config flexibility > sched: remove redundant macros Applied, thanks PS: please make all versions replying to the cover letter of v1. ^ permalink raw reply [flat|nested] 163+ messages in thread
* Re: [dpdk-dev] [PATCH v7 00/11] sched: feature enhancements 2019-07-22 13:15 ` [dpdk-dev] [PATCH v7 00/11] sched: feature enhancements Thomas Monjalon @ 2019-07-22 13:22 ` Singh, Jasvinder 2019-07-22 13:33 ` Thomas Monjalon 0 siblings, 1 reply; 163+ messages in thread From: Singh, Jasvinder @ 2019-07-22 13:22 UTC (permalink / raw) To: Thomas Monjalon, Yigit, Ferruh; +Cc: dev, Dumitrescu, Cristian > -----Original Message----- > From: Thomas Monjalon [mailto:thomas@monjalon.net] > Sent: Monday, July 22, 2019 2:16 PM > To: Singh, Jasvinder <jasvinder.singh@intel.com> > Cc: dev@dpdk.org; Dumitrescu, Cristian <cristian.dumitrescu@intel.com> > Subject: Re: [dpdk-dev] [PATCH v7 00/11] sched: feature enhancements > > > Jasvinder Singh (11): > > sched: remove wrr from strict priority tc queues > > sched: add config flexibility to tc queue sizes > > sched: add max pipe profiles config in run time > > sched: rename tc3 params to best-effort tc > > sched: improve error log messages > > sched: improve doxygen comments > > net/softnic: add config flexibility to softnic tm > > test_sched: modify tests for config flexibility > > examples/ip_pipeline: add config flexibility to tm function > > examples/qos_sched: add tc and queue config flexibility > > sched: remove redundant macros > > Applied, thanks > > PS: please make all versions replying to the cover letter of v1. > Thank you, Thomas. For sending new version, followed suggestion from Ferruh by replying to previous version, not the first version. ^ permalink raw reply [flat|nested] 163+ messages in thread
* Re: [dpdk-dev] [PATCH v7 00/11] sched: feature enhancements 2019-07-22 13:22 ` Singh, Jasvinder @ 2019-07-22 13:33 ` Thomas Monjalon 2019-07-22 13:53 ` Ferruh Yigit 0 siblings, 1 reply; 163+ messages in thread From: Thomas Monjalon @ 2019-07-22 13:33 UTC (permalink / raw) To: Singh, Jasvinder; +Cc: Yigit, Ferruh, dev, Dumitrescu, Cristian 22/07/2019 15:22, Singh, Jasvinder: > From: Thomas Monjalon [mailto:thomas@monjalon.net] > > PS: please make all versions replying to the cover letter of v1. > > For sending new version, followed suggestion from Ferruh by replying to previous version, not the first version. Replying to previous version creates an unneeded indentation. And, as you are replying to first patch (not cover letter), it makes new version in the middle of the previous one. ^ permalink raw reply [flat|nested] 163+ messages in thread
* Re: [dpdk-dev] [PATCH v7 00/11] sched: feature enhancements 2019-07-22 13:33 ` Thomas Monjalon @ 2019-07-22 13:53 ` Ferruh Yigit 2019-07-22 13:56 ` Bruce Richardson 0 siblings, 1 reply; 163+ messages in thread From: Ferruh Yigit @ 2019-07-22 13:53 UTC (permalink / raw) To: Thomas Monjalon, Singh, Jasvinder; +Cc: dev, Dumitrescu, Cristian On 7/22/2019 2:33 PM, Thomas Monjalon wrote: > 22/07/2019 15:22, Singh, Jasvinder: >> From: Thomas Monjalon [mailto:thomas@monjalon.net] >>> PS: please make all versions replying to the cover letter of v1. >> >> For sending new version, followed suggestion from Ferruh by replying to previous version, not the first version. > > Replying to previous version creates an unneeded indentation. > And, as you are replying to first patch (not cover letter), > it makes new version in the middle of the previous one. > Ahh, as Jasvinder said, I was always suggesting replying to first mail of the previous version. As long as agreed on one, I don't really mind one against other. What is the rule now, a new version replied to first mail of *first* version? ^ permalink raw reply [flat|nested] 163+ messages in thread
* Re: [dpdk-dev] [PATCH v7 00/11] sched: feature enhancements 2019-07-22 13:53 ` Ferruh Yigit @ 2019-07-22 13:56 ` Bruce Richardson 2019-07-22 14:08 ` Ferruh Yigit 2019-07-22 14:08 ` Thomas Monjalon 0 siblings, 2 replies; 163+ messages in thread From: Bruce Richardson @ 2019-07-22 13:56 UTC (permalink / raw) To: Ferruh Yigit; +Cc: Thomas Monjalon, Singh, Jasvinder, dev, Dumitrescu, Cristian On Mon, Jul 22, 2019 at 02:53:04PM +0100, Ferruh Yigit wrote: > On 7/22/2019 2:33 PM, Thomas Monjalon wrote: > > 22/07/2019 15:22, Singh, Jasvinder: > >> From: Thomas Monjalon [mailto:thomas@monjalon.net] > >>> PS: please make all versions replying to the cover letter of v1. > >> > >> For sending new version, followed suggestion from Ferruh by replying to previous version, not the first version. > > > > Replying to previous version creates an unneeded indentation. > > And, as you are replying to first patch (not cover letter), > > it makes new version in the middle of the previous one. > > > > Ahh, as Jasvinder said, I was always suggesting replying to first mail of the > previous version. As long as agreed on one, I don't really mind one against other. > > What is the rule now, a new version replied to first mail of *first* version? I would not use the term "first mail" as that is ambiguous and could imply the first patch. I always try and reply to the cover letter of the v1. That keeps things in thread without a new level of indentation each subsequent version. ^ permalink raw reply [flat|nested] 163+ messages in thread
* Re: [dpdk-dev] [PATCH v7 00/11] sched: feature enhancements 2019-07-22 13:56 ` Bruce Richardson @ 2019-07-22 14:08 ` Ferruh Yigit 2019-07-22 14:08 ` Thomas Monjalon 1 sibling, 0 replies; 163+ messages in thread From: Ferruh Yigit @ 2019-07-22 14:08 UTC (permalink / raw) To: Bruce Richardson Cc: Thomas Monjalon, Singh, Jasvinder, dev, Dumitrescu, Cristian On 7/22/2019 2:56 PM, Bruce Richardson wrote: > On Mon, Jul 22, 2019 at 02:53:04PM +0100, Ferruh Yigit wrote: >> On 7/22/2019 2:33 PM, Thomas Monjalon wrote: >>> 22/07/2019 15:22, Singh, Jasvinder: >>>> From: Thomas Monjalon [mailto:thomas@monjalon.net] >>>>> PS: please make all versions replying to the cover letter of v1. >>>> >>>> For sending new version, followed suggestion from Ferruh by replying to previous version, not the first version. >>> >>> Replying to previous version creates an unneeded indentation. >>> And, as you are replying to first patch (not cover letter), >>> it makes new version in the middle of the previous one. >>> >> >> Ahh, as Jasvinder said, I was always suggesting replying to first mail of the >> previous version. As long as agreed on one, I don't really mind one against other. >> >> What is the rule now, a new version replied to first mail of *first* version? > > I would not use the term "first mail" as that is ambiguous and could imply > the first patch. I always try and reply to the cover letter of the v1. That > keeps things in thread without a new level of indentation each subsequent > version. > I said "first mail" to escape from mentioned ambiguity :) If first mail is "cover letter" reply to that, if there is no cover letter, first mail is the 1/x patch, in this case reply to that patch. I think we are saying same thing at the end of the day. ^ permalink raw reply [flat|nested] 163+ messages in thread
* Re: [dpdk-dev] [PATCH v7 00/11] sched: feature enhancements 2019-07-22 13:56 ` Bruce Richardson 2019-07-22 14:08 ` Ferruh Yigit @ 2019-07-22 14:08 ` Thomas Monjalon 1 sibling, 0 replies; 163+ messages in thread From: Thomas Monjalon @ 2019-07-22 14:08 UTC (permalink / raw) To: Bruce Richardson Cc: Ferruh Yigit, Singh, Jasvinder, dev, Dumitrescu, Cristian 22/07/2019 15:56, Bruce Richardson: > On Mon, Jul 22, 2019 at 02:53:04PM +0100, Ferruh Yigit wrote: > > On 7/22/2019 2:33 PM, Thomas Monjalon wrote: > > > 22/07/2019 15:22, Singh, Jasvinder: > > >> From: Thomas Monjalon [mailto:thomas@monjalon.net] > > >>> PS: please make all versions replying to the cover letter of v1. > > >> > > >> For sending new version, followed suggestion from Ferruh by replying to previous version, not the first version. > > > > > > Replying to previous version creates an unneeded indentation. > > > And, as you are replying to first patch (not cover letter), > > > it makes new version in the middle of the previous one. > > > > > > > Ahh, as Jasvinder said, I was always suggesting replying to first mail of the > > previous version. As long as agreed on one, I don't really mind one against other. > > > > What is the rule now, a new version replied to first mail of *first* version? > > I would not use the term "first mail" as that is ambiguous and could imply > the first patch. I always try and reply to the cover letter of the v1. That > keeps things in thread without a new level of indentation each subsequent > version. I agree with Bruce ^ permalink raw reply [flat|nested] 163+ messages in thread
* [dpdk-dev] [PATCH v6 02/11] sched: add config flexibility to tc queue sizes 2019-07-19 14:18 ` [dpdk-dev] [PATCH v6 00/11] sched: feature enhancements Jasvinder Singh 2019-07-19 14:18 ` [dpdk-dev] [PATCH v6 01/11] sched: remove wrr from strict priority tc queues Jasvinder Singh @ 2019-07-19 14:18 ` Jasvinder Singh 2019-07-19 14:18 ` [dpdk-dev] [PATCH v6 03/11] sched: add max pipe profiles config in run time Jasvinder Singh ` (10 subsequent siblings) 12 siblings, 0 replies; 163+ messages in thread From: Jasvinder Singh @ 2019-07-19 14:18 UTC (permalink / raw) To: dev; +Cc: cristian.dumitrescu, Abraham Tovar, Lukasz Krakowiak Add support for zero queue sizes of the traffic classes. The queues which are not used can be set to zero size. This helps in reducing memory footprint of the hierarchical scheduler. Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com> Signed-off-by: Abraham Tovar <abrahamx.tovar@intel.com> Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com> --- lib/librte_sched/rte_sched.c | 379 +++++++++++++++++++++-------------- lib/librte_sched/rte_sched.h | 5 +- 2 files changed, 236 insertions(+), 148 deletions(-) diff --git a/lib/librte_sched/rte_sched.c b/lib/librte_sched/rte_sched.c index 1592c804b..17d7f833c 100644 --- a/lib/librte_sched/rte_sched.c +++ b/lib/librte_sched/rte_sched.c @@ -145,15 +145,15 @@ struct rte_sched_grinder { struct rte_sched_pipe_profile *pipe_params; /* TC cache */ - uint8_t tccache_qmask[4]; - uint32_t tccache_qindex[4]; + uint8_t tccache_qmask[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; + uint32_t tccache_qindex[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; uint32_t tccache_w; uint32_t tccache_r; /* Current TC */ uint32_t tc_index; - struct rte_sched_queue *queue[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; - struct rte_mbuf **qbase[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; + struct rte_sched_queue *queue[RTE_SCHED_MAX_QUEUES_PER_TC]; + struct rte_mbuf **qbase[RTE_SCHED_MAX_QUEUES_PER_TC]; uint32_t qindex[RTE_SCHED_MAX_QUEUES_PER_TC]; uint16_t qsize; uint32_t qmask; @@ -171,6 +171,9 @@ struct rte_sched_port { uint32_t n_subports_per_port; uint32_t n_pipes_per_subport; uint32_t n_pipes_per_subport_log2; + 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 rate; uint32_t mtu; uint32_t frame_overhead; @@ -256,14 +259,38 @@ rte_sched_port_qbase(struct rte_sched_port *port, uint32_t qindex) static inline uint16_t rte_sched_port_qsize(struct rte_sched_port *port, uint32_t qindex) { - uint32_t tc = (qindex >> 2) & 0x3; + uint32_t tc = port->pipe_tc[qindex & (RTE_SCHED_QUEUES_PER_PIPE - 1)]; return port->qsize[tc]; } +static inline uint16_t +rte_sched_port_pipe_queue(struct rte_sched_port *port, uint32_t traffic_class) +{ + uint16_t pipe_queue = port->pipe_queue[traffic_class]; + + return pipe_queue; +} + +static inline uint8_t +rte_sched_port_pipe_tc(struct rte_sched_port *port, uint32_t qindex) +{ + uint8_t pipe_tc = port->pipe_tc[qindex & (RTE_SCHED_QUEUES_PER_PIPE - 1)]; + + return pipe_tc; +} + +static inline uint8_t +rte_sched_port_tc_queue(struct rte_sched_port *port, uint32_t qindex) +{ + uint8_t tc_queue = port->tc_queue[qindex & (RTE_SCHED_QUEUES_PER_PIPE - 1)]; + + return tc_queue; +} + static int pipe_profile_check(struct rte_sched_pipe_params *params, - uint32_t rate) + uint32_t rate, uint16_t *qsize) { uint32_t i; @@ -280,25 +307,27 @@ pipe_profile_check(struct rte_sched_pipe_params *params, if (params->tb_size == 0) return -12; - /* TC rate: non-zero, less than pipe rate */ + /* TC rate: non-zero if qsize non-zero, less than pipe rate */ for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { - if (params->tc_rate[i] == 0 || - params->tc_rate[i] > params->tb_rate) + if ((qsize[i] == 0 && params->tc_rate[i] != 0) || + (qsize[i] != 0 && (params->tc_rate[i] == 0 || + params->tc_rate[i] > params->tb_rate))) return -13; } + if (params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE] == 0 || + qsize[RTE_SCHED_TRAFFIC_CLASS_BE] == 0) + return -13; /* TC period: non-zero */ if (params->tc_period == 0) return -14; -#ifdef RTE_SCHED_SUBPORT_TC_OV /* TC3 oversubscription weight: non-zero */ if (params->tc_ov_weight == 0) return -15; -#endif /* Queue WRR weights: non-zero */ - for (i = 0; i < RTE_SCHED_QUEUES_PER_PIPE; i++) { + for (i = 0; i < RTE_SCHED_BE_QUEUES_PER_PIPE; i++) { if (params->wrr_weights[i] == 0) return -16; } @@ -343,7 +372,8 @@ rte_sched_port_check_params(struct rte_sched_port_params *params) for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { uint16_t qsize = params->qsize[i]; - if (qsize == 0 || !rte_is_power_of_2(qsize)) + if ((qsize != 0 && !rte_is_power_of_2(qsize)) || + ((i == RTE_SCHED_TRAFFIC_CLASS_BE) && (qsize == 0))) return -8; } @@ -357,7 +387,7 @@ rte_sched_port_check_params(struct rte_sched_port_params *params) struct rte_sched_pipe_params *p = params->pipe_profiles + i; int status; - status = pipe_profile_check(p, params->rate); + status = pipe_profile_check(p, params->rate, ¶ms->qsize[0]); if (status != 0) return status; } @@ -387,8 +417,12 @@ rte_sched_port_get_array_base(struct rte_sched_port_params *params, enum rte_sch size_per_pipe_queue_array = 0; for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { - size_per_pipe_queue_array += RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS - * params->qsize[i] * sizeof(struct rte_mbuf *); + if (i < RTE_SCHED_TRAFFIC_CLASS_BE) + size_per_pipe_queue_array += + params->qsize[i] * sizeof(struct rte_mbuf *); + else + size_per_pipe_queue_array += RTE_SCHED_MAX_QUEUES_PER_TC * + params->qsize[i] * sizeof(struct rte_mbuf *); } size_queue_array = n_pipes_per_port * size_per_pipe_queue_array; @@ -448,31 +482,27 @@ rte_sched_port_get_memory_footprint(struct rte_sched_port_params *params) static void rte_sched_port_config_qsize(struct rte_sched_port *port) { - /* TC 0 */ + uint32_t i; + port->qsize_add[0] = 0; - port->qsize_add[1] = port->qsize_add[0] + port->qsize[0]; - port->qsize_add[2] = port->qsize_add[1] + port->qsize[0]; - port->qsize_add[3] = port->qsize_add[2] + port->qsize[0]; - - /* TC 1 */ - port->qsize_add[4] = port->qsize_add[3] + port->qsize[0]; - port->qsize_add[5] = port->qsize_add[4] + port->qsize[1]; - port->qsize_add[6] = port->qsize_add[5] + port->qsize[1]; - port->qsize_add[7] = port->qsize_add[6] + port->qsize[1]; - - /* TC 2 */ - port->qsize_add[8] = port->qsize_add[7] + port->qsize[1]; - port->qsize_add[9] = port->qsize_add[8] + port->qsize[2]; - port->qsize_add[10] = port->qsize_add[9] + port->qsize[2]; - port->qsize_add[11] = port->qsize_add[10] + port->qsize[2]; - - /* TC 3 */ - port->qsize_add[12] = port->qsize_add[11] + port->qsize[2]; - port->qsize_add[13] = port->qsize_add[12] + port->qsize[3]; - port->qsize_add[14] = port->qsize_add[13] + port->qsize[3]; - port->qsize_add[15] = port->qsize_add[14] + port->qsize[3]; - - port->qsize_sum = port->qsize_add[15] + port->qsize[3]; + + /* Strict prority traffic class */ + for (i = 1; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) + port->qsize_add[i] = port->qsize_add[i-1] + port->qsize[i-1]; + + /* Best-effort traffic class */ + port->qsize_add[RTE_SCHED_TRAFFIC_CLASS_BE + 1] = + port->qsize_add[RTE_SCHED_TRAFFIC_CLASS_BE] + + port->qsize[RTE_SCHED_TRAFFIC_CLASS_BE]; + port->qsize_add[RTE_SCHED_TRAFFIC_CLASS_BE + 2] = + port->qsize_add[RTE_SCHED_TRAFFIC_CLASS_BE + 1] + + port->qsize[RTE_SCHED_TRAFFIC_CLASS_BE]; + port->qsize_add[RTE_SCHED_TRAFFIC_CLASS_BE + 3] = + port->qsize_add[RTE_SCHED_TRAFFIC_CLASS_BE + 2] + + port->qsize[RTE_SCHED_TRAFFIC_CLASS_BE]; + + port->qsize_sum = port->qsize_add[RTE_SCHED_TRAFFIC_CLASS_BE + 3] + + port->qsize[RTE_SCHED_TRAFFIC_CLASS_BE]; } static void @@ -481,10 +511,11 @@ rte_sched_port_log_pipe_profile(struct rte_sched_port *port, uint32_t i) struct rte_sched_pipe_profile *p = port->pipe_profiles + i; RTE_LOG(DEBUG, SCHED, "Low level config for pipe profile %u:\n" - " Token bucket: period = %u, credits per period = %u, size = %u\n" - " Traffic classes: period = %u, credits per period = [%u, %u, %u, %u]\n" - " Traffic class 3 oversubscription: weight = %hhu\n" - " WRR cost: [%hhu, %hhu, %hhu, %hhu]\n", + " Token bucket: period = %u, credits per period = %u, size = %u\n" + " Traffic classes: period = %u,\n" + " credits per period = [%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u]\n" + " Best-effort traffic class oversubscription: weight = %hhu\n" + " WRR cost: [%hhu, %hhu, %hhu, %hhu]\n", i, /* Token bucket */ @@ -498,6 +529,15 @@ 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_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], /* Traffic class 3 oversubscription */ p->tc_ov_weight, @@ -517,7 +557,8 @@ rte_sched_time_ms_to_bytes(uint32_t time_ms, uint32_t rate) } static void -rte_sched_pipe_profile_convert(struct rte_sched_pipe_params *src, +rte_sched_pipe_profile_convert(struct rte_sched_port *port, + struct rte_sched_pipe_params *src, struct rte_sched_pipe_profile *dst, uint32_t rate) { @@ -545,13 +586,12 @@ rte_sched_pipe_profile_convert(struct rte_sched_pipe_params *src, 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]); + if (port->qsize[i]) + dst->tc_credits_per_period[i] + = rte_sched_time_ms_to_bytes(src->tc_period, + src->tc_rate[i]); -#ifdef RTE_SCHED_SUBPORT_TC_OV dst->tc_ov_weight = src->tc_ov_weight; -#endif /* WRR queues */ wrr_cost[0] = src->wrr_weights[0]; @@ -584,14 +624,14 @@ rte_sched_port_config_pipe_profile_table(struct rte_sched_port *port, struct rte_sched_pipe_params *src = params->pipe_profiles + i; struct rte_sched_pipe_profile *dst = port->pipe_profiles + i; - rte_sched_pipe_profile_convert(src, dst, params->rate); + rte_sched_pipe_profile_convert(port, src, dst, params->rate); 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]; + uint32_t pipe_tc3_rate = src->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE]; if (port->pipe_tc3_rate_max < pipe_tc3_rate) port->pipe_tc3_rate_max = pipe_tc3_rate; @@ -602,7 +642,7 @@ struct rte_sched_port * rte_sched_port_config(struct rte_sched_port_params *params) { struct rte_sched_port *port = NULL; - uint32_t mem_size, bmp_mem_size, n_queues_per_port, i, cycles_per_byte; + uint32_t mem_size, bmp_mem_size, n_queues_per_port, i, j, cycles_per_byte; /* Check user parameters. Determine the amount of memory to allocate */ mem_size = rte_sched_port_get_memory_footprint(params); @@ -624,6 +664,23 @@ rte_sched_port_config(struct rte_sched_port_params *params) port->n_pipes_per_subport = params->n_pipes_per_subport; port->n_pipes_per_subport_log2 = __builtin_ctz(params->n_pipes_per_subport); + + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) + port->pipe_queue[i] = i; + + for (i = 0, j = 0; i < RTE_SCHED_QUEUES_PER_PIPE; i++) { + port->pipe_tc[i] = j; + + if (j < RTE_SCHED_TRAFFIC_CLASS_BE) + j++; + } + + for (i = 0, j = 0; i < RTE_SCHED_QUEUES_PER_PIPE; i++) { + port->tc_queue[i] = j; + + if (i >= RTE_SCHED_TRAFFIC_CLASS_BE) + j++; + } port->rate = params->rate; port->mtu = params->mtu + params->frame_overhead; port->frame_overhead = params->frame_overhead; @@ -733,12 +790,14 @@ rte_sched_port_free(struct rte_sched_port *port) for (qindex = 0; qindex < n_queues_per_port; qindex++) { struct rte_mbuf **mbufs = rte_sched_port_qbase(port, qindex); uint16_t qsize = rte_sched_port_qsize(port, qindex); - struct rte_sched_queue *queue = port->queue + qindex; - uint16_t qr = queue->qr & (qsize - 1); - uint16_t qw = queue->qw & (qsize - 1); + if (qsize != 0) { + struct rte_sched_queue *queue = port->queue + qindex; + uint16_t qr = queue->qr & (qsize - 1); + uint16_t qw = queue->qw & (qsize - 1); - for (; qr != qw; qr = (qr + 1) & (qsize - 1)) - rte_pktmbuf_free(mbufs[qr]); + for (; qr != qw; qr = (qr + 1) & (qsize - 1)) + rte_pktmbuf_free(mbufs[qr]); + } } rte_bitmap_free(port->bmp); @@ -751,9 +810,10 @@ rte_sched_port_log_subport_config(struct rte_sched_port *port, uint32_t i) struct rte_sched_subport *s = port->subport + i; RTE_LOG(DEBUG, SCHED, "Low level config for subport %u:\n" - " Token bucket: period = %u, credits per period = %u, size = %u\n" - " Traffic classes: period = %u, credits per period = [%u, %u, %u, %u]\n" - " Traffic class 3 oversubscription: wm min = %u, wm max = %u\n", + " Token bucket: period = %u, credits per period = %u, size = %u\n" + " Traffic classes: period = %u\n" + " credits per period = [%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u]\n" + " Best effort traffic class oversubscription: wm min = %u, wm max = %u\n", i, /* Token bucket */ @@ -767,6 +827,15 @@ 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_credits_per_period[4], + s->tc_credits_per_period[5], + s->tc_credits_per_period[6], + s->tc_credits_per_period[7], + s->tc_credits_per_period[8], + s->tc_credits_per_period[9], + s->tc_credits_per_period[10], + s->tc_credits_per_period[11], + s->tc_credits_per_period[12], /* Traffic class 3 oversubscription */ s->tc_ov_wm_min, @@ -794,11 +863,19 @@ rte_sched_subport_config(struct rte_sched_port *port, return -3; for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { - if (params->tc_rate[i] == 0 || - params->tc_rate[i] > params->tb_rate) + uint32_t tc_rate = params->tc_rate[i]; + uint16_t qsize = port->qsize[i]; + + if ((qsize == 0 && tc_rate != 0) || + (qsize != 0 && tc_rate == 0) || + (tc_rate > params->tb_rate)) return -4; } + if (port->qsize[RTE_SCHED_TRAFFIC_CLASS_BE] == 0 || + params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE] == 0) + return -4; + if (params->tc_period == 0) return -5; @@ -822,15 +899,17 @@ rte_sched_subport_config(struct rte_sched_port *port, /* Traffic Classes (TCs) */ s->tc_period = rte_sched_time_ms_to_bytes(params->tc_period, port->rate); for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { - s->tc_credits_per_period[i] - = rte_sched_time_ms_to_bytes(params->tc_period, - params->tc_rate[i]); + if (port->qsize[i]) + s->tc_credits_per_period[i] + = rte_sched_time_ms_to_bytes(params->tc_period, + params->tc_rate[i]); + } s->tc_time = port->time + s->tc_period; for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) - s->tc_credits[i] = s->tc_credits_per_period[i]; + if (port->qsize[i]) + s->tc_credits[i] = s->tc_credits_per_period[i]; -#ifdef RTE_SCHED_SUBPORT_TC_OV /* TC oversubscription */ s->tc_ov_wm_min = port->mtu; s->tc_ov_wm_max = rte_sched_time_ms_to_bytes(params->tc_period, @@ -840,7 +919,6 @@ rte_sched_subport_config(struct rte_sched_port *port, s->tc_ov = 0; s->tc_ov_n = 0; s->tc_ov_rate = 0; -#endif rte_sched_port_log_subport_config(port, subport_id); @@ -880,10 +958,9 @@ rte_sched_pipe_config(struct rte_sched_port *port, if (p->tb_time) { params = port->pipe_profiles + p->profile; -#ifdef RTE_SCHED_SUBPORT_TC_OV - double subport_tc3_rate = (double) s->tc_credits_per_period[3] + double subport_tc3_rate = (double) s->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] / (double) s->tc_period; - double pipe_tc3_rate = (double) params->tc_credits_per_period[3] + double pipe_tc3_rate = (double) params->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] / (double) params->tc_period; uint32_t tc3_ov = s->tc_ov; @@ -897,7 +974,6 @@ rte_sched_pipe_config(struct rte_sched_port *port, "Subport %u TC3 oversubscription is OFF (%.4lf >= %.4lf)\n", subport_id, subport_tc3_rate, s->tc_ov_rate); } -#endif /* Reset the pipe */ memset(p, 0, sizeof(struct rte_sched_pipe)); @@ -916,15 +992,18 @@ rte_sched_pipe_config(struct rte_sched_port *port, /* Traffic Classes (TCs) */ p->tc_time = port->time + params->tc_period; + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) - p->tc_credits[i] = params->tc_credits_per_period[i]; + if (port->qsize[i]) + p->tc_credits[i] = params->tc_credits_per_period[i]; -#ifdef RTE_SCHED_SUBPORT_TC_OV { /* Subport TC3 oversubscription */ - double subport_tc3_rate = (double) s->tc_credits_per_period[3] + double subport_tc3_rate = + (double) s->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] / (double) s->tc_period; - double pipe_tc3_rate = (double) params->tc_credits_per_period[3] + double pipe_tc3_rate = + (double) params->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] / (double) params->tc_period; uint32_t tc3_ov = s->tc_ov; @@ -940,7 +1019,6 @@ rte_sched_pipe_config(struct rte_sched_port *port, p->tc_ov_period_id = s->tc_ov_period_id; p->tc_ov_credits = s->tc_ov_wm; } -#endif return 0; } @@ -963,12 +1041,12 @@ rte_sched_port_pipe_profile_add(struct rte_sched_port *port, return -2; /* Pipe params */ - status = pipe_profile_check(params, port->rate); + status = pipe_profile_check(params, port->rate, &port->qsize[0]); if (status != 0) return status; pp = &port->pipe_profiles[port->n_pipe_profiles]; - rte_sched_pipe_profile_convert(params, pp, port->rate); + rte_sched_pipe_profile_convert(port, params, pp, port->rate); /* Pipe profile not exists */ for (i = 0; i < port->n_pipe_profiles; i++) @@ -979,8 +1057,8 @@ rte_sched_port_pipe_profile_add(struct rte_sched_port *port, *pipe_profile_id = port->n_pipe_profiles; port->n_pipe_profiles++; - if (port->pipe_tc3_rate_max < params->tc_rate[3]) - port->pipe_tc3_rate_max = params->tc_rate[3]; + if (port->pipe_tc3_rate_max < params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE]) + port->pipe_tc3_rate_max = params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE]; rte_sched_port_log_pipe_profile(port, *pipe_profile_id); @@ -997,9 +1075,8 @@ rte_sched_port_qindex(struct rte_sched_port *port, return ((subport & (port->n_subports_per_port - 1)) << (port->n_pipes_per_subport_log2 + 4)) | ((pipe & (port->n_pipes_per_subport - 1)) << 4) | - ((traffic_class & - (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1)) << 2) | - (queue & (RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS - 1)); + ((rte_sched_port_pipe_queue(port, traffic_class) + queue) & + (RTE_SCHED_QUEUES_PER_PIPE - 1)); } void @@ -1009,8 +1086,9 @@ rte_sched_port_pkt_write(struct rte_sched_port *port, uint32_t traffic_class, uint32_t queue, enum rte_color color) { - uint32_t queue_id = rte_sched_port_qindex(port, subport, pipe, - traffic_class, queue); + uint32_t queue_id = + rte_sched_port_qindex(port, subport, pipe, traffic_class, queue); + rte_mbuf_sched_set(pkt, queue_id, traffic_class, (uint8_t)color); } @@ -1024,9 +1102,8 @@ rte_sched_port_pkt_read_tree_path(struct rte_sched_port *port, *subport = queue_id >> (port->n_pipes_per_subport_log2 + 4); *pipe = (queue_id >> 4) & (port->n_pipes_per_subport - 1); - *traffic_class = (queue_id >> 2) & - (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1); - *queue = queue_id & (RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS - 1); + *traffic_class = rte_sched_port_pipe_tc(port, queue_id); + *queue = rte_sched_port_tc_queue(port, queue_id); } enum rte_color @@ -1107,7 +1184,7 @@ static inline void rte_sched_port_update_subport_stats(struct rte_sched_port *port, uint32_t qindex, struct rte_mbuf *pkt) { struct rte_sched_subport *s = port->subport + (qindex / rte_sched_port_queues_per_subport(port)); - uint32_t tc_index = (qindex >> 2) & 0x3; + uint32_t tc_index = rte_sched_port_pipe_tc(port, qindex); uint32_t pkt_len = pkt->pkt_len; s->stats.n_pkts_tc[tc_index] += 1; @@ -1127,7 +1204,7 @@ rte_sched_port_update_subport_stats_on_drop(struct rte_sched_port *port, #endif { struct rte_sched_subport *s = port->subport + (qindex / rte_sched_port_queues_per_subport(port)); - uint32_t tc_index = (qindex >> 2) & 0x3; + uint32_t tc_index = rte_sched_port_pipe_tc(port, qindex); uint32_t pkt_len = pkt->pkt_len; s->stats.n_pkts_tc_dropped[tc_index] += 1; @@ -1182,7 +1259,7 @@ rte_sched_port_red_drop(struct rte_sched_port *port, struct rte_mbuf *pkt, uint3 uint32_t tc_index; enum rte_color color; - tc_index = (qindex >> 2) & 0x3; + tc_index = rte_sched_port_pipe_tc(port, qindex); color = rte_sched_port_pkt_read_color(pkt); red_cfg = &port->red_config[tc_index][color]; @@ -1499,6 +1576,7 @@ grinder_credits_update(struct rte_sched_port *port, uint32_t pos) struct rte_sched_pipe *pipe = grinder->pipe; struct rte_sched_pipe_profile *params = grinder->pipe_params; uint64_t n_periods; + uint32_t i; /* Subport TB */ n_periods = (port->time - subport->tb_time) / subport->tb_period; @@ -1514,19 +1592,17 @@ grinder_credits_update(struct rte_sched_port *port, uint32_t pos) /* Subport TCs */ 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]; + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) + subport->tc_credits[i] = subport->tc_credits_per_period[i]; + subport->tc_time = port->time + subport->tc_period; } /* Pipe TCs */ if (unlikely(port->time >= pipe->tc_time)) { - pipe->tc_credits[0] = params->tc_credits_per_period[0]; - pipe->tc_credits[1] = params->tc_credits_per_period[1]; - pipe->tc_credits[2] = params->tc_credits_per_period[2]; - pipe->tc_credits[3] = params->tc_credits_per_period[3]; + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) + pipe->tc_credits[i] = params->tc_credits_per_period[i]; + pipe->tc_time = port->time + params->tc_period; } } @@ -1539,21 +1615,29 @@ 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_consumption = 0, tc_ov_consumption_max; uint32_t tc_ov_wm = subport->tc_ov_wm; + uint32_t i; 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]; + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASS_BE; i++) { + tc_ov_consumption[i] = + subport->tc_credits_per_period[i] - subport->tc_credits[i]; + tc_consumption += tc_ov_consumption[i]; + } + + tc_ov_consumption[RTE_SCHED_TRAFFIC_CLASS_BE] = + subport->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] - + subport->tc_credits[RTE_SCHED_TRAFFIC_CLASS_BE]; - 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_consumption_max = + subport->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] - tc_consumption; + + if (tc_ov_consumption[RTE_SCHED_TRAFFIC_CLASS_BE] > + (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; @@ -1576,6 +1660,7 @@ grinder_credits_update(struct rte_sched_port *port, uint32_t pos) struct rte_sched_pipe *pipe = grinder->pipe; struct rte_sched_pipe_profile *params = grinder->pipe_params; uint64_t n_periods; + uint32_t i; /* Subport TB */ n_periods = (port->time - subport->tb_time) / subport->tb_period; @@ -1593,10 +1678,8 @@ grinder_credits_update(struct rte_sched_port *port, uint32_t pos) 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]; + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) + subport->tc_credits[i] = subport->tc_credits_per_period[i]; subport->tc_time = port->time + subport->tc_period; subport->tc_ov_period_id++; @@ -1604,10 +1687,8 @@ grinder_credits_update(struct rte_sched_port *port, uint32_t pos) /* Pipe TCs */ if (unlikely(port->time >= pipe->tc_time)) { - pipe->tc_credits[0] = params->tc_credits_per_period[0]; - pipe->tc_credits[1] = params->tc_credits_per_period[1]; - pipe->tc_credits[2] = params->tc_credits_per_period[2]; - pipe->tc_credits[3] = params->tc_credits_per_period[3]; + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) + pipe->tc_credits[i] = params->tc_credits_per_period[i]; pipe->tc_time = port->time + params->tc_period; } @@ -1672,11 +1753,18 @@ 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_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]; + uint32_t pipe_tc_ov_mask1[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; + uint32_t pipe_tc_ov_mask2[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE] = {0}; + uint32_t pipe_tc_ov_credits, i; int enough_credits; + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) + pipe_tc_ov_mask1[i] = UINT32_MAX; + + pipe_tc_ov_mask1[RTE_SCHED_TRAFFIC_CLASS_BE] = pipe->tc_ov_credits; + pipe_tc_ov_mask2[RTE_SCHED_TRAFFIC_CLASS_BE] = UINT32_MAX; + pipe_tc_ov_credits = pipe_tc_ov_mask1[tc_index]; + /* Check pipe and subport credits */ enough_credits = (pkt_len <= subport_tb_credits) && (pkt_len <= subport_tc_credits) && @@ -1831,31 +1919,23 @@ static inline void grinder_tccache_populate(struct rte_sched_port *port, uint32_t pos, uint32_t qindex, uint16_t qmask) { struct rte_sched_grinder *grinder = port->grinder + pos; - uint8_t b[4]; + uint8_t b, i; grinder->tccache_w = 0; grinder->tccache_r = 0; - b[0] = (uint8_t) (qmask & 0xF); - b[1] = (uint8_t) ((qmask >> 4) & 0xF); - b[2] = (uint8_t) ((qmask >> 8) & 0xF); - b[3] = (uint8_t) ((qmask >> 12) & 0xF); - - grinder->tccache_qmask[grinder->tccache_w] = b[0]; - grinder->tccache_qindex[grinder->tccache_w] = qindex; - grinder->tccache_w += (b[0] != 0); - - grinder->tccache_qmask[grinder->tccache_w] = b[1]; - grinder->tccache_qindex[grinder->tccache_w] = qindex + 4; - grinder->tccache_w += (b[1] != 0); - - grinder->tccache_qmask[grinder->tccache_w] = b[2]; - grinder->tccache_qindex[grinder->tccache_w] = qindex + 8; - grinder->tccache_w += (b[2] != 0); + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASS_BE; i++) { + b = (uint8_t) ((qmask >> i) & 0x1); + grinder->tccache_qmask[grinder->tccache_w] = b; + grinder->tccache_qindex[grinder->tccache_w] = qindex + i; + grinder->tccache_w += (b != 0); + } - grinder->tccache_qmask[grinder->tccache_w] = b[3]; - grinder->tccache_qindex[grinder->tccache_w] = qindex + 12; - grinder->tccache_w += (b[3] != 0); + b = (uint8_t) (qmask >> (RTE_SCHED_TRAFFIC_CLASS_BE)); + grinder->tccache_qmask[grinder->tccache_w] = b; + grinder->tccache_qindex[grinder->tccache_w] = qindex + + RTE_SCHED_TRAFFIC_CLASS_BE; + grinder->tccache_w += (b != 0); } static inline int @@ -1873,14 +1953,18 @@ grinder_next_tc(struct rte_sched_port *port, uint32_t pos) qbase = rte_sched_port_qbase(port, qindex); qsize = rte_sched_port_qsize(port, qindex); - grinder->tc_index = (qindex >> 2) & 0x3; + grinder->tc_index = rte_sched_port_pipe_tc(port, qindex); grinder->qmask = grinder->tccache_qmask[grinder->tccache_r]; grinder->qsize = qsize; - grinder->qindex[0] = qindex; - grinder->qindex[1] = qindex + 1; - grinder->qindex[2] = qindex + 2; - grinder->qindex[3] = qindex + 3; + if (grinder->tc_index < RTE_SCHED_TRAFFIC_CLASS_BE) { + grinder->queue[0] = port->queue + qindex; + grinder->qbase[0] = qbase; + grinder->qindex[0] = qindex; + grinder->tccache_r++; + + return 1; + } grinder->queue[0] = port->queue + qindex; grinder->queue[1] = port->queue + qindex + 1; @@ -1892,6 +1976,11 @@ grinder_next_tc(struct rte_sched_port *port, uint32_t pos) grinder->qbase[2] = qbase + 2 * qsize; grinder->qbase[3] = qbase + 3 * qsize; + grinder->qindex[0] = qindex; + grinder->qindex[1] = qindex + 1; + grinder->qindex[2] = qindex + 2; + grinder->qindex[3] = qindex + 3; + grinder->tccache_r++; return 1; } diff --git a/lib/librte_sched/rte_sched.h b/lib/librte_sched/rte_sched.h index 662c3a057..2b65420d1 100644 --- a/lib/librte_sched/rte_sched.h +++ b/lib/librte_sched/rte_sched.h @@ -85,7 +85,8 @@ extern "C" { /** Number of traffic classes per pipe (as well as subport). * Cannot be changed. */ -#define RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE 4 +#define RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE \ +(RTE_SCHED_QUEUES_PER_PIPE - RTE_SCHED_BE_QUEUES_PER_PIPE + 1) /** Best-effort traffic class ID * Can not change. @@ -177,9 +178,7 @@ struct rte_sched_pipe_params { /**< Traffic class rates (measured in bytes per second) */ uint32_t tc_period; /**< Enforcement period (measured in milliseconds) */ -#ifdef RTE_SCHED_SUBPORT_TC_OV uint8_t tc_ov_weight; /**< Weight Traffic class 3 oversubscription */ -#endif /* Pipe queues */ uint8_t wrr_weights[RTE_SCHED_BE_QUEUES_PER_PIPE]; /**< WRR weights */ -- 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* [dpdk-dev] [PATCH v6 03/11] sched: add max pipe profiles config in run time 2019-07-19 14:18 ` [dpdk-dev] [PATCH v6 00/11] sched: feature enhancements Jasvinder Singh 2019-07-19 14:18 ` [dpdk-dev] [PATCH v6 01/11] sched: remove wrr from strict priority tc queues Jasvinder Singh 2019-07-19 14:18 ` [dpdk-dev] [PATCH v6 02/11] sched: add config flexibility to tc queue sizes Jasvinder Singh @ 2019-07-19 14:18 ` Jasvinder Singh 2019-07-19 14:18 ` [dpdk-dev] [PATCH v6 04/11] sched: rename tc3 params to best-effort tc Jasvinder Singh ` (9 subsequent siblings) 12 siblings, 0 replies; 163+ messages in thread From: Jasvinder Singh @ 2019-07-19 14:18 UTC (permalink / raw) To: dev; +Cc: cristian.dumitrescu, Abraham Tovar, Lukasz Krakowiak Allow setting the maximum number of pipe profiles in run time. Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com> Signed-off-by: Abraham Tovar <abrahamx.tovar@intel.com> Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com> --- lib/librte_sched/rte_sched.c | 8 +++++--- lib/librte_sched/rte_sched.h | 2 ++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/librte_sched/rte_sched.c b/lib/librte_sched/rte_sched.c index 17d7f833c..e8614ba4c 100644 --- a/lib/librte_sched/rte_sched.c +++ b/lib/librte_sched/rte_sched.c @@ -179,6 +179,7 @@ struct rte_sched_port { uint32_t frame_overhead; uint16_t qsize[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; uint32_t n_pipe_profiles; + uint32_t n_max_pipe_profiles; uint32_t pipe_tc3_rate_max; #ifdef RTE_SCHED_RED struct rte_red_config red_config[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE][RTE_COLORS]; @@ -380,7 +381,7 @@ rte_sched_port_check_params(struct rte_sched_port_params *params) /* pipe_profiles and n_pipe_profiles */ if (params->pipe_profiles == NULL || params->n_pipe_profiles == 0 || - params->n_pipe_profiles > RTE_SCHED_PIPE_PROFILES_PER_PORT) + params->n_pipe_profiles > params->n_max_pipe_profiles) return -9; for (i = 0; i < params->n_pipe_profiles; i++) { @@ -409,7 +410,7 @@ rte_sched_port_get_array_base(struct rte_sched_port_params *params, enum rte_sch uint32_t size_queue_extra = n_queues_per_port * sizeof(struct rte_sched_queue_extra); uint32_t size_pipe_profiles - = RTE_SCHED_PIPE_PROFILES_PER_PORT * sizeof(struct rte_sched_pipe_profile); + = params->n_max_pipe_profiles * sizeof(struct rte_sched_pipe_profile); uint32_t size_bmp_array = rte_bitmap_get_memory_footprint(n_queues_per_port); uint32_t size_per_pipe_queue_array, size_queue_array; @@ -686,6 +687,7 @@ rte_sched_port_config(struct rte_sched_port_params *params) port->frame_overhead = params->frame_overhead; memcpy(port->qsize, params->qsize, sizeof(params->qsize)); port->n_pipe_profiles = params->n_pipe_profiles; + port->n_max_pipe_profiles = params->n_max_pipe_profiles; #ifdef RTE_SCHED_RED for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { @@ -1037,7 +1039,7 @@ rte_sched_port_pipe_profile_add(struct rte_sched_port *port, return -1; /* Pipe profiles not exceeds the max limit */ - if (port->n_pipe_profiles >= RTE_SCHED_PIPE_PROFILES_PER_PORT) + if (port->n_pipe_profiles >= port->n_max_pipe_profiles) return -2; /* Pipe params */ diff --git a/lib/librte_sched/rte_sched.h b/lib/librte_sched/rte_sched.h index 2b65420d1..d7d4f1767 100644 --- a/lib/librte_sched/rte_sched.h +++ b/lib/librte_sched/rte_sched.h @@ -220,6 +220,8 @@ struct rte_sched_port_params { /**< Pipe profile table. * Every pipe is configured using one of the profiles from this table. */ uint32_t n_pipe_profiles; /**< Profiles in the pipe profile table */ + uint32_t n_max_pipe_profiles; + /**< Max profiles allowed in the pipe profile table */ #ifdef RTE_SCHED_RED struct rte_red_params red_params[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE][RTE_COLORS]; /**< RED parameters */ #endif -- 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* [dpdk-dev] [PATCH v6 04/11] sched: rename tc3 params to best-effort tc 2019-07-19 14:18 ` [dpdk-dev] [PATCH v6 00/11] sched: feature enhancements Jasvinder Singh ` (2 preceding siblings ...) 2019-07-19 14:18 ` [dpdk-dev] [PATCH v6 03/11] sched: add max pipe profiles config in run time Jasvinder Singh @ 2019-07-19 14:18 ` Jasvinder Singh 2019-07-19 14:18 ` [dpdk-dev] [PATCH v6 05/11] sched: improve error log messages Jasvinder Singh ` (8 subsequent siblings) 12 siblings, 0 replies; 163+ messages in thread From: Jasvinder Singh @ 2019-07-19 14:18 UTC (permalink / raw) To: dev; +Cc: cristian.dumitrescu, Abraham Tovar, Lukasz Krakowiak Change the traffic class 3 related params name to best-effort(be) traffic class. Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com> Signed-off-by: Abraham Tovar <abrahamx.tovar@intel.com> Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com> --- lib/librte_sched/rte_sched.c | 56 ++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/lib/librte_sched/rte_sched.c b/lib/librte_sched/rte_sched.c index e8614ba4c..7e000c249 100644 --- a/lib/librte_sched/rte_sched.c +++ b/lib/librte_sched/rte_sched.c @@ -180,7 +180,7 @@ struct rte_sched_port { uint16_t qsize[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; uint32_t n_pipe_profiles; uint32_t n_max_pipe_profiles; - uint32_t pipe_tc3_rate_max; + uint32_t pipe_tc_be_rate_max; #ifdef RTE_SCHED_RED struct rte_red_config red_config[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE][RTE_COLORS]; #endif @@ -323,7 +323,7 @@ pipe_profile_check(struct rte_sched_pipe_params *params, if (params->tc_period == 0) return -14; - /* TC3 oversubscription weight: non-zero */ + /* Best effort tc oversubscription weight: non-zero */ if (params->tc_ov_weight == 0) return -15; @@ -540,7 +540,7 @@ rte_sched_port_log_pipe_profile(struct rte_sched_port *port, uint32_t i) p->tc_credits_per_period[11], p->tc_credits_per_period[12], - /* Traffic class 3 oversubscription */ + /* Best-effort traffic class oversubscription */ p->tc_ov_weight, /* WRR */ @@ -629,13 +629,13 @@ rte_sched_port_config_pipe_profile_table(struct rte_sched_port *port, rte_sched_port_log_pipe_profile(port, i); } - port->pipe_tc3_rate_max = 0; + port->pipe_tc_be_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[RTE_SCHED_TRAFFIC_CLASS_BE]; + uint32_t pipe_tc_be_rate = src->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE]; - if (port->pipe_tc3_rate_max < pipe_tc3_rate) - port->pipe_tc3_rate_max = pipe_tc3_rate; + if (port->pipe_tc_be_rate_max < pipe_tc_be_rate) + port->pipe_tc_be_rate_max = pipe_tc_be_rate; } } @@ -839,7 +839,7 @@ rte_sched_port_log_subport_config(struct rte_sched_port *port, uint32_t i) s->tc_credits_per_period[11], s->tc_credits_per_period[12], - /* Traffic class 3 oversubscription */ + /* Best effort traffic class oversubscription */ s->tc_ov_wm_min, s->tc_ov_wm_max); } @@ -915,7 +915,7 @@ rte_sched_subport_config(struct rte_sched_port *port, /* TC oversubscription */ s->tc_ov_wm_min = port->mtu; s->tc_ov_wm_max = rte_sched_time_ms_to_bytes(params->tc_period, - port->pipe_tc3_rate_max); + port->pipe_tc_be_rate_max); s->tc_ov_wm = s->tc_ov_wm_max; s->tc_ov_period_id = 0; s->tc_ov = 0; @@ -960,21 +960,21 @@ rte_sched_pipe_config(struct rte_sched_port *port, if (p->tb_time) { params = port->pipe_profiles + p->profile; - double subport_tc3_rate = (double) s->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] + double subport_tc_be_rate = (double) s->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] / (double) s->tc_period; - double pipe_tc3_rate = (double) params->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] + double pipe_tc_be_rate = (double) params->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] / (double) params->tc_period; - uint32_t tc3_ov = s->tc_ov; + uint32_t tc_be_ov = s->tc_ov; /* Unplug pipe from its subport */ 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; + s->tc_ov_rate -= pipe_tc_be_rate; + s->tc_ov = s->tc_ov_rate > subport_tc_be_rate; - if (s->tc_ov != tc3_ov) { + if (s->tc_ov != tc_be_ov) { RTE_LOG(DEBUG, SCHED, - "Subport %u TC3 oversubscription is OFF (%.4lf >= %.4lf)\n", - subport_id, subport_tc3_rate, s->tc_ov_rate); + "Subport %u Best effort TC oversubscription is OFF (%.4lf >= %.4lf)\n", + subport_id, subport_tc_be_rate, s->tc_ov_rate); } /* Reset the pipe */ @@ -1000,23 +1000,23 @@ rte_sched_pipe_config(struct rte_sched_port *port, p->tc_credits[i] = params->tc_credits_per_period[i]; { - /* Subport TC3 oversubscription */ - double subport_tc3_rate = + /* Subport best effort tc oversubscription */ + double subport_tc_be_rate = (double) s->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] / (double) s->tc_period; - double pipe_tc3_rate = + double pipe_tc_be_rate = (double) params->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] / (double) params->tc_period; - uint32_t tc3_ov = s->tc_ov; + uint32_t tc_be_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; + s->tc_ov_rate += pipe_tc_be_rate; + s->tc_ov = s->tc_ov_rate > subport_tc_be_rate; - if (s->tc_ov != tc3_ov) { + if (s->tc_ov != tc_be_ov) { RTE_LOG(DEBUG, SCHED, - "Subport %u TC3 oversubscription is ON (%.4lf < %.4lf)\n", - subport_id, subport_tc3_rate, s->tc_ov_rate); + "Subport %u Best effort TC oversubscription is ON (%.4lf < %.4lf)\n", + subport_id, subport_tc_be_rate, s->tc_ov_rate); } p->tc_ov_period_id = s->tc_ov_period_id; p->tc_ov_credits = s->tc_ov_wm; @@ -1059,8 +1059,8 @@ rte_sched_port_pipe_profile_add(struct rte_sched_port *port, *pipe_profile_id = port->n_pipe_profiles; port->n_pipe_profiles++; - if (port->pipe_tc3_rate_max < params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE]) - port->pipe_tc3_rate_max = params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE]; + if (port->pipe_tc_be_rate_max < params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE]) + port->pipe_tc_be_rate_max = params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE]; rte_sched_port_log_pipe_profile(port, *pipe_profile_id); -- 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* [dpdk-dev] [PATCH v6 05/11] sched: improve error log messages 2019-07-19 14:18 ` [dpdk-dev] [PATCH v6 00/11] sched: feature enhancements Jasvinder Singh ` (3 preceding siblings ...) 2019-07-19 14:18 ` [dpdk-dev] [PATCH v6 04/11] sched: rename tc3 params to best-effort tc Jasvinder Singh @ 2019-07-19 14:18 ` Jasvinder Singh 2019-07-19 14:18 ` [dpdk-dev] [PATCH v6 06/11] sched: improve doxygen comments Jasvinder Singh ` (7 subsequent siblings) 12 siblings, 0 replies; 163+ messages in thread From: Jasvinder Singh @ 2019-07-19 14:18 UTC (permalink / raw) To: dev; +Cc: cristian.dumitrescu, Abraham Tovar, Lukasz Krakowiak Replace hard-coded numbers for reporting errors with error messages. Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com> Signed-off-by: Abraham Tovar <abrahamx.tovar@intel.com> Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com> --- lib/librte_sched/rte_sched.c | 293 ++++++++++++++++++++++++++--------- 1 file changed, 221 insertions(+), 72 deletions(-) diff --git a/lib/librte_sched/rte_sched.c b/lib/librte_sched/rte_sched.c index 7e000c249..a173c7dbd 100644 --- a/lib/librte_sched/rte_sched.c +++ b/lib/librte_sched/rte_sched.c @@ -296,41 +296,66 @@ pipe_profile_check(struct rte_sched_pipe_params *params, uint32_t i; /* Pipe parameters */ - if (params == NULL) - return -10; + if (params == NULL) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for parameter params\n", __func__); + return -EINVAL; + } /* TB rate: non-zero, not greater than port rate */ if (params->tb_rate == 0 || - params->tb_rate > rate) - return -11; + params->tb_rate > rate) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for tb rate\n", __func__); + return -EINVAL; + } /* TB size: non-zero */ - if (params->tb_size == 0) - return -12; + if (params->tb_size == 0) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for tb size\n", __func__); + return -EINVAL; + } /* TC rate: non-zero if qsize non-zero, less than pipe rate */ for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { if ((qsize[i] == 0 && params->tc_rate[i] != 0) || (qsize[i] != 0 && (params->tc_rate[i] == 0 || - params->tc_rate[i] > params->tb_rate))) - return -13; + params->tc_rate[i] > params->tb_rate))) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for qsize or tc_rate\n", __func__); + return -EINVAL; + } } + if (params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE] == 0 || - qsize[RTE_SCHED_TRAFFIC_CLASS_BE] == 0) - return -13; + qsize[RTE_SCHED_TRAFFIC_CLASS_BE] == 0) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for be traffic class rate\n", __func__); + return -EINVAL; + } /* TC period: non-zero */ - if (params->tc_period == 0) - return -14; + if (params->tc_period == 0) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for tc period\n", __func__); + return -EINVAL; + } /* Best effort tc oversubscription weight: non-zero */ - if (params->tc_ov_weight == 0) - return -15; + if (params->tc_ov_weight == 0) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for tc ov weight\n", __func__); + return -EINVAL; + } /* Queue WRR weights: non-zero */ for (i = 0; i < RTE_SCHED_BE_QUEUES_PER_PIPE; i++) { - if (params->wrr_weights[i] == 0) - return -16; + if (params->wrr_weights[i] == 0) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for qsize or wrr weight\n", __func__); + return -EINVAL; + } } return 0; @@ -341,56 +366,83 @@ rte_sched_port_check_params(struct rte_sched_port_params *params) { uint32_t i; - if (params == NULL) - return -1; + if (params == NULL) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for parameter params\n", __func__); + return -EINVAL; + } /* socket */ - if (params->socket < 0) - return -3; + if (params->socket < 0) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for socket id\n", __func__); + return -EINVAL; + } /* rate */ - if (params->rate == 0) - return -4; + if (params->rate == 0) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for rate\n", __func__); + return -EINVAL; + } /* mtu */ - if (params->mtu == 0) - return -5; + if (params->mtu == 0) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for mtu\n", __func__); + return -EINVAL; + } /* n_subports_per_port: non-zero, limited to 16 bits, power of 2 */ if (params->n_subports_per_port == 0 || params->n_subports_per_port > 1u << 16 || - !rte_is_power_of_2(params->n_subports_per_port)) - return -6; + !rte_is_power_of_2(params->n_subports_per_port)) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for number of subports\n", __func__); + return -EINVAL; + } /* 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 -7; + !rte_is_power_of_2(params->n_pipes_per_subport)) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for pipes number\n", __func__); + return -EINVAL; + } - /* qsize: non-zero, power of 2, + /* qsize: if non-zero, power of 2, * no bigger than 32K (due to 16-bit read/write pointers) */ for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { uint16_t qsize = params->qsize[i]; if ((qsize != 0 && !rte_is_power_of_2(qsize)) || - ((i == RTE_SCHED_TRAFFIC_CLASS_BE) && (qsize == 0))) - return -8; + ((i == RTE_SCHED_TRAFFIC_CLASS_BE) && (qsize == 0))) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for tc rate\n", __func__); + return -EINVAL; + } } /* pipe_profiles and n_pipe_profiles */ if (params->pipe_profiles == NULL || params->n_pipe_profiles == 0 || - params->n_pipe_profiles > params->n_max_pipe_profiles) - return -9; + params->n_pipe_profiles > params->n_max_pipe_profiles) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for number of pipe profiles\n", __func__); + return -EINVAL; + } for (i = 0; i < params->n_pipe_profiles; i++) { struct rte_sched_pipe_params *p = params->pipe_profiles + i; int status; status = pipe_profile_check(p, params->rate, ¶ms->qsize[0]); - if (status != 0) - return status; + if (status != 0) { + RTE_LOG(ERR, SCHED, + "%s: Pipe profile check failed(%d)\n", __func__, status); + return -EINVAL; + } } return 0; @@ -853,16 +905,35 @@ rte_sched_subport_config(struct rte_sched_port *port, uint32_t i; /* Check user parameters */ - if (port == NULL || - subport_id >= port->n_subports_per_port || - params == NULL) - return -1; + if (port == NULL) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for parameter port\n", __func__); + return -EINVAL; + } - if (params->tb_rate == 0 || params->tb_rate > port->rate) - return -2; + if (subport_id >= port->n_subports_per_port) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for subport id\n", __func__); + return -EINVAL; + } - if (params->tb_size == 0) - return -3; + 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 > port->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++) { uint32_t tc_rate = params->tc_rate[i]; @@ -870,16 +941,25 @@ rte_sched_subport_config(struct rte_sched_port *port, if ((qsize == 0 && tc_rate != 0) || (qsize != 0 && tc_rate == 0) || - (tc_rate > params->tb_rate)) - return -4; + (tc_rate > params->tb_rate)) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for tc rate\n", __func__); + return -EINVAL; + } } if (port->qsize[RTE_SCHED_TRAFFIC_CLASS_BE] == 0 || - params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE] == 0) - return -4; + params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE] == 0) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for tc rate(best effort)\n", __func__); + return -EINVAL; + } - if (params->tc_period == 0) - return -5; + if (params->tc_period == 0) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for tc period\n", __func__); + return -EINVAL; + } s = port->subport + subport_id; @@ -942,17 +1022,37 @@ rte_sched_pipe_config(struct rte_sched_port *port, profile = (uint32_t) pipe_profile; deactivate = (pipe_profile < 0); - if (port == NULL || - subport_id >= port->n_subports_per_port || - pipe_id >= port->n_pipes_per_subport || - (!deactivate && profile >= port->n_pipe_profiles)) - return -1; + if (port == NULL) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for parameter port\n", __func__); + return -EINVAL; + } + + if (subport_id >= port->n_subports_per_port) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for parameter subport id\n", __func__); + return -EINVAL; + } + if (pipe_id >= port->n_pipes_per_subport) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for parameter pipe id\n", __func__); + return -EINVAL; + } + + if (!deactivate && profile >= port->n_pipe_profiles) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for parameter pipe profile\n", __func__); + return -EINVAL; + } /* Check that subport configuration is valid */ s = port->subport + subport_id; - if (s->tb_period == 0) - return -2; + if (s->tb_period == 0) { + RTE_LOG(ERR, SCHED, + "%s: Subport configuration invalid\n", __func__); + return -EINVAL; + } p = port->pipe + (subport_id * port->n_pipes_per_subport + pipe_id); @@ -1035,25 +1135,37 @@ rte_sched_port_pipe_profile_add(struct rte_sched_port *port, int status; /* Port */ - if (port == NULL) - return -1; + if (port == NULL) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for parameter port\n", __func__); + return -EINVAL; + } /* Pipe profiles not exceeds the max limit */ - if (port->n_pipe_profiles >= port->n_max_pipe_profiles) - return -2; + if (port->n_pipe_profiles >= port->n_max_pipe_profiles) { + RTE_LOG(ERR, SCHED, + "%s: Number of pipe profiles exceeds the max limit\n", __func__); + return -EINVAL; + } /* Pipe params */ status = pipe_profile_check(params, port->rate, &port->qsize[0]); - if (status != 0) - return status; + if (status != 0) { + RTE_LOG(ERR, SCHED, + "%s: Pipe profile check failed(%d)\n", __func__, status); + return -EINVAL; + } pp = &port->pipe_profiles[port->n_pipe_profiles]; rte_sched_pipe_profile_convert(port, params, pp, port->rate); /* Pipe profile not exists */ for (i = 0; i < port->n_pipe_profiles; i++) - if (memcmp(port->pipe_profiles + i, pp, sizeof(*pp)) == 0) - return -3; + if (memcmp(port->pipe_profiles + i, pp, sizeof(*pp)) == 0) { + RTE_LOG(ERR, SCHED, + "%s: Pipe profile doesn't exist\n", __func__); + return -EINVAL; + } /* Pipe profile commit */ *pipe_profile_id = port->n_pipe_profiles; @@ -1123,9 +1235,29 @@ rte_sched_subport_read_stats(struct rte_sched_port *port, struct rte_sched_subport *s; /* Check user parameters */ - if (port == NULL || subport_id >= port->n_subports_per_port || - stats == NULL || tc_ov == NULL) - return -1; + if (port == NULL) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for parameter port\n", __func__); + return -EINVAL; + } + + if (subport_id >= port->n_subports_per_port) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for subport id\n", __func__); + return -EINVAL; + } + + if (stats == NULL) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for parameter stats\n", __func__); + return -EINVAL; + } + + if (tc_ov == NULL) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for tc_ov\n", __func__); + return -EINVAL; + } s = port->subport + subport_id; @@ -1149,11 +1281,28 @@ rte_sched_queue_read_stats(struct rte_sched_port *port, struct rte_sched_queue_extra *qe; /* Check user parameters */ - if ((port == NULL) || - (queue_id >= rte_sched_port_queues_per_port(port)) || - (stats == NULL) || - (qlen == NULL)) { - return -1; + if (port == NULL) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for parameter port\n", __func__); + return -EINVAL; + } + + if (queue_id >= rte_sched_port_queues_per_port(port)) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for queue id\n", __func__); + return -EINVAL; + } + + if (stats == NULL) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for parameter stats\n", __func__); + return -EINVAL; + } + + if (qlen == NULL) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for parameter qlen\n", __func__); + return -EINVAL; } q = port->queue + queue_id; qe = port->queue_extra + queue_id; -- 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* [dpdk-dev] [PATCH v6 06/11] sched: improve doxygen comments 2019-07-19 14:18 ` [dpdk-dev] [PATCH v6 00/11] sched: feature enhancements Jasvinder Singh ` (4 preceding siblings ...) 2019-07-19 14:18 ` [dpdk-dev] [PATCH v6 05/11] sched: improve error log messages Jasvinder Singh @ 2019-07-19 14:18 ` Jasvinder Singh 2019-07-19 14:18 ` [dpdk-dev] [PATCH v6 07/11] net/softnic: add config flexibility to softnic tm Jasvinder Singh ` (6 subsequent siblings) 12 siblings, 0 replies; 163+ messages in thread From: Jasvinder Singh @ 2019-07-19 14:18 UTC (permalink / raw) To: dev; +Cc: cristian.dumitrescu, Abraham Tovar, Lukasz Krakowiak Improve doxygen comments. Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com> Signed-off-by: Abraham Tovar <abrahamx.tovar@intel.com> Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com> --- lib/librte_sched/rte_sched.h | 152 ++++++++++++++++++++++------------- 1 file changed, 94 insertions(+), 58 deletions(-) diff --git a/lib/librte_sched/rte_sched.h b/lib/librte_sched/rte_sched.h index d7d4f1767..fffbad696 100644 --- a/lib/librte_sched/rte_sched.h +++ b/lib/librte_sched/rte_sched.h @@ -52,7 +52,7 @@ extern "C" { * multiple connections of same traffic class belonging to * the same user; * - Weighted Round Robin (WRR) is used to service the - * queues within same pipe traffic class. + * queues within same pipe lowest priority traffic class (best-effort). * */ @@ -83,7 +83,8 @@ extern "C" { #define RTE_SCHED_BE_QUEUES_PER_PIPE 4 /** Number of traffic classes per pipe (as well as subport). - * Cannot be changed. + * @see struct rte_sched_subport_params + * @see struct rte_sched_pipe_params */ #define RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE \ (RTE_SCHED_QUEUES_PER_PIPE - RTE_SCHED_BE_QUEUES_PER_PIPE + 1) @@ -113,6 +114,8 @@ extern "C" { * * The FCS is considered overhead only if not included in the packet * length (field pkt_len of struct rte_mbuf). + * + * @see struct rte_sched_port_params */ #ifndef RTE_SCHED_FRAME_OVERHEAD_DEFAULT #define RTE_SCHED_FRAME_OVERHEAD_DEFAULT 24 @@ -128,34 +131,36 @@ extern "C" { * byte. */ struct rte_sched_subport_params { - /* Subport token bucket */ - uint32_t tb_rate; /**< Rate (measured in bytes per second) */ - uint32_t tb_size; /**< Size (measured in credits) */ + /** Token bucket rate (measured in bytes per second) */ + uint32_t tb_rate; + + /** Token bucket size (measured in credits) */ + uint32_t tb_size; - /* Subport traffic classes */ + /** Traffic class rates (measured in bytes per second) */ uint32_t tc_rate[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; - /**< Traffic class rates (measured in bytes per second) */ + + /** Enforcement period for rates (measured in milliseconds) */ uint32_t tc_period; - /**< Enforcement period for rates (measured in milliseconds) */ }; /** Subport statistics */ struct rte_sched_subport_stats { - /* Packets */ + /** Number of packets successfully written */ uint32_t n_pkts_tc[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; - /**< Number of packets successfully written */ + + /** Number of packets dropped */ uint32_t n_pkts_tc_dropped[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; - /**< Number of packets dropped */ - /* Bytes */ + /** Number of bytes successfully written for each traffic class */ uint32_t n_bytes_tc[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; - /**< Number of bytes successfully written for each traffic class */ + + /** Number of bytes dropped for each traffic class */ uint32_t n_bytes_tc_dropped[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; - /**< Number of bytes dropped for each traffic class */ #ifdef RTE_SCHED_RED + /** Number of packets dropped by red */ uint32_t n_pkts_red_dropped[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; - /**< Number of packets dropped by red */ #endif }; @@ -169,61 +174,90 @@ struct rte_sched_subport_stats { * byte. */ struct rte_sched_pipe_params { - /* Pipe token bucket */ - uint32_t tb_rate; /**< Rate (measured in bytes per second) */ - uint32_t tb_size; /**< Size (measured in credits) */ + /** Token bucket rate (measured in bytes per second) */ + uint32_t tb_rate; - /* Pipe traffic classes */ + /** Token bucket size (measured in credits) */ + uint32_t tb_size; + + /** Traffic class rates (measured in bytes per second) */ uint32_t tc_rate[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; - /**< Traffic class rates (measured in bytes per second) */ + + /** Enforcement period (measured in milliseconds) */ uint32_t tc_period; - /**< Enforcement period (measured in milliseconds) */ - uint8_t tc_ov_weight; /**< Weight Traffic class 3 oversubscription */ - /* Pipe queues */ - uint8_t wrr_weights[RTE_SCHED_BE_QUEUES_PER_PIPE]; /**< WRR weights */ + /** Best-effort traffic class oversubscription weight */ + uint8_t tc_ov_weight; + + /** WRR weights of best-effort traffic class queues */ + uint8_t wrr_weights[RTE_SCHED_BE_QUEUES_PER_PIPE]; }; /** Queue statistics */ struct rte_sched_queue_stats { - /* Packets */ - uint32_t n_pkts; /**< Packets successfully written */ - uint32_t n_pkts_dropped; /**< Packets dropped */ + /** Packets successfully written */ + uint32_t n_pkts; + + /** Packets dropped */ + uint32_t n_pkts_dropped; + #ifdef RTE_SCHED_RED - uint32_t n_pkts_red_dropped; /**< Packets dropped by RED */ + /** Packets dropped by RED */ + uint32_t n_pkts_red_dropped; #endif - /* Bytes */ - uint32_t n_bytes; /**< Bytes successfully written */ - uint32_t n_bytes_dropped; /**< Bytes dropped */ + /** Bytes successfully written */ + uint32_t n_bytes; + + /** Bytes dropped */ + uint32_t n_bytes_dropped; }; /** Port configuration parameters. */ struct rte_sched_port_params { - const char *name; /**< String to be associated */ - int socket; /**< CPU socket ID */ - uint32_t rate; /**< Output port rate - * (measured in bytes per second) */ - uint32_t mtu; /**< Maximum Ethernet frame size - * (measured in bytes). - * Should not include the framing overhead. */ - uint32_t frame_overhead; /**< Framing overhead per packet - * (measured in bytes) */ - uint32_t n_subports_per_port; /**< Number of subports */ - uint32_t n_pipes_per_subport; /**< Number of pipes per subport */ + /** Name of the port to be associated */ + const char *name; + + /** CPU socket ID */ + int socket; + + /** Output port rate (measured in bytes per second) */ + uint32_t rate; + + /** Maximum Ethernet frame size (measured in bytes). + * Should not include the framing overhead. + */ + uint32_t mtu; + + /** Framing overhead per packet (measured in bytes) */ + uint32_t frame_overhead; + + /** Number of subports */ + uint32_t n_subports_per_port; + + /** Number of subport_pipes */ + uint32_t n_pipes_per_subport; + + /** Packet queue size for each traffic class. + * All the pipes within the same subport share the similar + * configuration for the queues. + */ uint16_t qsize[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; - /**< Packet queue size for each traffic class. - * All queues within the same pipe traffic class have the same - * size. Queues from different pipes serving the same traffic - * class have the same size. */ + + /** Pipe profile table. + * Every pipe is configured using one of the profiles from this table. + */ struct rte_sched_pipe_params *pipe_profiles; - /**< Pipe profile table. - * Every pipe is configured using one of the profiles from this table. */ - uint32_t n_pipe_profiles; /**< Profiles in the pipe profile table */ + + /** Profiles in the pipe profile table */ + uint32_t n_pipe_profiles; + + /** Max profiles allowed in the pipe profile table */ uint32_t n_max_pipe_profiles; - /**< Max profiles allowed in the pipe profile table */ + #ifdef RTE_SCHED_RED - struct rte_red_params red_params[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE][RTE_COLORS]; /**< RED parameters */ + /** RED parameters */ + struct rte_red_params red_params[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE][RTE_COLORS]; #endif }; @@ -337,8 +371,9 @@ rte_sched_port_get_memory_footprint(struct rte_sched_port_params *params); * Pointer to pre-allocated subport statistics structure where the statistics * counters should be stored * @param tc_ov - * Pointer to pre-allocated 4-entry array where the oversubscription status for - * each of the 4 subport traffic classes should be stored. + * Pointer to pre-allocated RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE-entry array + * where the oversubscription status for each of the subport traffic classes + * should be stored. * @return * 0 upon success, error code otherwise */ @@ -383,9 +418,10 @@ rte_sched_queue_read_stats(struct rte_sched_port *port, * @param pipe * Pipe ID within subport * @param traffic_class - * Traffic class ID within pipe (0 .. 3) + * Traffic class ID within pipe (0 .. RTE_SCHED_TRAFFIC_CLASS_BE) * @param queue - * Queue ID within pipe traffic class (0 .. 3) + * Queue ID within pipe traffic class, 0 for high priority TCs, and + * 0 .. (RTE_SCHED_BE_QUEUES_PER_PIPE - 1) for best-effort TC * @param color * Packet color set */ @@ -410,10 +446,10 @@ rte_sched_port_pkt_write(struct rte_sched_port *port, * @param pipe * Pipe ID within subport * @param traffic_class - * Traffic class ID within pipe (0 .. 3) + * Traffic class ID within pipe (0 .. RTE_SCHED_TRAFFIC_CLASS_BE) * @param queue - * Queue ID within pipe traffic class (0 .. 3) - * + * Queue ID within pipe traffic class, 0 for high priority TCs, and + * 0 .. (RTE_SCHED_BE_QUEUES_PER_PIPE - 1) for best-effort TC */ void rte_sched_port_pkt_read_tree_path(struct rte_sched_port *port, -- 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* [dpdk-dev] [PATCH v6 07/11] net/softnic: add config flexibility to softnic tm 2019-07-19 14:18 ` [dpdk-dev] [PATCH v6 00/11] sched: feature enhancements Jasvinder Singh ` (5 preceding siblings ...) 2019-07-19 14:18 ` [dpdk-dev] [PATCH v6 06/11] sched: improve doxygen comments Jasvinder Singh @ 2019-07-19 14:18 ` Jasvinder Singh 2019-07-19 14:18 ` [dpdk-dev] [PATCH v6 08/11] test_sched: modify tests for config flexibility Jasvinder Singh ` (5 subsequent siblings) 12 siblings, 0 replies; 163+ messages in thread From: Jasvinder Singh @ 2019-07-19 14:18 UTC (permalink / raw) To: dev; +Cc: cristian.dumitrescu, Abraham Tovar, Lukasz Krakowiak Update softnic tm function for configuration flexiblity of pipe traffic classes and queues size. Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com> Signed-off-by: Abraham Tovar <abrahamx.tovar@intel.com> Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com> --- drivers/net/softnic/rte_eth_softnic.c | 98 ++++ drivers/net/softnic/rte_eth_softnic_cli.c | 448 ++++++++++++++++-- .../net/softnic/rte_eth_softnic_internals.h | 6 +- drivers/net/softnic/rte_eth_softnic_tm.c | 121 +++-- 4 files changed, 603 insertions(+), 70 deletions(-) diff --git a/drivers/net/softnic/rte_eth_softnic.c b/drivers/net/softnic/rte_eth_softnic.c index 4bda2f2b0..e3ad24161 100644 --- a/drivers/net/softnic/rte_eth_softnic.c +++ b/drivers/net/softnic/rte_eth_softnic.c @@ -28,6 +28,16 @@ #define PMD_PARAM_TM_QSIZE1 "tm_qsize1" #define PMD_PARAM_TM_QSIZE2 "tm_qsize2" #define PMD_PARAM_TM_QSIZE3 "tm_qsize3" +#define PMD_PARAM_TM_QSIZE4 "tm_qsize4" +#define PMD_PARAM_TM_QSIZE5 "tm_qsize5" +#define PMD_PARAM_TM_QSIZE6 "tm_qsize6" +#define PMD_PARAM_TM_QSIZE7 "tm_qsize7" +#define PMD_PARAM_TM_QSIZE8 "tm_qsize8" +#define PMD_PARAM_TM_QSIZE9 "tm_qsize9" +#define PMD_PARAM_TM_QSIZE10 "tm_qsize10" +#define PMD_PARAM_TM_QSIZE11 "tm_qsize11" +#define PMD_PARAM_TM_QSIZE12 "tm_qsize12" + static const char * const pmd_valid_args[] = { PMD_PARAM_FIRMWARE, @@ -39,6 +49,15 @@ static const char * const pmd_valid_args[] = { PMD_PARAM_TM_QSIZE1, PMD_PARAM_TM_QSIZE2, PMD_PARAM_TM_QSIZE3, + PMD_PARAM_TM_QSIZE4, + PMD_PARAM_TM_QSIZE5, + PMD_PARAM_TM_QSIZE6, + PMD_PARAM_TM_QSIZE7, + PMD_PARAM_TM_QSIZE8, + PMD_PARAM_TM_QSIZE9, + PMD_PARAM_TM_QSIZE10, + PMD_PARAM_TM_QSIZE11, + PMD_PARAM_TM_QSIZE12, NULL }; @@ -434,6 +453,15 @@ pmd_parse_args(struct pmd_params *p, const char *params) p->tm.qsize[1] = SOFTNIC_TM_QUEUE_SIZE; p->tm.qsize[2] = SOFTNIC_TM_QUEUE_SIZE; p->tm.qsize[3] = SOFTNIC_TM_QUEUE_SIZE; + p->tm.qsize[4] = SOFTNIC_TM_QUEUE_SIZE; + p->tm.qsize[5] = SOFTNIC_TM_QUEUE_SIZE; + p->tm.qsize[6] = SOFTNIC_TM_QUEUE_SIZE; + p->tm.qsize[7] = SOFTNIC_TM_QUEUE_SIZE; + p->tm.qsize[8] = SOFTNIC_TM_QUEUE_SIZE; + p->tm.qsize[9] = SOFTNIC_TM_QUEUE_SIZE; + p->tm.qsize[10] = SOFTNIC_TM_QUEUE_SIZE; + p->tm.qsize[11] = SOFTNIC_TM_QUEUE_SIZE; + p->tm.qsize[12] = SOFTNIC_TM_QUEUE_SIZE; /* Firmware script (optional) */ if (rte_kvargs_count(kvlist, PMD_PARAM_FIRMWARE) == 1) { @@ -504,6 +532,67 @@ pmd_parse_args(struct pmd_params *p, const char *params) goto out_free; } + if (rte_kvargs_count(kvlist, PMD_PARAM_TM_QSIZE4) == 1) { + ret = rte_kvargs_process(kvlist, PMD_PARAM_TM_QSIZE4, + &get_uint32, &p->tm.qsize[4]); + if (ret < 0) + goto out_free; + } + + if (rte_kvargs_count(kvlist, PMD_PARAM_TM_QSIZE5) == 1) { + ret = rte_kvargs_process(kvlist, PMD_PARAM_TM_QSIZE5, + &get_uint32, &p->tm.qsize[5]); + if (ret < 0) + goto out_free; + } + + if (rte_kvargs_count(kvlist, PMD_PARAM_TM_QSIZE6) == 1) { + ret = rte_kvargs_process(kvlist, PMD_PARAM_TM_QSIZE6, + &get_uint32, &p->tm.qsize[6]); + if (ret < 0) + goto out_free; + } + + if (rte_kvargs_count(kvlist, PMD_PARAM_TM_QSIZE7) == 1) { + ret = rte_kvargs_process(kvlist, PMD_PARAM_TM_QSIZE7, + &get_uint32, &p->tm.qsize[7]); + if (ret < 0) + goto out_free; + } + if (rte_kvargs_count(kvlist, PMD_PARAM_TM_QSIZE8) == 1) { + ret = rte_kvargs_process(kvlist, PMD_PARAM_TM_QSIZE8, + &get_uint32, &p->tm.qsize[8]); + if (ret < 0) + goto out_free; + } + if (rte_kvargs_count(kvlist, PMD_PARAM_TM_QSIZE9) == 1) { + ret = rte_kvargs_process(kvlist, PMD_PARAM_TM_QSIZE9, + &get_uint32, &p->tm.qsize[9]); + if (ret < 0) + goto out_free; + } + + if (rte_kvargs_count(kvlist, PMD_PARAM_TM_QSIZE10) == 1) { + ret = rte_kvargs_process(kvlist, PMD_PARAM_TM_QSIZE10, + &get_uint32, &p->tm.qsize[10]); + if (ret < 0) + goto out_free; + } + + if (rte_kvargs_count(kvlist, PMD_PARAM_TM_QSIZE11) == 1) { + ret = rte_kvargs_process(kvlist, PMD_PARAM_TM_QSIZE11, + &get_uint32, &p->tm.qsize[11]); + if (ret < 0) + goto out_free; + } + + if (rte_kvargs_count(kvlist, PMD_PARAM_TM_QSIZE12) == 1) { + ret = rte_kvargs_process(kvlist, PMD_PARAM_TM_QSIZE12, + &get_uint32, &p->tm.qsize[12]); + if (ret < 0) + goto out_free; + } + out_free: rte_kvargs_free(kvlist); return ret; @@ -588,6 +677,15 @@ RTE_PMD_REGISTER_PARAM_STRING(net_softnic, PMD_PARAM_TM_QSIZE1 "=<uint32> " PMD_PARAM_TM_QSIZE2 "=<uint32> " PMD_PARAM_TM_QSIZE3 "=<uint32>" + PMD_PARAM_TM_QSIZE4 "=<uint32> " + PMD_PARAM_TM_QSIZE5 "=<uint32> " + PMD_PARAM_TM_QSIZE6 "=<uint32> " + PMD_PARAM_TM_QSIZE7 "=<uint32> " + PMD_PARAM_TM_QSIZE8 "=<uint32> " + PMD_PARAM_TM_QSIZE9 "=<uint32> " + PMD_PARAM_TM_QSIZE10 "=<uint32> " + PMD_PARAM_TM_QSIZE11 "=<uint32>" + PMD_PARAM_TM_QSIZE12 "=<uint32>" ); diff --git a/drivers/net/softnic/rte_eth_softnic_cli.c b/drivers/net/softnic/rte_eth_softnic_cli.c index 56fc92ba2..dafc37bdf 100644 --- a/drivers/net/softnic/rte_eth_softnic_cli.c +++ b/drivers/net/softnic/rte_eth_softnic_cli.c @@ -566,8 +566,7 @@ queue_node_id(uint32_t n_spp __rte_unused, uint32_t tc_id, uint32_t queue_id) { - return queue_id + - tc_id * RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE + + return queue_id + tc_id + (pipe_id + subport_id * n_pps) * RTE_SCHED_QUEUES_PER_PIPE; } @@ -617,10 +616,20 @@ tmgr_hierarchy_default(struct pmd_internals *softnic, }, }; + uint32_t *shared_shaper_id = + (uint32_t *)calloc(RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE, + sizeof(uint32_t)); + + if (shared_shaper_id == NULL) + return -1; + + memcpy(shared_shaper_id, params->shared_shaper_id.tc, + sizeof(params->shared_shaper_id.tc)); + struct rte_tm_node_params tc_node_params[] = { [0] = { .shaper_profile_id = params->shaper_profile_id.tc[0], - .shared_shaper_id = ¶ms->shared_shaper_id.tc[0], + .shared_shaper_id = &shared_shaper_id[0], .n_shared_shapers = (¶ms->shared_shaper_id.tc_valid[0]) ? 1 : 0, .nonleaf = { @@ -630,7 +639,7 @@ tmgr_hierarchy_default(struct pmd_internals *softnic, [1] = { .shaper_profile_id = params->shaper_profile_id.tc[1], - .shared_shaper_id = ¶ms->shared_shaper_id.tc[1], + .shared_shaper_id = &shared_shaper_id[1], .n_shared_shapers = (¶ms->shared_shaper_id.tc_valid[1]) ? 1 : 0, .nonleaf = { @@ -640,7 +649,7 @@ tmgr_hierarchy_default(struct pmd_internals *softnic, [2] = { .shaper_profile_id = params->shaper_profile_id.tc[2], - .shared_shaper_id = ¶ms->shared_shaper_id.tc[2], + .shared_shaper_id = &shared_shaper_id[2], .n_shared_shapers = (¶ms->shared_shaper_id.tc_valid[2]) ? 1 : 0, .nonleaf = { @@ -650,13 +659,103 @@ tmgr_hierarchy_default(struct pmd_internals *softnic, [3] = { .shaper_profile_id = params->shaper_profile_id.tc[3], - .shared_shaper_id = ¶ms->shared_shaper_id.tc[3], + .shared_shaper_id = &shared_shaper_id[3], .n_shared_shapers = (¶ms->shared_shaper_id.tc_valid[3]) ? 1 : 0, .nonleaf = { .n_sp_priorities = 1, }, }, + + [4] = { + .shaper_profile_id = params->shaper_profile_id.tc[4], + .shared_shaper_id = &shared_shaper_id[4], + .n_shared_shapers = + (¶ms->shared_shaper_id.tc_valid[4]) ? 1 : 0, + .nonleaf = { + .n_sp_priorities = 1, + }, + }, + + [5] = { + .shaper_profile_id = params->shaper_profile_id.tc[5], + .shared_shaper_id = &shared_shaper_id[5], + .n_shared_shapers = + (¶ms->shared_shaper_id.tc_valid[5]) ? 1 : 0, + .nonleaf = { + .n_sp_priorities = 1, + }, + }, + + [6] = { + .shaper_profile_id = params->shaper_profile_id.tc[6], + .shared_shaper_id = &shared_shaper_id[6], + .n_shared_shapers = + (¶ms->shared_shaper_id.tc_valid[6]) ? 1 : 0, + .nonleaf = { + .n_sp_priorities = 1, + }, + }, + + [7] = { + .shaper_profile_id = params->shaper_profile_id.tc[7], + .shared_shaper_id = &shared_shaper_id[7], + .n_shared_shapers = + (¶ms->shared_shaper_id.tc_valid[7]) ? 1 : 0, + .nonleaf = { + .n_sp_priorities = 1, + }, + }, + + [8] = { + .shaper_profile_id = params->shaper_profile_id.tc[8], + .shared_shaper_id = &shared_shaper_id[8], + .n_shared_shapers = + (¶ms->shared_shaper_id.tc_valid[8]) ? 1 : 0, + .nonleaf = { + .n_sp_priorities = 1, + }, + }, + + [9] = { + .shaper_profile_id = params->shaper_profile_id.tc[9], + .shared_shaper_id = &shared_shaper_id[9], + .n_shared_shapers = + (¶ms->shared_shaper_id.tc_valid[9]) ? 1 : 0, + .nonleaf = { + .n_sp_priorities = 1, + }, + }, + + [10] = { + .shaper_profile_id = params->shaper_profile_id.tc[10], + .shared_shaper_id = &shared_shaper_id[10], + .n_shared_shapers = + (¶ms->shared_shaper_id.tc_valid[10]) ? 1 : 0, + .nonleaf = { + .n_sp_priorities = 1, + }, + }, + + [11] = { + .shaper_profile_id = params->shaper_profile_id.tc[11], + .shared_shaper_id = &shared_shaper_id[11], + .n_shared_shapers = + (¶ms->shared_shaper_id.tc_valid[11]) ? 1 : 0, + .nonleaf = { + .n_sp_priorities = 1, + }, + }, + + [12] = { + .shaper_profile_id = params->shaper_profile_id.tc[12], + .shared_shaper_id = &shared_shaper_id[12], + .n_shared_shapers = + (¶ms->shared_shaper_id.tc_valid[12]) ? 1 : 0, + .nonleaf = { + .n_sp_priorities = 1, + }, + }, }; struct rte_tm_node_params queue_node_params = { @@ -730,7 +829,23 @@ tmgr_hierarchy_default(struct pmd_internals *softnic, return -1; /* Hierarchy level 4: Queue nodes */ - for (q = 0; q < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; q++) { + if (t == RTE_SCHED_TRAFFIC_CLASS_BE) { + /* Best-effort traffic class queues */ + for (q = 0; q < RTE_SCHED_BE_QUEUES_PER_PIPE; q++) { + status = rte_tm_node_add(port_id, + queue_node_id(n_spp, n_pps, s, p, t, q), + tc_node_id(n_spp, n_pps, s, p, t), + 0, + params->weight.queue[q], + RTE_TM_NODE_LEVEL_ID_ANY, + &queue_node_params, + &error); + if (status) + return -1; + } + } else { + /* Strict-priority traffic class queues */ + q = 0; status = rte_tm_node_add(port_id, queue_node_id(n_spp, n_pps, s, p, t, q), tc_node_id(n_spp, n_pps, s, p, t), @@ -741,7 +856,7 @@ tmgr_hierarchy_default(struct pmd_internals *softnic, &error); if (status) return -1; - } /* Queue */ + } } /* TC */ } /* Pipe */ } /* Subport */ @@ -762,13 +877,31 @@ tmgr_hierarchy_default(struct pmd_internals *softnic, * tc1 <profile_id> * tc2 <profile_id> * tc3 <profile_id> + * tc4 <profile_id> + * tc5 <profile_id> + * tc6 <profile_id> + * tc7 <profile_id> + * tc8 <profile_id> + * tc9 <profile_id> + * tc10 <profile_id> + * tc11 <profile_id> + * tc12 <profile_id> * shared shaper * tc0 <id | none> * tc1 <id | none> * tc2 <id | none> * tc3 <id | none> + * tc4 <id | none> + * tc5 <id | none> + * tc6 <id | none> + * tc7 <id | none> + * tc8 <id | none> + * tc9 <id | none> + * tc10 <id | none> + * tc11 <id | none> + * tc12 <id | none> * weight - * queue <q0> ... <q15> + * queue <q12> ... <q15> */ static void cmd_tmgr_hierarchy_default(struct pmd_internals *softnic, @@ -778,11 +911,11 @@ cmd_tmgr_hierarchy_default(struct pmd_internals *softnic, size_t out_size) { struct tmgr_hierarchy_default_params p; - int i, status; + int i, j, status; memset(&p, 0, sizeof(p)); - if (n_tokens != 50) { + if (n_tokens != 74) { snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); return; } @@ -894,27 +1027,118 @@ cmd_tmgr_hierarchy_default(struct pmd_internals *softnic, return; } + if (strcmp(tokens[22], "tc4") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc4"); + return; + } + + if (softnic_parser_read_uint32(&p.shaper_profile_id.tc[4], tokens[23]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "tc4 profile id"); + return; + } + + if (strcmp(tokens[24], "tc5") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc5"); + return; + } + + if (softnic_parser_read_uint32(&p.shaper_profile_id.tc[5], tokens[25]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "tc5 profile id"); + return; + } + + if (strcmp(tokens[26], "tc6") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc6"); + return; + } + + if (softnic_parser_read_uint32(&p.shaper_profile_id.tc[6], tokens[27]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "tc6 profile id"); + return; + } + + if (strcmp(tokens[28], "tc7") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc7"); + return; + } + + if (softnic_parser_read_uint32(&p.shaper_profile_id.tc[7], tokens[29]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "tc7 profile id"); + return; + } + + if (strcmp(tokens[30], "tc8") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc8"); + return; + } + + if (softnic_parser_read_uint32(&p.shaper_profile_id.tc[8], tokens[31]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "tc8 profile id"); + return; + } + + if (strcmp(tokens[32], "tc9") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc9"); + return; + } + + if (softnic_parser_read_uint32(&p.shaper_profile_id.tc[9], tokens[33]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "tc9 profile id"); + return; + } + + if (strcmp(tokens[34], "tc10") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc10"); + return; + } + + if (softnic_parser_read_uint32(&p.shaper_profile_id.tc[10], tokens[35]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "tc10 profile id"); + return; + } + + if (strcmp(tokens[36], "tc11") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc11"); + return; + } + + if (softnic_parser_read_uint32(&p.shaper_profile_id.tc[11], tokens[37]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "tc11 profile id"); + return; + } + + if (strcmp(tokens[38], "tc12") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc12"); + return; + } + + if (softnic_parser_read_uint32(&p.shaper_profile_id.tc[12], tokens[39]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "tc12 profile id"); + return; + } + /* Shared shaper */ - if (strcmp(tokens[22], "shared") != 0) { + if (strcmp(tokens[40], "shared") != 0) { snprintf(out, out_size, MSG_ARG_NOT_FOUND, "shared"); return; } - if (strcmp(tokens[23], "shaper") != 0) { + if (strcmp(tokens[41], "shaper") != 0) { snprintf(out, out_size, MSG_ARG_NOT_FOUND, "shaper"); return; } - if (strcmp(tokens[24], "tc0") != 0) { + if (strcmp(tokens[42], "tc0") != 0) { snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc0"); return; } - if (strcmp(tokens[25], "none") == 0) + if (strcmp(tokens[43], "none") == 0) p.shared_shaper_id.tc_valid[0] = 0; else { - if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[0], tokens[25]) != 0) { + if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[0], + tokens[43]) != 0) { snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc0"); return; } @@ -922,15 +1146,16 @@ cmd_tmgr_hierarchy_default(struct pmd_internals *softnic, p.shared_shaper_id.tc_valid[0] = 1; } - if (strcmp(tokens[26], "tc1") != 0) { + if (strcmp(tokens[44], "tc1") != 0) { snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc1"); return; } - if (strcmp(tokens[27], "none") == 0) + if (strcmp(tokens[45], "none") == 0) p.shared_shaper_id.tc_valid[1] = 0; else { - if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[1], tokens[27]) != 0) { + if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[1], + tokens[45]) != 0) { snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc1"); return; } @@ -938,15 +1163,16 @@ cmd_tmgr_hierarchy_default(struct pmd_internals *softnic, p.shared_shaper_id.tc_valid[1] = 1; } - if (strcmp(tokens[28], "tc2") != 0) { + if (strcmp(tokens[46], "tc2") != 0) { snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc2"); return; } - if (strcmp(tokens[29], "none") == 0) + if (strcmp(tokens[47], "none") == 0) p.shared_shaper_id.tc_valid[2] = 0; else { - if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[2], tokens[29]) != 0) { + if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[2], + tokens[47]) != 0) { snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc2"); return; } @@ -954,15 +1180,16 @@ cmd_tmgr_hierarchy_default(struct pmd_internals *softnic, p.shared_shaper_id.tc_valid[2] = 1; } - if (strcmp(tokens[30], "tc3") != 0) { + if (strcmp(tokens[48], "tc3") != 0) { snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc3"); return; } - if (strcmp(tokens[31], "none") == 0) + if (strcmp(tokens[49], "none") == 0) p.shared_shaper_id.tc_valid[3] = 0; else { - if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[3], tokens[31]) != 0) { + if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[3], + tokens[49]) != 0) { snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc3"); return; } @@ -970,22 +1197,181 @@ cmd_tmgr_hierarchy_default(struct pmd_internals *softnic, p.shared_shaper_id.tc_valid[3] = 1; } + if (strcmp(tokens[50], "tc4") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc4"); + return; + } + + if (strcmp(tokens[51], "none") == 0) + p.shared_shaper_id.tc_valid[4] = 0; + else { + if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[4], + tokens[51]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc4"); + return; + } + + p.shared_shaper_id.tc_valid[4] = 1; + } + + if (strcmp(tokens[52], "tc5") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc5"); + return; + } + + if (strcmp(tokens[53], "none") == 0) + p.shared_shaper_id.tc_valid[5] = 0; + else { + if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[5], + tokens[53]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc5"); + return; + } + + p.shared_shaper_id.tc_valid[5] = 1; + } + + if (strcmp(tokens[54], "tc6") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc6"); + return; + } + + if (strcmp(tokens[55], "none") == 0) + p.shared_shaper_id.tc_valid[6] = 0; + else { + if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[6], + tokens[55]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc6"); + return; + } + + p.shared_shaper_id.tc_valid[6] = 1; + } + + if (strcmp(tokens[56], "tc7") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc7"); + return; + } + + if (strcmp(tokens[57], "none") == 0) + p.shared_shaper_id.tc_valid[7] = 0; + else { + if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[7], + tokens[57]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc7"); + return; + } + + p.shared_shaper_id.tc_valid[7] = 1; + } + + if (strcmp(tokens[58], "tc8") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc8"); + return; + } + + if (strcmp(tokens[59], "none") == 0) + p.shared_shaper_id.tc_valid[8] = 0; + else { + if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[8], + tokens[59]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc8"); + return; + } + + p.shared_shaper_id.tc_valid[8] = 1; + } + + if (strcmp(tokens[60], "tc9") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc9"); + return; + } + + if (strcmp(tokens[61], "none") == 0) + p.shared_shaper_id.tc_valid[9] = 0; + else { + if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[9], + tokens[61]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc9"); + return; + } + + p.shared_shaper_id.tc_valid[9] = 1; + } + + if (strcmp(tokens[62], "tc10") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc10"); + return; + } + + if (strcmp(tokens[63], "none") == 0) + p.shared_shaper_id.tc_valid[10] = 0; + else { + if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[10], + tokens[63]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc10"); + return; + } + + p.shared_shaper_id.tc_valid[10] = 1; + } + + if (strcmp(tokens[64], "tc11") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc11"); + return; + } + + if (strcmp(tokens[65], "none") == 0) + p.shared_shaper_id.tc_valid[11] = 0; + else { + if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[11], + tokens[65]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc11"); + return; + } + + p.shared_shaper_id.tc_valid[11] = 1; + } + + if (strcmp(tokens[66], "tc12") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc12"); + return; + } + + if (strcmp(tokens[67], "none") == 0) + p.shared_shaper_id.tc_valid[12] = 0; + else { + if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[12], + tokens[67]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc12"); + return; + } + + p.shared_shaper_id.tc_valid[12] = 1; + } + /* Weight */ - if (strcmp(tokens[32], "weight") != 0) { + if (strcmp(tokens[68], "weight") != 0) { snprintf(out, out_size, MSG_ARG_NOT_FOUND, "weight"); return; } - if (strcmp(tokens[33], "queue") != 0) { + if (strcmp(tokens[69], "queue") != 0) { snprintf(out, out_size, MSG_ARG_NOT_FOUND, "queue"); return; } - for (i = 0; i < 16; i++) { - if (softnic_parser_read_uint32(&p.weight.queue[i], tokens[34 + i]) != 0) { - snprintf(out, out_size, MSG_ARG_INVALID, "weight queue"); - return; + for (i = 0, j = 0; i < 16; i++) { + if (i < RTE_SCHED_TRAFFIC_CLASS_BE) { + p.weight.queue[i] = 1; + } else { + if (softnic_parser_read_uint32(&p.weight.queue[i], + tokens[70 + j]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "weight queue"); + return; + } + j++; } } diff --git a/drivers/net/softnic/rte_eth_softnic_internals.h b/drivers/net/softnic/rte_eth_softnic_internals.h index 415434d0d..0e3846893 100644 --- a/drivers/net/softnic/rte_eth_softnic_internals.h +++ b/drivers/net/softnic/rte_eth_softnic_internals.h @@ -161,13 +161,15 @@ TAILQ_HEAD(softnic_link_list, softnic_link); #define TM_MAX_PIPES_PER_SUBPORT 4096 #endif +#ifndef TM_MAX_PIPE_PROFILE +#define TM_MAX_PIPE_PROFILE 256 +#endif struct tm_params { struct rte_sched_port_params port_params; struct rte_sched_subport_params subport_params[TM_MAX_SUBPORTS]; - struct rte_sched_pipe_params - pipe_profiles[RTE_SCHED_PIPE_PROFILES_PER_PORT]; + struct rte_sched_pipe_params pipe_profiles[TM_MAX_PIPE_PROFILE]; uint32_t n_pipe_profiles; uint32_t pipe_to_profile[TM_MAX_SUBPORTS * TM_MAX_PIPES_PER_SUBPORT]; }; diff --git a/drivers/net/softnic/rte_eth_softnic_tm.c b/drivers/net/softnic/rte_eth_softnic_tm.c index 58744a9eb..fcc8e0da5 100644 --- a/drivers/net/softnic/rte_eth_softnic_tm.c +++ b/drivers/net/softnic/rte_eth_softnic_tm.c @@ -367,7 +367,8 @@ tm_level_get_max_nodes(struct rte_eth_dev *dev, enum tm_node_level level) { struct pmd_internals *p = dev->data->dev_private; uint32_t n_queues_max = p->params.tm.n_queues; - uint32_t n_tc_max = n_queues_max / RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; + uint32_t n_tc_max = + (n_queues_max * RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE) / RTE_SCHED_QUEUES_PER_PIPE; uint32_t n_pipes_max = n_tc_max / RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; uint32_t n_subports_max = n_pipes_max; uint32_t n_root_max = 1; @@ -625,10 +626,10 @@ static const struct rte_tm_level_capabilities tm_level_cap[] = { .shaper_shared_n_max = 1, .sched_n_children_max = - RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS, + RTE_SCHED_BE_QUEUES_PER_PIPE, .sched_sp_n_priorities_max = 1, .sched_wfq_n_children_per_group_max = - RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS, + RTE_SCHED_BE_QUEUES_PER_PIPE, .sched_wfq_n_groups_max = 1, .sched_wfq_weight_max = UINT32_MAX, @@ -793,10 +794,10 @@ static const struct rte_tm_node_capabilities tm_node_cap[] = { {.nonleaf = { .sched_n_children_max = - RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS, + RTE_SCHED_BE_QUEUES_PER_PIPE, .sched_sp_n_priorities_max = 1, .sched_wfq_n_children_per_group_max = - RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS, + RTE_SCHED_BE_QUEUES_PER_PIPE, .sched_wfq_n_groups_max = 1, .sched_wfq_weight_max = UINT32_MAX, } }, @@ -2027,9 +2028,7 @@ pipe_profile_build(struct rte_eth_dev *dev, /* Traffic Class (TC) */ pp->tc_period = PIPE_TC_PERIOD; -#ifdef RTE_SCHED_SUBPORT_TC_OV pp->tc_ov_weight = np->weight; -#endif TAILQ_FOREACH(nt, nl, node) { uint32_t queue_id = 0; @@ -2043,15 +2042,13 @@ pipe_profile_build(struct rte_eth_dev *dev, /* Queue */ TAILQ_FOREACH(nq, nl, node) { - uint32_t pipe_queue_id; if (nq->level != TM_NODE_LEVEL_QUEUE || nq->parent_node_id != nt->node_id) continue; - pipe_queue_id = nt->priority * - RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS + queue_id; - pp->wrr_weights[pipe_queue_id] = nq->weight; + if (nt->priority == RTE_SCHED_TRAFFIC_CLASS_BE) + pp->wrr_weights[queue_id] = nq->weight; queue_id++; } @@ -2065,7 +2062,7 @@ pipe_profile_free_exists(struct rte_eth_dev *dev, struct pmd_internals *p = dev->data->dev_private; struct tm_params *t = &p->soft.tm.params; - if (t->n_pipe_profiles < RTE_SCHED_PIPE_PROFILES_PER_PORT) { + if (t->n_pipe_profiles < TM_MAX_PIPE_PROFILE) { *pipe_profile_id = t->n_pipe_profiles; return 1; } @@ -2217,6 +2214,7 @@ wred_profiles_set(struct rte_eth_dev *dev) { struct pmd_internals *p = dev->data->dev_private; struct rte_sched_port_params *pp = &p->soft.tm.params.port_params; + uint32_t tc_id; enum rte_color color; @@ -2332,7 +2330,7 @@ hierarchy_commit_check(struct rte_eth_dev *dev, struct rte_tm_error *error) rte_strerror(EINVAL)); } - /* Each pipe has exactly 4 TCs, with exactly one TC for each priority */ + /* Each pipe has exactly 13 TCs, with exactly one TC for each priority */ TAILQ_FOREACH(np, nl, node) { uint32_t mask = 0, mask_expected = RTE_LEN2MASK(RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE, @@ -2364,12 +2362,14 @@ hierarchy_commit_check(struct rte_eth_dev *dev, struct rte_tm_error *error) rte_strerror(EINVAL)); } - /* Each TC has exactly 4 packet queues. */ + /** Each Strict priority TC has exactly 1 packet queues while + * lowest priority TC (Best-effort) has 4 queues. + */ TAILQ_FOREACH(nt, nl, node) { if (nt->level != TM_NODE_LEVEL_TC) continue; - if (nt->n_children != RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS) + if (nt->n_children != 1 && nt->n_children != RTE_SCHED_BE_QUEUES_PER_PIPE) return -rte_tm_error_set(error, EINVAL, RTE_TM_ERROR_TYPE_UNSPECIFIED, @@ -2531,9 +2531,19 @@ hierarchy_blueprints_create(struct rte_eth_dev *dev) p->params.tm.qsize[1], p->params.tm.qsize[2], p->params.tm.qsize[3], + p->params.tm.qsize[4], + p->params.tm.qsize[5], + p->params.tm.qsize[6], + p->params.tm.qsize[7], + p->params.tm.qsize[8], + p->params.tm.qsize[9], + p->params.tm.qsize[10], + p->params.tm.qsize[11], + p->params.tm.qsize[12], }, .pipe_profiles = t->pipe_profiles, .n_pipe_profiles = t->n_pipe_profiles, + .n_max_pipe_profiles = TM_MAX_PIPE_PROFILE, }; wred_profiles_set(dev); @@ -2566,8 +2576,17 @@ hierarchy_blueprints_create(struct rte_eth_dev *dev) tc_rate[1], tc_rate[2], tc_rate[3], - }, - .tc_period = SUBPORT_TC_PERIOD, + tc_rate[4], + tc_rate[5], + tc_rate[6], + tc_rate[7], + tc_rate[8], + tc_rate[9], + tc_rate[10], + tc_rate[11], + tc_rate[12], + }, + .tc_period = SUBPORT_TC_PERIOD, }; subport_id++; @@ -2657,7 +2676,6 @@ update_queue_weight(struct rte_eth_dev *dev, uint32_t queue_id = tm_node_queue_id(dev, nq); struct tm_node *nt = nq->parent_node; - uint32_t tc_id = tm_node_tc_id(dev, nt); struct tm_node *np = nt->parent_node; uint32_t pipe_id = tm_node_pipe_id(dev, np); @@ -2665,8 +2683,8 @@ update_queue_weight(struct rte_eth_dev *dev, struct tm_node *ns = np->parent_node; uint32_t subport_id = tm_node_subport_id(dev, ns); - uint32_t pipe_queue_id = - tc_id * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS + queue_id; + uint32_t pipe_be_queue_id = + queue_id - RTE_SCHED_TRAFFIC_CLASS_BE; struct rte_sched_pipe_params *profile0 = pipe_profile_get(dev, np); struct rte_sched_pipe_params profile1; @@ -2674,7 +2692,7 @@ update_queue_weight(struct rte_eth_dev *dev, /* Derive new pipe profile. */ memcpy(&profile1, profile0, sizeof(profile1)); - profile1.wrr_weights[pipe_queue_id] = (uint8_t)weight; + profile1.wrr_weights[pipe_be_queue_id] = (uint8_t)weight; /* Since implementation does not allow adding more pipe profiles after * port configuration, the pipe configuration can be successfully @@ -3020,12 +3038,11 @@ tm_port_queue_id(struct rte_eth_dev *dev, uint32_t port_pipe_id = port_subport_id * n_pipes_per_subport + subport_pipe_id; - uint32_t port_tc_id = - port_pipe_id * RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE + pipe_tc_id; + uint32_t port_queue_id = - port_tc_id * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS + tc_queue_id; + port_pipe_id * RTE_SCHED_QUEUES_PER_PIPE + pipe_tc_id + tc_queue_id; - return port_queue_id; + return port_queue_id; } static int @@ -3138,7 +3155,7 @@ read_pipe_stats(struct rte_eth_dev *dev, struct tm_node *ns = np->parent_node; uint32_t subport_id = tm_node_subport_id(dev, ns); - + uint32_t tc_id, queue_id; uint32_t i; /* Stats read */ @@ -3146,11 +3163,19 @@ read_pipe_stats(struct rte_eth_dev *dev, struct rte_sched_queue_stats s; uint16_t qlen; + if (i < RTE_SCHED_TRAFFIC_CLASS_BE) { + tc_id = i; + queue_id = i; + } else { + tc_id = RTE_SCHED_TRAFFIC_CLASS_BE; + queue_id = i - tc_id; + } + uint32_t qid = tm_port_queue_id(dev, subport_id, pipe_id, - i / RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS, - i % RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS); + tc_id, + queue_id); int status = rte_sched_queue_read_stats(SCHED(p), qid, @@ -3198,21 +3223,20 @@ read_tc_stats(struct rte_eth_dev *dev, struct tm_node *ns = np->parent_node; uint32_t subport_id = tm_node_subport_id(dev, ns); - - uint32_t i; + struct rte_sched_queue_stats s; + uint32_t qid, i; + uint16_t qlen; + int status; /* Stats read */ - for (i = 0; i < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; i++) { - struct rte_sched_queue_stats s; - uint16_t qlen; - - uint32_t qid = tm_port_queue_id(dev, + if (tc_id < RTE_SCHED_TRAFFIC_CLASS_BE) { + qid = tm_port_queue_id(dev, subport_id, pipe_id, tc_id, - i); + 0); - int status = rte_sched_queue_read_stats(SCHED(p), + status = rte_sched_queue_read_stats(SCHED(p), qid, &s, &qlen); @@ -3226,6 +3250,29 @@ read_tc_stats(struct rte_eth_dev *dev, nt->stats.leaf.n_bytes_dropped[RTE_COLOR_GREEN] += s.n_bytes_dropped; nt->stats.leaf.n_pkts_queued = qlen; + } else { + for (i = 0; i < RTE_SCHED_BE_QUEUES_PER_PIPE; i++) { + qid = tm_port_queue_id(dev, + subport_id, + pipe_id, + tc_id, + i); + + status = rte_sched_queue_read_stats(SCHED(p), + qid, + &s, + &qlen); + if (status) + return status; + + /* Stats accumulate */ + nt->stats.n_pkts += s.n_pkts - s.n_pkts_dropped; + nt->stats.n_bytes += s.n_bytes - s.n_bytes_dropped; + nt->stats.leaf.n_pkts_dropped[RTE_COLOR_GREEN] += s.n_pkts_dropped; + nt->stats.leaf.n_bytes_dropped[RTE_COLOR_GREEN] += + s.n_bytes_dropped; + nt->stats.leaf.n_pkts_queued = qlen; + } } /* Stats copy */ -- 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* [dpdk-dev] [PATCH v6 08/11] test_sched: modify tests for config flexibility 2019-07-19 14:18 ` [dpdk-dev] [PATCH v6 00/11] sched: feature enhancements Jasvinder Singh ` (6 preceding siblings ...) 2019-07-19 14:18 ` [dpdk-dev] [PATCH v6 07/11] net/softnic: add config flexibility to softnic tm Jasvinder Singh @ 2019-07-19 14:18 ` Jasvinder Singh 2019-07-19 14:18 ` [dpdk-dev] [PATCH v6 09/11] examples/ip_pipeline: add config flexibility to tm function Jasvinder Singh ` (4 subsequent siblings) 12 siblings, 0 replies; 163+ messages in thread From: Jasvinder Singh @ 2019-07-19 14:18 UTC (permalink / raw) To: dev; +Cc: cristian.dumitrescu, Abraham Tovar, Lukasz Krakowiak update unit tests for configuration flexibility of pipe traffic classes and queues size. Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com> Signed-off-by: Abraham Tovar <abrahamx.tovar@intel.com> Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com> --- app/test/test_sched.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/app/test/test_sched.c b/app/test/test_sched.c index 36fa2d425..afe0b0765 100644 --- a/app/test/test_sched.c +++ b/app/test/test_sched.c @@ -20,14 +20,16 @@ #define SUBPORT 0 #define PIPE 1 #define TC 2 -#define QUEUE 3 +#define QUEUE 0 static struct rte_sched_subport_params subport_param[] = { { .tb_rate = 1250000000, .tb_size = 1000000, - .tc_rate = {1250000000, 1250000000, 1250000000, 1250000000}, + .tc_rate = {1250000000, 1250000000, 1250000000, 1250000000, + 1250000000, 1250000000, 1250000000, 1250000000, 1250000000, + 1250000000, 1250000000, 1250000000, 1250000000}, .tc_period = 10, }, }; @@ -37,8 +39,10 @@ static struct rte_sched_pipe_params pipe_profile[] = { .tb_rate = 305175, .tb_size = 1000000, - .tc_rate = {305175, 305175, 305175, 305175}, + .tc_rate = {305175, 305175, 305175, 305175, 305175, 305175, + 305175, 305175, 305175, 305175, 305175, 305175, 305175}, .tc_period = 40, + .tc_ov_weight = 1, .wrr_weights = {1, 1, 1, 1}, }, @@ -51,9 +55,10 @@ static struct rte_sched_port_params port_param = { .frame_overhead = RTE_SCHED_FRAME_OVERHEAD_DEFAULT, .n_subports_per_port = 1, .n_pipes_per_subport = 1024, - .qsize = {32, 32, 32, 32}, + .qsize = {32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32}, .pipe_profiles = pipe_profile, .n_pipe_profiles = 1, + .n_max_pipe_profiles = 1, }; #define NB_MBUF 32 -- 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* [dpdk-dev] [PATCH v6 09/11] examples/ip_pipeline: add config flexibility to tm function 2019-07-19 14:18 ` [dpdk-dev] [PATCH v6 00/11] sched: feature enhancements Jasvinder Singh ` (7 preceding siblings ...) 2019-07-19 14:18 ` [dpdk-dev] [PATCH v6 08/11] test_sched: modify tests for config flexibility Jasvinder Singh @ 2019-07-19 14:18 ` Jasvinder Singh 2019-07-19 14:18 ` [dpdk-dev] [PATCH v6 10/11] examples/qos_sched: add tc and queue config flexibility Jasvinder Singh ` (3 subsequent siblings) 12 siblings, 0 replies; 163+ messages in thread From: Jasvinder Singh @ 2019-07-19 14:18 UTC (permalink / raw) To: dev; +Cc: cristian.dumitrescu, Abraham Tovar, Lukasz Krakowiak Update ip pipeline sample app for configuration flexiblity of pipe traffic classes and queues. Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com> Signed-off-by: Abraham Tovar <abrahamx.tovar@intel.com> Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com> --- examples/ip_pipeline/cli.c | 43 +++++++++++++++----------- examples/ip_pipeline/tmgr.h | 4 +-- lib/librte_pipeline/rte_table_action.c | 1 - lib/librte_pipeline/rte_table_action.h | 4 +-- 4 files changed, 29 insertions(+), 23 deletions(-) diff --git a/examples/ip_pipeline/cli.c b/examples/ip_pipeline/cli.c index 309b2936e..bfaa7f45e 100644 --- a/examples/ip_pipeline/cli.c +++ b/examples/ip_pipeline/cli.c @@ -377,7 +377,9 @@ cmd_swq(char **tokens, static const char cmd_tmgr_subport_profile_help[] = "tmgr subport profile\n" " <tb_rate> <tb_size>\n" -" <tc0_rate> <tc1_rate> <tc2_rate> <tc3_rate>\n" +" <tc0_rate> <tc1_rate> <tc2_rate> <tc3_rate> <tc4_rate>" +" <tc5_rate> <tc6_rate> <tc7_rate> <tc8_rate>" +" <tc9_rate> <tc10_rate> <tc11_rate> <tc12_rate>\n" " <tc_period>\n"; static void @@ -389,7 +391,7 @@ cmd_tmgr_subport_profile(char **tokens, struct rte_sched_subport_params p; int status, i; - if (n_tokens != 10) { + if (n_tokens != 19) { snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); return; } @@ -410,7 +412,7 @@ cmd_tmgr_subport_profile(char **tokens, return; } - if (parser_read_uint32(&p.tc_period, tokens[9]) != 0) { + if (parser_read_uint32(&p.tc_period, tokens[18]) != 0) { snprintf(out, out_size, MSG_ARG_INVALID, "tc_period"); return; } @@ -425,10 +427,12 @@ cmd_tmgr_subport_profile(char **tokens, static const char cmd_tmgr_pipe_profile_help[] = "tmgr pipe profile\n" " <tb_rate> <tb_size>\n" -" <tc0_rate> <tc1_rate> <tc2_rate> <tc3_rate>\n" +" <tc0_rate> <tc1_rate> <tc2_rate> <tc3_rate> <tc4_rate>" +" <tc5_rate> <tc6_rate> <tc7_rate> <tc8_rate>" +" <tc9_rate> <tc10_rate> <tc11_rate> <tc12_rate>\n" " <tc_period>\n" " <tc_ov_weight>\n" -" <wrr_weight0..15>\n"; +" <wrr_weight0..3>\n"; static void cmd_tmgr_pipe_profile(char **tokens, @@ -439,7 +443,7 @@ cmd_tmgr_pipe_profile(char **tokens, struct rte_sched_pipe_params p; int status, i; - if (n_tokens != 27) { + if (n_tokens != 24) { snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); return; } @@ -460,20 +464,20 @@ cmd_tmgr_pipe_profile(char **tokens, return; } - if (parser_read_uint32(&p.tc_period, tokens[9]) != 0) { + if (parser_read_uint32(&p.tc_period, tokens[18]) != 0) { snprintf(out, out_size, MSG_ARG_INVALID, "tc_period"); return; } #ifdef RTE_SCHED_SUBPORT_TC_OV - if (parser_read_uint8(&p.tc_ov_weight, tokens[10]) != 0) { + if (parser_read_uint8(&p.tc_ov_weight, tokens[19]) != 0) { snprintf(out, out_size, MSG_ARG_INVALID, "tc_ov_weight"); return; } #endif - for (i = 0; i < RTE_SCHED_QUEUES_PER_PIPE; i++) - if (parser_read_uint8(&p.wrr_weights[i], tokens[11 + i]) != 0) { + for (i = 0; i < RTE_SCHED_BE_QUEUES_PER_PIPE; i++) + if (parser_read_uint8(&p.wrr_weights[i], tokens[20 + i]) != 0) { snprintf(out, out_size, MSG_ARG_INVALID, "wrr_weights"); return; } @@ -490,7 +494,10 @@ static const char cmd_tmgr_help[] = " rate <rate>\n" " spp <n_subports_per_port>\n" " pps <n_pipes_per_subport>\n" -" qsize <qsize_tc0> <qsize_tc1> <qsize_tc2> <qsize_tc3>\n" +" qsize <qsize_tc0> <qsize_tc1> <qsize_tc2>" +" <qsize_tc3> <qsize_tc4> <qsize_tc5> <qsize_tc6>" +" <qsize_tc7> <qsize_tc8> <qsize_tc9> <qsize_tc10>" +" <qsize_tc11> <qsize_tc12>\n" " fo <frame_overhead>\n" " mtu <mtu>\n" " cpu <cpu_id>\n"; @@ -506,7 +513,7 @@ cmd_tmgr(char **tokens, struct tmgr_port *tmgr_port; int i; - if (n_tokens != 19) { + if (n_tokens != 28) { snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); return; } @@ -554,32 +561,32 @@ cmd_tmgr(char **tokens, return; } - if (strcmp(tokens[13], "fo") != 0) { + if (strcmp(tokens[22], "fo") != 0) { snprintf(out, out_size, MSG_ARG_NOT_FOUND, "fo"); return; } - if (parser_read_uint32(&p.frame_overhead, tokens[14]) != 0) { + if (parser_read_uint32(&p.frame_overhead, tokens[23]) != 0) { snprintf(out, out_size, MSG_ARG_INVALID, "frame_overhead"); return; } - if (strcmp(tokens[15], "mtu") != 0) { + if (strcmp(tokens[24], "mtu") != 0) { snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mtu"); return; } - if (parser_read_uint32(&p.mtu, tokens[16]) != 0) { + if (parser_read_uint32(&p.mtu, tokens[25]) != 0) { snprintf(out, out_size, MSG_ARG_INVALID, "mtu"); return; } - if (strcmp(tokens[17], "cpu") != 0) { + if (strcmp(tokens[26], "cpu") != 0) { snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cpu"); return; } - if (parser_read_uint32(&p.cpu_id, tokens[18]) != 0) { + if (parser_read_uint32(&p.cpu_id, tokens[27]) != 0) { snprintf(out, out_size, MSG_ARG_INVALID, "cpu_id"); return; } diff --git a/examples/ip_pipeline/tmgr.h b/examples/ip_pipeline/tmgr.h index 0b497e795..8703a2e00 100644 --- a/examples/ip_pipeline/tmgr.h +++ b/examples/ip_pipeline/tmgr.h @@ -39,11 +39,11 @@ tmgr_port_find(const char *name); struct tmgr_port_params { uint32_t rate; uint32_t n_subports_per_port; - uint32_t n_pipes_per_subport; - uint16_t qsize[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; uint32_t frame_overhead; uint32_t mtu; uint32_t cpu_id; + uint32_t n_pipes_per_subport; + uint16_t qsize[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; }; int diff --git a/lib/librte_pipeline/rte_table_action.c b/lib/librte_pipeline/rte_table_action.c index a54ec46bc..47d7efbc1 100644 --- a/lib/librte_pipeline/rte_table_action.c +++ b/lib/librte_pipeline/rte_table_action.c @@ -401,7 +401,6 @@ pkt_work_tm(struct rte_mbuf *mbuf, { struct dscp_table_entry_data *dscp_entry = &dscp_table->entry[dscp]; uint32_t queue_id = data->queue_id | - (dscp_entry->tc << 2) | dscp_entry->tc_queue; rte_mbuf_sched_set(mbuf, queue_id, dscp_entry->tc, (uint8_t)dscp_entry->color); diff --git a/lib/librte_pipeline/rte_table_action.h b/lib/librte_pipeline/rte_table_action.h index 44041b5c9..82bc9d9ac 100644 --- a/lib/librte_pipeline/rte_table_action.h +++ b/lib/librte_pipeline/rte_table_action.h @@ -181,10 +181,10 @@ struct rte_table_action_lb_params { * RTE_TABLE_ACTION_MTR */ /** Max number of traffic classes (TCs). */ -#define RTE_TABLE_ACTION_TC_MAX 4 +#define RTE_TABLE_ACTION_TC_MAX 16 /** Max number of queues per traffic class. */ -#define RTE_TABLE_ACTION_TC_QUEUE_MAX 4 +#define RTE_TABLE_ACTION_TC_QUEUE_MAX 16 /** Differentiated Services Code Point (DSCP) translation table entry. */ struct rte_table_action_dscp_table_entry { -- 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* [dpdk-dev] [PATCH v6 10/11] examples/qos_sched: add tc and queue config flexibility 2019-07-19 14:18 ` [dpdk-dev] [PATCH v6 00/11] sched: feature enhancements Jasvinder Singh ` (8 preceding siblings ...) 2019-07-19 14:18 ` [dpdk-dev] [PATCH v6 09/11] examples/ip_pipeline: add config flexibility to tm function Jasvinder Singh @ 2019-07-19 14:18 ` Jasvinder Singh 2019-07-19 14:18 ` [dpdk-dev] [PATCH v6 11/11] sched: remove redundant macros Jasvinder Singh ` (2 subsequent siblings) 12 siblings, 0 replies; 163+ messages in thread From: Jasvinder Singh @ 2019-07-19 14:18 UTC (permalink / raw) To: dev; +Cc: cristian.dumitrescu, Abraham Tovar, Lukasz Krakowiak Update qos sched sample app for configuration flexibility of pipe traffic classes and queues. Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com> Signed-off-by: Abraham Tovar <abrahamx.tovar@intel.com> Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com> --- examples/qos_sched/app_thread.c | 11 +- examples/qos_sched/cfg_file.c | 130 +++++--- examples/qos_sched/init.c | 63 +++- examples/qos_sched/main.h | 4 + examples/qos_sched/profile.cfg | 67 +++- examples/qos_sched/profile_ov.cfg | 54 +++- examples/qos_sched/stats.c | 517 +++++++++++++++++------------- 7 files changed, 550 insertions(+), 296 deletions(-) diff --git a/examples/qos_sched/app_thread.c b/examples/qos_sched/app_thread.c index e14b275e3..62a5cac31 100644 --- a/examples/qos_sched/app_thread.c +++ b/examples/qos_sched/app_thread.c @@ -20,13 +20,11 @@ * QoS parameters are encoded as follows: * Outer VLAN ID defines subport * Inner VLAN ID defines pipe - * Destination IP 0.0.XXX.0 defines traffic class * Destination IP host (0.0.0.XXX) defines queue * Values below define offset to each field from start of frame */ #define SUBPORT_OFFSET 7 #define PIPE_OFFSET 9 -#define TC_OFFSET 20 #define QUEUE_OFFSET 20 #define COLOR_OFFSET 19 @@ -35,15 +33,16 @@ get_pkt_sched(struct rte_mbuf *m, uint32_t *subport, uint32_t *pipe, uint32_t *traffic_class, uint32_t *queue, uint32_t *color) { uint16_t *pdata = rte_pktmbuf_mtod(m, uint16_t *); + uint16_t pipe_queue; *subport = (rte_be_to_cpu_16(pdata[SUBPORT_OFFSET]) & 0x0FFF) & (port_params.n_subports_per_port - 1); /* Outer VLAN ID*/ *pipe = (rte_be_to_cpu_16(pdata[PIPE_OFFSET]) & 0x0FFF) & (port_params.n_pipes_per_subport - 1); /* Inner VLAN ID */ - *traffic_class = (pdata[QUEUE_OFFSET] & 0x0F) & - (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1); /* Destination IP */ - *queue = ((pdata[QUEUE_OFFSET] >> 8) & 0x0F) & - (RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS - 1) ; /* Destination IP */ + pipe_queue = active_queues[(pdata[QUEUE_OFFSET] >> 8) % n_active_queues]; /* Destination IP */ + *traffic_class = pipe_queue > RTE_SCHED_TRAFFIC_CLASS_BE ? + RTE_SCHED_TRAFFIC_CLASS_BE : pipe_queue; + *queue = pipe_queue - *traffic_class; *color = pdata[COLOR_OFFSET] & 0x03; /* Destination IP */ return 0; diff --git a/examples/qos_sched/cfg_file.c b/examples/qos_sched/cfg_file.c index 76ffffc4b..45bf599e4 100644 --- a/examples/qos_sched/cfg_file.c +++ b/examples/qos_sched/cfg_file.c @@ -29,6 +29,9 @@ cfg_load_port(struct rte_cfgfile *cfg, struct rte_sched_port_params *port_params if (!cfg || !port_params) return -1; + memset(active_queues, 0, sizeof(active_queues)); + n_active_queues = 0; + entry = rte_cfgfile_get_entry(cfg, "port", "frame overhead"); if (entry) port_params->frame_overhead = (uint32_t)atoi(entry); @@ -45,12 +48,25 @@ cfg_load_port(struct rte_cfgfile *cfg, struct rte_sched_port_params *port_params if (entry) { char *next; - for(j = 0; j < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; j++) { + for (j = 0; j < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; j++) { port_params->qsize[j] = (uint16_t)strtol(entry, &next, 10); if (next == NULL) break; entry = next; } + + for (j = 0; j < RTE_SCHED_TRAFFIC_CLASS_BE; j++) + if (port_params->qsize[j]) { + active_queues[n_active_queues] = j; + n_active_queues++; + } + + if (port_params->qsize[RTE_SCHED_TRAFFIC_CLASS_BE]) + for (j = 0; j < RTE_SCHED_BE_QUEUES_PER_PIPE; j++) { + active_queues[n_active_queues] = + RTE_SCHED_TRAFFIC_CLASS_BE + j; + n_active_queues++; + } } #ifdef RTE_SCHED_RED @@ -173,46 +189,50 @@ cfg_load_pipe(struct rte_cfgfile *cfg, struct rte_sched_pipe_params *pipe_params if (entry) pipe_params[j].tc_rate[3] = (uint32_t)atoi(entry); -#ifdef RTE_SCHED_SUBPORT_TC_OV - entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 3 oversubscription weight"); + entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 4 rate"); + if (entry) + pipe_params[j].tc_rate[4] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 5 rate"); + if (entry) + pipe_params[j].tc_rate[5] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 6 rate"); + if (entry) + pipe_params[j].tc_rate[6] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 7 rate"); + if (entry) + pipe_params[j].tc_rate[7] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 8 rate"); + if (entry) + pipe_params[j].tc_rate[8] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 9 rate"); + if (entry) + pipe_params[j].tc_rate[9] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 10 rate"); + if (entry) + pipe_params[j].tc_rate[10] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 11 rate"); + if (entry) + pipe_params[j].tc_rate[11] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 12 rate"); + if (entry) + pipe_params[j].tc_rate[12] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 12 oversubscription weight"); if (entry) pipe_params[j].tc_ov_weight = (uint8_t)atoi(entry); -#endif - entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 0 wrr weights"); - if (entry) { - for(i = 0; i < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; i++) { - pipe_params[j].wrr_weights[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE*0 + i] = - (uint8_t)strtol(entry, &next, 10); - if (next == NULL) - break; - entry = next; - } - } - entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 1 wrr weights"); - if (entry) { - for(i = 0; i < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; i++) { - pipe_params[j].wrr_weights[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE*1 + i] = - (uint8_t)strtol(entry, &next, 10); - if (next == NULL) - break; - entry = next; - } - } - entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 2 wrr weights"); - if (entry) { - for(i = 0; i < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; i++) { - pipe_params[j].wrr_weights[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE*2 + i] = - (uint8_t)strtol(entry, &next, 10); - if (next == NULL) - break; - entry = next; - } - } - entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 3 wrr weights"); + entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 12 wrr weights"); if (entry) { - for(i = 0; i < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; i++) { - pipe_params[j].wrr_weights[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE*3 + i] = + for (i = 0; i < RTE_SCHED_BE_QUEUES_PER_PIPE; i++) { + pipe_params[j].wrr_weights[i] = (uint8_t)strtol(entry, &next, 10); if (next == NULL) break; @@ -267,6 +287,42 @@ cfg_load_subport(struct rte_cfgfile *cfg, struct rte_sched_subport_params *subpo if (entry) subport_params[i].tc_rate[3] = (uint32_t)atoi(entry); + entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 4 rate"); + if (entry) + subport_params[i].tc_rate[4] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 5 rate"); + if (entry) + subport_params[i].tc_rate[5] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 6 rate"); + if (entry) + subport_params[i].tc_rate[6] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 7 rate"); + if (entry) + subport_params[i].tc_rate[7] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 8 rate"); + if (entry) + subport_params[i].tc_rate[8] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 9 rate"); + if (entry) + subport_params[i].tc_rate[9] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 10 rate"); + if (entry) + subport_params[i].tc_rate[10] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 11 rate"); + if (entry) + subport_params[i].tc_rate[11] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 12 rate"); + if (entry) + subport_params[i].tc_rate[12] = (uint32_t)atoi(entry); + int n_entries = rte_cfgfile_section_num_entries(cfg, sec_name); struct rte_cfgfile_entry entries[n_entries]; diff --git a/examples/qos_sched/init.c b/examples/qos_sched/init.c index 6b63d4e0e..b05206d5a 100644 --- a/examples/qos_sched/init.c +++ b/examples/qos_sched/init.c @@ -170,17 +170,20 @@ static struct rte_sched_subport_params subport_params[MAX_SCHED_SUBPORTS] = { .tb_rate = 1250000000, .tb_size = 1000000, - .tc_rate = {1250000000, 1250000000, 1250000000, 1250000000}, + .tc_rate = {1250000000, 1250000000, 1250000000, 1250000000, + 1250000000, 1250000000, 1250000000, 1250000000, 1250000000, + 1250000000, 1250000000, 1250000000, 1250000000}, .tc_period = 10, }, }; -static struct rte_sched_pipe_params pipe_profiles[RTE_SCHED_PIPE_PROFILES_PER_PORT] = { +static struct rte_sched_pipe_params pipe_profiles[MAX_SCHED_PIPE_PROFILES] = { { /* Profile #0 */ .tb_rate = 305175, .tb_size = 1000000, - .tc_rate = {305175, 305175, 305175, 305175}, + .tc_rate = {305175, 305175, 305175, 305175, 305175, 305175, + 305175, 305175, 305175, 305175, 305175, 305175, 305175}, .tc_period = 40, #ifdef RTE_SCHED_SUBPORT_TC_OV .tc_ov_weight = 1, @@ -198,9 +201,10 @@ struct rte_sched_port_params port_params = { .frame_overhead = RTE_SCHED_FRAME_OVERHEAD_DEFAULT, .n_subports_per_port = 1, .n_pipes_per_subport = 4096, - .qsize = {64, 64, 64, 64}, + .qsize = {64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64}, .pipe_profiles = pipe_profiles, .n_pipe_profiles = sizeof(pipe_profiles) / sizeof(struct rte_sched_pipe_params), + .n_max_pipe_profiles = MAX_SCHED_PIPE_PROFILES, #ifdef RTE_SCHED_RED .red_params = { @@ -222,8 +226,53 @@ struct rte_sched_port_params port_params = { /* Traffic Class 3 - Colors Green / Yellow / Red */ [3][0] = {.min_th = 48, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, [3][1] = {.min_th = 40, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, - [3][2] = {.min_th = 32, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9} - } + [3][2] = {.min_th = 32, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + + /* Traffic Class 4 - Colors Green / Yellow / Red */ + [4][0] = {.min_th = 48, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [4][1] = {.min_th = 40, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [4][2] = {.min_th = 32, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + + /* Traffic Class 5 - Colors Green / Yellow / Red */ + [5][0] = {.min_th = 48, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [5][1] = {.min_th = 40, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [5][2] = {.min_th = 32, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + + /* Traffic Class 6 - Colors Green / Yellow / Red */ + [6][0] = {.min_th = 48, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [6][1] = {.min_th = 40, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [6][2] = {.min_th = 32, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + + /* Traffic Class 7 - Colors Green / Yellow / Red */ + [7][0] = {.min_th = 48, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [7][1] = {.min_th = 40, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [7][2] = {.min_th = 32, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + + /* Traffic Class 8 - Colors Green / Yellow / Red */ + [8][0] = {.min_th = 48, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [8][1] = {.min_th = 40, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [8][2] = {.min_th = 32, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + + /* Traffic Class 9 - Colors Green / Yellow / Red */ + [9][0] = {.min_th = 48, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [9][1] = {.min_th = 40, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [9][2] = {.min_th = 32, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + + /* Traffic Class 10 - Colors Green / Yellow / Red */ + [10][0] = {.min_th = 48, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [10][1] = {.min_th = 40, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [10][2] = {.min_th = 32, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + + /* Traffic Class 11 - Colors Green / Yellow / Red */ + [11][0] = {.min_th = 48, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [11][1] = {.min_th = 40, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [11][2] = {.min_th = 32, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + + /* Traffic Class 12 - Colors Green / Yellow / Red */ + [12][0] = {.min_th = 48, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [12][1] = {.min_th = 40, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [12][2] = {.min_th = 32, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + }, #endif /* RTE_SCHED_RED */ }; @@ -255,7 +304,7 @@ app_init_sched_port(uint32_t portid, uint32_t socketid) subport, err); } - for (pipe = 0; pipe < port_params.n_pipes_per_subport; pipe ++) { + for (pipe = 0; pipe < port_params.n_pipes_per_subport; pipe++) { if (app_pipe_to_profile[subport][pipe] != -1) { err = rte_sched_pipe_config(port, subport, pipe, app_pipe_to_profile[subport][pipe]); diff --git a/examples/qos_sched/main.h b/examples/qos_sched/main.h index 8a2741c58..d8f890b64 100644 --- a/examples/qos_sched/main.h +++ b/examples/qos_sched/main.h @@ -50,6 +50,7 @@ extern "C" { #define MAX_DATA_STREAMS (APP_MAX_LCORE/2) #define MAX_SCHED_SUBPORTS 8 #define MAX_SCHED_PIPES 4096 +#define MAX_SCHED_PIPE_PROFILES 256 #ifndef APP_COLLECT_STAT #define APP_COLLECT_STAT 1 @@ -147,6 +148,9 @@ extern struct burst_conf burst_conf; extern struct ring_thresh rx_thresh; extern struct ring_thresh tx_thresh; +uint32_t active_queues[RTE_SCHED_QUEUES_PER_PIPE]; +uint32_t n_active_queues; + extern struct rte_sched_port_params port_params; int app_parse_args(int argc, char **argv); diff --git a/examples/qos_sched/profile.cfg b/examples/qos_sched/profile.cfg index f5b704cc6..df7c6d1d8 100644 --- a/examples/qos_sched/profile.cfg +++ b/examples/qos_sched/profile.cfg @@ -1,6 +1,6 @@ ; BSD LICENSE ; -; Copyright(c) 2010-2014 Intel Corporation. All rights reserved. +; Copyright(c) 2010-2019 Intel Corporation. All rights reserved. ; All rights reserved. ; ; Redistribution and use in source and binary forms, with or without @@ -33,12 +33,13 @@ ; 10GbE output port: ; * Single subport (subport 0): ; - Subport rate set to 100% of port rate -; - Each of the 4 traffic classes has rate set to 100% of port rate +; - Each of the 13 traffic classes has rate set to 100% of port rate ; * 4K pipes per subport 0 (pipes 0 .. 4095) with identical configuration: ; - Pipe rate set to 1/4K of port rate -; - Each of the 4 traffic classes has rate set to 100% of pipe rate -; - Within each traffic class, the byte-level WRR weights for the 4 queues -; are set to 1:1:1:1 +; - Each of the 13 traffic classes has rate set to 100% of pipe rate +; - Within lowest priority traffic class (best-effort), the byte-level +; WRR weights for the 4 queues of best effort traffic class are set +; to 1:1:1:1 ; ; For more details, please refer to chapter "Quality of Service (QoS) Framework" ; of Data Plane Development Kit (DPDK) Programmer's Guide. @@ -48,7 +49,7 @@ frame overhead = 24 number of subports per port = 1 number of pipes per subport = 4096 -queue sizes = 64 64 64 64 +queue sizes = 64 64 64 64 64 64 64 64 64 64 64 64 64 ; Subport configuration [subport 0] @@ -59,6 +60,16 @@ tc 0 rate = 1250000000 ; Bytes per second tc 1 rate = 1250000000 ; Bytes per second tc 2 rate = 1250000000 ; Bytes per second tc 3 rate = 1250000000 ; Bytes per second +tc 4 rate = 1250000000 ; Bytes per second +tc 5 rate = 1250000000 ; Bytes per second +tc 6 rate = 1250000000 ; Bytes per second +tc 7 rate = 1250000000 ; Bytes per second +tc 8 rate = 1250000000 ; Bytes per second +tc 9 rate = 1250000000 ; Bytes per second +tc 10 rate = 1250000000 ; Bytes per second +tc 11 rate = 1250000000 ; Bytes per second +tc 12 rate = 1250000000 ; Bytes per second + tc period = 10 ; Milliseconds pipe 0-4095 = 0 ; These pipes are configured with pipe profile 0 @@ -72,14 +83,21 @@ tc 0 rate = 305175 ; Bytes per second tc 1 rate = 305175 ; Bytes per second tc 2 rate = 305175 ; Bytes per second tc 3 rate = 305175 ; Bytes per second -tc period = 40 ; Milliseconds +tc 4 rate = 305175 ; Bytes per second +tc 5 rate = 305175 ; Bytes per second +tc 6 rate = 305175 ; Bytes per second +tc 7 rate = 305175 ; Bytes per second +tc 8 rate = 305175 ; Bytes per second +tc 9 rate = 305175 ; Bytes per second +tc 10 rate = 305175 ; Bytes per second +tc 11 rate = 305175 ; Bytes per second +tc 12 rate = 305175 ; Bytes per second + +tc period = 40 ; Milliseconds -tc 3 oversubscription weight = 1 +tc 12 oversubscription weight = 1 -tc 0 wrr weights = 1 1 1 1 -tc 1 wrr weights = 1 1 1 1 -tc 2 wrr weights = 1 1 1 1 -tc 3 wrr weights = 1 1 1 1 +tc 12 wrr weights = 1 1 1 1 ; RED params per traffic class and color (Green / Yellow / Red) [red] @@ -102,3 +120,28 @@ tc 3 wred min = 48 40 32 tc 3 wred max = 64 64 64 tc 3 wred inv prob = 10 10 10 tc 3 wred weight = 9 9 9 + +tc 4 wred min = 48 40 32 +tc 4 wred max = 64 64 64 +tc 4 wred inv prob = 10 10 10 +tc 4 wred weight = 9 9 9 + +tc 5 wred min = 48 40 32 +tc 5 wred max = 64 64 64 +tc 5 wred inv prob = 10 10 10 +tc 5 wred weight = 9 9 9 + +tc 6 wred min = 48 40 32 +tc 6 wred max = 64 64 64 +tc 6 wred inv prob = 10 10 10 +tc 6 wred weight = 9 9 9 + +tc 7 wred min = 48 40 32 +tc 7 wred max = 64 64 64 +tc 7 wred inv prob = 10 10 10 +tc 7 wred weight = 9 9 9 + +tc 8 wred min = 48 40 32 +tc 8 wred max = 64 64 64 +tc 8 wred inv prob = 10 10 10 +tc 8 wred weight = 9 9 9 diff --git a/examples/qos_sched/profile_ov.cfg b/examples/qos_sched/profile_ov.cfg index 33000df9e..c0b7b3c3d 100644 --- a/examples/qos_sched/profile_ov.cfg +++ b/examples/qos_sched/profile_ov.cfg @@ -1,6 +1,6 @@ ; BSD LICENSE ; -; Copyright(c) 2010-2014 Intel Corporation. All rights reserved. +; Copyright(c) 2010-2019 Intel Corporation. All rights reserved. ; All rights reserved. ; ; Redistribution and use in source and binary forms, with or without @@ -34,7 +34,7 @@ frame overhead = 24 number of subports per port = 1 number of pipes per subport = 32 -queue sizes = 64 64 64 64 +queue sizes = 64 64 64 64 64 64 64 64 64 64 64 64 64 ; Subport configuration [subport 0] @@ -45,6 +45,15 @@ tc 0 rate = 8400000 ; Bytes per second tc 1 rate = 8400000 ; Bytes per second tc 2 rate = 8400000 ; Bytes per second tc 3 rate = 8400000 ; Bytes per second +tc 4 rate = 8400000 ; Bytes per second +tc 5 rate = 8400000 ; Bytes per second +tc 6 rate = 8400000 ; Bytes per second +tc 7 rate = 8400000 ; Bytes per second +tc 8 rate = 8400000 ; Bytes per second +tc 9 rate = 8400000 ; Bytes per second +tc 10 rate = 8400000 ; Bytes per second +tc 11 rate = 8400000 ; Bytes per second +tc 12 rate = 8400000 ; Bytes per second tc period = 10 ; Milliseconds pipe 0-31 = 0 ; These pipes are configured with pipe profile 0 @@ -58,14 +67,20 @@ tc 0 rate = 16800000 ; Bytes per second tc 1 rate = 16800000 ; Bytes per second tc 2 rate = 16800000 ; Bytes per second tc 3 rate = 16800000 ; Bytes per second +tc 4 rate = 16800000 ; Bytes per second +tc 5 rate = 16800000 ; Bytes per second +tc 6 rate = 16800000 ; Bytes per second +tc 7 rate = 16800000 ; Bytes per second +tc 8 rate = 16800000 ; Bytes per second +tc 9 rate = 16800000 ; Bytes per second +tc 10 rate = 16800000 ; Bytes per second +tc 11 rate = 16800000 ; Bytes per second +tc 12 rate = 16800000 ; Bytes per second tc period = 28 ; Milliseconds -tc 3 oversubscription weight = 1 +tc 12 oversubscription weight = 1 -tc 0 wrr weights = 1 1 1 1 -tc 1 wrr weights = 1 1 1 1 -tc 2 wrr weights = 1 1 1 1 -tc 3 wrr weights = 1 1 1 1 +tc 12 wrr weights = 1 1 1 1 ; RED params per traffic class and color (Green / Yellow / Red) [red] @@ -88,3 +103,28 @@ tc 3 wred min = 48 40 32 tc 3 wred max = 64 64 64 tc 3 wred inv prob = 10 10 10 tc 3 wred weight = 9 9 9 + +tc 4 wred min = 48 40 32 +tc 4 wred max = 64 64 64 +tc 4 wred inv prob = 10 10 10 +tc 4 wred weight = 9 9 9 + +tc 5 wred min = 48 40 32 +tc 5 wred max = 64 64 64 +tc 5 wred inv prob = 10 10 10 +tc 5 wred weight = 9 9 9 + +tc 6 wred min = 48 40 32 +tc 6 wred max = 64 64 64 +tc 6 wred inv prob = 10 10 10 +tc 6 wred weight = 9 9 9 + +tc 7 wred min = 48 40 32 +tc 7 wred max = 64 64 64 +tc 7 wred inv prob = 10 10 10 +tc 7 wred weight = 9 9 9 + +tc 8 wred min = 48 40 32 +tc 8 wred max = 64 64 64 +tc 8 wred inv prob = 10 10 10 +tc 8 wred weight = 9 9 9 diff --git a/examples/qos_sched/stats.c b/examples/qos_sched/stats.c index 8193d964c..6f69dcfbe 100644 --- a/examples/qos_sched/stats.c +++ b/examples/qos_sched/stats.c @@ -11,278 +11,341 @@ int qavg_q(uint16_t port_id, uint32_t subport_id, uint32_t pipe_id, uint8_t tc, uint8_t q) { - struct rte_sched_queue_stats stats; - struct rte_sched_port *port; - uint16_t qlen; - uint32_t queue_id, count, i; - uint32_t average; - - for (i = 0; i < nb_pfc; i++) { - if (qos_conf[i].tx_port == port_id) - break; - } - if (i == nb_pfc || subport_id >= port_params.n_subports_per_port || pipe_id >= port_params.n_pipes_per_subport - || tc >= RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE || q >= RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS) - return -1; - - port = qos_conf[i].sched_port; - - queue_id = RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS * (subport_id * port_params.n_pipes_per_subport + pipe_id); - queue_id = queue_id + (tc * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS + q); - - average = 0; - - for (count = 0; count < qavg_ntimes; count++) { - rte_sched_queue_read_stats(port, queue_id, &stats, &qlen); - average += qlen; - usleep(qavg_period); - } - - average /= qavg_ntimes; - - printf("\nAverage queue size: %" PRIu32 " bytes.\n\n", average); - - return 0; + struct rte_sched_queue_stats stats; + struct rte_sched_port *port; + uint16_t qlen; + uint32_t count, i, queue_id = 0; + uint32_t average; + + for (i = 0; i < nb_pfc; i++) { + if (qos_conf[i].tx_port == port_id) + break; + } + + if (i == nb_pfc || + subport_id >= port_params.n_subports_per_port || + pipe_id >= port_params.n_pipes_per_subport || + tc >= RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE || + q >= RTE_SCHED_BE_QUEUES_PER_PIPE || + (tc < RTE_SCHED_TRAFFIC_CLASS_BE && q > 0)) + return -1; + + port = qos_conf[i].sched_port; + for (i = 0; i < subport_id; i++) + queue_id += port_params.n_pipes_per_subport * + RTE_SCHED_QUEUES_PER_PIPE; + if (tc < RTE_SCHED_TRAFFIC_CLASS_BE) + queue_id += pipe_id * RTE_SCHED_QUEUES_PER_PIPE + tc; + else + queue_id += pipe_id * RTE_SCHED_QUEUES_PER_PIPE + tc + q; + + average = 0; + for (count = 0; count < qavg_ntimes; count++) { + rte_sched_queue_read_stats(port, queue_id, &stats, &qlen); + average += qlen; + usleep(qavg_period); + } + + average /= qavg_ntimes; + + printf("\nAverage queue size: %" PRIu32 " bytes.\n\n", average); + + return 0; } int qavg_tcpipe(uint16_t port_id, uint32_t subport_id, uint32_t pipe_id, - uint8_t tc) + uint8_t tc) { - struct rte_sched_queue_stats stats; - struct rte_sched_port *port; - uint16_t qlen; - uint32_t queue_id, count, i; - uint32_t average, part_average; - - for (i = 0; i < nb_pfc; i++) { - if (qos_conf[i].tx_port == port_id) - break; - } - if (i == nb_pfc || subport_id >= port_params.n_subports_per_port || pipe_id >= port_params.n_pipes_per_subport - || tc >= RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE) - return -1; - - port = qos_conf[i].sched_port; - - queue_id = RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS * (subport_id * port_params.n_pipes_per_subport + pipe_id); - - average = 0; - - for (count = 0; count < qavg_ntimes; count++) { - part_average = 0; - for (i = 0; i < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; i++) { - rte_sched_queue_read_stats(port, queue_id + (tc * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS + i), &stats, &qlen); - part_average += qlen; - } - average += part_average / RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; - usleep(qavg_period); - } - - average /= qavg_ntimes; - - printf("\nAverage queue size: %" PRIu32 " bytes.\n\n", average); - - return 0; + struct rte_sched_queue_stats stats; + struct rte_sched_port *port; + uint16_t qlen; + uint32_t count, i, queue_id = 0; + uint32_t average, part_average; + + for (i = 0; i < nb_pfc; i++) { + if (qos_conf[i].tx_port == port_id) + break; + } + + if (i == nb_pfc || subport_id >= port_params.n_subports_per_port || + pipe_id >= port_params.n_pipes_per_subport || + tc >= RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE) + return -1; + + port = qos_conf[i].sched_port; + + for (i = 0; i < subport_id; i++) + queue_id += port_params.n_pipes_per_subport * RTE_SCHED_QUEUES_PER_PIPE; + + queue_id += pipe_id * RTE_SCHED_QUEUES_PER_PIPE + tc; + + average = 0; + + for (count = 0; count < qavg_ntimes; count++) { + part_average = 0; + + if (tc < RTE_SCHED_TRAFFIC_CLASS_BE) { + rte_sched_queue_read_stats(port, queue_id, + &stats, &qlen); + part_average += qlen; + } else { + for (i = 0; i < RTE_SCHED_BE_QUEUES_PER_PIPE; i++) { + rte_sched_queue_read_stats(port, queue_id + i, + &stats, &qlen); + part_average += qlen; + } + average += part_average / RTE_SCHED_BE_QUEUES_PER_PIPE; + } + usleep(qavg_period); + } + + average /= qavg_ntimes; + + printf("\nAverage queue size: %" PRIu32 " bytes.\n\n", average); + + return 0; } int qavg_pipe(uint16_t port_id, uint32_t subport_id, uint32_t pipe_id) { - struct rte_sched_queue_stats stats; - struct rte_sched_port *port; - uint16_t qlen; - uint32_t queue_id, count, i; - uint32_t average, part_average; + struct rte_sched_queue_stats stats; + struct rte_sched_port *port; + uint16_t qlen; + uint32_t count, i, queue_id = 0; + uint32_t average, part_average; + + for (i = 0; i < nb_pfc; i++) { + if (qos_conf[i].tx_port == port_id) + break; + } - for (i = 0; i < nb_pfc; i++) { - if (qos_conf[i].tx_port == port_id) - break; - } - if (i == nb_pfc || subport_id >= port_params.n_subports_per_port || pipe_id >= port_params.n_pipes_per_subport) - return -1; + if (i == nb_pfc || + subport_id >= port_params.n_subports_per_port || + pipe_id >= port_params.n_pipes_per_subport) + return -1; - port = qos_conf[i].sched_port; + port = qos_conf[i].sched_port; - queue_id = RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS * (subport_id * port_params.n_pipes_per_subport + pipe_id); + for (i = 0; i < subport_id; i++) + queue_id += port_params.n_pipes_per_subport * + RTE_SCHED_QUEUES_PER_PIPE; - average = 0; + queue_id += pipe_id * RTE_SCHED_QUEUES_PER_PIPE; - for (count = 0; count < qavg_ntimes; count++) { - part_average = 0; - for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; i++) { - rte_sched_queue_read_stats(port, queue_id + i, &stats, &qlen); - part_average += qlen; - } - average += part_average / (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS); - usleep(qavg_period); - } + average = 0; - average /= qavg_ntimes; + for (count = 0; count < qavg_ntimes; count++) { + part_average = 0; + for (i = 0; i < RTE_SCHED_QUEUES_PER_PIPE; i++) { + rte_sched_queue_read_stats(port, queue_id + i, + &stats, &qlen); + part_average += qlen; + } + average += part_average / RTE_SCHED_QUEUES_PER_PIPE; + usleep(qavg_period); + } - printf("\nAverage queue size: %" PRIu32 " bytes.\n\n", average); + average /= qavg_ntimes; - return 0; + printf("\nAverage queue size: %" PRIu32 " bytes.\n\n", average); + + return 0; } int qavg_tcsubport(uint16_t port_id, uint32_t subport_id, uint8_t tc) { - struct rte_sched_queue_stats stats; - struct rte_sched_port *port; - uint16_t qlen; - uint32_t queue_id, count, i, j; - uint32_t average, part_average; - - for (i = 0; i < nb_pfc; i++) { - if (qos_conf[i].tx_port == port_id) - break; - } - if (i == nb_pfc || subport_id >= port_params.n_subports_per_port || tc >= RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE) - return -1; - - port = qos_conf[i].sched_port; - - average = 0; - - for (count = 0; count < qavg_ntimes; count++) { - part_average = 0; - for (i = 0; i < port_params.n_pipes_per_subport; i++) { - queue_id = RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS * (subport_id * port_params.n_pipes_per_subport + i); - - for (j = 0; j < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; j++) { - rte_sched_queue_read_stats(port, queue_id + (tc * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS + j), &stats, &qlen); - part_average += qlen; - } - } - - average += part_average / (port_params.n_pipes_per_subport * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS); - usleep(qavg_period); - } - - average /= qavg_ntimes; - - printf("\nAverage queue size: %" PRIu32 " bytes.\n\n", average); - - return 0; + struct rte_sched_queue_stats stats; + struct rte_sched_port *port; + uint16_t qlen; + uint32_t queue_id, count, i, j, subport_queue_id = 0; + uint32_t average, part_average; + + for (i = 0; i < nb_pfc; i++) { + if (qos_conf[i].tx_port == port_id) + break; + } + + if (i == nb_pfc || + subport_id >= port_params.n_subports_per_port || + tc >= RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE) + return -1; + + port = qos_conf[i].sched_port; + + for (i = 0; i < subport_id; i++) + subport_queue_id += port_params.n_pipes_per_subport * RTE_SCHED_QUEUES_PER_PIPE; + + average = 0; + + for (count = 0; count < qavg_ntimes; count++) { + part_average = 0; + for (i = 0; i < port_params.n_pipes_per_subport; i++) { + if (tc < RTE_SCHED_TRAFFIC_CLASS_BE) { + queue_id = subport_queue_id + i * RTE_SCHED_QUEUES_PER_PIPE + tc; + rte_sched_queue_read_stats(port, queue_id, + &stats, &qlen); + part_average += qlen; + } else { + for (j = 0; j < RTE_SCHED_BE_QUEUES_PER_PIPE; j++) { + queue_id = subport_queue_id + + i * RTE_SCHED_QUEUES_PER_PIPE + tc + j; + rte_sched_queue_read_stats(port, queue_id, + &stats, &qlen); + part_average += qlen; + } + } + } + + if (tc < RTE_SCHED_TRAFFIC_CLASS_BE) + average += part_average / (port_params.n_pipes_per_subport); + else + average += + part_average / (port_params.n_pipes_per_subport) * RTE_SCHED_BE_QUEUES_PER_PIPE; + + usleep(qavg_period); + } + + average /= qavg_ntimes; + + printf("\nAverage queue size: %" PRIu32 " bytes.\n\n", average); + + return 0; } int qavg_subport(uint16_t port_id, uint32_t subport_id) { - struct rte_sched_queue_stats stats; - struct rte_sched_port *port; - uint16_t qlen; - uint32_t queue_id, count, i, j; - uint32_t average, part_average; + struct rte_sched_queue_stats stats; + struct rte_sched_port *port; + uint16_t qlen; + uint32_t queue_id, count, i, j, subport_queue_id = 0; + uint32_t average, part_average; + + for (i = 0; i < nb_pfc; i++) { + if (qos_conf[i].tx_port == port_id) + break; + } + + if (i == nb_pfc || + subport_id >= port_params.n_subports_per_port) + return -1; - for (i = 0; i < nb_pfc; i++) { - if (qos_conf[i].tx_port == port_id) - break; - } - if (i == nb_pfc || subport_id >= port_params.n_subports_per_port) - return -1; + port = qos_conf[i].sched_port; - port = qos_conf[i].sched_port; + for (i = 0; i < subport_id; i++) + subport_queue_id += port_params.n_pipes_per_subport * RTE_SCHED_QUEUES_PER_PIPE; - average = 0; + average = 0; - for (count = 0; count < qavg_ntimes; count++) { - part_average = 0; - for (i = 0; i < port_params.n_pipes_per_subport; i++) { - queue_id = RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS * (subport_id * port_params.n_pipes_per_subport + i); + for (count = 0; count < qavg_ntimes; count++) { + part_average = 0; + for (i = 0; i < port_params.n_pipes_per_subport; i++) { + queue_id = subport_queue_id + i * RTE_SCHED_QUEUES_PER_PIPE; - for (j = 0; j < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; j++) { - rte_sched_queue_read_stats(port, queue_id + j, &stats, &qlen); - part_average += qlen; - } - } + for (j = 0; j < RTE_SCHED_QUEUES_PER_PIPE; j++) { + rte_sched_queue_read_stats(port, queue_id + j, + &stats, &qlen); + part_average += qlen; + } + } - average += part_average / (port_params.n_pipes_per_subport * RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS); - usleep(qavg_period); - } + average += part_average / (port_params.n_pipes_per_subport * RTE_SCHED_QUEUES_PER_PIPE); + usleep(qavg_period); + } - average /= qavg_ntimes; + average /= qavg_ntimes; - printf("\nAverage queue size: %" PRIu32 " bytes.\n\n", average); + printf("\nAverage queue size: %" PRIu32 " bytes.\n\n", average); - return 0; + return 0; } int subport_stat(uint16_t port_id, uint32_t subport_id) { - struct rte_sched_subport_stats stats; - struct rte_sched_port *port; - uint32_t tc_ov[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; - uint8_t i; - - for (i = 0; i < nb_pfc; i++) { - if (qos_conf[i].tx_port == port_id) - break; - } - if (i == nb_pfc || subport_id >= port_params.n_subports_per_port) - return -1; - - port = qos_conf[i].sched_port; - memset (tc_ov, 0, sizeof(tc_ov)); - - rte_sched_subport_read_stats(port, subport_id, &stats, tc_ov); - - printf("\n"); - printf("+----+-------------+-------------+-------------+-------------+-------------+\n"); - printf("| TC | Pkts OK |Pkts Dropped | Bytes OK |Bytes Dropped| OV Status |\n"); - printf("+----+-------------+-------------+-------------+-------------+-------------+\n"); - - for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { - printf("| %d | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " |\n", i, - stats.n_pkts_tc[i], stats.n_pkts_tc_dropped[i], - stats.n_bytes_tc[i], stats.n_bytes_tc_dropped[i], tc_ov[i]); - printf("+----+-------------+-------------+-------------+-------------+-------------+\n"); - } - printf("\n"); - - return 0; + struct rte_sched_subport_stats stats; + struct rte_sched_port *port; + uint32_t tc_ov[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; + uint8_t i; + + for (i = 0; i < nb_pfc; i++) { + if (qos_conf[i].tx_port == port_id) + break; + } + + if (i == nb_pfc || subport_id >= port_params.n_subports_per_port) + return -1; + + port = qos_conf[i].sched_port; + memset(tc_ov, 0, sizeof(tc_ov)); + + rte_sched_subport_read_stats(port, subport_id, &stats, tc_ov); + + printf("\n"); + printf("+----+-------------+-------------+-------------+-------------+-------------+\n"); + printf("| TC | Pkts OK |Pkts Dropped | Bytes OK |Bytes Dropped| OV Status |\n"); + printf("+----+-------------+-------------+-------------+-------------+-------------+\n"); + + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { + printf("| %d | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " |\n", i, + stats.n_pkts_tc[i], stats.n_pkts_tc_dropped[i], + stats.n_bytes_tc[i], stats.n_bytes_tc_dropped[i], tc_ov[i]); + printf("+----+-------------+-------------+-------------+-------------+-------------+\n"); + } + printf("\n"); + + return 0; } int pipe_stat(uint16_t port_id, uint32_t subport_id, uint32_t pipe_id) { - struct rte_sched_queue_stats stats; - struct rte_sched_port *port; - uint16_t qlen; - uint8_t i, j; - uint32_t queue_id; - - for (i = 0; i < nb_pfc; i++) { - if (qos_conf[i].tx_port == port_id) - break; - } - if (i == nb_pfc || subport_id >= port_params.n_subports_per_port || pipe_id >= port_params.n_pipes_per_subport) - return -1; - - port = qos_conf[i].sched_port; - - queue_id = RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS * (subport_id * port_params.n_pipes_per_subport + pipe_id); - - printf("\n"); - printf("+----+-------+-------------+-------------+-------------+-------------+-------------+\n"); - printf("| TC | Queue | Pkts OK |Pkts Dropped | Bytes OK |Bytes Dropped| Length |\n"); - printf("+----+-------+-------------+-------------+-------------+-------------+-------------+\n"); - - for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { - for (j = 0; j < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; j++) { - - rte_sched_queue_read_stats(port, queue_id + (i * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS + j), &stats, &qlen); - - printf("| %d | %d | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " | %11i |\n", i, j, - stats.n_pkts, stats.n_pkts_dropped, stats.n_bytes, stats.n_bytes_dropped, qlen); - printf("+----+-------+-------------+-------------+-------------+-------------+-------------+\n"); - } - if (i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1) - printf("+----+-------+-------------+-------------+-------------+-------------+-------------+\n"); - } - printf("\n"); - - return 0; + struct rte_sched_queue_stats stats; + struct rte_sched_port *port; + uint16_t qlen; + uint8_t i, j; + uint32_t queue_id = 0; + + for (i = 0; i < nb_pfc; i++) { + if (qos_conf[i].tx_port == port_id) + break; + } + + if (i == nb_pfc || + subport_id >= port_params.n_subports_per_port || + pipe_id >= port_params.n_pipes_per_subport) + return -1; + + port = qos_conf[i].sched_port; + for (i = 0; i < subport_id; i++) + queue_id += port_params.n_pipes_per_subport * RTE_SCHED_QUEUES_PER_PIPE; + + queue_id += pipe_id * RTE_SCHED_QUEUES_PER_PIPE; + + printf("\n"); + printf("+----+-------+-------------+-------------+-------------+-------------+-------------+\n"); + printf("| TC | Queue | Pkts OK |Pkts Dropped | Bytes OK |Bytes Dropped| Length |\n"); + printf("+----+-------+-------------+-------------+-------------+-------------+-------------+\n"); + + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { + if (i < RTE_SCHED_TRAFFIC_CLASS_BE) { + rte_sched_queue_read_stats(port, queue_id + i, &stats, &qlen); + printf("| %d | %d | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " | %11i |\n", i, 0, + stats.n_pkts, stats.n_pkts_dropped, stats.n_bytes, stats.n_bytes_dropped, qlen); + printf("+----+-------+-------------+-------------+-------------+-------------+-------------+\n"); + } else { + for (j = 0; j < RTE_SCHED_BE_QUEUES_PER_PIPE; j++) { + rte_sched_queue_read_stats(port, queue_id + i + j, &stats, &qlen); + printf("| %d | %d | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " | %11i |\n", i, j, + stats.n_pkts, stats.n_pkts_dropped, stats.n_bytes, stats.n_bytes_dropped, qlen); + printf("+----+-------+-------------+-------------+-------------+-------------+-------------+\n"); + } + } + } + printf("\n"); + + return 0; } -- 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* [dpdk-dev] [PATCH v6 11/11] sched: remove redundant macros 2019-07-19 14:18 ` [dpdk-dev] [PATCH v6 00/11] sched: feature enhancements Jasvinder Singh ` (9 preceding siblings ...) 2019-07-19 14:18 ` [dpdk-dev] [PATCH v6 10/11] examples/qos_sched: add tc and queue config flexibility Jasvinder Singh @ 2019-07-19 14:18 ` Jasvinder Singh 2019-07-22 8:19 ` [dpdk-dev] [PATCH v6 00/11] sched: feature enhancements Thomas Monjalon 2019-07-22 9:56 ` Dumitrescu, Cristian 12 siblings, 0 replies; 163+ messages in thread From: Jasvinder Singh @ 2019-07-19 14:18 UTC (permalink / raw) To: dev; +Cc: cristian.dumitrescu, Abraham Tovar, Lukasz Krakowiak Remove unused macros from the library, and update release notes. Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com> Signed-off-by: Abraham Tovar <abrahamx.tovar@intel.com> Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com> --- doc/guides/rel_notes/release_19_08.rst | 10 +++++++++- lib/librte_sched/rte_sched.h | 11 ----------- 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/doc/guides/rel_notes/release_19_08.rst b/doc/guides/rel_notes/release_19_08.rst index 4a1fd8dd8..5f6f56666 100644 --- a/doc/guides/rel_notes/release_19_08.rst +++ b/doc/guides/rel_notes/release_19_08.rst @@ -251,6 +251,14 @@ API Changes * malloc: The function ``rte_malloc_set_limit`` was never implemented is deprecated and will be removed in a future release. +* sched: Macros ``RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS`` and + ``RTE_SCHED_PIPE_PROFILES_PER_PORT`` are removed for flexible configuration + of pipe traffic classes and their queues size, and for runtime configuration + of maximum number of pipe profiles, respectively. In addtion, wrr_weights + field of struct ``rte_sched_pipe_params`` is modifed to be used only for + best-effort tc, and qsize field of struct ``rte_sched_port_params`` is + changed to allow different size of the each queue. + * eventdev: No longer marked as experimental. The eventdev functions are no longer marked as experimental, and have @@ -385,7 +393,7 @@ The libraries prepended with a plus sign were incremented in this version. librte_rcu.so.1 librte_reorder.so.1 librte_ring.so.2 - librte_sched.so.2 + + librte_sched.so.3 librte_security.so.2 librte_stack.so.1 librte_table.so.3 diff --git a/lib/librte_sched/rte_sched.h b/lib/librte_sched/rte_sched.h index fffbad696..eac6db274 100644 --- a/lib/librte_sched/rte_sched.h +++ b/lib/librte_sched/rte_sched.h @@ -94,17 +94,6 @@ extern "C" { */ #define RTE_SCHED_TRAFFIC_CLASS_BE (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1) -/** Number of queues per pipe traffic class. Cannot be changed. */ -#define RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS 4 - - -/** Maximum number of pipe profiles that can be defined per port. - * Compile-time configurable. - */ -#ifndef RTE_SCHED_PIPE_PROFILES_PER_PORT -#define RTE_SCHED_PIPE_PROFILES_PER_PORT 256 -#endif - /* * Ethernet framing overhead. Overhead fields per Ethernet frame: * 1. Preamble: 7 bytes; -- 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* Re: [dpdk-dev] [PATCH v6 00/11] sched: feature enhancements 2019-07-19 14:18 ` [dpdk-dev] [PATCH v6 00/11] sched: feature enhancements Jasvinder Singh ` (10 preceding siblings ...) 2019-07-19 14:18 ` [dpdk-dev] [PATCH v6 11/11] sched: remove redundant macros Jasvinder Singh @ 2019-07-22 8:19 ` Thomas Monjalon 2019-07-22 11:05 ` Singh, Jasvinder 2019-07-22 9:56 ` Dumitrescu, Cristian 12 siblings, 1 reply; 163+ messages in thread From: Thomas Monjalon @ 2019-07-22 8:19 UTC (permalink / raw) To: Jasvinder Singh; +Cc: dev, cristian.dumitrescu 19/07/2019 16:18, Jasvinder Singh: > v6: > - add functions to access port internal struct fields (e.g. pipe queues and tc) > - Move definition of RTE_SCHED_TRAFFIC_CLASS_BE to rte_sched.h > - fix doxygen comments Thank you It would be perfect if checkpatches issues were resolved: ### [dpdk-dev] [PATCH v6 02/11] sched: add config flexibility to tc queue sizes WARNING:LONG_LINE: line over 100 characters #579: FILE: lib/librte_sched/rte_sched.c:961: + double subport_tc3_rate = (double) s->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] WARNING:LONG_LINE: line over 100 characters #582: FILE: lib/librte_sched/rte_sched.c:963: + double pipe_tc3_rate = (double) params->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] total: 0 errors, 2 warnings, 728 lines checked ### [dpdk-dev] [PATCH v6 04/11] sched: rename tc3 params to best-effort tc WARNING:LONG_LINE: line over 100 characters #235: FILE: lib/librte_sched/rte_sched.c:963: + double subport_tc_be_rate = (double) s->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] WARNING:LONG_LINE: line over 100 characters #238: FILE: lib/librte_sched/rte_sched.c:965: + double pipe_tc_be_rate = (double) params->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] total: 0 errors, 2 warnings, 128 lines checked ### [dpdk-dev] [PATCH v6 07/11] net/softnic: add config flexibility to softnic tm WARNING:DEEP_INDENTATION: Too many leading tabs - consider code refactoring #479: FILE: drivers/net/softnic/rte_eth_softnic_cli.c:843: + if (status) CHECK:BRACES: braces {} should be used on all arms of this statement #737: FILE: drivers/net/softnic/rte_eth_softnic_cli.c:1205: + if (strcmp(tokens[51], "none") == 0) [...] + else { [...] CHECK:BRACES: Unbalanced braces around else statement #739: FILE: drivers/net/softnic/rte_eth_softnic_cli.c:1207: + else { CHECK:BRACES: braces {} should be used on all arms of this statement #754: FILE: drivers/net/softnic/rte_eth_softnic_cli.c:1222: + if (strcmp(tokens[53], "none") == 0) [...] + else { [...] CHECK:BRACES: Unbalanced braces around else statement #756: FILE: drivers/net/softnic/rte_eth_softnic_cli.c:1224: + else { CHECK:BRACES: braces {} should be used on all arms of this statement #771: FILE: drivers/net/softnic/rte_eth_softnic_cli.c:1239: + if (strcmp(tokens[55], "none") == 0) [...] + else { [...] CHECK:BRACES: Unbalanced braces around else statement #773: FILE: drivers/net/softnic/rte_eth_softnic_cli.c:1241: + else { CHECK:BRACES: braces {} should be used on all arms of this statement #788: FILE: drivers/net/softnic/rte_eth_softnic_cli.c:1256: + if (strcmp(tokens[57], "none") == 0) [...] + else { [...] CHECK:BRACES: Unbalanced braces around else statement #790: FILE: drivers/net/softnic/rte_eth_softnic_cli.c:1258: + else { CHECK:BRACES: braces {} should be used on all arms of this statement #805: FILE: drivers/net/softnic/rte_eth_softnic_cli.c:1273: + if (strcmp(tokens[59], "none") == 0) [...] + else { [...] CHECK:BRACES: Unbalanced braces around else statement #807: FILE: drivers/net/softnic/rte_eth_softnic_cli.c:1275: + else { CHECK:BRACES: braces {} should be used on all arms of this statement #822: FILE: drivers/net/softnic/rte_eth_softnic_cli.c:1290: + if (strcmp(tokens[61], "none") == 0) [...] + else { [...] CHECK:BRACES: Unbalanced braces around else statement #824: FILE: drivers/net/softnic/rte_eth_softnic_cli.c:1292: + else { CHECK:BRACES: braces {} should be used on all arms of this statement #839: FILE: drivers/net/softnic/rte_eth_softnic_cli.c:1307: + if (strcmp(tokens[63], "none") == 0) [...] + else { [...] CHECK:BRACES: Unbalanced braces around else statement #841: FILE: drivers/net/softnic/rte_eth_softnic_cli.c:1309: + else { CHECK:BRACES: braces {} should be used on all arms of this statement #856: FILE: drivers/net/softnic/rte_eth_softnic_cli.c:1324: + if (strcmp(tokens[65], "none") == 0) [...] + else { [...] CHECK:BRACES: Unbalanced braces around else statement #858: FILE: drivers/net/softnic/rte_eth_softnic_cli.c:1326: + else { CHECK:BRACES: braces {} should be used on all arms of this statement #873: FILE: drivers/net/softnic/rte_eth_softnic_cli.c:1341: + if (strcmp(tokens[67], "none") == 0) [...] + else { [...] CHECK:BRACES: Unbalanced braces around else statement #875: FILE: drivers/net/softnic/rte_eth_softnic_cli.c:1343: + else { WARNING:SPACE_BEFORE_TAB: please, no space before tabs #1129: FILE: drivers/net/softnic/rte_eth_softnic_tm.c:3045: +^Ireturn ^Iport_queue_id;$ total: 0 errors, 2 warnings, 18 checks, 1002 lines checked ### [dpdk-dev] [PATCH v6 10/11] examples/qos_sched: add tc and queue config flexibility WARNING:LONG_LINE_COMMENT: line over 100 characters #201: FILE: examples/qos_sched/app_thread.c:42: + pipe_queue = active_queues[(pdata[QUEUE_OFFSET] >> 8) % n_active_queues]; /* Destination IP */ WARNING:LONG_LINE: line over 100 characters #1042: FILE: examples/qos_sched/stats.c:206: + part_average / (port_params.n_pipes_per_subport) * RTE_SCHED_BE_QUEUES_PER_PIPE; WARNING:LONG_LINE: line over 100 characters #1116: FILE: examples/qos_sched/stats.c:255: + average += part_average / (port_params.n_pipes_per_subport * RTE_SCHED_QUEUES_PER_PIPE); WARNING:LONG_LINE: line over 100 characters #1188: FILE: examples/qos_sched/stats.c:293: + printf("| %d | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " |\n", i, WARNING:LONG_LINE: line over 100 characters #1268: FILE: examples/qos_sched/stats.c:336: + printf("| %d | %d | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " | %11i |\n", i, 0, WARNING:LONG_LINE: line over 100 characters #1269: FILE: examples/qos_sched/stats.c:337: + stats.n_pkts, stats.n_pkts_dropped, stats.n_bytes, stats.n_bytes_dropped, qlen); WARNING:LONG_LINE: line over 100 characters #1274: FILE: examples/qos_sched/stats.c:342: + printf("| %d | %d | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " | %11i |\n", i, j, WARNING:LONG_LINE: line over 100 characters #1275: FILE: examples/qos_sched/stats.c:343: + stats.n_pkts, stats.n_pkts_dropped, stats.n_bytes, stats.n_bytes_dropped, qlen); total: 0 errors, 8 warnings, 1063 lines checked ^ permalink raw reply [flat|nested] 163+ messages in thread
* Re: [dpdk-dev] [PATCH v6 00/11] sched: feature enhancements 2019-07-22 8:19 ` [dpdk-dev] [PATCH v6 00/11] sched: feature enhancements Thomas Monjalon @ 2019-07-22 11:05 ` Singh, Jasvinder 0 siblings, 0 replies; 163+ messages in thread From: Singh, Jasvinder @ 2019-07-22 11:05 UTC (permalink / raw) To: Thomas Monjalon; +Cc: dev, Dumitrescu, Cristian > -----Original Message----- > From: Thomas Monjalon [mailto:thomas@monjalon.net] > Sent: Monday, July 22, 2019 9:20 AM > To: Singh, Jasvinder <jasvinder.singh@intel.com> > Cc: dev@dpdk.org; Dumitrescu, Cristian <cristian.dumitrescu@intel.com> > Subject: Re: [dpdk-dev] [PATCH v6 00/11] sched: feature enhancements > > 19/07/2019 16:18, Jasvinder Singh: > > v6: > > - add functions to access port internal struct fields (e.g. pipe queues and tc) > > - Move definition of RTE_SCHED_TRAFFIC_CLASS_BE to rte_sched.h > > - fix doxygen comments > > Thank you > > It would be perfect if checkpatches issues were resolved: > Sent version 7 with most of the checkpatch warnings fixed. Thanks. ^ permalink raw reply [flat|nested] 163+ messages in thread
* Re: [dpdk-dev] [PATCH v6 00/11] sched: feature enhancements 2019-07-19 14:18 ` [dpdk-dev] [PATCH v6 00/11] sched: feature enhancements Jasvinder Singh ` (11 preceding siblings ...) 2019-07-22 8:19 ` [dpdk-dev] [PATCH v6 00/11] sched: feature enhancements Thomas Monjalon @ 2019-07-22 9:56 ` Dumitrescu, Cristian 12 siblings, 0 replies; 163+ messages in thread From: Dumitrescu, Cristian @ 2019-07-22 9:56 UTC (permalink / raw) To: Singh, Jasvinder, dev > -----Original Message----- > From: Singh, Jasvinder > Sent: Friday, July 19, 2019 3:18 PM > To: dev@dpdk.org > Cc: Dumitrescu, Cristian <cristian.dumitrescu@intel.com> > Subject: [PATCH v6 00/11] sched: feature enhancements > > This patchset refactors the dpdk qos sched library to allow flexibile > configuration of the pipe traffic classes and queue sizes. > > Currently, each pipe has 16 queues hardwired into 4 TCs scheduled with > strict priority, and each TC has exactly with 4 queues that are > scheduled with Weighted Fair Queuing (WFQ). > > Instead of hardwiring queues to traffic class within the specific pipe, > the new implementation allows more flexible/configurable split of pipe > queues between strict priority (SP) and best-effort (BE) traffic classes > along with the support of more number of traffic classes i.e. max 16. > > All the high priority TCs (TC1, TC2, ...) have exactly 1 queue, while > the lowest priority best-effort traffic class can have 1, 4 or 8 queues. > This is justified by the fact that all the high priority TCs are fully > provisioned (small to medium traffic rates), while most of the traffic > fits into the BE class, which is typically oversubscribed. > > Furthermore, this change allows to use less than 16 queues per pipe when > not all the 16 queues are needed. Therefore, no memory will be allocated > to the queues that are not needed. > > v6: > - add functions to access port internal struct fields (e.g. pipe queues and tc) > - Move definition of RTE_SCHED_TRAFFIC_CLASS_BE to rte_sched.h > - fix doxygen comments > > v5: > - fix traffic class and queue mapping in api function > - remove n_be_queues parameter from internal pipe profile and pipe struct > - replace int multiplication in grinder_schedule func with bitwise & operation > - remove TC_OV logic flag from all the configuration/initialization code > - fix traffic qsize per traffic class instead of individual queue of the pipe > > v4: > - fix build errors > - fix checkpatch errors > > v3: > - remove code related to subport level configuration of the pipe > - remove tc oversubscription flag from struct rte_sched_pipe_params > - replace RTE_SCHED_PIPE_PROFILES_PER_PORT with port param field > > v2: > - fix bug in subport parameters check > - remove redundant RTE_SCHED_SUBPORT_PER_PORT macro > - fix bug in grinder_scheduler function > - improve doxygen comments > - add error log information > > Jasvinder Singh (11): > sched: remove wrr from strict priority tc queues > sched: add config flexibility to tc queue sizes > sched: add max pipe profiles config in run time > sched: rename tc3 params to best-effort tc > sched: improve error log messages > sched: improve doxygen comments > net/softnic: add config flexibility to softnic tm > test_sched: modify tests for config flexibility > examples/ip_pipeline: add config flexibility to tm function > examples/qos_sched: add tc and queue config flexibility > sched: remove redundant macros > > app/test/test_sched.c | 15 +- > doc/guides/rel_notes/release_19_08.rst | 10 +- > drivers/net/softnic/rte_eth_softnic.c | 98 ++ > drivers/net/softnic/rte_eth_softnic_cli.c | 448 ++++++++- > .../net/softnic/rte_eth_softnic_internals.h | 6 +- > drivers/net/softnic/rte_eth_softnic_tm.c | 121 ++- > examples/ip_pipeline/cli.c | 43 +- > examples/ip_pipeline/tmgr.h | 4 +- > examples/qos_sched/app_thread.c | 11 +- > examples/qos_sched/cfg_file.c | 130 ++- > examples/qos_sched/init.c | 65 +- > examples/qos_sched/main.h | 4 + > examples/qos_sched/profile.cfg | 67 +- > examples/qos_sched/profile_ov.cfg | 54 +- > examples/qos_sched/stats.c | 517 ++++++----- > lib/librte_pipeline/rte_table_action.c | 1 - > lib/librte_pipeline/rte_table_action.h | 4 +- > lib/librte_sched/Makefile | 2 +- > lib/librte_sched/meson.build | 2 +- > lib/librte_sched/rte_sched.c | 857 ++++++++++++------ > lib/librte_sched/rte_sched.h | 187 ++-- > 21 files changed, 1874 insertions(+), 772 deletions(-) > > -- > 2.21.0 This patchset already has my ack starting from V5. Series-acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com> ^ permalink raw reply [flat|nested] 163+ messages in thread
* [dpdk-dev] [PATCH v5 02/11] sched: add config flexibility to tc queue sizes 2019-07-17 14:42 ` [dpdk-dev] [PATCH v5 00/11] sched: feature enhancements Jasvinder Singh 2019-07-17 14:42 ` [dpdk-dev] [PATCH v5 01/11] sched: remove wrr from strict priority tc queues Jasvinder Singh @ 2019-07-17 14:42 ` Jasvinder Singh 2019-07-18 23:04 ` Dumitrescu, Cristian 2019-07-17 14:42 ` [dpdk-dev] [PATCH v5 03/11] sched: add max pipe profiles config in run time Jasvinder Singh ` (9 subsequent siblings) 11 siblings, 1 reply; 163+ messages in thread From: Jasvinder Singh @ 2019-07-17 14:42 UTC (permalink / raw) To: dev; +Cc: cristian.dumitrescu, Abraham Tovar, Lukasz Krakowiak Add support for zero queue sizes of the traffic classes. The queues which are not used can be set to zero size. This helps in reducing memory footprint of the hierarchical scheduler. Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com> Signed-off-by: Abraham Tovar <abrahamx.tovar@intel.com> Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com> --- lib/librte_sched/rte_sched.c | 356 +++++++++++++++++++++-------------- lib/librte_sched/rte_sched.h | 6 +- 2 files changed, 214 insertions(+), 148 deletions(-) diff --git a/lib/librte_sched/rte_sched.c b/lib/librte_sched/rte_sched.c index f7c218ef0..3d3d4c69f 100644 --- a/lib/librte_sched/rte_sched.c +++ b/lib/librte_sched/rte_sched.c @@ -146,15 +146,15 @@ struct rte_sched_grinder { struct rte_sched_pipe_profile *pipe_params; /* TC cache */ - uint8_t tccache_qmask[4]; - uint32_t tccache_qindex[4]; + uint8_t tccache_qmask[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; + uint32_t tccache_qindex[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; uint32_t tccache_w; uint32_t tccache_r; /* Current TC */ uint32_t tc_index; - struct rte_sched_queue *queue[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; - struct rte_mbuf **qbase[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; + struct rte_sched_queue *queue[RTE_SCHED_MAX_QUEUES_PER_TC]; + struct rte_mbuf **qbase[RTE_SCHED_MAX_QUEUES_PER_TC]; uint32_t qindex[RTE_SCHED_MAX_QUEUES_PER_TC]; uint16_t qsize; uint32_t qmask; @@ -172,6 +172,9 @@ struct rte_sched_port { uint32_t n_subports_per_port; uint32_t n_pipes_per_subport; uint32_t n_pipes_per_subport_log2; + 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 rate; uint32_t mtu; uint32_t frame_overhead; @@ -257,14 +260,14 @@ rte_sched_port_qbase(struct rte_sched_port *port, uint32_t qindex) static inline uint16_t rte_sched_port_qsize(struct rte_sched_port *port, uint32_t qindex) { - uint32_t tc = (qindex >> 2) & 0x3; + uint32_t tc = port->pipe_tc[qindex & (RTE_SCHED_QUEUES_PER_PIPE - 1)]; return port->qsize[tc]; } static int pipe_profile_check(struct rte_sched_pipe_params *params, - uint32_t rate) + uint32_t rate, uint16_t *qsize) { uint32_t i; @@ -281,25 +284,27 @@ pipe_profile_check(struct rte_sched_pipe_params *params, if (params->tb_size == 0) return -12; - /* TC rate: non-zero, less than pipe rate */ + /* TC rate: non-zero if qsize non-zero, less than pipe rate */ for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { - if (params->tc_rate[i] == 0 || - params->tc_rate[i] > params->tb_rate) + if ((qsize[i] == 0 && params->tc_rate[i] != 0) || + (qsize[i] != 0 && (params->tc_rate[i] == 0 || + params->tc_rate[i] > params->tb_rate))) return -13; } + if (params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE] == 0 || + qsize[RTE_SCHED_TRAFFIC_CLASS_BE] == 0) + return -13; /* TC period: non-zero */ if (params->tc_period == 0) return -14; -#ifdef RTE_SCHED_SUBPORT_TC_OV /* TC3 oversubscription weight: non-zero */ if (params->tc_ov_weight == 0) return -15; -#endif /* Queue WRR weights: non-zero */ - for (i = 0; i < RTE_SCHED_QUEUES_PER_PIPE; i++) { + for (i = 0; i < RTE_SCHED_BE_QUEUES_PER_PIPE; i++) { if (params->wrr_weights[i] == 0) return -16; } @@ -344,7 +349,8 @@ rte_sched_port_check_params(struct rte_sched_port_params *params) for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { uint16_t qsize = params->qsize[i]; - if (qsize == 0 || !rte_is_power_of_2(qsize)) + if ((qsize != 0 && !rte_is_power_of_2(qsize)) || + ((i == RTE_SCHED_TRAFFIC_CLASS_BE) && (qsize == 0))) return -8; } @@ -358,7 +364,7 @@ rte_sched_port_check_params(struct rte_sched_port_params *params) struct rte_sched_pipe_params *p = params->pipe_profiles + i; int status; - status = pipe_profile_check(p, params->rate); + status = pipe_profile_check(p, params->rate, ¶ms->qsize[0]); if (status != 0) return status; } @@ -388,8 +394,12 @@ rte_sched_port_get_array_base(struct rte_sched_port_params *params, enum rte_sch size_per_pipe_queue_array = 0; for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { - size_per_pipe_queue_array += RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS - * params->qsize[i] * sizeof(struct rte_mbuf *); + if (i < RTE_SCHED_TRAFFIC_CLASS_BE) + size_per_pipe_queue_array += + params->qsize[i] * sizeof(struct rte_mbuf *); + else + size_per_pipe_queue_array += RTE_SCHED_MAX_QUEUES_PER_TC * + params->qsize[i] * sizeof(struct rte_mbuf *); } size_queue_array = n_pipes_per_port * size_per_pipe_queue_array; @@ -449,31 +459,27 @@ rte_sched_port_get_memory_footprint(struct rte_sched_port_params *params) static void rte_sched_port_config_qsize(struct rte_sched_port *port) { - /* TC 0 */ + uint32_t i; + port->qsize_add[0] = 0; - port->qsize_add[1] = port->qsize_add[0] + port->qsize[0]; - port->qsize_add[2] = port->qsize_add[1] + port->qsize[0]; - port->qsize_add[3] = port->qsize_add[2] + port->qsize[0]; - - /* TC 1 */ - port->qsize_add[4] = port->qsize_add[3] + port->qsize[0]; - port->qsize_add[5] = port->qsize_add[4] + port->qsize[1]; - port->qsize_add[6] = port->qsize_add[5] + port->qsize[1]; - port->qsize_add[7] = port->qsize_add[6] + port->qsize[1]; - - /* TC 2 */ - port->qsize_add[8] = port->qsize_add[7] + port->qsize[1]; - port->qsize_add[9] = port->qsize_add[8] + port->qsize[2]; - port->qsize_add[10] = port->qsize_add[9] + port->qsize[2]; - port->qsize_add[11] = port->qsize_add[10] + port->qsize[2]; - - /* TC 3 */ - port->qsize_add[12] = port->qsize_add[11] + port->qsize[2]; - port->qsize_add[13] = port->qsize_add[12] + port->qsize[3]; - port->qsize_add[14] = port->qsize_add[13] + port->qsize[3]; - port->qsize_add[15] = port->qsize_add[14] + port->qsize[3]; - - port->qsize_sum = port->qsize_add[15] + port->qsize[3]; + + /* Strict prority traffic class */ + for (i = 1; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) + port->qsize_add[i] = port->qsize_add[i-1] + port->qsize[i-1]; + + /* Best-effort traffic class */ + port->qsize_add[RTE_SCHED_TRAFFIC_CLASS_BE + 1] = + port->qsize_add[RTE_SCHED_TRAFFIC_CLASS_BE] + + port->qsize[RTE_SCHED_TRAFFIC_CLASS_BE]; + port->qsize_add[RTE_SCHED_TRAFFIC_CLASS_BE + 2] = + port->qsize_add[RTE_SCHED_TRAFFIC_CLASS_BE + 1] + + port->qsize[RTE_SCHED_TRAFFIC_CLASS_BE]; + port->qsize_add[RTE_SCHED_TRAFFIC_CLASS_BE + 3] = + port->qsize_add[RTE_SCHED_TRAFFIC_CLASS_BE + 2] + + port->qsize[RTE_SCHED_TRAFFIC_CLASS_BE]; + + port->qsize_sum = port->qsize_add[RTE_SCHED_TRAFFIC_CLASS_BE + 3] + + port->qsize[RTE_SCHED_TRAFFIC_CLASS_BE]; } static void @@ -482,10 +488,11 @@ rte_sched_port_log_pipe_profile(struct rte_sched_port *port, uint32_t i) struct rte_sched_pipe_profile *p = port->pipe_profiles + i; RTE_LOG(DEBUG, SCHED, "Low level config for pipe profile %u:\n" - " Token bucket: period = %u, credits per period = %u, size = %u\n" - " Traffic classes: period = %u, credits per period = [%u, %u, %u, %u]\n" - " Traffic class 3 oversubscription: weight = %hhu\n" - " WRR cost: [%hhu, %hhu, %hhu, %hhu]\n", + " Token bucket: period = %u, credits per period = %u, size = %u\n" + " Traffic classes: period = %u,\n" + " credits per period = [%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u]\n" + " Best-effort traffic class oversubscription: weight = %hhu\n" + " WRR cost: [%hhu, %hhu, %hhu, %hhu]\n", i, /* Token bucket */ @@ -499,6 +506,15 @@ 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_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], /* Traffic class 3 oversubscription */ p->tc_ov_weight, @@ -518,7 +534,8 @@ rte_sched_time_ms_to_bytes(uint32_t time_ms, uint32_t rate) } static void -rte_sched_pipe_profile_convert(struct rte_sched_pipe_params *src, +rte_sched_pipe_profile_convert(struct rte_sched_port *port, + struct rte_sched_pipe_params *src, struct rte_sched_pipe_profile *dst, uint32_t rate) { @@ -546,13 +563,12 @@ rte_sched_pipe_profile_convert(struct rte_sched_pipe_params *src, 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]); + if (port->qsize[i]) + dst->tc_credits_per_period[i] + = rte_sched_time_ms_to_bytes(src->tc_period, + src->tc_rate[i]); -#ifdef RTE_SCHED_SUBPORT_TC_OV dst->tc_ov_weight = src->tc_ov_weight; -#endif /* WRR queues */ wrr_cost[0] = src->wrr_weights[0]; @@ -585,14 +601,14 @@ rte_sched_port_config_pipe_profile_table(struct rte_sched_port *port, struct rte_sched_pipe_params *src = params->pipe_profiles + i; struct rte_sched_pipe_profile *dst = port->pipe_profiles + i; - rte_sched_pipe_profile_convert(src, dst, params->rate); + rte_sched_pipe_profile_convert(port, src, dst, params->rate); 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]; + uint32_t pipe_tc3_rate = src->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE]; if (port->pipe_tc3_rate_max < pipe_tc3_rate) port->pipe_tc3_rate_max = pipe_tc3_rate; @@ -603,7 +619,7 @@ struct rte_sched_port * rte_sched_port_config(struct rte_sched_port_params *params) { struct rte_sched_port *port = NULL; - uint32_t mem_size, bmp_mem_size, n_queues_per_port, i, cycles_per_byte; + uint32_t mem_size, bmp_mem_size, n_queues_per_port, i, j, cycles_per_byte; /* Check user parameters. Determine the amount of memory to allocate */ mem_size = rte_sched_port_get_memory_footprint(params); @@ -625,6 +641,23 @@ rte_sched_port_config(struct rte_sched_port_params *params) port->n_pipes_per_subport = params->n_pipes_per_subport; port->n_pipes_per_subport_log2 = __builtin_ctz(params->n_pipes_per_subport); + + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) + port->pipe_queue[i] = i; + + for (i = 0, j = 0; i < RTE_SCHED_QUEUES_PER_PIPE; i++) { + port->pipe_tc[i] = j; + + if (j < RTE_SCHED_TRAFFIC_CLASS_BE) + j++; + } + + for (i = 0, j = 0; i < RTE_SCHED_QUEUES_PER_PIPE; i++) { + port->tc_queue[i] = j; + + if (i >= RTE_SCHED_TRAFFIC_CLASS_BE) + j++; + } port->rate = params->rate; port->mtu = params->mtu + params->frame_overhead; port->frame_overhead = params->frame_overhead; @@ -734,12 +767,14 @@ rte_sched_port_free(struct rte_sched_port *port) for (qindex = 0; qindex < n_queues_per_port; qindex++) { struct rte_mbuf **mbufs = rte_sched_port_qbase(port, qindex); uint16_t qsize = rte_sched_port_qsize(port, qindex); - struct rte_sched_queue *queue = port->queue + qindex; - uint16_t qr = queue->qr & (qsize - 1); - uint16_t qw = queue->qw & (qsize - 1); + if (qsize != 0) { + struct rte_sched_queue *queue = port->queue + qindex; + uint16_t qr = queue->qr & (qsize - 1); + uint16_t qw = queue->qw & (qsize - 1); - for (; qr != qw; qr = (qr + 1) & (qsize - 1)) - rte_pktmbuf_free(mbufs[qr]); + for (; qr != qw; qr = (qr + 1) & (qsize - 1)) + rte_pktmbuf_free(mbufs[qr]); + } } rte_bitmap_free(port->bmp); @@ -752,9 +787,10 @@ rte_sched_port_log_subport_config(struct rte_sched_port *port, uint32_t i) struct rte_sched_subport *s = port->subport + i; RTE_LOG(DEBUG, SCHED, "Low level config for subport %u:\n" - " Token bucket: period = %u, credits per period = %u, size = %u\n" - " Traffic classes: period = %u, credits per period = [%u, %u, %u, %u]\n" - " Traffic class 3 oversubscription: wm min = %u, wm max = %u\n", + " Token bucket: period = %u, credits per period = %u, size = %u\n" + " Traffic classes: period = %u\n" + " credits per period = [%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u]\n" + " Best effort traffic class oversubscription: wm min = %u, wm max = %u\n", i, /* Token bucket */ @@ -768,6 +804,15 @@ 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_credits_per_period[4], + s->tc_credits_per_period[5], + s->tc_credits_per_period[6], + s->tc_credits_per_period[7], + s->tc_credits_per_period[8], + s->tc_credits_per_period[9], + s->tc_credits_per_period[10], + s->tc_credits_per_period[11], + s->tc_credits_per_period[12], /* Traffic class 3 oversubscription */ s->tc_ov_wm_min, @@ -795,11 +840,19 @@ rte_sched_subport_config(struct rte_sched_port *port, return -3; for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { - if (params->tc_rate[i] == 0 || - params->tc_rate[i] > params->tb_rate) + uint32_t tc_rate = params->tc_rate[i]; + uint16_t qsize = port->qsize[i]; + + if ((qsize == 0 && tc_rate != 0) || + (qsize != 0 && tc_rate == 0) || + (tc_rate > params->tb_rate)) return -4; } + if (port->qsize[RTE_SCHED_TRAFFIC_CLASS_BE] == 0 || + params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE] == 0) + return -4; + if (params->tc_period == 0) return -5; @@ -823,15 +876,17 @@ rte_sched_subport_config(struct rte_sched_port *port, /* Traffic Classes (TCs) */ s->tc_period = rte_sched_time_ms_to_bytes(params->tc_period, port->rate); for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { - s->tc_credits_per_period[i] - = rte_sched_time_ms_to_bytes(params->tc_period, - params->tc_rate[i]); + if (port->qsize[i]) + s->tc_credits_per_period[i] + = rte_sched_time_ms_to_bytes(params->tc_period, + params->tc_rate[i]); + } s->tc_time = port->time + s->tc_period; for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) - s->tc_credits[i] = s->tc_credits_per_period[i]; + if (port->qsize[i]) + s->tc_credits[i] = s->tc_credits_per_period[i]; -#ifdef RTE_SCHED_SUBPORT_TC_OV /* TC oversubscription */ s->tc_ov_wm_min = port->mtu; s->tc_ov_wm_max = rte_sched_time_ms_to_bytes(params->tc_period, @@ -841,7 +896,6 @@ rte_sched_subport_config(struct rte_sched_port *port, s->tc_ov = 0; s->tc_ov_n = 0; s->tc_ov_rate = 0; -#endif rte_sched_port_log_subport_config(port, subport_id); @@ -881,10 +935,9 @@ rte_sched_pipe_config(struct rte_sched_port *port, if (p->tb_time) { params = port->pipe_profiles + p->profile; -#ifdef RTE_SCHED_SUBPORT_TC_OV - double subport_tc3_rate = (double) s->tc_credits_per_period[3] + double subport_tc3_rate = (double) s->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] / (double) s->tc_period; - double pipe_tc3_rate = (double) params->tc_credits_per_period[3] + double pipe_tc3_rate = (double) params->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] / (double) params->tc_period; uint32_t tc3_ov = s->tc_ov; @@ -898,7 +951,6 @@ rte_sched_pipe_config(struct rte_sched_port *port, "Subport %u TC3 oversubscription is OFF (%.4lf >= %.4lf)\n", subport_id, subport_tc3_rate, s->tc_ov_rate); } -#endif /* Reset the pipe */ memset(p, 0, sizeof(struct rte_sched_pipe)); @@ -917,15 +969,18 @@ rte_sched_pipe_config(struct rte_sched_port *port, /* Traffic Classes (TCs) */ p->tc_time = port->time + params->tc_period; + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) - p->tc_credits[i] = params->tc_credits_per_period[i]; + if (port->qsize[i]) + p->tc_credits[i] = params->tc_credits_per_period[i]; -#ifdef RTE_SCHED_SUBPORT_TC_OV { /* Subport TC3 oversubscription */ - double subport_tc3_rate = (double) s->tc_credits_per_period[3] + double subport_tc3_rate = + (double) s->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] / (double) s->tc_period; - double pipe_tc3_rate = (double) params->tc_credits_per_period[3] + double pipe_tc3_rate = + (double) params->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] / (double) params->tc_period; uint32_t tc3_ov = s->tc_ov; @@ -941,7 +996,6 @@ rte_sched_pipe_config(struct rte_sched_port *port, p->tc_ov_period_id = s->tc_ov_period_id; p->tc_ov_credits = s->tc_ov_wm; } -#endif return 0; } @@ -964,12 +1018,12 @@ rte_sched_port_pipe_profile_add(struct rte_sched_port *port, return -2; /* Pipe params */ - status = pipe_profile_check(params, port->rate); + status = pipe_profile_check(params, port->rate, &port->qsize[0]); if (status != 0) return status; pp = &port->pipe_profiles[port->n_pipe_profiles]; - rte_sched_pipe_profile_convert(params, pp, port->rate); + rte_sched_pipe_profile_convert(port, params, pp, port->rate); /* Pipe profile not exists */ for (i = 0; i < port->n_pipe_profiles; i++) @@ -980,8 +1034,8 @@ rte_sched_port_pipe_profile_add(struct rte_sched_port *port, *pipe_profile_id = port->n_pipe_profiles; port->n_pipe_profiles++; - if (port->pipe_tc3_rate_max < params->tc_rate[3]) - port->pipe_tc3_rate_max = params->tc_rate[3]; + if (port->pipe_tc3_rate_max < params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE]) + port->pipe_tc3_rate_max = params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE]; rte_sched_port_log_pipe_profile(port, *pipe_profile_id); @@ -998,9 +1052,8 @@ rte_sched_port_qindex(struct rte_sched_port *port, return ((subport & (port->n_subports_per_port - 1)) << (port->n_pipes_per_subport_log2 + 4)) | ((pipe & (port->n_pipes_per_subport - 1)) << 4) | - ((traffic_class & - (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1)) << 2) | - (queue & (RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS - 1)); + ((port->pipe_queue[traffic_class] + queue) & + (RTE_SCHED_QUEUES_PER_PIPE - 1)); } void @@ -1010,8 +1063,9 @@ rte_sched_port_pkt_write(struct rte_sched_port *port, uint32_t traffic_class, uint32_t queue, enum rte_color color) { - uint32_t queue_id = rte_sched_port_qindex(port, subport, pipe, - traffic_class, queue); + uint32_t queue_id = + rte_sched_port_qindex(port, subport, pipe, traffic_class, queue); + rte_mbuf_sched_set(pkt, queue_id, traffic_class, (uint8_t)color); } @@ -1022,12 +1076,12 @@ rte_sched_port_pkt_read_tree_path(struct rte_sched_port *port, uint32_t *traffic_class, uint32_t *queue) { uint32_t queue_id = rte_mbuf_sched_queue_get(pkt); + uint32_t pipe_queue = queue_id & (RTE_SCHED_QUEUES_PER_PIPE - 1); *subport = queue_id >> (port->n_pipes_per_subport_log2 + 4); *pipe = (queue_id >> 4) & (port->n_pipes_per_subport - 1); - *traffic_class = (queue_id >> 2) & - (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1); - *queue = queue_id & (RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS - 1); + *traffic_class = port->pipe_tc[pipe_queue]; + *queue = port->tc_queue[pipe_queue]; } enum rte_color @@ -1108,7 +1162,7 @@ static inline void rte_sched_port_update_subport_stats(struct rte_sched_port *port, uint32_t qindex, struct rte_mbuf *pkt) { struct rte_sched_subport *s = port->subport + (qindex / rte_sched_port_queues_per_subport(port)); - uint32_t tc_index = (qindex >> 2) & 0x3; + uint32_t tc_index = port->pipe_tc[qindex & (RTE_SCHED_QUEUES_PER_PIPE - 1)]; uint32_t pkt_len = pkt->pkt_len; s->stats.n_pkts_tc[tc_index] += 1; @@ -1128,7 +1182,7 @@ rte_sched_port_update_subport_stats_on_drop(struct rte_sched_port *port, #endif { struct rte_sched_subport *s = port->subport + (qindex / rte_sched_port_queues_per_subport(port)); - uint32_t tc_index = (qindex >> 2) & 0x3; + uint32_t tc_index = port->pipe_tc[qindex & (RTE_SCHED_QUEUES_PER_PIPE - 1)]; uint32_t pkt_len = pkt->pkt_len; s->stats.n_pkts_tc_dropped[tc_index] += 1; @@ -1183,7 +1237,7 @@ rte_sched_port_red_drop(struct rte_sched_port *port, struct rte_mbuf *pkt, uint3 uint32_t tc_index; enum rte_color color; - tc_index = (qindex >> 2) & 0x3; + tc_index = port->pipe_tc[qindex & (RTE_SCHED_QUEUES_PER_PIPE - 1)]; color = rte_sched_port_pkt_read_color(pkt); red_cfg = &port->red_config[tc_index][color]; @@ -1500,6 +1554,7 @@ grinder_credits_update(struct rte_sched_port *port, uint32_t pos) struct rte_sched_pipe *pipe = grinder->pipe; struct rte_sched_pipe_profile *params = grinder->pipe_params; uint64_t n_periods; + uint32_t i; /* Subport TB */ n_periods = (port->time - subport->tb_time) / subport->tb_period; @@ -1515,19 +1570,17 @@ grinder_credits_update(struct rte_sched_port *port, uint32_t pos) /* Subport TCs */ 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]; + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) + subport->tc_credits[i] = subport->tc_credits_per_period[i]; + subport->tc_time = port->time + subport->tc_period; } /* Pipe TCs */ if (unlikely(port->time >= pipe->tc_time)) { - pipe->tc_credits[0] = params->tc_credits_per_period[0]; - pipe->tc_credits[1] = params->tc_credits_per_period[1]; - pipe->tc_credits[2] = params->tc_credits_per_period[2]; - pipe->tc_credits[3] = params->tc_credits_per_period[3]; + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) + pipe->tc_credits[i] = params->tc_credits_per_period[i]; + pipe->tc_time = port->time + params->tc_period; } } @@ -1540,21 +1593,29 @@ 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_consumption = 0, tc_ov_consumption_max; uint32_t tc_ov_wm = subport->tc_ov_wm; + uint32_t i; 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]; + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASS_BE; i++) { + tc_ov_consumption[i] = + subport->tc_credits_per_period[i] - subport->tc_credits[i]; + tc_consumption += tc_ov_consumption[i]; + } + + tc_ov_consumption[RTE_SCHED_TRAFFIC_CLASS_BE] = + subport->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] - + subport->tc_credits[RTE_SCHED_TRAFFIC_CLASS_BE]; - 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_consumption_max = + subport->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] - tc_consumption; + + if (tc_ov_consumption[RTE_SCHED_TRAFFIC_CLASS_BE] > + (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; @@ -1577,6 +1638,7 @@ grinder_credits_update(struct rte_sched_port *port, uint32_t pos) struct rte_sched_pipe *pipe = grinder->pipe; struct rte_sched_pipe_profile *params = grinder->pipe_params; uint64_t n_periods; + uint32_t i; /* Subport TB */ n_periods = (port->time - subport->tb_time) / subport->tb_period; @@ -1594,10 +1656,8 @@ grinder_credits_update(struct rte_sched_port *port, uint32_t pos) 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]; + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) + subport->tc_credits[i] = subport->tc_credits_per_period[i]; subport->tc_time = port->time + subport->tc_period; subport->tc_ov_period_id++; @@ -1605,10 +1665,8 @@ grinder_credits_update(struct rte_sched_port *port, uint32_t pos) /* Pipe TCs */ if (unlikely(port->time >= pipe->tc_time)) { - pipe->tc_credits[0] = params->tc_credits_per_period[0]; - pipe->tc_credits[1] = params->tc_credits_per_period[1]; - pipe->tc_credits[2] = params->tc_credits_per_period[2]; - pipe->tc_credits[3] = params->tc_credits_per_period[3]; + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) + pipe->tc_credits[i] = params->tc_credits_per_period[i]; pipe->tc_time = port->time + params->tc_period; } @@ -1673,11 +1731,18 @@ 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_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]; + uint32_t pipe_tc_ov_mask1[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; + uint32_t pipe_tc_ov_mask2[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE] = {0}; + uint32_t pipe_tc_ov_credits, i; int enough_credits; + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) + pipe_tc_ov_mask1[i] = UINT32_MAX; + + pipe_tc_ov_mask1[RTE_SCHED_TRAFFIC_CLASS_BE] = pipe->tc_ov_credits; + pipe_tc_ov_mask2[RTE_SCHED_TRAFFIC_CLASS_BE] = UINT32_MAX; + pipe_tc_ov_credits = pipe_tc_ov_mask1[tc_index]; + /* Check pipe and subport credits */ enough_credits = (pkt_len <= subport_tb_credits) && (pkt_len <= subport_tc_credits) && @@ -1832,31 +1897,23 @@ static inline void grinder_tccache_populate(struct rte_sched_port *port, uint32_t pos, uint32_t qindex, uint16_t qmask) { struct rte_sched_grinder *grinder = port->grinder + pos; - uint8_t b[4]; + uint8_t b, i; grinder->tccache_w = 0; grinder->tccache_r = 0; - b[0] = (uint8_t) (qmask & 0xF); - b[1] = (uint8_t) ((qmask >> 4) & 0xF); - b[2] = (uint8_t) ((qmask >> 8) & 0xF); - b[3] = (uint8_t) ((qmask >> 12) & 0xF); - - grinder->tccache_qmask[grinder->tccache_w] = b[0]; - grinder->tccache_qindex[grinder->tccache_w] = qindex; - grinder->tccache_w += (b[0] != 0); - - grinder->tccache_qmask[grinder->tccache_w] = b[1]; - grinder->tccache_qindex[grinder->tccache_w] = qindex + 4; - grinder->tccache_w += (b[1] != 0); - - grinder->tccache_qmask[grinder->tccache_w] = b[2]; - grinder->tccache_qindex[grinder->tccache_w] = qindex + 8; - grinder->tccache_w += (b[2] != 0); + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASS_BE; i++) { + b = (uint8_t) ((qmask >> i) & 0x1); + grinder->tccache_qmask[grinder->tccache_w] = b; + grinder->tccache_qindex[grinder->tccache_w] = qindex + i; + grinder->tccache_w += (b != 0); + } - grinder->tccache_qmask[grinder->tccache_w] = b[3]; - grinder->tccache_qindex[grinder->tccache_w] = qindex + 12; - grinder->tccache_w += (b[3] != 0); + b = (uint8_t) (qmask >> (RTE_SCHED_TRAFFIC_CLASS_BE)); + grinder->tccache_qmask[grinder->tccache_w] = b; + grinder->tccache_qindex[grinder->tccache_w] = qindex + + RTE_SCHED_TRAFFIC_CLASS_BE; + grinder->tccache_w += (b != 0); } static inline int @@ -1874,14 +1931,18 @@ grinder_next_tc(struct rte_sched_port *port, uint32_t pos) qbase = rte_sched_port_qbase(port, qindex); qsize = rte_sched_port_qsize(port, qindex); - grinder->tc_index = (qindex >> 2) & 0x3; + grinder->tc_index = port->pipe_tc[qindex & (RTE_SCHED_QUEUES_PER_PIPE - 1)]; grinder->qmask = grinder->tccache_qmask[grinder->tccache_r]; grinder->qsize = qsize; - grinder->qindex[0] = qindex; - grinder->qindex[1] = qindex + 1; - grinder->qindex[2] = qindex + 2; - grinder->qindex[3] = qindex + 3; + if (grinder->tc_index < RTE_SCHED_TRAFFIC_CLASS_BE) { + grinder->queue[0] = port->queue + qindex; + grinder->qbase[0] = qbase; + grinder->qindex[0] = qindex; + grinder->tccache_r++; + + return 1; + } grinder->queue[0] = port->queue + qindex; grinder->queue[1] = port->queue + qindex + 1; @@ -1893,6 +1954,11 @@ grinder_next_tc(struct rte_sched_port *port, uint32_t pos) grinder->qbase[2] = qbase + 2 * qsize; grinder->qbase[3] = qbase + 3 * qsize; + grinder->qindex[0] = qindex; + grinder->qindex[1] = qindex + 1; + grinder->qindex[2] = qindex + 2; + grinder->qindex[3] = qindex + 3; + grinder->tccache_r++; return 1; } diff --git a/lib/librte_sched/rte_sched.h b/lib/librte_sched/rte_sched.h index f9947c4cd..2b55c97ab 100644 --- a/lib/librte_sched/rte_sched.h +++ b/lib/librte_sched/rte_sched.h @@ -85,7 +85,9 @@ extern "C" { /** Number of traffic classes per pipe (as well as subport). * Cannot be changed. */ -#define RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE 4 +#define RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE \ +(RTE_SCHED_QUEUES_PER_PIPE - RTE_SCHED_BE_QUEUES_PER_PIPE + 1) + /** Number of queues per pipe traffic class. Cannot be changed. */ #define RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS 4 @@ -172,9 +174,7 @@ struct rte_sched_pipe_params { /**< Traffic class rates (measured in bytes per second) */ uint32_t tc_period; /**< Enforcement period (measured in milliseconds) */ -#ifdef RTE_SCHED_SUBPORT_TC_OV uint8_t tc_ov_weight; /**< Weight Traffic class 3 oversubscription */ -#endif /* Pipe queues */ uint8_t wrr_weights[RTE_SCHED_BE_QUEUES_PER_PIPE]; /**< WRR weights */ -- 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* Re: [dpdk-dev] [PATCH v5 02/11] sched: add config flexibility to tc queue sizes 2019-07-17 14:42 ` [dpdk-dev] [PATCH v5 02/11] sched: add config flexibility to tc queue sizes Jasvinder Singh @ 2019-07-18 23:04 ` Dumitrescu, Cristian 2019-07-19 15:25 ` Singh, Jasvinder 0 siblings, 1 reply; 163+ messages in thread From: Dumitrescu, Cristian @ 2019-07-18 23:04 UTC (permalink / raw) To: Singh, Jasvinder, dev; +Cc: Tovar, AbrahamX, Krakowiak, LukaszX > -----Original Message----- > From: Singh, Jasvinder > Sent: Wednesday, July 17, 2019 4:43 PM > To: dev@dpdk.org > Cc: Dumitrescu, Cristian <cristian.dumitrescu@intel.com>; Tovar, AbrahamX > <abrahamx.tovar@intel.com>; Krakowiak, LukaszX > <lukaszx.krakowiak@intel.com> > Subject: [PATCH v5 02/11] sched: add config flexibility to tc queue sizes > > Add support for zero queue sizes of the traffic classes. The queues > which are not used can be set to zero size. This helps in reducing > memory footprint of the hierarchical scheduler. > > Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com> > Signed-off-by: Abraham Tovar <abrahamx.tovar@intel.com> > Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com> > --- > lib/librte_sched/rte_sched.c | 356 +++++++++++++++++++++-------------- > lib/librte_sched/rte_sched.h | 6 +- > 2 files changed, 214 insertions(+), 148 deletions(-) > > diff --git a/lib/librte_sched/rte_sched.c b/lib/librte_sched/rte_sched.c > index f7c218ef0..3d3d4c69f 100644 > --- a/lib/librte_sched/rte_sched.c > +++ b/lib/librte_sched/rte_sched.c > @@ -146,15 +146,15 @@ struct rte_sched_grinder { > struct rte_sched_pipe_profile *pipe_params; > > /* TC cache */ > - uint8_t tccache_qmask[4]; > - uint32_t tccache_qindex[4]; > + uint8_t tccache_qmask[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; > + uint32_t tccache_qindex[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; > uint32_t tccache_w; > uint32_t tccache_r; > > /* Current TC */ > uint32_t tc_index; > - struct rte_sched_queue > *queue[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; > - struct rte_mbuf **qbase[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; > + struct rte_sched_queue > *queue[RTE_SCHED_MAX_QUEUES_PER_TC]; > + struct rte_mbuf **qbase[RTE_SCHED_MAX_QUEUES_PER_TC]; > uint32_t qindex[RTE_SCHED_MAX_QUEUES_PER_TC]; > uint16_t qsize; > uint32_t qmask; > @@ -172,6 +172,9 @@ struct rte_sched_port { > uint32_t n_subports_per_port; > uint32_t n_pipes_per_subport; > uint32_t n_pipes_per_subport_log2; > + 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]; I suggest we create simple functions to access the above 3 data structures as opposed to access them directly, similar to the rte_sched_port_qsize() function (and maybe place them just below this function). > uint32_t rate; > uint32_t mtu; > uint32_t frame_overhead; > @@ -257,14 +260,14 @@ rte_sched_port_qbase(struct rte_sched_port > *port, uint32_t qindex) > static inline uint16_t > rte_sched_port_qsize(struct rte_sched_port *port, uint32_t qindex) > { > - uint32_t tc = (qindex >> 2) & 0x3; > + uint32_t tc = port->pipe_tc[qindex & > (RTE_SCHED_QUEUES_PER_PIPE - 1)]; > > return port->qsize[tc]; > } > > static int > pipe_profile_check(struct rte_sched_pipe_params *params, > - uint32_t rate) > + uint32_t rate, uint16_t *qsize) > { > uint32_t i; > > @@ -281,25 +284,27 @@ pipe_profile_check(struct rte_sched_pipe_params > *params, > if (params->tb_size == 0) > return -12; > > - /* TC rate: non-zero, less than pipe rate */ > + /* TC rate: non-zero if qsize non-zero, less than pipe rate */ > for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { > - if (params->tc_rate[i] == 0 || > - params->tc_rate[i] > params->tb_rate) > + if ((qsize[i] == 0 && params->tc_rate[i] != 0) || > + (qsize[i] != 0 && (params->tc_rate[i] == 0 || > + params->tc_rate[i] > params->tb_rate))) > return -13; > } > + if (params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE] == 0 || > + qsize[RTE_SCHED_TRAFFIC_CLASS_BE] == 0) > + return -13; > > /* TC period: non-zero */ > if (params->tc_period == 0) > return -14; > > -#ifdef RTE_SCHED_SUBPORT_TC_OV > /* TC3 oversubscription weight: non-zero */ > if (params->tc_ov_weight == 0) > return -15; > -#endif > > /* Queue WRR weights: non-zero */ > - for (i = 0; i < RTE_SCHED_QUEUES_PER_PIPE; i++) { > + for (i = 0; i < RTE_SCHED_BE_QUEUES_PER_PIPE; i++) { > if (params->wrr_weights[i] == 0) > return -16; > } > @@ -344,7 +349,8 @@ rte_sched_port_check_params(struct > rte_sched_port_params *params) > for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { > uint16_t qsize = params->qsize[i]; > > - if (qsize == 0 || !rte_is_power_of_2(qsize)) > + if ((qsize != 0 && !rte_is_power_of_2(qsize)) || > + ((i == RTE_SCHED_TRAFFIC_CLASS_BE) && (qsize == > 0))) > return -8; > } > > @@ -358,7 +364,7 @@ rte_sched_port_check_params(struct > rte_sched_port_params *params) > struct rte_sched_pipe_params *p = params->pipe_profiles + > i; > int status; > > - status = pipe_profile_check(p, params->rate); > + status = pipe_profile_check(p, params->rate, ¶ms- > >qsize[0]); > if (status != 0) > return status; > } > @@ -388,8 +394,12 @@ rte_sched_port_get_array_base(struct > rte_sched_port_params *params, enum rte_sch > > size_per_pipe_queue_array = 0; > for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { > - size_per_pipe_queue_array += > RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS > - * params->qsize[i] * sizeof(struct rte_mbuf *); > + if (i < RTE_SCHED_TRAFFIC_CLASS_BE) > + size_per_pipe_queue_array += > + params->qsize[i] * sizeof(struct rte_mbuf *); > + else > + size_per_pipe_queue_array += > RTE_SCHED_MAX_QUEUES_PER_TC * > + params->qsize[i] * sizeof(struct rte_mbuf *); > } > size_queue_array = n_pipes_per_port * > size_per_pipe_queue_array; > > @@ -449,31 +459,27 @@ rte_sched_port_get_memory_footprint(struct > rte_sched_port_params *params) > static void > rte_sched_port_config_qsize(struct rte_sched_port *port) > { > - /* TC 0 */ > + uint32_t i; > + > port->qsize_add[0] = 0; > - port->qsize_add[1] = port->qsize_add[0] + port->qsize[0]; > - port->qsize_add[2] = port->qsize_add[1] + port->qsize[0]; > - port->qsize_add[3] = port->qsize_add[2] + port->qsize[0]; > - > - /* TC 1 */ > - port->qsize_add[4] = port->qsize_add[3] + port->qsize[0]; > - port->qsize_add[5] = port->qsize_add[4] + port->qsize[1]; > - port->qsize_add[6] = port->qsize_add[5] + port->qsize[1]; > - port->qsize_add[7] = port->qsize_add[6] + port->qsize[1]; > - > - /* TC 2 */ > - port->qsize_add[8] = port->qsize_add[7] + port->qsize[1]; > - port->qsize_add[9] = port->qsize_add[8] + port->qsize[2]; > - port->qsize_add[10] = port->qsize_add[9] + port->qsize[2]; > - port->qsize_add[11] = port->qsize_add[10] + port->qsize[2]; > - > - /* TC 3 */ > - port->qsize_add[12] = port->qsize_add[11] + port->qsize[2]; > - port->qsize_add[13] = port->qsize_add[12] + port->qsize[3]; > - port->qsize_add[14] = port->qsize_add[13] + port->qsize[3]; > - port->qsize_add[15] = port->qsize_add[14] + port->qsize[3]; > - > - port->qsize_sum = port->qsize_add[15] + port->qsize[3]; > + > + /* Strict prority traffic class */ > + for (i = 1; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) > + port->qsize_add[i] = port->qsize_add[i-1] + port->qsize[i-1]; > + > + /* Best-effort traffic class */ > + port->qsize_add[RTE_SCHED_TRAFFIC_CLASS_BE + 1] = > + port->qsize_add[RTE_SCHED_TRAFFIC_CLASS_BE] + > + port->qsize[RTE_SCHED_TRAFFIC_CLASS_BE]; > + port->qsize_add[RTE_SCHED_TRAFFIC_CLASS_BE + 2] = > + port->qsize_add[RTE_SCHED_TRAFFIC_CLASS_BE + 1] + > + port->qsize[RTE_SCHED_TRAFFIC_CLASS_BE]; > + port->qsize_add[RTE_SCHED_TRAFFIC_CLASS_BE + 3] = > + port->qsize_add[RTE_SCHED_TRAFFIC_CLASS_BE + 2] + > + port->qsize[RTE_SCHED_TRAFFIC_CLASS_BE]; > + > + port->qsize_sum = port->qsize_add[RTE_SCHED_TRAFFIC_CLASS_BE > + 3] + > + port->qsize[RTE_SCHED_TRAFFIC_CLASS_BE]; > } > > static void > @@ -482,10 +488,11 @@ rte_sched_port_log_pipe_profile(struct > rte_sched_port *port, uint32_t i) > struct rte_sched_pipe_profile *p = port->pipe_profiles + i; > > RTE_LOG(DEBUG, SCHED, "Low level config for pipe profile %u:\n" > - " Token bucket: period = %u, credits per period = %u, size = > %u\n" > - " Traffic classes: period = %u, credits per period = [%u, %u, > %u, %u]\n" > - " Traffic class 3 oversubscription: weight = %hhu\n" > - " WRR cost: [%hhu, %hhu, %hhu, %hhu]\n", > + " Token bucket: period = %u, credits per period = %u, > size = %u\n" > + " Traffic classes: period = %u,\n" > + " credits per period = [%u, %u, %u, %u, %u, %u, %u, > %u, %u, %u, %u, %u, %u]\n" > + " Best-effort traffic class oversubscription: weight = > %hhu\n" > + " WRR cost: [%hhu, %hhu, %hhu, %hhu]\n", > i, > > /* Token bucket */ > @@ -499,6 +506,15 @@ 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_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], > > /* Traffic class 3 oversubscription */ > p->tc_ov_weight, > @@ -518,7 +534,8 @@ rte_sched_time_ms_to_bytes(uint32_t time_ms, > uint32_t rate) > } > > static void > -rte_sched_pipe_profile_convert(struct rte_sched_pipe_params *src, > +rte_sched_pipe_profile_convert(struct rte_sched_port *port, > + struct rte_sched_pipe_params *src, > struct rte_sched_pipe_profile *dst, > uint32_t rate) > { > @@ -546,13 +563,12 @@ rte_sched_pipe_profile_convert(struct > rte_sched_pipe_params *src, > 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]); > + if (port->qsize[i]) > + dst->tc_credits_per_period[i] > + = rte_sched_time_ms_to_bytes(src- > >tc_period, > + src->tc_rate[i]); > > -#ifdef RTE_SCHED_SUBPORT_TC_OV > dst->tc_ov_weight = src->tc_ov_weight; > -#endif > > /* WRR queues */ > wrr_cost[0] = src->wrr_weights[0]; > @@ -585,14 +601,14 @@ rte_sched_port_config_pipe_profile_table(struct > rte_sched_port *port, > struct rte_sched_pipe_params *src = params->pipe_profiles > + i; > struct rte_sched_pipe_profile *dst = port->pipe_profiles + i; > > - rte_sched_pipe_profile_convert(src, dst, params->rate); > + rte_sched_pipe_profile_convert(port, src, dst, params- > >rate); > 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]; > + uint32_t pipe_tc3_rate = src- > >tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE]; > > if (port->pipe_tc3_rate_max < pipe_tc3_rate) > port->pipe_tc3_rate_max = pipe_tc3_rate; > @@ -603,7 +619,7 @@ struct rte_sched_port * > rte_sched_port_config(struct rte_sched_port_params *params) > { > struct rte_sched_port *port = NULL; > - uint32_t mem_size, bmp_mem_size, n_queues_per_port, i, > cycles_per_byte; > + uint32_t mem_size, bmp_mem_size, n_queues_per_port, i, j, > cycles_per_byte; > > /* Check user parameters. Determine the amount of memory to > allocate */ > mem_size = rte_sched_port_get_memory_footprint(params); > @@ -625,6 +641,23 @@ rte_sched_port_config(struct > rte_sched_port_params *params) > port->n_pipes_per_subport = params->n_pipes_per_subport; > port->n_pipes_per_subport_log2 = > __builtin_ctz(params->n_pipes_per_subport); > + > + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) > + port->pipe_queue[i] = i; > + > + for (i = 0, j = 0; i < RTE_SCHED_QUEUES_PER_PIPE; i++) { > + port->pipe_tc[i] = j; > + > + if (j < RTE_SCHED_TRAFFIC_CLASS_BE) > + j++; > + } > + > + for (i = 0, j = 0; i < RTE_SCHED_QUEUES_PER_PIPE; i++) { > + port->tc_queue[i] = j; > + > + if (i >= RTE_SCHED_TRAFFIC_CLASS_BE) > + j++; > + } > port->rate = params->rate; > port->mtu = params->mtu + params->frame_overhead; > port->frame_overhead = params->frame_overhead; > @@ -734,12 +767,14 @@ rte_sched_port_free(struct rte_sched_port *port) > for (qindex = 0; qindex < n_queues_per_port; qindex++) { > struct rte_mbuf **mbufs = rte_sched_port_qbase(port, > qindex); > uint16_t qsize = rte_sched_port_qsize(port, qindex); > - struct rte_sched_queue *queue = port->queue + qindex; > - uint16_t qr = queue->qr & (qsize - 1); > - uint16_t qw = queue->qw & (qsize - 1); > + if (qsize != 0) { > + struct rte_sched_queue *queue = port->queue + > qindex; > + uint16_t qr = queue->qr & (qsize - 1); > + uint16_t qw = queue->qw & (qsize - 1); > > - for (; qr != qw; qr = (qr + 1) & (qsize - 1)) > - rte_pktmbuf_free(mbufs[qr]); > + for (; qr != qw; qr = (qr + 1) & (qsize - 1)) > + rte_pktmbuf_free(mbufs[qr]); > + } > } > > rte_bitmap_free(port->bmp); > @@ -752,9 +787,10 @@ rte_sched_port_log_subport_config(struct > rte_sched_port *port, uint32_t i) > struct rte_sched_subport *s = port->subport + i; > > RTE_LOG(DEBUG, SCHED, "Low level config for subport %u:\n" > - " Token bucket: period = %u, credits per period = %u, size = > %u\n" > - " Traffic classes: period = %u, credits per period = [%u, %u, > %u, %u]\n" > - " Traffic class 3 oversubscription: wm min = %u, wm max = > %u\n", > + " Token bucket: period = %u, credits per period = %u, > size = %u\n" > + " Traffic classes: period = %u\n" > + " credits per period = [%u, %u, %u, %u, %u, %u, %u, > %u, %u, %u, %u, %u, %u]\n" > + " Best effort traffic class oversubscription: wm min = > %u, wm max = %u\n", > i, > > /* Token bucket */ > @@ -768,6 +804,15 @@ 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_credits_per_period[4], > + s->tc_credits_per_period[5], > + s->tc_credits_per_period[6], > + s->tc_credits_per_period[7], > + s->tc_credits_per_period[8], > + s->tc_credits_per_period[9], > + s->tc_credits_per_period[10], > + s->tc_credits_per_period[11], > + s->tc_credits_per_period[12], > > /* Traffic class 3 oversubscription */ > s->tc_ov_wm_min, > @@ -795,11 +840,19 @@ rte_sched_subport_config(struct rte_sched_port > *port, > return -3; > > for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { > - if (params->tc_rate[i] == 0 || > - params->tc_rate[i] > params->tb_rate) > + uint32_t tc_rate = params->tc_rate[i]; > + uint16_t qsize = port->qsize[i]; > + > + if ((qsize == 0 && tc_rate != 0) || > + (qsize != 0 && tc_rate == 0) || > + (tc_rate > params->tb_rate)) > return -4; > } > > + if (port->qsize[RTE_SCHED_TRAFFIC_CLASS_BE] == 0 || > + params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE] == 0) > + return -4; > + > if (params->tc_period == 0) > return -5; > > @@ -823,15 +876,17 @@ rte_sched_subport_config(struct rte_sched_port > *port, > /* Traffic Classes (TCs) */ > s->tc_period = rte_sched_time_ms_to_bytes(params->tc_period, > port->rate); > for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { > - s->tc_credits_per_period[i] > - = rte_sched_time_ms_to_bytes(params->tc_period, > - params->tc_rate[i]); > + if (port->qsize[i]) > + s->tc_credits_per_period[i] > + = rte_sched_time_ms_to_bytes(params- > >tc_period, > + params- > >tc_rate[i]); > + > } > s->tc_time = port->time + s->tc_period; > for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) > - s->tc_credits[i] = s->tc_credits_per_period[i]; > + if (port->qsize[i]) > + s->tc_credits[i] = s->tc_credits_per_period[i]; > > -#ifdef RTE_SCHED_SUBPORT_TC_OV > /* TC oversubscription */ > s->tc_ov_wm_min = port->mtu; > s->tc_ov_wm_max = rte_sched_time_ms_to_bytes(params- > >tc_period, > @@ -841,7 +896,6 @@ rte_sched_subport_config(struct rte_sched_port > *port, > s->tc_ov = 0; > s->tc_ov_n = 0; > s->tc_ov_rate = 0; > -#endif > > rte_sched_port_log_subport_config(port, subport_id); > > @@ -881,10 +935,9 @@ rte_sched_pipe_config(struct rte_sched_port *port, > if (p->tb_time) { > params = port->pipe_profiles + p->profile; > > -#ifdef RTE_SCHED_SUBPORT_TC_OV > - double subport_tc3_rate = (double) s- > >tc_credits_per_period[3] > + double subport_tc3_rate = (double) s- > >tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] > / (double) s->tc_period; > - double pipe_tc3_rate = (double) params- > >tc_credits_per_period[3] > + double pipe_tc3_rate = (double) params- > >tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] > / (double) params->tc_period; > uint32_t tc3_ov = s->tc_ov; > > @@ -898,7 +951,6 @@ rte_sched_pipe_config(struct rte_sched_port *port, > "Subport %u TC3 oversubscription is OFF > (%.4lf >= %.4lf)\n", > subport_id, subport_tc3_rate, s- > >tc_ov_rate); > } > -#endif > > /* Reset the pipe */ > memset(p, 0, sizeof(struct rte_sched_pipe)); > @@ -917,15 +969,18 @@ rte_sched_pipe_config(struct rte_sched_port > *port, > > /* Traffic Classes (TCs) */ > p->tc_time = port->time + params->tc_period; > + > for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) > - p->tc_credits[i] = params->tc_credits_per_period[i]; > + if (port->qsize[i]) > + p->tc_credits[i] = params->tc_credits_per_period[i]; > > -#ifdef RTE_SCHED_SUBPORT_TC_OV > { > /* Subport TC3 oversubscription */ > - double subport_tc3_rate = (double) s- > >tc_credits_per_period[3] > + double subport_tc3_rate = > + (double) s- > >tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] > / (double) s->tc_period; > - double pipe_tc3_rate = (double) params- > >tc_credits_per_period[3] > + double pipe_tc3_rate = > + (double) params- > >tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] > / (double) params->tc_period; > uint32_t tc3_ov = s->tc_ov; > > @@ -941,7 +996,6 @@ rte_sched_pipe_config(struct rte_sched_port *port, > p->tc_ov_period_id = s->tc_ov_period_id; > p->tc_ov_credits = s->tc_ov_wm; > } > -#endif > > return 0; > } > @@ -964,12 +1018,12 @@ rte_sched_port_pipe_profile_add(struct > rte_sched_port *port, > return -2; > > /* Pipe params */ > - status = pipe_profile_check(params, port->rate); > + status = pipe_profile_check(params, port->rate, &port->qsize[0]); > if (status != 0) > return status; > > pp = &port->pipe_profiles[port->n_pipe_profiles]; > - rte_sched_pipe_profile_convert(params, pp, port->rate); > + rte_sched_pipe_profile_convert(port, params, pp, port->rate); > > /* Pipe profile not exists */ > for (i = 0; i < port->n_pipe_profiles; i++) > @@ -980,8 +1034,8 @@ rte_sched_port_pipe_profile_add(struct > rte_sched_port *port, > *pipe_profile_id = port->n_pipe_profiles; > port->n_pipe_profiles++; > > - if (port->pipe_tc3_rate_max < params->tc_rate[3]) > - port->pipe_tc3_rate_max = params->tc_rate[3]; > + if (port->pipe_tc3_rate_max < params- > >tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE]) > + port->pipe_tc3_rate_max = params- > >tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE]; > > rte_sched_port_log_pipe_profile(port, *pipe_profile_id); > > @@ -998,9 +1052,8 @@ rte_sched_port_qindex(struct rte_sched_port > *port, > return ((subport & (port->n_subports_per_port - 1)) << > (port->n_pipes_per_subport_log2 + 4)) | > ((pipe & (port->n_pipes_per_subport - 1)) << 4) | > - ((traffic_class & > - (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1)) << > 2) | > - (queue & > (RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS - 1)); > + ((port->pipe_queue[traffic_class] + queue) & > + (RTE_SCHED_QUEUES_PER_PIPE - 1)); > } > > void > @@ -1010,8 +1063,9 @@ rte_sched_port_pkt_write(struct rte_sched_port > *port, > uint32_t traffic_class, > uint32_t queue, enum rte_color color) > { > - uint32_t queue_id = rte_sched_port_qindex(port, subport, pipe, > - traffic_class, queue); > + uint32_t queue_id = > + rte_sched_port_qindex(port, subport, pipe, traffic_class, > queue); > + > rte_mbuf_sched_set(pkt, queue_id, traffic_class, (uint8_t)color); > } > > @@ -1022,12 +1076,12 @@ rte_sched_port_pkt_read_tree_path(struct > rte_sched_port *port, > uint32_t *traffic_class, uint32_t *queue) > { > uint32_t queue_id = rte_mbuf_sched_queue_get(pkt); > + uint32_t pipe_queue = queue_id & (RTE_SCHED_QUEUES_PER_PIPE > - 1); > > *subport = queue_id >> (port->n_pipes_per_subport_log2 + 4); > *pipe = (queue_id >> 4) & (port->n_pipes_per_subport - 1); > - *traffic_class = (queue_id >> 2) & > - (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - > 1); > - *queue = queue_id & (RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS - > 1); > + *traffic_class = port->pipe_tc[pipe_queue]; > + *queue = port->tc_queue[pipe_queue]; > } > > enum rte_color > @@ -1108,7 +1162,7 @@ static inline void > rte_sched_port_update_subport_stats(struct rte_sched_port *port, > uint32_t qindex, struct rte_mbuf *pkt) > { > struct rte_sched_subport *s = port->subport + (qindex / > rte_sched_port_queues_per_subport(port)); > - uint32_t tc_index = (qindex >> 2) & 0x3; > + uint32_t tc_index = port->pipe_tc[qindex & > (RTE_SCHED_QUEUES_PER_PIPE - 1)]; > uint32_t pkt_len = pkt->pkt_len; > > s->stats.n_pkts_tc[tc_index] += 1; > @@ -1128,7 +1182,7 @@ > rte_sched_port_update_subport_stats_on_drop(struct rte_sched_port > *port, > #endif > { > struct rte_sched_subport *s = port->subport + (qindex / > rte_sched_port_queues_per_subport(port)); > - uint32_t tc_index = (qindex >> 2) & 0x3; > + uint32_t tc_index = port->pipe_tc[qindex & > (RTE_SCHED_QUEUES_PER_PIPE - 1)]; > uint32_t pkt_len = pkt->pkt_len; > > s->stats.n_pkts_tc_dropped[tc_index] += 1; > @@ -1183,7 +1237,7 @@ rte_sched_port_red_drop(struct rte_sched_port > *port, struct rte_mbuf *pkt, uint3 > uint32_t tc_index; > enum rte_color color; > > - tc_index = (qindex >> 2) & 0x3; > + tc_index = port->pipe_tc[qindex & (RTE_SCHED_QUEUES_PER_PIPE > - 1)]; > color = rte_sched_port_pkt_read_color(pkt); > red_cfg = &port->red_config[tc_index][color]; > > @@ -1500,6 +1554,7 @@ grinder_credits_update(struct rte_sched_port > *port, uint32_t pos) > struct rte_sched_pipe *pipe = grinder->pipe; > struct rte_sched_pipe_profile *params = grinder->pipe_params; > uint64_t n_periods; > + uint32_t i; > > /* Subport TB */ > n_periods = (port->time - subport->tb_time) / subport->tb_period; > @@ -1515,19 +1570,17 @@ grinder_credits_update(struct rte_sched_port > *port, uint32_t pos) > > /* Subport TCs */ > 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]; > + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) > + subport->tc_credits[i] = subport- > >tc_credits_per_period[i]; > + > subport->tc_time = port->time + subport->tc_period; > } > > /* Pipe TCs */ > if (unlikely(port->time >= pipe->tc_time)) { > - pipe->tc_credits[0] = params->tc_credits_per_period[0]; > - pipe->tc_credits[1] = params->tc_credits_per_period[1]; > - pipe->tc_credits[2] = params->tc_credits_per_period[2]; > - pipe->tc_credits[3] = params->tc_credits_per_period[3]; > + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) > + pipe->tc_credits[i] = params- > >tc_credits_per_period[i]; > + > pipe->tc_time = port->time + params->tc_period; > } > } > @@ -1540,21 +1593,29 @@ 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_consumption = 0, tc_ov_consumption_max; > uint32_t tc_ov_wm = subport->tc_ov_wm; > + uint32_t i; > > 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]; > + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASS_BE; i++) { > + tc_ov_consumption[i] = > + subport->tc_credits_per_period[i] - subport- > >tc_credits[i]; > + tc_consumption += tc_ov_consumption[i]; > + } > + > + tc_ov_consumption[RTE_SCHED_TRAFFIC_CLASS_BE] = > + subport- > >tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] - > + subport->tc_credits[RTE_SCHED_TRAFFIC_CLASS_BE]; > > - 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_consumption_max = > + subport- > >tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] - tc_consumption; > + > + if (tc_ov_consumption[RTE_SCHED_TRAFFIC_CLASS_BE] > > + (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; > @@ -1577,6 +1638,7 @@ grinder_credits_update(struct rte_sched_port > *port, uint32_t pos) > struct rte_sched_pipe *pipe = grinder->pipe; > struct rte_sched_pipe_profile *params = grinder->pipe_params; > uint64_t n_periods; > + uint32_t i; > > /* Subport TB */ > n_periods = (port->time - subport->tb_time) / subport->tb_period; > @@ -1594,10 +1656,8 @@ grinder_credits_update(struct rte_sched_port > *port, uint32_t pos) > 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]; > + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) > + subport->tc_credits[i] = subport- > >tc_credits_per_period[i]; > > subport->tc_time = port->time + subport->tc_period; > subport->tc_ov_period_id++; > @@ -1605,10 +1665,8 @@ grinder_credits_update(struct rte_sched_port > *port, uint32_t pos) > > /* Pipe TCs */ > if (unlikely(port->time >= pipe->tc_time)) { > - pipe->tc_credits[0] = params->tc_credits_per_period[0]; > - pipe->tc_credits[1] = params->tc_credits_per_period[1]; > - pipe->tc_credits[2] = params->tc_credits_per_period[2]; > - pipe->tc_credits[3] = params->tc_credits_per_period[3]; > + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) > + pipe->tc_credits[i] = params- > >tc_credits_per_period[i]; > pipe->tc_time = port->time + params->tc_period; > } > > @@ -1673,11 +1731,18 @@ 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_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]; > + uint32_t > pipe_tc_ov_mask1[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; > + uint32_t > pipe_tc_ov_mask2[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE] = {0}; > + uint32_t pipe_tc_ov_credits, i; > int enough_credits; > > + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) > + pipe_tc_ov_mask1[i] = UINT32_MAX; > + > + pipe_tc_ov_mask1[RTE_SCHED_TRAFFIC_CLASS_BE] = pipe- > >tc_ov_credits; > + pipe_tc_ov_mask2[RTE_SCHED_TRAFFIC_CLASS_BE] = > UINT32_MAX; > + pipe_tc_ov_credits = pipe_tc_ov_mask1[tc_index]; > + > /* Check pipe and subport credits */ > enough_credits = (pkt_len <= subport_tb_credits) && > (pkt_len <= subport_tc_credits) && > @@ -1832,31 +1897,23 @@ static inline void > grinder_tccache_populate(struct rte_sched_port *port, uint32_t pos, > uint32_t qindex, uint16_t qmask) > { > struct rte_sched_grinder *grinder = port->grinder + pos; > - uint8_t b[4]; > + uint8_t b, i; > > grinder->tccache_w = 0; > grinder->tccache_r = 0; > > - b[0] = (uint8_t) (qmask & 0xF); > - b[1] = (uint8_t) ((qmask >> 4) & 0xF); > - b[2] = (uint8_t) ((qmask >> 8) & 0xF); > - b[3] = (uint8_t) ((qmask >> 12) & 0xF); > - > - grinder->tccache_qmask[grinder->tccache_w] = b[0]; > - grinder->tccache_qindex[grinder->tccache_w] = qindex; > - grinder->tccache_w += (b[0] != 0); > - > - grinder->tccache_qmask[grinder->tccache_w] = b[1]; > - grinder->tccache_qindex[grinder->tccache_w] = qindex + 4; > - grinder->tccache_w += (b[1] != 0); > - > - grinder->tccache_qmask[grinder->tccache_w] = b[2]; > - grinder->tccache_qindex[grinder->tccache_w] = qindex + 8; > - grinder->tccache_w += (b[2] != 0); > + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASS_BE; i++) { > + b = (uint8_t) ((qmask >> i) & 0x1); > + grinder->tccache_qmask[grinder->tccache_w] = b; > + grinder->tccache_qindex[grinder->tccache_w] = qindex + i; > + grinder->tccache_w += (b != 0); > + } > > - grinder->tccache_qmask[grinder->tccache_w] = b[3]; > - grinder->tccache_qindex[grinder->tccache_w] = qindex + 12; > - grinder->tccache_w += (b[3] != 0); > + b = (uint8_t) (qmask >> (RTE_SCHED_TRAFFIC_CLASS_BE)); > + grinder->tccache_qmask[grinder->tccache_w] = b; > + grinder->tccache_qindex[grinder->tccache_w] = qindex + > + RTE_SCHED_TRAFFIC_CLASS_BE; > + grinder->tccache_w += (b != 0); > } > > static inline int > @@ -1874,14 +1931,18 @@ grinder_next_tc(struct rte_sched_port *port, > uint32_t pos) > qbase = rte_sched_port_qbase(port, qindex); > qsize = rte_sched_port_qsize(port, qindex); > > - grinder->tc_index = (qindex >> 2) & 0x3; > + grinder->tc_index = port->pipe_tc[qindex & > (RTE_SCHED_QUEUES_PER_PIPE - 1)]; > grinder->qmask = grinder->tccache_qmask[grinder->tccache_r]; > grinder->qsize = qsize; > > - grinder->qindex[0] = qindex; > - grinder->qindex[1] = qindex + 1; > - grinder->qindex[2] = qindex + 2; > - grinder->qindex[3] = qindex + 3; > + if (grinder->tc_index < RTE_SCHED_TRAFFIC_CLASS_BE) { > + grinder->queue[0] = port->queue + qindex; > + grinder->qbase[0] = qbase; > + grinder->qindex[0] = qindex; > + grinder->tccache_r++; > + > + return 1; > + } > > grinder->queue[0] = port->queue + qindex; > grinder->queue[1] = port->queue + qindex + 1; > @@ -1893,6 +1954,11 @@ grinder_next_tc(struct rte_sched_port *port, > uint32_t pos) > grinder->qbase[2] = qbase + 2 * qsize; > grinder->qbase[3] = qbase + 3 * qsize; > > + grinder->qindex[0] = qindex; > + grinder->qindex[1] = qindex + 1; > + grinder->qindex[2] = qindex + 2; > + grinder->qindex[3] = qindex + 3; > + > grinder->tccache_r++; > return 1; > } > diff --git a/lib/librte_sched/rte_sched.h b/lib/librte_sched/rte_sched.h > index f9947c4cd..2b55c97ab 100644 > --- a/lib/librte_sched/rte_sched.h > +++ b/lib/librte_sched/rte_sched.h > @@ -85,7 +85,9 @@ extern "C" { > /** Number of traffic classes per pipe (as well as subport). > * Cannot be changed. > */ > -#define RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE 4 > +#define RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE \ > +(RTE_SCHED_QUEUES_PER_PIPE - RTE_SCHED_BE_QUEUES_PER_PIPE + 1) > + > > /** Number of queues per pipe traffic class. Cannot be changed. */ > #define RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS 4 > @@ -172,9 +174,7 @@ struct rte_sched_pipe_params { > /**< Traffic class rates (measured in bytes per second) */ > uint32_t tc_period; > /**< Enforcement period (measured in milliseconds) */ > -#ifdef RTE_SCHED_SUBPORT_TC_OV > uint8_t tc_ov_weight; /**< Weight Traffic class 3 > oversubscription */ > -#endif > > /* Pipe queues */ > uint8_t wrr_weights[RTE_SCHED_BE_QUEUES_PER_PIPE]; /**< > WRR weights */ > -- > 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* Re: [dpdk-dev] [PATCH v5 02/11] sched: add config flexibility to tc queue sizes 2019-07-18 23:04 ` Dumitrescu, Cristian @ 2019-07-19 15:25 ` Singh, Jasvinder 0 siblings, 0 replies; 163+ messages in thread From: Singh, Jasvinder @ 2019-07-19 15:25 UTC (permalink / raw) To: Dumitrescu, Cristian, dev; +Cc: Tovar, AbrahamX, Krakowiak, LukaszX <snip> > > diff --git a/lib/librte_sched/rte_sched.c > > b/lib/librte_sched/rte_sched.c index f7c218ef0..3d3d4c69f 100644 > > --- a/lib/librte_sched/rte_sched.c > > +++ b/lib/librte_sched/rte_sched.c > > @@ -146,15 +146,15 @@ struct rte_sched_grinder { > > struct rte_sched_pipe_profile *pipe_params; > > > > /* TC cache */ > > - uint8_t tccache_qmask[4]; > > - uint32_t tccache_qindex[4]; > > + uint8_t tccache_qmask[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; > > + uint32_t tccache_qindex[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; > > uint32_t tccache_w; > > uint32_t tccache_r; > > > > /* Current TC */ > > uint32_t tc_index; > > - struct rte_sched_queue > > *queue[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; > > - struct rte_mbuf **qbase[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; > > + struct rte_sched_queue > > *queue[RTE_SCHED_MAX_QUEUES_PER_TC]; > > + struct rte_mbuf **qbase[RTE_SCHED_MAX_QUEUES_PER_TC]; > > uint32_t qindex[RTE_SCHED_MAX_QUEUES_PER_TC]; > > uint16_t qsize; > > uint32_t qmask; > > @@ -172,6 +172,9 @@ struct rte_sched_port { > > uint32_t n_subports_per_port; > > uint32_t n_pipes_per_subport; > > uint32_t n_pipes_per_subport_log2; > > + 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]; > > I suggest we create simple functions to access the above 3 data structures as > opposed to access them directly, similar to the rte_sched_port_qsize() function > (and maybe place them just below this function). Suggested changes are made in v6.. > > > uint32_t rate; > > uint32_t mtu; > > uint32_t frame_overhead; > > @@ -257,14 +260,14 @@ rte_sched_port_qbase(struct rte_sched_port > > *port, uint32_t qindex) static inline uint16_t > > rte_sched_port_qsize(struct rte_sched_port *port, uint32_t qindex) { > > - uint32_t tc = (qindex >> 2) & 0x3; > > + uint32_t tc = port->pipe_tc[qindex & > > (RTE_SCHED_QUEUES_PER_PIPE - 1)]; > > > > return port->qsize[tc]; > > } > > > > static int > > pipe_profile_check(struct rte_sched_pipe_params *params, > > - uint32_t rate) > > + uint32_t rate, uint16_t *qsize) > > { > > uint32_t i; > > > > @@ -281,25 +284,27 @@ pipe_profile_check(struct rte_sched_pipe_params > > *params, > > if (params->tb_size == 0) > > return -12; > > > > - /* TC rate: non-zero, less than pipe rate */ > > + /* TC rate: non-zero if qsize non-zero, less than pipe rate */ > > for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { > > - if (params->tc_rate[i] == 0 || > > - params->tc_rate[i] > params->tb_rate) > > + if ((qsize[i] == 0 && params->tc_rate[i] != 0) || > > + (qsize[i] != 0 && (params->tc_rate[i] == 0 || > > + params->tc_rate[i] > params->tb_rate))) > > return -13; > > } > > + if (params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE] == 0 || > > + qsize[RTE_SCHED_TRAFFIC_CLASS_BE] == 0) > > + return -13; > > > > /* TC period: non-zero */ > > if (params->tc_period == 0) > > return -14; > > > > -#ifdef RTE_SCHED_SUBPORT_TC_OV > > /* TC3 oversubscription weight: non-zero */ > > if (params->tc_ov_weight == 0) > > return -15; > > -#endif > > > > /* Queue WRR weights: non-zero */ > > - for (i = 0; i < RTE_SCHED_QUEUES_PER_PIPE; i++) { > > + for (i = 0; i < RTE_SCHED_BE_QUEUES_PER_PIPE; i++) { > > if (params->wrr_weights[i] == 0) > > return -16; > > } > > @@ -344,7 +349,8 @@ rte_sched_port_check_params(struct > > rte_sched_port_params *params) > > for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { > > uint16_t qsize = params->qsize[i]; > > > > - if (qsize == 0 || !rte_is_power_of_2(qsize)) > > + if ((qsize != 0 && !rte_is_power_of_2(qsize)) || > > + ((i == RTE_SCHED_TRAFFIC_CLASS_BE) && (qsize == > > 0))) > > return -8; > > } > > > > @@ -358,7 +364,7 @@ rte_sched_port_check_params(struct > > rte_sched_port_params *params) > > struct rte_sched_pipe_params *p = params->pipe_profiles + i; > > int status; > > > > - status = pipe_profile_check(p, params->rate); > > + status = pipe_profile_check(p, params->rate, ¶ms- > > >qsize[0]); > > if (status != 0) > > return status; > > } > > @@ -388,8 +394,12 @@ rte_sched_port_get_array_base(struct > > rte_sched_port_params *params, enum rte_sch > > > > size_per_pipe_queue_array = 0; > > for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { > > - size_per_pipe_queue_array += > > RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS > > - * params->qsize[i] * sizeof(struct rte_mbuf *); > > + if (i < RTE_SCHED_TRAFFIC_CLASS_BE) > > + size_per_pipe_queue_array += > > + params->qsize[i] * sizeof(struct rte_mbuf *); > > + else > > + size_per_pipe_queue_array += > > RTE_SCHED_MAX_QUEUES_PER_TC * > > + params->qsize[i] * sizeof(struct rte_mbuf *); > > } > > size_queue_array = n_pipes_per_port * size_per_pipe_queue_array; > > > > @@ -449,31 +459,27 @@ rte_sched_port_get_memory_footprint(struct > > rte_sched_port_params *params) > > static void > > rte_sched_port_config_qsize(struct rte_sched_port *port) { > > - /* TC 0 */ > > + uint32_t i; > > + > > port->qsize_add[0] = 0; > > - port->qsize_add[1] = port->qsize_add[0] + port->qsize[0]; > > - port->qsize_add[2] = port->qsize_add[1] + port->qsize[0]; > > - port->qsize_add[3] = port->qsize_add[2] + port->qsize[0]; > > - > > - /* TC 1 */ > > - port->qsize_add[4] = port->qsize_add[3] + port->qsize[0]; > > - port->qsize_add[5] = port->qsize_add[4] + port->qsize[1]; > > - port->qsize_add[6] = port->qsize_add[5] + port->qsize[1]; > > - port->qsize_add[7] = port->qsize_add[6] + port->qsize[1]; > > - > > - /* TC 2 */ > > - port->qsize_add[8] = port->qsize_add[7] + port->qsize[1]; > > - port->qsize_add[9] = port->qsize_add[8] + port->qsize[2]; > > - port->qsize_add[10] = port->qsize_add[9] + port->qsize[2]; > > - port->qsize_add[11] = port->qsize_add[10] + port->qsize[2]; > > - > > - /* TC 3 */ > > - port->qsize_add[12] = port->qsize_add[11] + port->qsize[2]; > > - port->qsize_add[13] = port->qsize_add[12] + port->qsize[3]; > > - port->qsize_add[14] = port->qsize_add[13] + port->qsize[3]; > > - port->qsize_add[15] = port->qsize_add[14] + port->qsize[3]; > > - > > - port->qsize_sum = port->qsize_add[15] + port->qsize[3]; > > + > > + /* Strict prority traffic class */ > > + for (i = 1; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) > > + port->qsize_add[i] = port->qsize_add[i-1] + port->qsize[i-1]; > > + > > + /* Best-effort traffic class */ > > + port->qsize_add[RTE_SCHED_TRAFFIC_CLASS_BE + 1] = > > + port->qsize_add[RTE_SCHED_TRAFFIC_CLASS_BE] + > > + port->qsize[RTE_SCHED_TRAFFIC_CLASS_BE]; > > + port->qsize_add[RTE_SCHED_TRAFFIC_CLASS_BE + 2] = > > + port->qsize_add[RTE_SCHED_TRAFFIC_CLASS_BE + 1] + > > + port->qsize[RTE_SCHED_TRAFFIC_CLASS_BE]; > > + port->qsize_add[RTE_SCHED_TRAFFIC_CLASS_BE + 3] = > > + port->qsize_add[RTE_SCHED_TRAFFIC_CLASS_BE + 2] + > > + port->qsize[RTE_SCHED_TRAFFIC_CLASS_BE]; > > + > > + port->qsize_sum = port->qsize_add[RTE_SCHED_TRAFFIC_CLASS_BE > > + 3] + > > + port->qsize[RTE_SCHED_TRAFFIC_CLASS_BE]; > > } > > > > static void > > @@ -482,10 +488,11 @@ rte_sched_port_log_pipe_profile(struct > > rte_sched_port *port, uint32_t i) > > struct rte_sched_pipe_profile *p = port->pipe_profiles + i; > > > > RTE_LOG(DEBUG, SCHED, "Low level config for pipe profile %u:\n" > > - " Token bucket: period = %u, credits per period = %u, size = > > %u\n" > > - " Traffic classes: period = %u, credits per period = [%u, %u, > > %u, %u]\n" > > - " Traffic class 3 oversubscription: weight = %hhu\n" > > - " WRR cost: [%hhu, %hhu, %hhu, %hhu]\n", > > + " Token bucket: period = %u, credits per period = %u, > > size = %u\n" > > + " Traffic classes: period = %u,\n" > > + " credits per period = [%u, %u, %u, %u, %u, %u, %u, > > %u, %u, %u, %u, %u, %u]\n" > > + " Best-effort traffic class oversubscription: weight = > > %hhu\n" > > + " WRR cost: [%hhu, %hhu, %hhu, %hhu]\n", > > i, > > > > /* Token bucket */ > > @@ -499,6 +506,15 @@ 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_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], > > > > /* Traffic class 3 oversubscription */ > > p->tc_ov_weight, > > @@ -518,7 +534,8 @@ rte_sched_time_ms_to_bytes(uint32_t time_ms, > > uint32_t rate) } > > > > static void > > -rte_sched_pipe_profile_convert(struct rte_sched_pipe_params *src, > > +rte_sched_pipe_profile_convert(struct rte_sched_port *port, > > + struct rte_sched_pipe_params *src, > > struct rte_sched_pipe_profile *dst, > > uint32_t rate) > > { > > @@ -546,13 +563,12 @@ rte_sched_pipe_profile_convert(struct > > rte_sched_pipe_params *src, > > 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]); > > + if (port->qsize[i]) > > + dst->tc_credits_per_period[i] > > + = rte_sched_time_ms_to_bytes(src- > > >tc_period, > > + src->tc_rate[i]); > > > > -#ifdef RTE_SCHED_SUBPORT_TC_OV > > dst->tc_ov_weight = src->tc_ov_weight; -#endif > > > > /* WRR queues */ > > wrr_cost[0] = src->wrr_weights[0]; > > @@ -585,14 +601,14 @@ rte_sched_port_config_pipe_profile_table(struct > > rte_sched_port *port, > > struct rte_sched_pipe_params *src = params->pipe_profiles > > + i; > > struct rte_sched_pipe_profile *dst = port->pipe_profiles + i; > > > > - rte_sched_pipe_profile_convert(src, dst, params->rate); > > + rte_sched_pipe_profile_convert(port, src, dst, params- > > >rate); > > 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]; > > + uint32_t pipe_tc3_rate = src- > > >tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE]; > > > > if (port->pipe_tc3_rate_max < pipe_tc3_rate) > > port->pipe_tc3_rate_max = pipe_tc3_rate; @@ -603,7 > +619,7 @@ > > struct rte_sched_port * rte_sched_port_config(struct > > rte_sched_port_params *params) { > > struct rte_sched_port *port = NULL; > > - uint32_t mem_size, bmp_mem_size, n_queues_per_port, i, > > cycles_per_byte; > > + uint32_t mem_size, bmp_mem_size, n_queues_per_port, i, j, > > cycles_per_byte; > > > > /* Check user parameters. Determine the amount of memory to > allocate > > */ > > mem_size = rte_sched_port_get_memory_footprint(params); > > @@ -625,6 +641,23 @@ rte_sched_port_config(struct > > rte_sched_port_params *params) > > port->n_pipes_per_subport = params->n_pipes_per_subport; > > port->n_pipes_per_subport_log2 = > > __builtin_ctz(params->n_pipes_per_subport); > > + > > + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) > > + port->pipe_queue[i] = i; > > + > > + for (i = 0, j = 0; i < RTE_SCHED_QUEUES_PER_PIPE; i++) { > > + port->pipe_tc[i] = j; > > + > > + if (j < RTE_SCHED_TRAFFIC_CLASS_BE) > > + j++; > > + } > > + > > + for (i = 0, j = 0; i < RTE_SCHED_QUEUES_PER_PIPE; i++) { > > + port->tc_queue[i] = j; > > + > > + if (i >= RTE_SCHED_TRAFFIC_CLASS_BE) > > + j++; > > + } > > port->rate = params->rate; > > port->mtu = params->mtu + params->frame_overhead; > > port->frame_overhead = params->frame_overhead; @@ -734,12 > +767,14 @@ > > rte_sched_port_free(struct rte_sched_port *port) > > for (qindex = 0; qindex < n_queues_per_port; qindex++) { > > struct rte_mbuf **mbufs = rte_sched_port_qbase(port, > qindex); > > uint16_t qsize = rte_sched_port_qsize(port, qindex); > > - struct rte_sched_queue *queue = port->queue + qindex; > > - uint16_t qr = queue->qr & (qsize - 1); > > - uint16_t qw = queue->qw & (qsize - 1); > > + if (qsize != 0) { > > + struct rte_sched_queue *queue = port->queue + > > qindex; > > + uint16_t qr = queue->qr & (qsize - 1); > > + uint16_t qw = queue->qw & (qsize - 1); > > > > - for (; qr != qw; qr = (qr + 1) & (qsize - 1)) > > - rte_pktmbuf_free(mbufs[qr]); > > + for (; qr != qw; qr = (qr + 1) & (qsize - 1)) > > + rte_pktmbuf_free(mbufs[qr]); > > + } > > } > > > > rte_bitmap_free(port->bmp); > > @@ -752,9 +787,10 @@ rte_sched_port_log_subport_config(struct > > rte_sched_port *port, uint32_t i) > > struct rte_sched_subport *s = port->subport + i; > > > > RTE_LOG(DEBUG, SCHED, "Low level config for subport %u:\n" > > - " Token bucket: period = %u, credits per period = %u, size = > > %u\n" > > - " Traffic classes: period = %u, credits per period = [%u, %u, > > %u, %u]\n" > > - " Traffic class 3 oversubscription: wm min = %u, wm max = > > %u\n", > > + " Token bucket: period = %u, credits per period = %u, > > size = %u\n" > > + " Traffic classes: period = %u\n" > > + " credits per period = [%u, %u, %u, %u, %u, %u, %u, > > %u, %u, %u, %u, %u, %u]\n" > > + " Best effort traffic class oversubscription: wm min = > > %u, wm max = %u\n", > > i, > > > > /* Token bucket */ > > @@ -768,6 +804,15 @@ 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_credits_per_period[4], > > + s->tc_credits_per_period[5], > > + s->tc_credits_per_period[6], > > + s->tc_credits_per_period[7], > > + s->tc_credits_per_period[8], > > + s->tc_credits_per_period[9], > > + s->tc_credits_per_period[10], > > + s->tc_credits_per_period[11], > > + s->tc_credits_per_period[12], > > > > /* Traffic class 3 oversubscription */ > > s->tc_ov_wm_min, > > @@ -795,11 +840,19 @@ rte_sched_subport_config(struct rte_sched_port > > *port, > > return -3; > > > > for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { > > - if (params->tc_rate[i] == 0 || > > - params->tc_rate[i] > params->tb_rate) > > + uint32_t tc_rate = params->tc_rate[i]; > > + uint16_t qsize = port->qsize[i]; > > + > > + if ((qsize == 0 && tc_rate != 0) || > > + (qsize != 0 && tc_rate == 0) || > > + (tc_rate > params->tb_rate)) > > return -4; > > } > > > > + if (port->qsize[RTE_SCHED_TRAFFIC_CLASS_BE] == 0 || > > + params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE] == 0) > > + return -4; > > + > > if (params->tc_period == 0) > > return -5; > > > > @@ -823,15 +876,17 @@ rte_sched_subport_config(struct rte_sched_port > > *port, > > /* Traffic Classes (TCs) */ > > s->tc_period = rte_sched_time_ms_to_bytes(params->tc_period, > > port->rate); > > for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { > > - s->tc_credits_per_period[i] > > - = rte_sched_time_ms_to_bytes(params->tc_period, > > - params->tc_rate[i]); > > + if (port->qsize[i]) > > + s->tc_credits_per_period[i] > > + = rte_sched_time_ms_to_bytes(params- > > >tc_period, > > + params- > > >tc_rate[i]); > > + > > } > > s->tc_time = port->time + s->tc_period; > > for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) > > - s->tc_credits[i] = s->tc_credits_per_period[i]; > > + if (port->qsize[i]) > > + s->tc_credits[i] = s->tc_credits_per_period[i]; > > > > -#ifdef RTE_SCHED_SUBPORT_TC_OV > > /* TC oversubscription */ > > s->tc_ov_wm_min = port->mtu; > > s->tc_ov_wm_max = rte_sched_time_ms_to_bytes(params- > > >tc_period, > > @@ -841,7 +896,6 @@ rte_sched_subport_config(struct rte_sched_port > > *port, > > s->tc_ov = 0; > > s->tc_ov_n = 0; > > s->tc_ov_rate = 0; > > -#endif > > > > rte_sched_port_log_subport_config(port, subport_id); > > > > @@ -881,10 +935,9 @@ rte_sched_pipe_config(struct rte_sched_port *port, > > if (p->tb_time) { > > params = port->pipe_profiles + p->profile; > > > > -#ifdef RTE_SCHED_SUBPORT_TC_OV > > - double subport_tc3_rate = (double) s- > > >tc_credits_per_period[3] > > + double subport_tc3_rate = (double) s- > > >tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] > > / (double) s->tc_period; > > - double pipe_tc3_rate = (double) params- > > >tc_credits_per_period[3] > > + double pipe_tc3_rate = (double) params- > > >tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] > > / (double) params->tc_period; > > uint32_t tc3_ov = s->tc_ov; > > > > @@ -898,7 +951,6 @@ rte_sched_pipe_config(struct rte_sched_port *port, > > "Subport %u TC3 oversubscription is OFF (%.4lf > >= %.4lf)\n", > > subport_id, subport_tc3_rate, s- > > >tc_ov_rate); > > } > > -#endif > > > > /* Reset the pipe */ > > memset(p, 0, sizeof(struct rte_sched_pipe)); @@ -917,15 > +969,18 @@ > > rte_sched_pipe_config(struct rte_sched_port *port, > > > > /* Traffic Classes (TCs) */ > > p->tc_time = port->time + params->tc_period; > > + > > for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) > > - p->tc_credits[i] = params->tc_credits_per_period[i]; > > + if (port->qsize[i]) > > + p->tc_credits[i] = params->tc_credits_per_period[i]; > > > > -#ifdef RTE_SCHED_SUBPORT_TC_OV > > { > > /* Subport TC3 oversubscription */ > > - double subport_tc3_rate = (double) s- > > >tc_credits_per_period[3] > > + double subport_tc3_rate = > > + (double) s- > > >tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] > > / (double) s->tc_period; > > - double pipe_tc3_rate = (double) params- > > >tc_credits_per_period[3] > > + double pipe_tc3_rate = > > + (double) params- > > >tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] > > / (double) params->tc_period; > > uint32_t tc3_ov = s->tc_ov; > > > > @@ -941,7 +996,6 @@ rte_sched_pipe_config(struct rte_sched_port *port, > > p->tc_ov_period_id = s->tc_ov_period_id; > > p->tc_ov_credits = s->tc_ov_wm; > > } > > -#endif > > > > return 0; > > } > > @@ -964,12 +1018,12 @@ rte_sched_port_pipe_profile_add(struct > > rte_sched_port *port, > > return -2; > > > > /* Pipe params */ > > - status = pipe_profile_check(params, port->rate); > > + status = pipe_profile_check(params, port->rate, &port->qsize[0]); > > if (status != 0) > > return status; > > > > pp = &port->pipe_profiles[port->n_pipe_profiles]; > > - rte_sched_pipe_profile_convert(params, pp, port->rate); > > + rte_sched_pipe_profile_convert(port, params, pp, port->rate); > > > > /* Pipe profile not exists */ > > for (i = 0; i < port->n_pipe_profiles; i++) @@ -980,8 +1034,8 @@ > > rte_sched_port_pipe_profile_add(struct > > rte_sched_port *port, > > *pipe_profile_id = port->n_pipe_profiles; > > port->n_pipe_profiles++; > > > > - if (port->pipe_tc3_rate_max < params->tc_rate[3]) > > - port->pipe_tc3_rate_max = params->tc_rate[3]; > > + if (port->pipe_tc3_rate_max < params- > > >tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE]) > > + port->pipe_tc3_rate_max = params- > > >tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE]; > > > > rte_sched_port_log_pipe_profile(port, *pipe_profile_id); > > > > @@ -998,9 +1052,8 @@ rte_sched_port_qindex(struct rte_sched_port > > *port, > > return ((subport & (port->n_subports_per_port - 1)) << > > (port->n_pipes_per_subport_log2 + 4)) | > > ((pipe & (port->n_pipes_per_subport - 1)) << 4) | > > - ((traffic_class & > > - (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1)) << > > 2) | > > - (queue & > > (RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS - 1)); > > + ((port->pipe_queue[traffic_class] + queue) & > > + (RTE_SCHED_QUEUES_PER_PIPE - 1)); > > } > > > > void > > @@ -1010,8 +1063,9 @@ rte_sched_port_pkt_write(struct rte_sched_port > > *port, > > uint32_t traffic_class, > > uint32_t queue, enum rte_color color) { > > - uint32_t queue_id = rte_sched_port_qindex(port, subport, pipe, > > - traffic_class, queue); > > + uint32_t queue_id = > > + rte_sched_port_qindex(port, subport, pipe, traffic_class, > > queue); > > + > > rte_mbuf_sched_set(pkt, queue_id, traffic_class, (uint8_t)color); } > > > > @@ -1022,12 +1076,12 @@ rte_sched_port_pkt_read_tree_path(struct > > rte_sched_port *port, > > uint32_t *traffic_class, uint32_t *queue) { > > uint32_t queue_id = rte_mbuf_sched_queue_get(pkt); > > + uint32_t pipe_queue = queue_id & (RTE_SCHED_QUEUES_PER_PIPE > > - 1); > > > > *subport = queue_id >> (port->n_pipes_per_subport_log2 + 4); > > *pipe = (queue_id >> 4) & (port->n_pipes_per_subport - 1); > > - *traffic_class = (queue_id >> 2) & > > - (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - > > 1); > > - *queue = queue_id & (RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS - > > 1); > > + *traffic_class = port->pipe_tc[pipe_queue]; > > + *queue = port->tc_queue[pipe_queue]; > > } > > > > enum rte_color > > @@ -1108,7 +1162,7 @@ static inline void > > rte_sched_port_update_subport_stats(struct rte_sched_port *port, > > uint32_t qindex, struct rte_mbuf *pkt) { > > struct rte_sched_subport *s = port->subport + (qindex / > > rte_sched_port_queues_per_subport(port)); > > - uint32_t tc_index = (qindex >> 2) & 0x3; > > + uint32_t tc_index = port->pipe_tc[qindex & > > (RTE_SCHED_QUEUES_PER_PIPE - 1)]; > > uint32_t pkt_len = pkt->pkt_len; > > > > s->stats.n_pkts_tc[tc_index] += 1; > > @@ -1128,7 +1182,7 @@ > > rte_sched_port_update_subport_stats_on_drop(struct rte_sched_port > > *port, #endif { > > struct rte_sched_subport *s = port->subport + (qindex / > > rte_sched_port_queues_per_subport(port)); > > - uint32_t tc_index = (qindex >> 2) & 0x3; > > + uint32_t tc_index = port->pipe_tc[qindex & > > (RTE_SCHED_QUEUES_PER_PIPE - 1)]; > > uint32_t pkt_len = pkt->pkt_len; > > > > s->stats.n_pkts_tc_dropped[tc_index] += 1; @@ -1183,7 +1237,7 @@ > > rte_sched_port_red_drop(struct rte_sched_port *port, struct rte_mbuf > > *pkt, uint3 > > uint32_t tc_index; > > enum rte_color color; > > > > - tc_index = (qindex >> 2) & 0x3; > > + tc_index = port->pipe_tc[qindex & (RTE_SCHED_QUEUES_PER_PIPE > > - 1)]; > > color = rte_sched_port_pkt_read_color(pkt); > > red_cfg = &port->red_config[tc_index][color]; > > > > @@ -1500,6 +1554,7 @@ grinder_credits_update(struct rte_sched_port > > *port, uint32_t pos) > > struct rte_sched_pipe *pipe = grinder->pipe; > > struct rte_sched_pipe_profile *params = grinder->pipe_params; > > uint64_t n_periods; > > + uint32_t i; > > > > /* Subport TB */ > > n_periods = (port->time - subport->tb_time) / subport->tb_period; @@ > > -1515,19 +1570,17 @@ grinder_credits_update(struct rte_sched_port > > *port, uint32_t pos) > > > > /* Subport TCs */ > > 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]; > > + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) > > + subport->tc_credits[i] = subport- > > >tc_credits_per_period[i]; > > + > > subport->tc_time = port->time + subport->tc_period; > > } > > > > /* Pipe TCs */ > > if (unlikely(port->time >= pipe->tc_time)) { > > - pipe->tc_credits[0] = params->tc_credits_per_period[0]; > > - pipe->tc_credits[1] = params->tc_credits_per_period[1]; > > - pipe->tc_credits[2] = params->tc_credits_per_period[2]; > > - pipe->tc_credits[3] = params->tc_credits_per_period[3]; > > + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) > > + pipe->tc_credits[i] = params- > > >tc_credits_per_period[i]; > > + > > pipe->tc_time = port->time + params->tc_period; > > } > > } > > @@ -1540,21 +1593,29 @@ 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_consumption = 0, tc_ov_consumption_max; > > uint32_t tc_ov_wm = subport->tc_ov_wm; > > + uint32_t i; > > > > 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]; > > + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASS_BE; i++) { > > + tc_ov_consumption[i] = > > + subport->tc_credits_per_period[i] - subport- > > >tc_credits[i]; > > + tc_consumption += tc_ov_consumption[i]; > > + } > > + > > + tc_ov_consumption[RTE_SCHED_TRAFFIC_CLASS_BE] = > > + subport- > > >tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] - > > + subport->tc_credits[RTE_SCHED_TRAFFIC_CLASS_BE]; > > > > - 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_consumption_max = > > + subport- > > >tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] - tc_consumption; > > + > > + if (tc_ov_consumption[RTE_SCHED_TRAFFIC_CLASS_BE] > > > + (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; > > @@ -1577,6 +1638,7 @@ grinder_credits_update(struct rte_sched_port > > *port, uint32_t pos) > > struct rte_sched_pipe *pipe = grinder->pipe; > > struct rte_sched_pipe_profile *params = grinder->pipe_params; > > uint64_t n_periods; > > + uint32_t i; > > > > /* Subport TB */ > > n_periods = (port->time - subport->tb_time) / subport->tb_period; @@ > > -1594,10 +1656,8 @@ grinder_credits_update(struct rte_sched_port > > *port, uint32_t pos) > > 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]; > > + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) > > + subport->tc_credits[i] = subport- > > >tc_credits_per_period[i]; > > > > subport->tc_time = port->time + subport->tc_period; > > subport->tc_ov_period_id++; > > @@ -1605,10 +1665,8 @@ grinder_credits_update(struct rte_sched_port > > *port, uint32_t pos) > > > > /* Pipe TCs */ > > if (unlikely(port->time >= pipe->tc_time)) { > > - pipe->tc_credits[0] = params->tc_credits_per_period[0]; > > - pipe->tc_credits[1] = params->tc_credits_per_period[1]; > > - pipe->tc_credits[2] = params->tc_credits_per_period[2]; > > - pipe->tc_credits[3] = params->tc_credits_per_period[3]; > > + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) > > + pipe->tc_credits[i] = params- > > >tc_credits_per_period[i]; > > pipe->tc_time = port->time + params->tc_period; > > } > > > > @@ -1673,11 +1731,18 @@ 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_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]; > > + uint32_t > > pipe_tc_ov_mask1[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; > > + uint32_t > > pipe_tc_ov_mask2[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE] = {0}; > > + uint32_t pipe_tc_ov_credits, i; > > int enough_credits; > > > > + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) > > + pipe_tc_ov_mask1[i] = UINT32_MAX; > > + > > + pipe_tc_ov_mask1[RTE_SCHED_TRAFFIC_CLASS_BE] = pipe- > > >tc_ov_credits; > > + pipe_tc_ov_mask2[RTE_SCHED_TRAFFIC_CLASS_BE] = > > UINT32_MAX; > > + pipe_tc_ov_credits = pipe_tc_ov_mask1[tc_index]; > > + > > /* Check pipe and subport credits */ > > enough_credits = (pkt_len <= subport_tb_credits) && > > (pkt_len <= subport_tc_credits) && > > @@ -1832,31 +1897,23 @@ static inline void > > grinder_tccache_populate(struct rte_sched_port *port, uint32_t pos, > > uint32_t qindex, uint16_t qmask) { > > struct rte_sched_grinder *grinder = port->grinder + pos; > > - uint8_t b[4]; > > + uint8_t b, i; > > > > grinder->tccache_w = 0; > > grinder->tccache_r = 0; > > > > - b[0] = (uint8_t) (qmask & 0xF); > > - b[1] = (uint8_t) ((qmask >> 4) & 0xF); > > - b[2] = (uint8_t) ((qmask >> 8) & 0xF); > > - b[3] = (uint8_t) ((qmask >> 12) & 0xF); > > - > > - grinder->tccache_qmask[grinder->tccache_w] = b[0]; > > - grinder->tccache_qindex[grinder->tccache_w] = qindex; > > - grinder->tccache_w += (b[0] != 0); > > - > > - grinder->tccache_qmask[grinder->tccache_w] = b[1]; > > - grinder->tccache_qindex[grinder->tccache_w] = qindex + 4; > > - grinder->tccache_w += (b[1] != 0); > > - > > - grinder->tccache_qmask[grinder->tccache_w] = b[2]; > > - grinder->tccache_qindex[grinder->tccache_w] = qindex + 8; > > - grinder->tccache_w += (b[2] != 0); > > + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASS_BE; i++) { > > + b = (uint8_t) ((qmask >> i) & 0x1); > > + grinder->tccache_qmask[grinder->tccache_w] = b; > > + grinder->tccache_qindex[grinder->tccache_w] = qindex + i; > > + grinder->tccache_w += (b != 0); > > + } > > > > - grinder->tccache_qmask[grinder->tccache_w] = b[3]; > > - grinder->tccache_qindex[grinder->tccache_w] = qindex + 12; > > - grinder->tccache_w += (b[3] != 0); > > + b = (uint8_t) (qmask >> (RTE_SCHED_TRAFFIC_CLASS_BE)); > > + grinder->tccache_qmask[grinder->tccache_w] = b; > > + grinder->tccache_qindex[grinder->tccache_w] = qindex + > > + RTE_SCHED_TRAFFIC_CLASS_BE; > > + grinder->tccache_w += (b != 0); > > } > > > > static inline int > > @@ -1874,14 +1931,18 @@ grinder_next_tc(struct rte_sched_port *port, > > uint32_t pos) > > qbase = rte_sched_port_qbase(port, qindex); > > qsize = rte_sched_port_qsize(port, qindex); > > > > - grinder->tc_index = (qindex >> 2) & 0x3; > > + grinder->tc_index = port->pipe_tc[qindex & > > (RTE_SCHED_QUEUES_PER_PIPE - 1)]; > > grinder->qmask = grinder->tccache_qmask[grinder->tccache_r]; > > grinder->qsize = qsize; > > > > - grinder->qindex[0] = qindex; > > - grinder->qindex[1] = qindex + 1; > > - grinder->qindex[2] = qindex + 2; > > - grinder->qindex[3] = qindex + 3; > > + if (grinder->tc_index < RTE_SCHED_TRAFFIC_CLASS_BE) { > > + grinder->queue[0] = port->queue + qindex; > > + grinder->qbase[0] = qbase; > > + grinder->qindex[0] = qindex; > > + grinder->tccache_r++; > > + > > + return 1; > > + } > > > > grinder->queue[0] = port->queue + qindex; > > grinder->queue[1] = port->queue + qindex + 1; @@ -1893,6 +1954,11 > @@ > > grinder_next_tc(struct rte_sched_port *port, uint32_t pos) > > grinder->qbase[2] = qbase + 2 * qsize; > > grinder->qbase[3] = qbase + 3 * qsize; > > > > + grinder->qindex[0] = qindex; > > + grinder->qindex[1] = qindex + 1; > > + grinder->qindex[2] = qindex + 2; > > + grinder->qindex[3] = qindex + 3; > > + > > grinder->tccache_r++; > > return 1; > > } > > diff --git a/lib/librte_sched/rte_sched.h > > b/lib/librte_sched/rte_sched.h index f9947c4cd..2b55c97ab 100644 > > --- a/lib/librte_sched/rte_sched.h > > +++ b/lib/librte_sched/rte_sched.h > > @@ -85,7 +85,9 @@ extern "C" { > > /** Number of traffic classes per pipe (as well as subport). > > * Cannot be changed. > > */ > > -#define RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE 4 > > +#define RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE \ > > +(RTE_SCHED_QUEUES_PER_PIPE - RTE_SCHED_BE_QUEUES_PER_PIPE + 1) > > + > > > > /** Number of queues per pipe traffic class. Cannot be changed. */ > > #define RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS 4 > > @@ -172,9 +174,7 @@ struct rte_sched_pipe_params { > > /**< Traffic class rates (measured in bytes per second) */ > > uint32_t tc_period; > > /**< Enforcement period (measured in milliseconds) */ -#ifdef > > RTE_SCHED_SUBPORT_TC_OV > > uint8_t tc_ov_weight; /**< Weight Traffic class 3 > > oversubscription */ > > -#endif > > > > /* Pipe queues */ > > uint8_t wrr_weights[RTE_SCHED_BE_QUEUES_PER_PIPE]; /**< WRR > weights > > */ > > -- > > 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* [dpdk-dev] [PATCH v5 03/11] sched: add max pipe profiles config in run time 2019-07-17 14:42 ` [dpdk-dev] [PATCH v5 00/11] sched: feature enhancements Jasvinder Singh 2019-07-17 14:42 ` [dpdk-dev] [PATCH v5 01/11] sched: remove wrr from strict priority tc queues Jasvinder Singh 2019-07-17 14:42 ` [dpdk-dev] [PATCH v5 02/11] sched: add config flexibility to tc queue sizes Jasvinder Singh @ 2019-07-17 14:42 ` Jasvinder Singh 2019-07-17 14:42 ` [dpdk-dev] [PATCH v5 04/11] sched: rename tc3 params to best-effort tc Jasvinder Singh ` (8 subsequent siblings) 11 siblings, 0 replies; 163+ messages in thread From: Jasvinder Singh @ 2019-07-17 14:42 UTC (permalink / raw) To: dev; +Cc: cristian.dumitrescu, Abraham Tovar, Lukasz Krakowiak Allow setting the maximum number of pipe profiles in run time. Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com> Signed-off-by: Abraham Tovar <abrahamx.tovar@intel.com> Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com> --- lib/librte_sched/rte_sched.c | 8 +++++--- lib/librte_sched/rte_sched.h | 2 ++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/librte_sched/rte_sched.c b/lib/librte_sched/rte_sched.c index 3d3d4c69f..8aff34f5c 100644 --- a/lib/librte_sched/rte_sched.c +++ b/lib/librte_sched/rte_sched.c @@ -180,6 +180,7 @@ struct rte_sched_port { uint32_t frame_overhead; uint16_t qsize[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; uint32_t n_pipe_profiles; + uint32_t n_max_pipe_profiles; uint32_t pipe_tc3_rate_max; #ifdef RTE_SCHED_RED struct rte_red_config red_config[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE][RTE_COLORS]; @@ -357,7 +358,7 @@ rte_sched_port_check_params(struct rte_sched_port_params *params) /* pipe_profiles and n_pipe_profiles */ if (params->pipe_profiles == NULL || params->n_pipe_profiles == 0 || - params->n_pipe_profiles > RTE_SCHED_PIPE_PROFILES_PER_PORT) + params->n_pipe_profiles > params->n_max_pipe_profiles) return -9; for (i = 0; i < params->n_pipe_profiles; i++) { @@ -386,7 +387,7 @@ rte_sched_port_get_array_base(struct rte_sched_port_params *params, enum rte_sch uint32_t size_queue_extra = n_queues_per_port * sizeof(struct rte_sched_queue_extra); uint32_t size_pipe_profiles - = RTE_SCHED_PIPE_PROFILES_PER_PORT * sizeof(struct rte_sched_pipe_profile); + = params->n_max_pipe_profiles * sizeof(struct rte_sched_pipe_profile); uint32_t size_bmp_array = rte_bitmap_get_memory_footprint(n_queues_per_port); uint32_t size_per_pipe_queue_array, size_queue_array; @@ -663,6 +664,7 @@ rte_sched_port_config(struct rte_sched_port_params *params) port->frame_overhead = params->frame_overhead; memcpy(port->qsize, params->qsize, sizeof(params->qsize)); port->n_pipe_profiles = params->n_pipe_profiles; + port->n_max_pipe_profiles = params->n_max_pipe_profiles; #ifdef RTE_SCHED_RED for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { @@ -1014,7 +1016,7 @@ rte_sched_port_pipe_profile_add(struct rte_sched_port *port, return -1; /* Pipe profiles not exceeds the max limit */ - if (port->n_pipe_profiles >= RTE_SCHED_PIPE_PROFILES_PER_PORT) + if (port->n_pipe_profiles >= port->n_max_pipe_profiles) return -2; /* Pipe params */ diff --git a/lib/librte_sched/rte_sched.h b/lib/librte_sched/rte_sched.h index 2b55c97ab..fb2688ff0 100644 --- a/lib/librte_sched/rte_sched.h +++ b/lib/librte_sched/rte_sched.h @@ -216,6 +216,8 @@ struct rte_sched_port_params { /**< Pipe profile table. * Every pipe is configured using one of the profiles from this table. */ uint32_t n_pipe_profiles; /**< Profiles in the pipe profile table */ + uint32_t n_max_pipe_profiles; + /**< Max profiles allowed in the pipe profile table */ #ifdef RTE_SCHED_RED struct rte_red_params red_params[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE][RTE_COLORS]; /**< RED parameters */ #endif -- 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* [dpdk-dev] [PATCH v5 04/11] sched: rename tc3 params to best-effort tc 2019-07-17 14:42 ` [dpdk-dev] [PATCH v5 00/11] sched: feature enhancements Jasvinder Singh ` (2 preceding siblings ...) 2019-07-17 14:42 ` [dpdk-dev] [PATCH v5 03/11] sched: add max pipe profiles config in run time Jasvinder Singh @ 2019-07-17 14:42 ` Jasvinder Singh 2019-07-17 14:42 ` [dpdk-dev] [PATCH v5 05/11] sched: improve error log messages Jasvinder Singh ` (7 subsequent siblings) 11 siblings, 0 replies; 163+ messages in thread From: Jasvinder Singh @ 2019-07-17 14:42 UTC (permalink / raw) To: dev; +Cc: cristian.dumitrescu, Abraham Tovar, Lukasz Krakowiak Change the traffic class 3 related params name to best-effort(be) traffic class. Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com> Signed-off-by: Abraham Tovar <abrahamx.tovar@intel.com> Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com> --- lib/librte_sched/rte_sched.c | 56 ++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/lib/librte_sched/rte_sched.c b/lib/librte_sched/rte_sched.c index 8aff34f5c..1b0e10911 100644 --- a/lib/librte_sched/rte_sched.c +++ b/lib/librte_sched/rte_sched.c @@ -181,7 +181,7 @@ struct rte_sched_port { uint16_t qsize[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; uint32_t n_pipe_profiles; uint32_t n_max_pipe_profiles; - uint32_t pipe_tc3_rate_max; + uint32_t pipe_tc_be_rate_max; #ifdef RTE_SCHED_RED struct rte_red_config red_config[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE][RTE_COLORS]; #endif @@ -300,7 +300,7 @@ pipe_profile_check(struct rte_sched_pipe_params *params, if (params->tc_period == 0) return -14; - /* TC3 oversubscription weight: non-zero */ + /* Best effort tc oversubscription weight: non-zero */ if (params->tc_ov_weight == 0) return -15; @@ -517,7 +517,7 @@ rte_sched_port_log_pipe_profile(struct rte_sched_port *port, uint32_t i) p->tc_credits_per_period[11], p->tc_credits_per_period[12], - /* Traffic class 3 oversubscription */ + /* Best-effort traffic class oversubscription */ p->tc_ov_weight, /* WRR */ @@ -606,13 +606,13 @@ rte_sched_port_config_pipe_profile_table(struct rte_sched_port *port, rte_sched_port_log_pipe_profile(port, i); } - port->pipe_tc3_rate_max = 0; + port->pipe_tc_be_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[RTE_SCHED_TRAFFIC_CLASS_BE]; + uint32_t pipe_tc_be_rate = src->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE]; - if (port->pipe_tc3_rate_max < pipe_tc3_rate) - port->pipe_tc3_rate_max = pipe_tc3_rate; + if (port->pipe_tc_be_rate_max < pipe_tc_be_rate) + port->pipe_tc_be_rate_max = pipe_tc_be_rate; } } @@ -816,7 +816,7 @@ rte_sched_port_log_subport_config(struct rte_sched_port *port, uint32_t i) s->tc_credits_per_period[11], s->tc_credits_per_period[12], - /* Traffic class 3 oversubscription */ + /* Best effort traffic class oversubscription */ s->tc_ov_wm_min, s->tc_ov_wm_max); } @@ -892,7 +892,7 @@ rte_sched_subport_config(struct rte_sched_port *port, /* TC oversubscription */ s->tc_ov_wm_min = port->mtu; s->tc_ov_wm_max = rte_sched_time_ms_to_bytes(params->tc_period, - port->pipe_tc3_rate_max); + port->pipe_tc_be_rate_max); s->tc_ov_wm = s->tc_ov_wm_max; s->tc_ov_period_id = 0; s->tc_ov = 0; @@ -937,21 +937,21 @@ rte_sched_pipe_config(struct rte_sched_port *port, if (p->tb_time) { params = port->pipe_profiles + p->profile; - double subport_tc3_rate = (double) s->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] + double subport_tc_be_rate = (double) s->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] / (double) s->tc_period; - double pipe_tc3_rate = (double) params->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] + double pipe_tc_be_rate = (double) params->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] / (double) params->tc_period; - uint32_t tc3_ov = s->tc_ov; + uint32_t tc_be_ov = s->tc_ov; /* Unplug pipe from its subport */ 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; + s->tc_ov_rate -= pipe_tc_be_rate; + s->tc_ov = s->tc_ov_rate > subport_tc_be_rate; - if (s->tc_ov != tc3_ov) { + if (s->tc_ov != tc_be_ov) { RTE_LOG(DEBUG, SCHED, - "Subport %u TC3 oversubscription is OFF (%.4lf >= %.4lf)\n", - subport_id, subport_tc3_rate, s->tc_ov_rate); + "Subport %u Best effort TC oversubscription is OFF (%.4lf >= %.4lf)\n", + subport_id, subport_tc_be_rate, s->tc_ov_rate); } /* Reset the pipe */ @@ -977,23 +977,23 @@ rte_sched_pipe_config(struct rte_sched_port *port, p->tc_credits[i] = params->tc_credits_per_period[i]; { - /* Subport TC3 oversubscription */ - double subport_tc3_rate = + /* Subport best effort tc oversubscription */ + double subport_tc_be_rate = (double) s->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] / (double) s->tc_period; - double pipe_tc3_rate = + double pipe_tc_be_rate = (double) params->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] / (double) params->tc_period; - uint32_t tc3_ov = s->tc_ov; + uint32_t tc_be_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; + s->tc_ov_rate += pipe_tc_be_rate; + s->tc_ov = s->tc_ov_rate > subport_tc_be_rate; - if (s->tc_ov != tc3_ov) { + if (s->tc_ov != tc_be_ov) { RTE_LOG(DEBUG, SCHED, - "Subport %u TC3 oversubscription is ON (%.4lf < %.4lf)\n", - subport_id, subport_tc3_rate, s->tc_ov_rate); + "Subport %u Best effort TC oversubscription is ON (%.4lf < %.4lf)\n", + subport_id, subport_tc_be_rate, s->tc_ov_rate); } p->tc_ov_period_id = s->tc_ov_period_id; p->tc_ov_credits = s->tc_ov_wm; @@ -1036,8 +1036,8 @@ rte_sched_port_pipe_profile_add(struct rte_sched_port *port, *pipe_profile_id = port->n_pipe_profiles; port->n_pipe_profiles++; - if (port->pipe_tc3_rate_max < params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE]) - port->pipe_tc3_rate_max = params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE]; + if (port->pipe_tc_be_rate_max < params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE]) + port->pipe_tc_be_rate_max = params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE]; rte_sched_port_log_pipe_profile(port, *pipe_profile_id); -- 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* [dpdk-dev] [PATCH v5 05/11] sched: improve error log messages 2019-07-17 14:42 ` [dpdk-dev] [PATCH v5 00/11] sched: feature enhancements Jasvinder Singh ` (3 preceding siblings ...) 2019-07-17 14:42 ` [dpdk-dev] [PATCH v5 04/11] sched: rename tc3 params to best-effort tc Jasvinder Singh @ 2019-07-17 14:42 ` Jasvinder Singh 2019-07-17 14:42 ` [dpdk-dev] [PATCH v5 06/11] sched: improve doxygen comments Jasvinder Singh ` (6 subsequent siblings) 11 siblings, 0 replies; 163+ messages in thread From: Jasvinder Singh @ 2019-07-17 14:42 UTC (permalink / raw) To: dev; +Cc: cristian.dumitrescu, Abraham Tovar, Lukasz Krakowiak Replace hard-coded numbers for reporting errors with error messages. Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com> Signed-off-by: Abraham Tovar <abrahamx.tovar@intel.com> Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com> --- lib/librte_sched/rte_sched.c | 293 ++++++++++++++++++++++++++--------- 1 file changed, 221 insertions(+), 72 deletions(-) diff --git a/lib/librte_sched/rte_sched.c b/lib/librte_sched/rte_sched.c index 1b0e10911..bcd98a73c 100644 --- a/lib/librte_sched/rte_sched.c +++ b/lib/librte_sched/rte_sched.c @@ -273,41 +273,66 @@ pipe_profile_check(struct rte_sched_pipe_params *params, uint32_t i; /* Pipe parameters */ - if (params == NULL) - return -10; + if (params == NULL) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for parameter params\n", __func__); + return -EINVAL; + } /* TB rate: non-zero, not greater than port rate */ if (params->tb_rate == 0 || - params->tb_rate > rate) - return -11; + params->tb_rate > rate) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for tb rate\n", __func__); + return -EINVAL; + } /* TB size: non-zero */ - if (params->tb_size == 0) - return -12; + if (params->tb_size == 0) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for tb size\n", __func__); + return -EINVAL; + } /* TC rate: non-zero if qsize non-zero, less than pipe rate */ for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { if ((qsize[i] == 0 && params->tc_rate[i] != 0) || (qsize[i] != 0 && (params->tc_rate[i] == 0 || - params->tc_rate[i] > params->tb_rate))) - return -13; + params->tc_rate[i] > params->tb_rate))) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for qsize or tc_rate\n", __func__); + return -EINVAL; + } } + if (params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE] == 0 || - qsize[RTE_SCHED_TRAFFIC_CLASS_BE] == 0) - return -13; + qsize[RTE_SCHED_TRAFFIC_CLASS_BE] == 0) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for be traffic class rate\n", __func__); + return -EINVAL; + } /* TC period: non-zero */ - if (params->tc_period == 0) - return -14; + if (params->tc_period == 0) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for tc period\n", __func__); + return -EINVAL; + } /* Best effort tc oversubscription weight: non-zero */ - if (params->tc_ov_weight == 0) - return -15; + if (params->tc_ov_weight == 0) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for tc ov weight\n", __func__); + return -EINVAL; + } /* Queue WRR weights: non-zero */ for (i = 0; i < RTE_SCHED_BE_QUEUES_PER_PIPE; i++) { - if (params->wrr_weights[i] == 0) - return -16; + if (params->wrr_weights[i] == 0) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for qsize or wrr weight\n", __func__); + return -EINVAL; + } } return 0; @@ -318,56 +343,83 @@ rte_sched_port_check_params(struct rte_sched_port_params *params) { uint32_t i; - if (params == NULL) - return -1; + if (params == NULL) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for parameter params\n", __func__); + return -EINVAL; + } /* socket */ - if (params->socket < 0) - return -3; + if (params->socket < 0) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for socket id\n", __func__); + return -EINVAL; + } /* rate */ - if (params->rate == 0) - return -4; + if (params->rate == 0) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for rate\n", __func__); + return -EINVAL; + } /* mtu */ - if (params->mtu == 0) - return -5; + if (params->mtu == 0) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for mtu\n", __func__); + return -EINVAL; + } /* n_subports_per_port: non-zero, limited to 16 bits, power of 2 */ if (params->n_subports_per_port == 0 || params->n_subports_per_port > 1u << 16 || - !rte_is_power_of_2(params->n_subports_per_port)) - return -6; + !rte_is_power_of_2(params->n_subports_per_port)) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for number of subports\n", __func__); + return -EINVAL; + } /* 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 -7; + !rte_is_power_of_2(params->n_pipes_per_subport)) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for pipes number\n", __func__); + return -EINVAL; + } - /* qsize: non-zero, power of 2, + /* qsize: if non-zero, power of 2, * no bigger than 32K (due to 16-bit read/write pointers) */ for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { uint16_t qsize = params->qsize[i]; if ((qsize != 0 && !rte_is_power_of_2(qsize)) || - ((i == RTE_SCHED_TRAFFIC_CLASS_BE) && (qsize == 0))) - return -8; + ((i == RTE_SCHED_TRAFFIC_CLASS_BE) && (qsize == 0))) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for tc rate\n", __func__); + return -EINVAL; + } } /* pipe_profiles and n_pipe_profiles */ if (params->pipe_profiles == NULL || params->n_pipe_profiles == 0 || - params->n_pipe_profiles > params->n_max_pipe_profiles) - return -9; + params->n_pipe_profiles > params->n_max_pipe_profiles) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for number of pipe profiles\n", __func__); + return -EINVAL; + } for (i = 0; i < params->n_pipe_profiles; i++) { struct rte_sched_pipe_params *p = params->pipe_profiles + i; int status; status = pipe_profile_check(p, params->rate, ¶ms->qsize[0]); - if (status != 0) - return status; + if (status != 0) { + RTE_LOG(ERR, SCHED, + "%s: Pipe profile check failed(%d)\n", __func__, status); + return -EINVAL; + } } return 0; @@ -830,16 +882,35 @@ rte_sched_subport_config(struct rte_sched_port *port, uint32_t i; /* Check user parameters */ - if (port == NULL || - subport_id >= port->n_subports_per_port || - params == NULL) - return -1; + if (port == NULL) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for parameter port\n", __func__); + return -EINVAL; + } - if (params->tb_rate == 0 || params->tb_rate > port->rate) - return -2; + if (subport_id >= port->n_subports_per_port) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for subport id\n", __func__); + return -EINVAL; + } - if (params->tb_size == 0) - return -3; + 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 > port->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++) { uint32_t tc_rate = params->tc_rate[i]; @@ -847,16 +918,25 @@ rte_sched_subport_config(struct rte_sched_port *port, if ((qsize == 0 && tc_rate != 0) || (qsize != 0 && tc_rate == 0) || - (tc_rate > params->tb_rate)) - return -4; + (tc_rate > params->tb_rate)) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for tc rate\n", __func__); + return -EINVAL; + } } if (port->qsize[RTE_SCHED_TRAFFIC_CLASS_BE] == 0 || - params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE] == 0) - return -4; + params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE] == 0) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for tc rate(best effort)\n", __func__); + return -EINVAL; + } - if (params->tc_period == 0) - return -5; + if (params->tc_period == 0) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for tc period\n", __func__); + return -EINVAL; + } s = port->subport + subport_id; @@ -919,17 +999,37 @@ rte_sched_pipe_config(struct rte_sched_port *port, profile = (uint32_t) pipe_profile; deactivate = (pipe_profile < 0); - if (port == NULL || - subport_id >= port->n_subports_per_port || - pipe_id >= port->n_pipes_per_subport || - (!deactivate && profile >= port->n_pipe_profiles)) - return -1; + if (port == NULL) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for parameter port\n", __func__); + return -EINVAL; + } + + if (subport_id >= port->n_subports_per_port) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for parameter subport id\n", __func__); + return -EINVAL; + } + if (pipe_id >= port->n_pipes_per_subport) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for parameter pipe id\n", __func__); + return -EINVAL; + } + + if (!deactivate && profile >= port->n_pipe_profiles) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for parameter pipe profile\n", __func__); + return -EINVAL; + } /* Check that subport configuration is valid */ s = port->subport + subport_id; - if (s->tb_period == 0) - return -2; + if (s->tb_period == 0) { + RTE_LOG(ERR, SCHED, + "%s: Subport configuration invalid\n", __func__); + return -EINVAL; + } p = port->pipe + (subport_id * port->n_pipes_per_subport + pipe_id); @@ -1012,25 +1112,37 @@ rte_sched_port_pipe_profile_add(struct rte_sched_port *port, int status; /* Port */ - if (port == NULL) - return -1; + if (port == NULL) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for parameter port\n", __func__); + return -EINVAL; + } /* Pipe profiles not exceeds the max limit */ - if (port->n_pipe_profiles >= port->n_max_pipe_profiles) - return -2; + if (port->n_pipe_profiles >= port->n_max_pipe_profiles) { + RTE_LOG(ERR, SCHED, + "%s: Number of pipe profiles exceeds the max limit\n", __func__); + return -EINVAL; + } /* Pipe params */ status = pipe_profile_check(params, port->rate, &port->qsize[0]); - if (status != 0) - return status; + if (status != 0) { + RTE_LOG(ERR, SCHED, + "%s: Pipe profile check failed(%d)\n", __func__, status); + return -EINVAL; + } pp = &port->pipe_profiles[port->n_pipe_profiles]; rte_sched_pipe_profile_convert(port, params, pp, port->rate); /* Pipe profile not exists */ for (i = 0; i < port->n_pipe_profiles; i++) - if (memcmp(port->pipe_profiles + i, pp, sizeof(*pp)) == 0) - return -3; + if (memcmp(port->pipe_profiles + i, pp, sizeof(*pp)) == 0) { + RTE_LOG(ERR, SCHED, + "%s: Pipe profile doesn't exist\n", __func__); + return -EINVAL; + } /* Pipe profile commit */ *pipe_profile_id = port->n_pipe_profiles; @@ -1101,9 +1213,29 @@ rte_sched_subport_read_stats(struct rte_sched_port *port, struct rte_sched_subport *s; /* Check user parameters */ - if (port == NULL || subport_id >= port->n_subports_per_port || - stats == NULL || tc_ov == NULL) - return -1; + if (port == NULL) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for parameter port\n", __func__); + return -EINVAL; + } + + if (subport_id >= port->n_subports_per_port) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for subport id\n", __func__); + return -EINVAL; + } + + if (stats == NULL) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for parameter stats\n", __func__); + return -EINVAL; + } + + if (tc_ov == NULL) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for tc_ov\n", __func__); + return -EINVAL; + } s = port->subport + subport_id; @@ -1127,11 +1259,28 @@ rte_sched_queue_read_stats(struct rte_sched_port *port, struct rte_sched_queue_extra *qe; /* Check user parameters */ - if ((port == NULL) || - (queue_id >= rte_sched_port_queues_per_port(port)) || - (stats == NULL) || - (qlen == NULL)) { - return -1; + if (port == NULL) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for parameter port\n", __func__); + return -EINVAL; + } + + if (queue_id >= rte_sched_port_queues_per_port(port)) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for queue id\n", __func__); + return -EINVAL; + } + + if (stats == NULL) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for parameter stats\n", __func__); + return -EINVAL; + } + + if (qlen == NULL) { + RTE_LOG(ERR, SCHED, + "%s: Incorrect value for parameter qlen\n", __func__); + return -EINVAL; } q = port->queue + queue_id; qe = port->queue_extra + queue_id; -- 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* [dpdk-dev] [PATCH v5 06/11] sched: improve doxygen comments 2019-07-17 14:42 ` [dpdk-dev] [PATCH v5 00/11] sched: feature enhancements Jasvinder Singh ` (4 preceding siblings ...) 2019-07-17 14:42 ` [dpdk-dev] [PATCH v5 05/11] sched: improve error log messages Jasvinder Singh @ 2019-07-17 14:42 ` Jasvinder Singh 2019-07-18 23:12 ` Dumitrescu, Cristian 2019-07-17 14:42 ` [dpdk-dev] [PATCH v5 07/11] net/softnic: add config flexibility to softnic tm Jasvinder Singh ` (5 subsequent siblings) 11 siblings, 1 reply; 163+ messages in thread From: Jasvinder Singh @ 2019-07-17 14:42 UTC (permalink / raw) To: dev; +Cc: cristian.dumitrescu, Abraham Tovar, Lukasz Krakowiak Improve doxygen comments. Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com> Signed-off-by: Abraham Tovar <abrahamx.tovar@intel.com> Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com> --- lib/librte_sched/rte_sched.h | 151 +++++++++++++++++++++-------------- 1 file changed, 93 insertions(+), 58 deletions(-) diff --git a/lib/librte_sched/rte_sched.h b/lib/librte_sched/rte_sched.h index fb2688ff0..caf9fa406 100644 --- a/lib/librte_sched/rte_sched.h +++ b/lib/librte_sched/rte_sched.h @@ -52,7 +52,7 @@ extern "C" { * multiple connections of same traffic class belonging to * the same user; * - Weighted Round Robin (WRR) is used to service the - * queues within same pipe traffic class. + * queues within same pipe lowest priority traffic class (best-effort). * */ @@ -83,7 +83,8 @@ extern "C" { #define RTE_SCHED_BE_QUEUES_PER_PIPE 4 /** Number of traffic classes per pipe (as well as subport). - * Cannot be changed. + * @see struct rte_sched_subport_params + * @see struct rte_sched_pipe_params */ #define RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE \ (RTE_SCHED_QUEUES_PER_PIPE - RTE_SCHED_BE_QUEUES_PER_PIPE + 1) @@ -109,6 +110,8 @@ extern "C" { * * The FCS is considered overhead only if not included in the packet * length (field pkt_len of struct rte_mbuf). + * + * @see struct rte_sched_port_params */ #ifndef RTE_SCHED_FRAME_OVERHEAD_DEFAULT #define RTE_SCHED_FRAME_OVERHEAD_DEFAULT 24 @@ -124,34 +127,36 @@ extern "C" { * byte. */ struct rte_sched_subport_params { - /* Subport token bucket */ - uint32_t tb_rate; /**< Rate (measured in bytes per second) */ - uint32_t tb_size; /**< Size (measured in credits) */ + /** Token bucket rate (measured in bytes per second) */ + uint32_t tb_rate; + + /** Token bucket size (measured in credits) */ + uint32_t tb_size; - /* Subport traffic classes */ + /** Traffic class rates (measured in bytes per second) */ uint32_t tc_rate[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; - /**< Traffic class rates (measured in bytes per second) */ + + /** Enforcement period for rates (measured in milliseconds) */ uint32_t tc_period; - /**< Enforcement period for rates (measured in milliseconds) */ }; /** Subport statistics */ struct rte_sched_subport_stats { - /* Packets */ + /** Number of packets successfully written */ uint32_t n_pkts_tc[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; - /**< Number of packets successfully written */ + + /** Number of packets dropped */ uint32_t n_pkts_tc_dropped[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; - /**< Number of packets dropped */ - /* Bytes */ + /** Number of bytes successfully written for each traffic class */ uint32_t n_bytes_tc[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; - /**< Number of bytes successfully written for each traffic class */ + + /** Number of bytes dropped for each traffic class */ uint32_t n_bytes_tc_dropped[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; - /**< Number of bytes dropped for each traffic class */ #ifdef RTE_SCHED_RED + /** Number of packets dropped by red */ uint32_t n_pkts_red_dropped[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; - /**< Number of packets dropped by red */ #endif }; @@ -165,61 +170,90 @@ struct rte_sched_subport_stats { * byte. */ struct rte_sched_pipe_params { - /* Pipe token bucket */ - uint32_t tb_rate; /**< Rate (measured in bytes per second) */ - uint32_t tb_size; /**< Size (measured in credits) */ + /** Token bucket rate (measured in bytes per second) */ + uint32_t tb_rate; - /* Pipe traffic classes */ + /** Token bucket size (measured in credits) */ + uint32_t tb_size; + + /** Traffic class rates (measured in bytes per second) */ uint32_t tc_rate[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; - /**< Traffic class rates (measured in bytes per second) */ + + /** Enforcement period (measured in milliseconds) */ uint32_t tc_period; - /**< Enforcement period (measured in milliseconds) */ - uint8_t tc_ov_weight; /**< Weight Traffic class 3 oversubscription */ - /* Pipe queues */ - uint8_t wrr_weights[RTE_SCHED_BE_QUEUES_PER_PIPE]; /**< WRR weights */ + /** Best-effort traffic class oversubscription weight */ + uint8_t tc_ov_weight; + + /** WRR weights of best-effort traffic class queues */ + uint8_t wrr_weights[RTE_SCHED_BE_QUEUES_PER_PIPE]; }; /** Queue statistics */ struct rte_sched_queue_stats { - /* Packets */ - uint32_t n_pkts; /**< Packets successfully written */ - uint32_t n_pkts_dropped; /**< Packets dropped */ + /** Packets successfully written */ + uint32_t n_pkts; + + /** Packets dropped */ + uint32_t n_pkts_dropped; + #ifdef RTE_SCHED_RED - uint32_t n_pkts_red_dropped; /**< Packets dropped by RED */ + /** Packets dropped by RED */ + uint32_t n_pkts_red_dropped; #endif - /* Bytes */ - uint32_t n_bytes; /**< Bytes successfully written */ - uint32_t n_bytes_dropped; /**< Bytes dropped */ + /** Bytes successfully written */ + uint32_t n_bytes; + + /** Bytes dropped */ + uint32_t n_bytes_dropped; }; /** Port configuration parameters. */ struct rte_sched_port_params { - const char *name; /**< String to be associated */ - int socket; /**< CPU socket ID */ - uint32_t rate; /**< Output port rate - * (measured in bytes per second) */ - uint32_t mtu; /**< Maximum Ethernet frame size - * (measured in bytes). - * Should not include the framing overhead. */ - uint32_t frame_overhead; /**< Framing overhead per packet - * (measured in bytes) */ - uint32_t n_subports_per_port; /**< Number of subports */ - uint32_t n_pipes_per_subport; /**< Number of pipes per subport */ + /** Name of the port to be associated */ + const char *name; + + /** CPU socket ID */ + int socket; + + /** Output port rate (measured in bytes per second) */ + uint32_t rate; + + /** Maximum Ethernet frame size (measured in bytes). + * Should not include the framing overhead. + */ + uint32_t mtu; + + /** Framing overhead per packet (measured in bytes) */ + uint32_t frame_overhead; + + /** Number of subports */ + uint32_t n_subports_per_port; + + /** Number of subport_pipes */ + uint32_t n_pipes_per_subport; + + /** Packet queue size for each traffic class. + * All the pipes within the same subport share the similar + * configuration for the queues. + */ uint16_t qsize[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; - /**< Packet queue size for each traffic class. - * All queues within the same pipe traffic class have the same - * size. Queues from different pipes serving the same traffic - * class have the same size. */ + + /** Pipe profile table. + * Every pipe is configured using one of the profiles from this table. + */ struct rte_sched_pipe_params *pipe_profiles; - /**< Pipe profile table. - * Every pipe is configured using one of the profiles from this table. */ - uint32_t n_pipe_profiles; /**< Profiles in the pipe profile table */ + + /** Profiles in the pipe profile table */ + uint32_t n_pipe_profiles; + + /** Max profiles allowed in the pipe profile table */ uint32_t n_max_pipe_profiles; - /**< Max profiles allowed in the pipe profile table */ + #ifdef RTE_SCHED_RED - struct rte_red_params red_params[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE][RTE_COLORS]; /**< RED parameters */ + /** RED parameters */ + struct rte_red_params red_params[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE][RTE_COLORS]; #endif }; @@ -333,8 +367,8 @@ rte_sched_port_get_memory_footprint(struct rte_sched_port_params *params); * Pointer to pre-allocated subport statistics structure where the statistics * counters should be stored * @param tc_ov - * Pointer to pre-allocated 4-entry array where the oversubscription status for - * each of the 4 subport traffic classes should be stored. + * Pointer to pre-allocated 13-entry array where the oversubscription status for + * each of the subport traffic classes should be stored. * @return * 0 upon success, error code otherwise */ @@ -379,9 +413,10 @@ rte_sched_queue_read_stats(struct rte_sched_port *port, * @param pipe * Pipe ID within subport * @param traffic_class - * Traffic class ID within pipe (0 .. 3) + * Traffic class ID within pipe (0 .. RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1) * @param queue - * Queue ID within pipe traffic class (0 .. 3) + * Queue ID within pipe traffic class, 0 for high priority TCs, and + * 0 .. (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE-1) for best-effort TC * @param color * Packet color set */ @@ -406,10 +441,10 @@ rte_sched_port_pkt_write(struct rte_sched_port *port, * @param pipe * Pipe ID within subport * @param traffic_class - * Traffic class ID within pipe (0 .. 3) + * Traffic class ID within pipe (0 .. RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE-1) * @param queue - * Queue ID within pipe traffic class (0 .. 3) - * + * Queue ID within pipe traffic class, 0 for high priority TCs, and + * 0 .. (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE-1) for best-effort TC */ void rte_sched_port_pkt_read_tree_path(struct rte_sched_port *port, -- 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* Re: [dpdk-dev] [PATCH v5 06/11] sched: improve doxygen comments 2019-07-17 14:42 ` [dpdk-dev] [PATCH v5 06/11] sched: improve doxygen comments Jasvinder Singh @ 2019-07-18 23:12 ` Dumitrescu, Cristian 2019-07-19 15:25 ` Singh, Jasvinder 0 siblings, 1 reply; 163+ messages in thread From: Dumitrescu, Cristian @ 2019-07-18 23:12 UTC (permalink / raw) To: Singh, Jasvinder, dev; +Cc: Tovar, AbrahamX, Krakowiak, LukaszX > -----Original Message----- > From: Singh, Jasvinder > Sent: Wednesday, July 17, 2019 4:43 PM > To: dev@dpdk.org > Cc: Dumitrescu, Cristian <cristian.dumitrescu@intel.com>; Tovar, AbrahamX > <abrahamx.tovar@intel.com>; Krakowiak, LukaszX > <lukaszx.krakowiak@intel.com> > Subject: [PATCH v5 06/11] sched: improve doxygen comments > > Improve doxygen comments. > > Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com> > Signed-off-by: Abraham Tovar <abrahamx.tovar@intel.com> > Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com> > --- > lib/librte_sched/rte_sched.h | 151 +++++++++++++++++++++-------------- > 1 file changed, 93 insertions(+), 58 deletions(-) > > diff --git a/lib/librte_sched/rte_sched.h b/lib/librte_sched/rte_sched.h > index fb2688ff0..caf9fa406 100644 > --- a/lib/librte_sched/rte_sched.h > +++ b/lib/librte_sched/rte_sched.h > @@ -52,7 +52,7 @@ extern "C" { > * multiple connections of same traffic class belonging to > * the same user; > * - Weighted Round Robin (WRR) is used to service the > - * queues within same pipe traffic class. > + * queues within same pipe lowest priority traffic class (best-effort). > * > */ > > @@ -83,7 +83,8 @@ extern "C" { > #define RTE_SCHED_BE_QUEUES_PER_PIPE 4 > > /** Number of traffic classes per pipe (as well as subport). > - * Cannot be changed. > + * @see struct rte_sched_subport_params > + * @see struct rte_sched_pipe_params > */ > #define RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE \ > (RTE_SCHED_QUEUES_PER_PIPE - RTE_SCHED_BE_QUEUES_PER_PIPE + 1) > @@ -109,6 +110,8 @@ extern "C" { > * > * The FCS is considered overhead only if not included in the packet > * length (field pkt_len of struct rte_mbuf). > + * > + * @see struct rte_sched_port_params > */ > #ifndef RTE_SCHED_FRAME_OVERHEAD_DEFAULT > #define RTE_SCHED_FRAME_OVERHEAD_DEFAULT 24 > @@ -124,34 +127,36 @@ extern "C" { > * byte. > */ > struct rte_sched_subport_params { > - /* Subport token bucket */ > - uint32_t tb_rate; /**< Rate (measured in bytes per second) > */ > - uint32_t tb_size; /**< Size (measured in credits) */ > + /** Token bucket rate (measured in bytes per second) */ > + uint32_t tb_rate; > + > + /** Token bucket size (measured in credits) */ > + uint32_t tb_size; > > - /* Subport traffic classes */ > + /** Traffic class rates (measured in bytes per second) */ > uint32_t tc_rate[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; > - /**< Traffic class rates (measured in bytes per second) */ > + > + /** Enforcement period for rates (measured in milliseconds) */ > uint32_t tc_period; > - /**< Enforcement period for rates (measured in milliseconds) */ > }; > > /** Subport statistics */ > struct rte_sched_subport_stats { > - /* Packets */ > + /** Number of packets successfully written */ > uint32_t n_pkts_tc[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; > - /**< Number of packets successfully written */ > + > + /** Number of packets dropped */ > uint32_t > n_pkts_tc_dropped[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; > - /**< Number of packets dropped */ > > - /* Bytes */ > + /** Number of bytes successfully written for each traffic class */ > uint32_t n_bytes_tc[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; > - /**< Number of bytes successfully written for each traffic class */ > + > + /** Number of bytes dropped for each traffic class */ > uint32_t > n_bytes_tc_dropped[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; > - /**< Number of bytes dropped for each traffic class */ > > #ifdef RTE_SCHED_RED > + /** Number of packets dropped by red */ > uint32_t > n_pkts_red_dropped[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; > - /**< Number of packets dropped by red */ > #endif > }; > > @@ -165,61 +170,90 @@ struct rte_sched_subport_stats { > * byte. > */ > struct rte_sched_pipe_params { > - /* Pipe token bucket */ > - uint32_t tb_rate; /**< Rate (measured in bytes per second) > */ > - uint32_t tb_size; /**< Size (measured in credits) */ > + /** Token bucket rate (measured in bytes per second) */ > + uint32_t tb_rate; > > - /* Pipe traffic classes */ > + /** Token bucket size (measured in credits) */ > + uint32_t tb_size; > + > + /** Traffic class rates (measured in bytes per second) */ > uint32_t tc_rate[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; > - /**< Traffic class rates (measured in bytes per second) */ > + > + /** Enforcement period (measured in milliseconds) */ > uint32_t tc_period; > - /**< Enforcement period (measured in milliseconds) */ > - uint8_t tc_ov_weight; /**< Weight Traffic class 3 > oversubscription */ > > - /* Pipe queues */ > - uint8_t wrr_weights[RTE_SCHED_BE_QUEUES_PER_PIPE]; /**< > WRR weights */ > + /** Best-effort traffic class oversubscription weight */ > + uint8_t tc_ov_weight; > + > + /** WRR weights of best-effort traffic class queues */ > + uint8_t wrr_weights[RTE_SCHED_BE_QUEUES_PER_PIPE]; > }; > > /** Queue statistics */ > struct rte_sched_queue_stats { > - /* Packets */ > - uint32_t n_pkts; /**< Packets successfully written */ > - uint32_t n_pkts_dropped; /**< Packets dropped */ > + /** Packets successfully written */ > + uint32_t n_pkts; > + > + /** Packets dropped */ > + uint32_t n_pkts_dropped; > + > #ifdef RTE_SCHED_RED > - uint32_t n_pkts_red_dropped; /**< Packets dropped by RED */ > + /** Packets dropped by RED */ > + uint32_t n_pkts_red_dropped; > #endif > > - /* Bytes */ > - uint32_t n_bytes; /**< Bytes successfully written */ > - uint32_t n_bytes_dropped; /**< Bytes dropped */ > + /** Bytes successfully written */ > + uint32_t n_bytes; > + > + /** Bytes dropped */ > + uint32_t n_bytes_dropped; > }; > > /** Port configuration parameters. */ > struct rte_sched_port_params { > - const char *name; /**< String to be associated */ > - int socket; /**< CPU socket ID */ > - uint32_t rate; /**< Output port rate > - * (measured in bytes per second) */ > - uint32_t mtu; /**< Maximum Ethernet frame size > - * (measured in bytes). > - * Should not include the framing > overhead. */ > - uint32_t frame_overhead; /**< Framing overhead per packet > - * (measured in bytes) */ > - uint32_t n_subports_per_port; /**< Number of subports */ > - uint32_t n_pipes_per_subport; /**< Number of pipes per subport > */ > + /** Name of the port to be associated */ > + const char *name; > + > + /** CPU socket ID */ > + int socket; > + > + /** Output port rate (measured in bytes per second) */ > + uint32_t rate; > + > + /** Maximum Ethernet frame size (measured in bytes). > + * Should not include the framing overhead. > + */ > + uint32_t mtu; > + > + /** Framing overhead per packet (measured in bytes) */ > + uint32_t frame_overhead; > + > + /** Number of subports */ > + uint32_t n_subports_per_port; > + > + /** Number of subport_pipes */ > + uint32_t n_pipes_per_subport; > + > + /** Packet queue size for each traffic class. > + * All the pipes within the same subport share the similar > + * configuration for the queues. > + */ > uint16_t qsize[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; > - /**< Packet queue size for each traffic class. > - * All queues within the same pipe traffic class have the same > - * size. Queues from different pipes serving the same traffic > - * class have the same size. */ > + > + /** Pipe profile table. > + * Every pipe is configured using one of the profiles from this table. > + */ > struct rte_sched_pipe_params *pipe_profiles; > - /**< Pipe profile table. > - * Every pipe is configured using one of the profiles from this table. > */ > - uint32_t n_pipe_profiles; /**< Profiles in the pipe profile table */ > + > + /** Profiles in the pipe profile table */ > + uint32_t n_pipe_profiles; > + > + /** Max profiles allowed in the pipe profile table */ > uint32_t n_max_pipe_profiles; > - /**< Max profiles allowed in the pipe profile table */ > + > #ifdef RTE_SCHED_RED > - struct rte_red_params > red_params[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE][RTE_COLORS]; /**< > RED parameters */ > + /** RED parameters */ > + struct rte_red_params > red_params[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE][RTE_COLORS]; > #endif > }; > > @@ -333,8 +367,8 @@ rte_sched_port_get_memory_footprint(struct > rte_sched_port_params *params); > * Pointer to pre-allocated subport statistics structure where the statistics > * counters should be stored > * @param tc_ov > - * Pointer to pre-allocated 4-entry array where the oversubscription status > for > - * each of the 4 subport traffic classes should be stored. > + * Pointer to pre-allocated 13-entry array where the oversubscription Please replace "13" by RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE. I also suggest moving the definition of RTE_SCHED_TRAFFIC_CLASS_BE to this file. > status for > + * each of the subport traffic classes should be stored. > * @return > * 0 upon success, error code otherwise > */ > @@ -379,9 +413,10 @@ rte_sched_queue_read_stats(struct rte_sched_port > *port, > * @param pipe > * Pipe ID within subport > * @param traffic_class > - * Traffic class ID within pipe (0 .. 3) > + * Traffic class ID within pipe (0 .. RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE > - 1) > * @param queue > - * Queue ID within pipe traffic class (0 .. 3) > + * Queue ID within pipe traffic class, 0 for high priority TCs, and > + * 0 .. (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE-1) for best-effort TC This should be: 0 .. (RTE_SCHED_BE_QUEUES_PER_PIPE - 1) for the Best Effort traffic class. > * @param color > * Packet color set > */ > @@ -406,10 +441,10 @@ rte_sched_port_pkt_write(struct rte_sched_port > *port, > * @param pipe > * Pipe ID within subport > * @param traffic_class > - * Traffic class ID within pipe (0 .. 3) > + * Traffic class ID within pipe (0 .. > RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE-1) > * @param queue > - * Queue ID within pipe traffic class (0 .. 3) > - * > + * Queue ID within pipe traffic class, 0 for high priority TCs, and > + * 0 .. (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE-1) for best-effort TC This should be: 0 .. (RTE_SCHED_BE_QUEUES_PER_PIPE - 1) for the Best Effort traffic class. > */ > void > rte_sched_port_pkt_read_tree_path(struct rte_sched_port *port, > -- > 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* Re: [dpdk-dev] [PATCH v5 06/11] sched: improve doxygen comments 2019-07-18 23:12 ` Dumitrescu, Cristian @ 2019-07-19 15:25 ` Singh, Jasvinder 0 siblings, 0 replies; 163+ messages in thread From: Singh, Jasvinder @ 2019-07-19 15:25 UTC (permalink / raw) To: Dumitrescu, Cristian, dev; +Cc: Tovar, AbrahamX, Krakowiak, LukaszX <snip> > > @@ -165,61 +170,90 @@ struct rte_sched_subport_stats { > > * byte. > > */ > > struct rte_sched_pipe_params { > > - /* Pipe token bucket */ > > - uint32_t tb_rate; /**< Rate (measured in bytes per second) > > */ > > - uint32_t tb_size; /**< Size (measured in credits) */ > > + /** Token bucket rate (measured in bytes per second) */ > > + uint32_t tb_rate; > > > > - /* Pipe traffic classes */ > > + /** Token bucket size (measured in credits) */ > > + uint32_t tb_size; > > + > > + /** Traffic class rates (measured in bytes per second) */ > > uint32_t tc_rate[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; > > - /**< Traffic class rates (measured in bytes per second) */ > > + > > + /** Enforcement period (measured in milliseconds) */ > > uint32_t tc_period; > > - /**< Enforcement period (measured in milliseconds) */ > > - uint8_t tc_ov_weight; /**< Weight Traffic class 3 > > oversubscription */ > > > > - /* Pipe queues */ > > - uint8_t wrr_weights[RTE_SCHED_BE_QUEUES_PER_PIPE]; /**< > > WRR weights */ > > + /** Best-effort traffic class oversubscription weight */ > > + uint8_t tc_ov_weight; > > + > > + /** WRR weights of best-effort traffic class queues */ > > + uint8_t wrr_weights[RTE_SCHED_BE_QUEUES_PER_PIPE]; > > }; > > > > /** Queue statistics */ > > struct rte_sched_queue_stats { > > - /* Packets */ > > - uint32_t n_pkts; /**< Packets successfully written */ > > - uint32_t n_pkts_dropped; /**< Packets dropped */ > > + /** Packets successfully written */ > > + uint32_t n_pkts; > > + > > + /** Packets dropped */ > > + uint32_t n_pkts_dropped; > > + > > #ifdef RTE_SCHED_RED > > - uint32_t n_pkts_red_dropped; /**< Packets dropped by RED */ > > + /** Packets dropped by RED */ > > + uint32_t n_pkts_red_dropped; > > #endif > > > > - /* Bytes */ > > - uint32_t n_bytes; /**< Bytes successfully written */ > > - uint32_t n_bytes_dropped; /**< Bytes dropped */ > > + /** Bytes successfully written */ > > + uint32_t n_bytes; > > + > > + /** Bytes dropped */ > > + uint32_t n_bytes_dropped; > > }; > > > > /** Port configuration parameters. */ struct rte_sched_port_params { > > - const char *name; /**< String to be associated */ > > - int socket; /**< CPU socket ID */ > > - uint32_t rate; /**< Output port rate > > - * (measured in bytes per second) */ > > - uint32_t mtu; /**< Maximum Ethernet frame size > > - * (measured in bytes). > > - * Should not include the framing > > overhead. */ > > - uint32_t frame_overhead; /**< Framing overhead per packet > > - * (measured in bytes) */ > > - uint32_t n_subports_per_port; /**< Number of subports */ > > - uint32_t n_pipes_per_subport; /**< Number of pipes per subport > > */ > > + /** Name of the port to be associated */ > > + const char *name; > > + > > + /** CPU socket ID */ > > + int socket; > > + > > + /** Output port rate (measured in bytes per second) */ > > + uint32_t rate; > > + > > + /** Maximum Ethernet frame size (measured in bytes). > > + * Should not include the framing overhead. > > + */ > > + uint32_t mtu; > > + > > + /** Framing overhead per packet (measured in bytes) */ > > + uint32_t frame_overhead; > > + > > + /** Number of subports */ > > + uint32_t n_subports_per_port; > > + > > + /** Number of subport_pipes */ > > + uint32_t n_pipes_per_subport; > > + > > + /** Packet queue size for each traffic class. > > + * All the pipes within the same subport share the similar > > + * configuration for the queues. > > + */ > > uint16_t qsize[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; > > - /**< Packet queue size for each traffic class. > > - * All queues within the same pipe traffic class have the same > > - * size. Queues from different pipes serving the same traffic > > - * class have the same size. */ > > + > > + /** Pipe profile table. > > + * Every pipe is configured using one of the profiles from this table. > > + */ > > struct rte_sched_pipe_params *pipe_profiles; > > - /**< Pipe profile table. > > - * Every pipe is configured using one of the profiles from this table. > > */ > > - uint32_t n_pipe_profiles; /**< Profiles in the pipe profile table */ > > + > > + /** Profiles in the pipe profile table */ > > + uint32_t n_pipe_profiles; > > + > > + /** Max profiles allowed in the pipe profile table */ > > uint32_t n_max_pipe_profiles; > > - /**< Max profiles allowed in the pipe profile table */ > > + > > #ifdef RTE_SCHED_RED > > - struct rte_red_params > > red_params[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE][RTE_COLORS]; /**< > RED > > parameters */ > > + /** RED parameters */ > > + struct rte_red_params > > red_params[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE][RTE_COLORS]; > > #endif > > }; > > > > @@ -333,8 +367,8 @@ rte_sched_port_get_memory_footprint(struct > > rte_sched_port_params *params); > > * Pointer to pre-allocated subport statistics structure where the statistics > > * counters should be stored > > * @param tc_ov > > - * Pointer to pre-allocated 4-entry array where the oversubscription status > > for > > - * each of the 4 subport traffic classes should be stored. > > + * Pointer to pre-allocated 13-entry array where the oversubscription > > Please replace "13" by RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE. Done in v6. > I also suggest moving the definition of RTE_SCHED_TRAFFIC_CLASS_BE to this > file. Done in v6. > > status for > > + * each of the subport traffic classes should be stored. > > * @return > > * 0 upon success, error code otherwise > > */ > > @@ -379,9 +413,10 @@ rte_sched_queue_read_stats(struct rte_sched_port > > *port, > > * @param pipe > > * Pipe ID within subport > > * @param traffic_class > > - * Traffic class ID within pipe (0 .. 3) > > + * Traffic class ID within pipe (0 .. RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE > > - 1) > > * @param queue > > - * Queue ID within pipe traffic class (0 .. 3) > > + * Queue ID within pipe traffic class, 0 for high priority TCs, and > > + * 0 .. (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE-1) for best-effort TC > > This should be: 0 .. (RTE_SCHED_BE_QUEUES_PER_PIPE - 1) for the Best Effort > traffic class. Fixed in v6, thanks. > > > * @param color > > * Packet color set > > */ > > @@ -406,10 +441,10 @@ rte_sched_port_pkt_write(struct rte_sched_port > > *port, > > * @param pipe > > * Pipe ID within subport > > * @param traffic_class > > - * Traffic class ID within pipe (0 .. 3) > > + * Traffic class ID within pipe (0 .. > > RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE-1) > > * @param queue > > - * Queue ID within pipe traffic class (0 .. 3) > > - * > > + * Queue ID within pipe traffic class, 0 for high priority TCs, and > > + * 0 .. (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE-1) for best-effort TC > > This should be: 0 .. (RTE_SCHED_BE_QUEUES_PER_PIPE - 1) for the Best Effort > traffic class. Fixed in v6. > > */ > > void > > rte_sched_port_pkt_read_tree_path(struct rte_sched_port *port, > > -- > > 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* [dpdk-dev] [PATCH v5 07/11] net/softnic: add config flexibility to softnic tm 2019-07-17 14:42 ` [dpdk-dev] [PATCH v5 00/11] sched: feature enhancements Jasvinder Singh ` (5 preceding siblings ...) 2019-07-17 14:42 ` [dpdk-dev] [PATCH v5 06/11] sched: improve doxygen comments Jasvinder Singh @ 2019-07-17 14:42 ` Jasvinder Singh 2019-07-17 14:42 ` [dpdk-dev] [PATCH v5 08/11] test_sched: modify tests for config flexibility Jasvinder Singh ` (4 subsequent siblings) 11 siblings, 0 replies; 163+ messages in thread From: Jasvinder Singh @ 2019-07-17 14:42 UTC (permalink / raw) To: dev; +Cc: cristian.dumitrescu, Abraham Tovar, Lukasz Krakowiak Update softnic tm function for configuration flexiblity of pipe traffic classes and queues size. Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com> Signed-off-by: Abraham Tovar <abrahamx.tovar@intel.com> Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com> --- drivers/net/softnic/rte_eth_softnic.c | 98 ++++ drivers/net/softnic/rte_eth_softnic_cli.c | 448 ++++++++++++++++-- .../net/softnic/rte_eth_softnic_internals.h | 6 +- drivers/net/softnic/rte_eth_softnic_tm.c | 121 +++-- 4 files changed, 603 insertions(+), 70 deletions(-) diff --git a/drivers/net/softnic/rte_eth_softnic.c b/drivers/net/softnic/rte_eth_softnic.c index 4bda2f2b0..e3ad24161 100644 --- a/drivers/net/softnic/rte_eth_softnic.c +++ b/drivers/net/softnic/rte_eth_softnic.c @@ -28,6 +28,16 @@ #define PMD_PARAM_TM_QSIZE1 "tm_qsize1" #define PMD_PARAM_TM_QSIZE2 "tm_qsize2" #define PMD_PARAM_TM_QSIZE3 "tm_qsize3" +#define PMD_PARAM_TM_QSIZE4 "tm_qsize4" +#define PMD_PARAM_TM_QSIZE5 "tm_qsize5" +#define PMD_PARAM_TM_QSIZE6 "tm_qsize6" +#define PMD_PARAM_TM_QSIZE7 "tm_qsize7" +#define PMD_PARAM_TM_QSIZE8 "tm_qsize8" +#define PMD_PARAM_TM_QSIZE9 "tm_qsize9" +#define PMD_PARAM_TM_QSIZE10 "tm_qsize10" +#define PMD_PARAM_TM_QSIZE11 "tm_qsize11" +#define PMD_PARAM_TM_QSIZE12 "tm_qsize12" + static const char * const pmd_valid_args[] = { PMD_PARAM_FIRMWARE, @@ -39,6 +49,15 @@ static const char * const pmd_valid_args[] = { PMD_PARAM_TM_QSIZE1, PMD_PARAM_TM_QSIZE2, PMD_PARAM_TM_QSIZE3, + PMD_PARAM_TM_QSIZE4, + PMD_PARAM_TM_QSIZE5, + PMD_PARAM_TM_QSIZE6, + PMD_PARAM_TM_QSIZE7, + PMD_PARAM_TM_QSIZE8, + PMD_PARAM_TM_QSIZE9, + PMD_PARAM_TM_QSIZE10, + PMD_PARAM_TM_QSIZE11, + PMD_PARAM_TM_QSIZE12, NULL }; @@ -434,6 +453,15 @@ pmd_parse_args(struct pmd_params *p, const char *params) p->tm.qsize[1] = SOFTNIC_TM_QUEUE_SIZE; p->tm.qsize[2] = SOFTNIC_TM_QUEUE_SIZE; p->tm.qsize[3] = SOFTNIC_TM_QUEUE_SIZE; + p->tm.qsize[4] = SOFTNIC_TM_QUEUE_SIZE; + p->tm.qsize[5] = SOFTNIC_TM_QUEUE_SIZE; + p->tm.qsize[6] = SOFTNIC_TM_QUEUE_SIZE; + p->tm.qsize[7] = SOFTNIC_TM_QUEUE_SIZE; + p->tm.qsize[8] = SOFTNIC_TM_QUEUE_SIZE; + p->tm.qsize[9] = SOFTNIC_TM_QUEUE_SIZE; + p->tm.qsize[10] = SOFTNIC_TM_QUEUE_SIZE; + p->tm.qsize[11] = SOFTNIC_TM_QUEUE_SIZE; + p->tm.qsize[12] = SOFTNIC_TM_QUEUE_SIZE; /* Firmware script (optional) */ if (rte_kvargs_count(kvlist, PMD_PARAM_FIRMWARE) == 1) { @@ -504,6 +532,67 @@ pmd_parse_args(struct pmd_params *p, const char *params) goto out_free; } + if (rte_kvargs_count(kvlist, PMD_PARAM_TM_QSIZE4) == 1) { + ret = rte_kvargs_process(kvlist, PMD_PARAM_TM_QSIZE4, + &get_uint32, &p->tm.qsize[4]); + if (ret < 0) + goto out_free; + } + + if (rte_kvargs_count(kvlist, PMD_PARAM_TM_QSIZE5) == 1) { + ret = rte_kvargs_process(kvlist, PMD_PARAM_TM_QSIZE5, + &get_uint32, &p->tm.qsize[5]); + if (ret < 0) + goto out_free; + } + + if (rte_kvargs_count(kvlist, PMD_PARAM_TM_QSIZE6) == 1) { + ret = rte_kvargs_process(kvlist, PMD_PARAM_TM_QSIZE6, + &get_uint32, &p->tm.qsize[6]); + if (ret < 0) + goto out_free; + } + + if (rte_kvargs_count(kvlist, PMD_PARAM_TM_QSIZE7) == 1) { + ret = rte_kvargs_process(kvlist, PMD_PARAM_TM_QSIZE7, + &get_uint32, &p->tm.qsize[7]); + if (ret < 0) + goto out_free; + } + if (rte_kvargs_count(kvlist, PMD_PARAM_TM_QSIZE8) == 1) { + ret = rte_kvargs_process(kvlist, PMD_PARAM_TM_QSIZE8, + &get_uint32, &p->tm.qsize[8]); + if (ret < 0) + goto out_free; + } + if (rte_kvargs_count(kvlist, PMD_PARAM_TM_QSIZE9) == 1) { + ret = rte_kvargs_process(kvlist, PMD_PARAM_TM_QSIZE9, + &get_uint32, &p->tm.qsize[9]); + if (ret < 0) + goto out_free; + } + + if (rte_kvargs_count(kvlist, PMD_PARAM_TM_QSIZE10) == 1) { + ret = rte_kvargs_process(kvlist, PMD_PARAM_TM_QSIZE10, + &get_uint32, &p->tm.qsize[10]); + if (ret < 0) + goto out_free; + } + + if (rte_kvargs_count(kvlist, PMD_PARAM_TM_QSIZE11) == 1) { + ret = rte_kvargs_process(kvlist, PMD_PARAM_TM_QSIZE11, + &get_uint32, &p->tm.qsize[11]); + if (ret < 0) + goto out_free; + } + + if (rte_kvargs_count(kvlist, PMD_PARAM_TM_QSIZE12) == 1) { + ret = rte_kvargs_process(kvlist, PMD_PARAM_TM_QSIZE12, + &get_uint32, &p->tm.qsize[12]); + if (ret < 0) + goto out_free; + } + out_free: rte_kvargs_free(kvlist); return ret; @@ -588,6 +677,15 @@ RTE_PMD_REGISTER_PARAM_STRING(net_softnic, PMD_PARAM_TM_QSIZE1 "=<uint32> " PMD_PARAM_TM_QSIZE2 "=<uint32> " PMD_PARAM_TM_QSIZE3 "=<uint32>" + PMD_PARAM_TM_QSIZE4 "=<uint32> " + PMD_PARAM_TM_QSIZE5 "=<uint32> " + PMD_PARAM_TM_QSIZE6 "=<uint32> " + PMD_PARAM_TM_QSIZE7 "=<uint32> " + PMD_PARAM_TM_QSIZE8 "=<uint32> " + PMD_PARAM_TM_QSIZE9 "=<uint32> " + PMD_PARAM_TM_QSIZE10 "=<uint32> " + PMD_PARAM_TM_QSIZE11 "=<uint32>" + PMD_PARAM_TM_QSIZE12 "=<uint32>" ); diff --git a/drivers/net/softnic/rte_eth_softnic_cli.c b/drivers/net/softnic/rte_eth_softnic_cli.c index 56fc92ba2..f7a3db21a 100644 --- a/drivers/net/softnic/rte_eth_softnic_cli.c +++ b/drivers/net/softnic/rte_eth_softnic_cli.c @@ -566,8 +566,7 @@ queue_node_id(uint32_t n_spp __rte_unused, uint32_t tc_id, uint32_t queue_id) { - return queue_id + - tc_id * RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE + + return queue_id + tc_id + (pipe_id + subport_id * n_pps) * RTE_SCHED_QUEUES_PER_PIPE; } @@ -617,10 +616,20 @@ tmgr_hierarchy_default(struct pmd_internals *softnic, }, }; + uint32_t *shared_shaper_id = + (uint32_t *)calloc(RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE, + sizeof(uint32_t)); + + if (shared_shaper_id == NULL) + return -1; + + memcpy(shared_shaper_id, params->shared_shaper_id.tc, + sizeof(params->shared_shaper_id.tc)); + struct rte_tm_node_params tc_node_params[] = { [0] = { .shaper_profile_id = params->shaper_profile_id.tc[0], - .shared_shaper_id = ¶ms->shared_shaper_id.tc[0], + .shared_shaper_id = &shared_shaper_id[0], .n_shared_shapers = (¶ms->shared_shaper_id.tc_valid[0]) ? 1 : 0, .nonleaf = { @@ -630,7 +639,7 @@ tmgr_hierarchy_default(struct pmd_internals *softnic, [1] = { .shaper_profile_id = params->shaper_profile_id.tc[1], - .shared_shaper_id = ¶ms->shared_shaper_id.tc[1], + .shared_shaper_id = &shared_shaper_id[1], .n_shared_shapers = (¶ms->shared_shaper_id.tc_valid[1]) ? 1 : 0, .nonleaf = { @@ -640,7 +649,7 @@ tmgr_hierarchy_default(struct pmd_internals *softnic, [2] = { .shaper_profile_id = params->shaper_profile_id.tc[2], - .shared_shaper_id = ¶ms->shared_shaper_id.tc[2], + .shared_shaper_id = &shared_shaper_id[2], .n_shared_shapers = (¶ms->shared_shaper_id.tc_valid[2]) ? 1 : 0, .nonleaf = { @@ -650,13 +659,103 @@ tmgr_hierarchy_default(struct pmd_internals *softnic, [3] = { .shaper_profile_id = params->shaper_profile_id.tc[3], - .shared_shaper_id = ¶ms->shared_shaper_id.tc[3], + .shared_shaper_id = &shared_shaper_id[3], .n_shared_shapers = (¶ms->shared_shaper_id.tc_valid[3]) ? 1 : 0, .nonleaf = { .n_sp_priorities = 1, }, }, + + [4] = { + .shaper_profile_id = params->shaper_profile_id.tc[4], + .shared_shaper_id = &shared_shaper_id[4], + .n_shared_shapers = + (¶ms->shared_shaper_id.tc_valid[4]) ? 1 : 0, + .nonleaf = { + .n_sp_priorities = 1, + }, + }, + + [5] = { + .shaper_profile_id = params->shaper_profile_id.tc[5], + .shared_shaper_id = &shared_shaper_id[5], + .n_shared_shapers = + (¶ms->shared_shaper_id.tc_valid[5]) ? 1 : 0, + .nonleaf = { + .n_sp_priorities = 1, + }, + }, + + [6] = { + .shaper_profile_id = params->shaper_profile_id.tc[6], + .shared_shaper_id = &shared_shaper_id[6], + .n_shared_shapers = + (¶ms->shared_shaper_id.tc_valid[6]) ? 1 : 0, + .nonleaf = { + .n_sp_priorities = 1, + }, + }, + + [7] = { + .shaper_profile_id = params->shaper_profile_id.tc[7], + .shared_shaper_id = &shared_shaper_id[7], + .n_shared_shapers = + (¶ms->shared_shaper_id.tc_valid[7]) ? 1 : 0, + .nonleaf = { + .n_sp_priorities = 1, + }, + }, + + [8] = { + .shaper_profile_id = params->shaper_profile_id.tc[8], + .shared_shaper_id = &shared_shaper_id[8], + .n_shared_shapers = + (¶ms->shared_shaper_id.tc_valid[8]) ? 1 : 0, + .nonleaf = { + .n_sp_priorities = 1, + }, + }, + + [9] = { + .shaper_profile_id = params->shaper_profile_id.tc[9], + .shared_shaper_id = &shared_shaper_id[9], + .n_shared_shapers = + (¶ms->shared_shaper_id.tc_valid[9]) ? 1 : 0, + .nonleaf = { + .n_sp_priorities = 1, + }, + }, + + [10] = { + .shaper_profile_id = params->shaper_profile_id.tc[10], + .shared_shaper_id = &shared_shaper_id[10], + .n_shared_shapers = + (¶ms->shared_shaper_id.tc_valid[10]) ? 1 : 0, + .nonleaf = { + .n_sp_priorities = 1, + }, + }, + + [11] = { + .shaper_profile_id = params->shaper_profile_id.tc[11], + .shared_shaper_id = &shared_shaper_id[11], + .n_shared_shapers = + (¶ms->shared_shaper_id.tc_valid[11]) ? 1 : 0, + .nonleaf = { + .n_sp_priorities = 1, + }, + }, + + [12] = { + .shaper_profile_id = params->shaper_profile_id.tc[12], + .shared_shaper_id = &shared_shaper_id[12], + .n_shared_shapers = + (¶ms->shared_shaper_id.tc_valid[12]) ? 1 : 0, + .nonleaf = { + .n_sp_priorities = 1, + }, + }, }; struct rte_tm_node_params queue_node_params = { @@ -730,7 +829,23 @@ tmgr_hierarchy_default(struct pmd_internals *softnic, return -1; /* Hierarchy level 4: Queue nodes */ - for (q = 0; q < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; q++) { + if (t == RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1) { + /* Best-effort traffic class queues */ + for (q = 0; q < RTE_SCHED_BE_QUEUES_PER_PIPE; q++) { + status = rte_tm_node_add(port_id, + queue_node_id(n_spp, n_pps, s, p, t, q), + tc_node_id(n_spp, n_pps, s, p, t), + 0, + params->weight.queue[q], + RTE_TM_NODE_LEVEL_ID_ANY, + &queue_node_params, + &error); + if (status) + return -1; + } + } else { + /* Strict-priority traffic class queues */ + q = 0; status = rte_tm_node_add(port_id, queue_node_id(n_spp, n_pps, s, p, t, q), tc_node_id(n_spp, n_pps, s, p, t), @@ -741,7 +856,7 @@ tmgr_hierarchy_default(struct pmd_internals *softnic, &error); if (status) return -1; - } /* Queue */ + } } /* TC */ } /* Pipe */ } /* Subport */ @@ -762,13 +877,31 @@ tmgr_hierarchy_default(struct pmd_internals *softnic, * tc1 <profile_id> * tc2 <profile_id> * tc3 <profile_id> + * tc4 <profile_id> + * tc5 <profile_id> + * tc6 <profile_id> + * tc7 <profile_id> + * tc8 <profile_id> + * tc9 <profile_id> + * tc10 <profile_id> + * tc11 <profile_id> + * tc12 <profile_id> * shared shaper * tc0 <id | none> * tc1 <id | none> * tc2 <id | none> * tc3 <id | none> + * tc4 <id | none> + * tc5 <id | none> + * tc6 <id | none> + * tc7 <id | none> + * tc8 <id | none> + * tc9 <id | none> + * tc10 <id | none> + * tc11 <id | none> + * tc12 <id | none> * weight - * queue <q0> ... <q15> + * queue <q12> ... <q15> */ static void cmd_tmgr_hierarchy_default(struct pmd_internals *softnic, @@ -778,11 +911,11 @@ cmd_tmgr_hierarchy_default(struct pmd_internals *softnic, size_t out_size) { struct tmgr_hierarchy_default_params p; - int i, status; + int i, j, status; memset(&p, 0, sizeof(p)); - if (n_tokens != 50) { + if (n_tokens != 74) { snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); return; } @@ -894,27 +1027,118 @@ cmd_tmgr_hierarchy_default(struct pmd_internals *softnic, return; } + if (strcmp(tokens[22], "tc4") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc4"); + return; + } + + if (softnic_parser_read_uint32(&p.shaper_profile_id.tc[4], tokens[23]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "tc4 profile id"); + return; + } + + if (strcmp(tokens[24], "tc5") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc5"); + return; + } + + if (softnic_parser_read_uint32(&p.shaper_profile_id.tc[5], tokens[25]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "tc5 profile id"); + return; + } + + if (strcmp(tokens[26], "tc6") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc6"); + return; + } + + if (softnic_parser_read_uint32(&p.shaper_profile_id.tc[6], tokens[27]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "tc6 profile id"); + return; + } + + if (strcmp(tokens[28], "tc7") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc7"); + return; + } + + if (softnic_parser_read_uint32(&p.shaper_profile_id.tc[7], tokens[29]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "tc7 profile id"); + return; + } + + if (strcmp(tokens[30], "tc8") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc8"); + return; + } + + if (softnic_parser_read_uint32(&p.shaper_profile_id.tc[8], tokens[31]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "tc8 profile id"); + return; + } + + if (strcmp(tokens[32], "tc9") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc9"); + return; + } + + if (softnic_parser_read_uint32(&p.shaper_profile_id.tc[9], tokens[33]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "tc9 profile id"); + return; + } + + if (strcmp(tokens[34], "tc10") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc10"); + return; + } + + if (softnic_parser_read_uint32(&p.shaper_profile_id.tc[10], tokens[35]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "tc10 profile id"); + return; + } + + if (strcmp(tokens[36], "tc11") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc11"); + return; + } + + if (softnic_parser_read_uint32(&p.shaper_profile_id.tc[11], tokens[37]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "tc11 profile id"); + return; + } + + if (strcmp(tokens[38], "tc12") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc12"); + return; + } + + if (softnic_parser_read_uint32(&p.shaper_profile_id.tc[12], tokens[39]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "tc12 profile id"); + return; + } + /* Shared shaper */ - if (strcmp(tokens[22], "shared") != 0) { + if (strcmp(tokens[40], "shared") != 0) { snprintf(out, out_size, MSG_ARG_NOT_FOUND, "shared"); return; } - if (strcmp(tokens[23], "shaper") != 0) { + if (strcmp(tokens[41], "shaper") != 0) { snprintf(out, out_size, MSG_ARG_NOT_FOUND, "shaper"); return; } - if (strcmp(tokens[24], "tc0") != 0) { + if (strcmp(tokens[42], "tc0") != 0) { snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc0"); return; } - if (strcmp(tokens[25], "none") == 0) + if (strcmp(tokens[43], "none") == 0) p.shared_shaper_id.tc_valid[0] = 0; else { - if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[0], tokens[25]) != 0) { + if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[0], + tokens[43]) != 0) { snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc0"); return; } @@ -922,15 +1146,16 @@ cmd_tmgr_hierarchy_default(struct pmd_internals *softnic, p.shared_shaper_id.tc_valid[0] = 1; } - if (strcmp(tokens[26], "tc1") != 0) { + if (strcmp(tokens[44], "tc1") != 0) { snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc1"); return; } - if (strcmp(tokens[27], "none") == 0) + if (strcmp(tokens[45], "none") == 0) p.shared_shaper_id.tc_valid[1] = 0; else { - if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[1], tokens[27]) != 0) { + if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[1], + tokens[45]) != 0) { snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc1"); return; } @@ -938,15 +1163,16 @@ cmd_tmgr_hierarchy_default(struct pmd_internals *softnic, p.shared_shaper_id.tc_valid[1] = 1; } - if (strcmp(tokens[28], "tc2") != 0) { + if (strcmp(tokens[46], "tc2") != 0) { snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc2"); return; } - if (strcmp(tokens[29], "none") == 0) + if (strcmp(tokens[47], "none") == 0) p.shared_shaper_id.tc_valid[2] = 0; else { - if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[2], tokens[29]) != 0) { + if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[2], + tokens[47]) != 0) { snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc2"); return; } @@ -954,15 +1180,16 @@ cmd_tmgr_hierarchy_default(struct pmd_internals *softnic, p.shared_shaper_id.tc_valid[2] = 1; } - if (strcmp(tokens[30], "tc3") != 0) { + if (strcmp(tokens[48], "tc3") != 0) { snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc3"); return; } - if (strcmp(tokens[31], "none") == 0) + if (strcmp(tokens[49], "none") == 0) p.shared_shaper_id.tc_valid[3] = 0; else { - if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[3], tokens[31]) != 0) { + if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[3], + tokens[49]) != 0) { snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc3"); return; } @@ -970,22 +1197,181 @@ cmd_tmgr_hierarchy_default(struct pmd_internals *softnic, p.shared_shaper_id.tc_valid[3] = 1; } + if (strcmp(tokens[50], "tc4") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc4"); + return; + } + + if (strcmp(tokens[51], "none") == 0) + p.shared_shaper_id.tc_valid[4] = 0; + else { + if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[4], + tokens[51]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc4"); + return; + } + + p.shared_shaper_id.tc_valid[4] = 1; + } + + if (strcmp(tokens[52], "tc5") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc5"); + return; + } + + if (strcmp(tokens[53], "none") == 0) + p.shared_shaper_id.tc_valid[5] = 0; + else { + if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[5], + tokens[53]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc5"); + return; + } + + p.shared_shaper_id.tc_valid[5] = 1; + } + + if (strcmp(tokens[54], "tc6") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc6"); + return; + } + + if (strcmp(tokens[55], "none") == 0) + p.shared_shaper_id.tc_valid[6] = 0; + else { + if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[6], + tokens[55]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc6"); + return; + } + + p.shared_shaper_id.tc_valid[6] = 1; + } + + if (strcmp(tokens[56], "tc7") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc7"); + return; + } + + if (strcmp(tokens[57], "none") == 0) + p.shared_shaper_id.tc_valid[7] = 0; + else { + if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[7], + tokens[57]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc7"); + return; + } + + p.shared_shaper_id.tc_valid[7] = 1; + } + + if (strcmp(tokens[58], "tc8") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc8"); + return; + } + + if (strcmp(tokens[59], "none") == 0) + p.shared_shaper_id.tc_valid[8] = 0; + else { + if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[8], + tokens[59]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc8"); + return; + } + + p.shared_shaper_id.tc_valid[8] = 1; + } + + if (strcmp(tokens[60], "tc9") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc9"); + return; + } + + if (strcmp(tokens[61], "none") == 0) + p.shared_shaper_id.tc_valid[9] = 0; + else { + if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[9], + tokens[61]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc9"); + return; + } + + p.shared_shaper_id.tc_valid[9] = 1; + } + + if (strcmp(tokens[62], "tc10") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc10"); + return; + } + + if (strcmp(tokens[63], "none") == 0) + p.shared_shaper_id.tc_valid[10] = 0; + else { + if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[10], + tokens[63]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc10"); + return; + } + + p.shared_shaper_id.tc_valid[10] = 1; + } + + if (strcmp(tokens[64], "tc11") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc11"); + return; + } + + if (strcmp(tokens[65], "none") == 0) + p.shared_shaper_id.tc_valid[11] = 0; + else { + if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[11], + tokens[65]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc11"); + return; + } + + p.shared_shaper_id.tc_valid[11] = 1; + } + + if (strcmp(tokens[66], "tc12") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "tc12"); + return; + } + + if (strcmp(tokens[67], "none") == 0) + p.shared_shaper_id.tc_valid[12] = 0; + else { + if (softnic_parser_read_uint32(&p.shared_shaper_id.tc[12], + tokens[67]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "shared shaper tc12"); + return; + } + + p.shared_shaper_id.tc_valid[12] = 1; + } + /* Weight */ - if (strcmp(tokens[32], "weight") != 0) { + if (strcmp(tokens[68], "weight") != 0) { snprintf(out, out_size, MSG_ARG_NOT_FOUND, "weight"); return; } - if (strcmp(tokens[33], "queue") != 0) { + if (strcmp(tokens[69], "queue") != 0) { snprintf(out, out_size, MSG_ARG_NOT_FOUND, "queue"); return; } - for (i = 0; i < 16; i++) { - if (softnic_parser_read_uint32(&p.weight.queue[i], tokens[34 + i]) != 0) { - snprintf(out, out_size, MSG_ARG_INVALID, "weight queue"); - return; + for (i = 0, j = 0; i < 16; i++) { + if (i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1) { + p.weight.queue[i] = 1; + } else { + if (softnic_parser_read_uint32(&p.weight.queue[i], + tokens[70 + j]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "weight queue"); + return; + } + j++; } } diff --git a/drivers/net/softnic/rte_eth_softnic_internals.h b/drivers/net/softnic/rte_eth_softnic_internals.h index 415434d0d..0e3846893 100644 --- a/drivers/net/softnic/rte_eth_softnic_internals.h +++ b/drivers/net/softnic/rte_eth_softnic_internals.h @@ -161,13 +161,15 @@ TAILQ_HEAD(softnic_link_list, softnic_link); #define TM_MAX_PIPES_PER_SUBPORT 4096 #endif +#ifndef TM_MAX_PIPE_PROFILE +#define TM_MAX_PIPE_PROFILE 256 +#endif struct tm_params { struct rte_sched_port_params port_params; struct rte_sched_subport_params subport_params[TM_MAX_SUBPORTS]; - struct rte_sched_pipe_params - pipe_profiles[RTE_SCHED_PIPE_PROFILES_PER_PORT]; + struct rte_sched_pipe_params pipe_profiles[TM_MAX_PIPE_PROFILE]; uint32_t n_pipe_profiles; uint32_t pipe_to_profile[TM_MAX_SUBPORTS * TM_MAX_PIPES_PER_SUBPORT]; }; diff --git a/drivers/net/softnic/rte_eth_softnic_tm.c b/drivers/net/softnic/rte_eth_softnic_tm.c index 58744a9eb..efbf34dd3 100644 --- a/drivers/net/softnic/rte_eth_softnic_tm.c +++ b/drivers/net/softnic/rte_eth_softnic_tm.c @@ -367,7 +367,8 @@ tm_level_get_max_nodes(struct rte_eth_dev *dev, enum tm_node_level level) { struct pmd_internals *p = dev->data->dev_private; uint32_t n_queues_max = p->params.tm.n_queues; - uint32_t n_tc_max = n_queues_max / RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; + uint32_t n_tc_max = + (n_queues_max * RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE) / RTE_SCHED_QUEUES_PER_PIPE; uint32_t n_pipes_max = n_tc_max / RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; uint32_t n_subports_max = n_pipes_max; uint32_t n_root_max = 1; @@ -625,10 +626,10 @@ static const struct rte_tm_level_capabilities tm_level_cap[] = { .shaper_shared_n_max = 1, .sched_n_children_max = - RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS, + RTE_SCHED_BE_QUEUES_PER_PIPE, .sched_sp_n_priorities_max = 1, .sched_wfq_n_children_per_group_max = - RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS, + RTE_SCHED_BE_QUEUES_PER_PIPE, .sched_wfq_n_groups_max = 1, .sched_wfq_weight_max = UINT32_MAX, @@ -793,10 +794,10 @@ static const struct rte_tm_node_capabilities tm_node_cap[] = { {.nonleaf = { .sched_n_children_max = - RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS, + RTE_SCHED_BE_QUEUES_PER_PIPE, .sched_sp_n_priorities_max = 1, .sched_wfq_n_children_per_group_max = - RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS, + RTE_SCHED_BE_QUEUES_PER_PIPE, .sched_wfq_n_groups_max = 1, .sched_wfq_weight_max = UINT32_MAX, } }, @@ -2027,9 +2028,7 @@ pipe_profile_build(struct rte_eth_dev *dev, /* Traffic Class (TC) */ pp->tc_period = PIPE_TC_PERIOD; -#ifdef RTE_SCHED_SUBPORT_TC_OV pp->tc_ov_weight = np->weight; -#endif TAILQ_FOREACH(nt, nl, node) { uint32_t queue_id = 0; @@ -2043,15 +2042,13 @@ pipe_profile_build(struct rte_eth_dev *dev, /* Queue */ TAILQ_FOREACH(nq, nl, node) { - uint32_t pipe_queue_id; if (nq->level != TM_NODE_LEVEL_QUEUE || nq->parent_node_id != nt->node_id) continue; - pipe_queue_id = nt->priority * - RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS + queue_id; - pp->wrr_weights[pipe_queue_id] = nq->weight; + if (nt->priority == RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1) + pp->wrr_weights[queue_id] = nq->weight; queue_id++; } @@ -2065,7 +2062,7 @@ pipe_profile_free_exists(struct rte_eth_dev *dev, struct pmd_internals *p = dev->data->dev_private; struct tm_params *t = &p->soft.tm.params; - if (t->n_pipe_profiles < RTE_SCHED_PIPE_PROFILES_PER_PORT) { + if (t->n_pipe_profiles < TM_MAX_PIPE_PROFILE) { *pipe_profile_id = t->n_pipe_profiles; return 1; } @@ -2217,6 +2214,7 @@ wred_profiles_set(struct rte_eth_dev *dev) { struct pmd_internals *p = dev->data->dev_private; struct rte_sched_port_params *pp = &p->soft.tm.params.port_params; + uint32_t tc_id; enum rte_color color; @@ -2332,7 +2330,7 @@ hierarchy_commit_check(struct rte_eth_dev *dev, struct rte_tm_error *error) rte_strerror(EINVAL)); } - /* Each pipe has exactly 4 TCs, with exactly one TC for each priority */ + /* Each pipe has exactly 13 TCs, with exactly one TC for each priority */ TAILQ_FOREACH(np, nl, node) { uint32_t mask = 0, mask_expected = RTE_LEN2MASK(RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE, @@ -2364,12 +2362,14 @@ hierarchy_commit_check(struct rte_eth_dev *dev, struct rte_tm_error *error) rte_strerror(EINVAL)); } - /* Each TC has exactly 4 packet queues. */ + /** Each Strict priority TC has exactly 1 packet queues while + * lowest priority TC (Best-effort) has 4 queues. + */ TAILQ_FOREACH(nt, nl, node) { if (nt->level != TM_NODE_LEVEL_TC) continue; - if (nt->n_children != RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS) + if (nt->n_children != 1 && nt->n_children != RTE_SCHED_BE_QUEUES_PER_PIPE) return -rte_tm_error_set(error, EINVAL, RTE_TM_ERROR_TYPE_UNSPECIFIED, @@ -2531,9 +2531,19 @@ hierarchy_blueprints_create(struct rte_eth_dev *dev) p->params.tm.qsize[1], p->params.tm.qsize[2], p->params.tm.qsize[3], + p->params.tm.qsize[4], + p->params.tm.qsize[5], + p->params.tm.qsize[6], + p->params.tm.qsize[7], + p->params.tm.qsize[8], + p->params.tm.qsize[9], + p->params.tm.qsize[10], + p->params.tm.qsize[11], + p->params.tm.qsize[12], }, .pipe_profiles = t->pipe_profiles, .n_pipe_profiles = t->n_pipe_profiles, + .n_max_pipe_profiles = TM_MAX_PIPE_PROFILE, }; wred_profiles_set(dev); @@ -2566,8 +2576,17 @@ hierarchy_blueprints_create(struct rte_eth_dev *dev) tc_rate[1], tc_rate[2], tc_rate[3], - }, - .tc_period = SUBPORT_TC_PERIOD, + tc_rate[4], + tc_rate[5], + tc_rate[6], + tc_rate[7], + tc_rate[8], + tc_rate[9], + tc_rate[10], + tc_rate[11], + tc_rate[12], + }, + .tc_period = SUBPORT_TC_PERIOD, }; subport_id++; @@ -2657,7 +2676,6 @@ update_queue_weight(struct rte_eth_dev *dev, uint32_t queue_id = tm_node_queue_id(dev, nq); struct tm_node *nt = nq->parent_node; - uint32_t tc_id = tm_node_tc_id(dev, nt); struct tm_node *np = nt->parent_node; uint32_t pipe_id = tm_node_pipe_id(dev, np); @@ -2665,8 +2683,8 @@ update_queue_weight(struct rte_eth_dev *dev, struct tm_node *ns = np->parent_node; uint32_t subport_id = tm_node_subport_id(dev, ns); - uint32_t pipe_queue_id = - tc_id * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS + queue_id; + uint32_t pipe_be_queue_id = + queue_id - (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1); struct rte_sched_pipe_params *profile0 = pipe_profile_get(dev, np); struct rte_sched_pipe_params profile1; @@ -2674,7 +2692,7 @@ update_queue_weight(struct rte_eth_dev *dev, /* Derive new pipe profile. */ memcpy(&profile1, profile0, sizeof(profile1)); - profile1.wrr_weights[pipe_queue_id] = (uint8_t)weight; + profile1.wrr_weights[pipe_be_queue_id] = (uint8_t)weight; /* Since implementation does not allow adding more pipe profiles after * port configuration, the pipe configuration can be successfully @@ -3020,12 +3038,11 @@ tm_port_queue_id(struct rte_eth_dev *dev, uint32_t port_pipe_id = port_subport_id * n_pipes_per_subport + subport_pipe_id; - uint32_t port_tc_id = - port_pipe_id * RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE + pipe_tc_id; + uint32_t port_queue_id = - port_tc_id * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS + tc_queue_id; + port_pipe_id * RTE_SCHED_QUEUES_PER_PIPE + pipe_tc_id + tc_queue_id; - return port_queue_id; + return port_queue_id; } static int @@ -3138,7 +3155,7 @@ read_pipe_stats(struct rte_eth_dev *dev, struct tm_node *ns = np->parent_node; uint32_t subport_id = tm_node_subport_id(dev, ns); - + uint32_t tc_id, queue_id; uint32_t i; /* Stats read */ @@ -3146,11 +3163,19 @@ read_pipe_stats(struct rte_eth_dev *dev, struct rte_sched_queue_stats s; uint16_t qlen; + if (i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1) { + tc_id = i; + queue_id = i; + } else { + tc_id = RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1; + queue_id = i - tc_id; + } + uint32_t qid = tm_port_queue_id(dev, subport_id, pipe_id, - i / RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS, - i % RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS); + tc_id, + queue_id); int status = rte_sched_queue_read_stats(SCHED(p), qid, @@ -3198,21 +3223,20 @@ read_tc_stats(struct rte_eth_dev *dev, struct tm_node *ns = np->parent_node; uint32_t subport_id = tm_node_subport_id(dev, ns); - - uint32_t i; + struct rte_sched_queue_stats s; + uint32_t qid, i; + uint16_t qlen; + int status; /* Stats read */ - for (i = 0; i < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; i++) { - struct rte_sched_queue_stats s; - uint16_t qlen; - - uint32_t qid = tm_port_queue_id(dev, + if (tc_id < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1) { + qid = tm_port_queue_id(dev, subport_id, pipe_id, tc_id, - i); + 0); - int status = rte_sched_queue_read_stats(SCHED(p), + status = rte_sched_queue_read_stats(SCHED(p), qid, &s, &qlen); @@ -3226,6 +3250,29 @@ read_tc_stats(struct rte_eth_dev *dev, nt->stats.leaf.n_bytes_dropped[RTE_COLOR_GREEN] += s.n_bytes_dropped; nt->stats.leaf.n_pkts_queued = qlen; + } else { + for (i = 0; i < RTE_SCHED_BE_QUEUES_PER_PIPE; i++) { + qid = tm_port_queue_id(dev, + subport_id, + pipe_id, + tc_id, + i); + + status = rte_sched_queue_read_stats(SCHED(p), + qid, + &s, + &qlen); + if (status) + return status; + + /* Stats accumulate */ + nt->stats.n_pkts += s.n_pkts - s.n_pkts_dropped; + nt->stats.n_bytes += s.n_bytes - s.n_bytes_dropped; + nt->stats.leaf.n_pkts_dropped[RTE_COLOR_GREEN] += s.n_pkts_dropped; + nt->stats.leaf.n_bytes_dropped[RTE_COLOR_GREEN] += + s.n_bytes_dropped; + nt->stats.leaf.n_pkts_queued = qlen; + } } /* Stats copy */ -- 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* [dpdk-dev] [PATCH v5 08/11] test_sched: modify tests for config flexibility 2019-07-17 14:42 ` [dpdk-dev] [PATCH v5 00/11] sched: feature enhancements Jasvinder Singh ` (6 preceding siblings ...) 2019-07-17 14:42 ` [dpdk-dev] [PATCH v5 07/11] net/softnic: add config flexibility to softnic tm Jasvinder Singh @ 2019-07-17 14:42 ` Jasvinder Singh 2019-07-17 14:42 ` [dpdk-dev] [PATCH v5 09/11] examples/ip_pipeline: add config flexibility to tm function Jasvinder Singh ` (3 subsequent siblings) 11 siblings, 0 replies; 163+ messages in thread From: Jasvinder Singh @ 2019-07-17 14:42 UTC (permalink / raw) To: dev; +Cc: cristian.dumitrescu, Abraham Tovar, Lukasz Krakowiak update unit tests for configuration flexibility of pipe traffic classes and queues size. Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com> Signed-off-by: Abraham Tovar <abrahamx.tovar@intel.com> Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com> --- app/test/test_sched.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/app/test/test_sched.c b/app/test/test_sched.c index 36fa2d425..afe0b0765 100644 --- a/app/test/test_sched.c +++ b/app/test/test_sched.c @@ -20,14 +20,16 @@ #define SUBPORT 0 #define PIPE 1 #define TC 2 -#define QUEUE 3 +#define QUEUE 0 static struct rte_sched_subport_params subport_param[] = { { .tb_rate = 1250000000, .tb_size = 1000000, - .tc_rate = {1250000000, 1250000000, 1250000000, 1250000000}, + .tc_rate = {1250000000, 1250000000, 1250000000, 1250000000, + 1250000000, 1250000000, 1250000000, 1250000000, 1250000000, + 1250000000, 1250000000, 1250000000, 1250000000}, .tc_period = 10, }, }; @@ -37,8 +39,10 @@ static struct rte_sched_pipe_params pipe_profile[] = { .tb_rate = 305175, .tb_size = 1000000, - .tc_rate = {305175, 305175, 305175, 305175}, + .tc_rate = {305175, 305175, 305175, 305175, 305175, 305175, + 305175, 305175, 305175, 305175, 305175, 305175, 305175}, .tc_period = 40, + .tc_ov_weight = 1, .wrr_weights = {1, 1, 1, 1}, }, @@ -51,9 +55,10 @@ static struct rte_sched_port_params port_param = { .frame_overhead = RTE_SCHED_FRAME_OVERHEAD_DEFAULT, .n_subports_per_port = 1, .n_pipes_per_subport = 1024, - .qsize = {32, 32, 32, 32}, + .qsize = {32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32}, .pipe_profiles = pipe_profile, .n_pipe_profiles = 1, + .n_max_pipe_profiles = 1, }; #define NB_MBUF 32 -- 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* [dpdk-dev] [PATCH v5 09/11] examples/ip_pipeline: add config flexibility to tm function 2019-07-17 14:42 ` [dpdk-dev] [PATCH v5 00/11] sched: feature enhancements Jasvinder Singh ` (7 preceding siblings ...) 2019-07-17 14:42 ` [dpdk-dev] [PATCH v5 08/11] test_sched: modify tests for config flexibility Jasvinder Singh @ 2019-07-17 14:42 ` Jasvinder Singh 2019-07-17 14:42 ` [dpdk-dev] [PATCH v5 10/11] examples/qos_sched: add tc and queue config flexibility Jasvinder Singh ` (2 subsequent siblings) 11 siblings, 0 replies; 163+ messages in thread From: Jasvinder Singh @ 2019-07-17 14:42 UTC (permalink / raw) To: dev; +Cc: cristian.dumitrescu, Abraham Tovar, Lukasz Krakowiak Update ip pipeline sample app for configuration flexiblity of pipe traffic classes and queues. Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com> Signed-off-by: Abraham Tovar <abrahamx.tovar@intel.com> Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com> --- examples/ip_pipeline/cli.c | 43 +++++++++++++++----------- examples/ip_pipeline/tmgr.h | 4 +-- lib/librte_pipeline/rte_table_action.c | 1 - lib/librte_pipeline/rte_table_action.h | 4 +-- 4 files changed, 29 insertions(+), 23 deletions(-) diff --git a/examples/ip_pipeline/cli.c b/examples/ip_pipeline/cli.c index 309b2936e..bfaa7f45e 100644 --- a/examples/ip_pipeline/cli.c +++ b/examples/ip_pipeline/cli.c @@ -377,7 +377,9 @@ cmd_swq(char **tokens, static const char cmd_tmgr_subport_profile_help[] = "tmgr subport profile\n" " <tb_rate> <tb_size>\n" -" <tc0_rate> <tc1_rate> <tc2_rate> <tc3_rate>\n" +" <tc0_rate> <tc1_rate> <tc2_rate> <tc3_rate> <tc4_rate>" +" <tc5_rate> <tc6_rate> <tc7_rate> <tc8_rate>" +" <tc9_rate> <tc10_rate> <tc11_rate> <tc12_rate>\n" " <tc_period>\n"; static void @@ -389,7 +391,7 @@ cmd_tmgr_subport_profile(char **tokens, struct rte_sched_subport_params p; int status, i; - if (n_tokens != 10) { + if (n_tokens != 19) { snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); return; } @@ -410,7 +412,7 @@ cmd_tmgr_subport_profile(char **tokens, return; } - if (parser_read_uint32(&p.tc_period, tokens[9]) != 0) { + if (parser_read_uint32(&p.tc_period, tokens[18]) != 0) { snprintf(out, out_size, MSG_ARG_INVALID, "tc_period"); return; } @@ -425,10 +427,12 @@ cmd_tmgr_subport_profile(char **tokens, static const char cmd_tmgr_pipe_profile_help[] = "tmgr pipe profile\n" " <tb_rate> <tb_size>\n" -" <tc0_rate> <tc1_rate> <tc2_rate> <tc3_rate>\n" +" <tc0_rate> <tc1_rate> <tc2_rate> <tc3_rate> <tc4_rate>" +" <tc5_rate> <tc6_rate> <tc7_rate> <tc8_rate>" +" <tc9_rate> <tc10_rate> <tc11_rate> <tc12_rate>\n" " <tc_period>\n" " <tc_ov_weight>\n" -" <wrr_weight0..15>\n"; +" <wrr_weight0..3>\n"; static void cmd_tmgr_pipe_profile(char **tokens, @@ -439,7 +443,7 @@ cmd_tmgr_pipe_profile(char **tokens, struct rte_sched_pipe_params p; int status, i; - if (n_tokens != 27) { + if (n_tokens != 24) { snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); return; } @@ -460,20 +464,20 @@ cmd_tmgr_pipe_profile(char **tokens, return; } - if (parser_read_uint32(&p.tc_period, tokens[9]) != 0) { + if (parser_read_uint32(&p.tc_period, tokens[18]) != 0) { snprintf(out, out_size, MSG_ARG_INVALID, "tc_period"); return; } #ifdef RTE_SCHED_SUBPORT_TC_OV - if (parser_read_uint8(&p.tc_ov_weight, tokens[10]) != 0) { + if (parser_read_uint8(&p.tc_ov_weight, tokens[19]) != 0) { snprintf(out, out_size, MSG_ARG_INVALID, "tc_ov_weight"); return; } #endif - for (i = 0; i < RTE_SCHED_QUEUES_PER_PIPE; i++) - if (parser_read_uint8(&p.wrr_weights[i], tokens[11 + i]) != 0) { + for (i = 0; i < RTE_SCHED_BE_QUEUES_PER_PIPE; i++) + if (parser_read_uint8(&p.wrr_weights[i], tokens[20 + i]) != 0) { snprintf(out, out_size, MSG_ARG_INVALID, "wrr_weights"); return; } @@ -490,7 +494,10 @@ static const char cmd_tmgr_help[] = " rate <rate>\n" " spp <n_subports_per_port>\n" " pps <n_pipes_per_subport>\n" -" qsize <qsize_tc0> <qsize_tc1> <qsize_tc2> <qsize_tc3>\n" +" qsize <qsize_tc0> <qsize_tc1> <qsize_tc2>" +" <qsize_tc3> <qsize_tc4> <qsize_tc5> <qsize_tc6>" +" <qsize_tc7> <qsize_tc8> <qsize_tc9> <qsize_tc10>" +" <qsize_tc11> <qsize_tc12>\n" " fo <frame_overhead>\n" " mtu <mtu>\n" " cpu <cpu_id>\n"; @@ -506,7 +513,7 @@ cmd_tmgr(char **tokens, struct tmgr_port *tmgr_port; int i; - if (n_tokens != 19) { + if (n_tokens != 28) { snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); return; } @@ -554,32 +561,32 @@ cmd_tmgr(char **tokens, return; } - if (strcmp(tokens[13], "fo") != 0) { + if (strcmp(tokens[22], "fo") != 0) { snprintf(out, out_size, MSG_ARG_NOT_FOUND, "fo"); return; } - if (parser_read_uint32(&p.frame_overhead, tokens[14]) != 0) { + if (parser_read_uint32(&p.frame_overhead, tokens[23]) != 0) { snprintf(out, out_size, MSG_ARG_INVALID, "frame_overhead"); return; } - if (strcmp(tokens[15], "mtu") != 0) { + if (strcmp(tokens[24], "mtu") != 0) { snprintf(out, out_size, MSG_ARG_NOT_FOUND, "mtu"); return; } - if (parser_read_uint32(&p.mtu, tokens[16]) != 0) { + if (parser_read_uint32(&p.mtu, tokens[25]) != 0) { snprintf(out, out_size, MSG_ARG_INVALID, "mtu"); return; } - if (strcmp(tokens[17], "cpu") != 0) { + if (strcmp(tokens[26], "cpu") != 0) { snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cpu"); return; } - if (parser_read_uint32(&p.cpu_id, tokens[18]) != 0) { + if (parser_read_uint32(&p.cpu_id, tokens[27]) != 0) { snprintf(out, out_size, MSG_ARG_INVALID, "cpu_id"); return; } diff --git a/examples/ip_pipeline/tmgr.h b/examples/ip_pipeline/tmgr.h index 0b497e795..8703a2e00 100644 --- a/examples/ip_pipeline/tmgr.h +++ b/examples/ip_pipeline/tmgr.h @@ -39,11 +39,11 @@ tmgr_port_find(const char *name); struct tmgr_port_params { uint32_t rate; uint32_t n_subports_per_port; - uint32_t n_pipes_per_subport; - uint16_t qsize[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; uint32_t frame_overhead; uint32_t mtu; uint32_t cpu_id; + uint32_t n_pipes_per_subport; + uint16_t qsize[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; }; int diff --git a/lib/librte_pipeline/rte_table_action.c b/lib/librte_pipeline/rte_table_action.c index a54ec46bc..47d7efbc1 100644 --- a/lib/librte_pipeline/rte_table_action.c +++ b/lib/librte_pipeline/rte_table_action.c @@ -401,7 +401,6 @@ pkt_work_tm(struct rte_mbuf *mbuf, { struct dscp_table_entry_data *dscp_entry = &dscp_table->entry[dscp]; uint32_t queue_id = data->queue_id | - (dscp_entry->tc << 2) | dscp_entry->tc_queue; rte_mbuf_sched_set(mbuf, queue_id, dscp_entry->tc, (uint8_t)dscp_entry->color); diff --git a/lib/librte_pipeline/rte_table_action.h b/lib/librte_pipeline/rte_table_action.h index 44041b5c9..82bc9d9ac 100644 --- a/lib/librte_pipeline/rte_table_action.h +++ b/lib/librte_pipeline/rte_table_action.h @@ -181,10 +181,10 @@ struct rte_table_action_lb_params { * RTE_TABLE_ACTION_MTR */ /** Max number of traffic classes (TCs). */ -#define RTE_TABLE_ACTION_TC_MAX 4 +#define RTE_TABLE_ACTION_TC_MAX 16 /** Max number of queues per traffic class. */ -#define RTE_TABLE_ACTION_TC_QUEUE_MAX 4 +#define RTE_TABLE_ACTION_TC_QUEUE_MAX 16 /** Differentiated Services Code Point (DSCP) translation table entry. */ struct rte_table_action_dscp_table_entry { -- 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* [dpdk-dev] [PATCH v5 10/11] examples/qos_sched: add tc and queue config flexibility 2019-07-17 14:42 ` [dpdk-dev] [PATCH v5 00/11] sched: feature enhancements Jasvinder Singh ` (8 preceding siblings ...) 2019-07-17 14:42 ` [dpdk-dev] [PATCH v5 09/11] examples/ip_pipeline: add config flexibility to tm function Jasvinder Singh @ 2019-07-17 14:42 ` Jasvinder Singh 2019-07-17 14:42 ` [dpdk-dev] [PATCH v5 11/11] sched: remove redundant macros Jasvinder Singh 2019-07-18 22:57 ` [dpdk-dev] [PATCH v5 00/11] sched: feature enhancements Dumitrescu, Cristian 11 siblings, 0 replies; 163+ messages in thread From: Jasvinder Singh @ 2019-07-17 14:42 UTC (permalink / raw) To: dev; +Cc: cristian.dumitrescu, Abraham Tovar, Lukasz Krakowiak Update qos sched sample app for configuration flexibility of pipe traffic classes and queues. Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com> Signed-off-by: Abraham Tovar <abrahamx.tovar@intel.com> Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com> --- examples/qos_sched/app_thread.c | 11 +- examples/qos_sched/cfg_file.c | 130 +++++--- examples/qos_sched/init.c | 63 +++- examples/qos_sched/main.h | 4 + examples/qos_sched/profile.cfg | 67 +++- examples/qos_sched/profile_ov.cfg | 54 +++- examples/qos_sched/stats.c | 517 +++++++++++++++++------------- 7 files changed, 550 insertions(+), 296 deletions(-) diff --git a/examples/qos_sched/app_thread.c b/examples/qos_sched/app_thread.c index e14b275e3..fd47b8f62 100644 --- a/examples/qos_sched/app_thread.c +++ b/examples/qos_sched/app_thread.c @@ -20,13 +20,11 @@ * QoS parameters are encoded as follows: * Outer VLAN ID defines subport * Inner VLAN ID defines pipe - * Destination IP 0.0.XXX.0 defines traffic class * Destination IP host (0.0.0.XXX) defines queue * Values below define offset to each field from start of frame */ #define SUBPORT_OFFSET 7 #define PIPE_OFFSET 9 -#define TC_OFFSET 20 #define QUEUE_OFFSET 20 #define COLOR_OFFSET 19 @@ -35,15 +33,16 @@ get_pkt_sched(struct rte_mbuf *m, uint32_t *subport, uint32_t *pipe, uint32_t *traffic_class, uint32_t *queue, uint32_t *color) { uint16_t *pdata = rte_pktmbuf_mtod(m, uint16_t *); + uint16_t pipe_queue; *subport = (rte_be_to_cpu_16(pdata[SUBPORT_OFFSET]) & 0x0FFF) & (port_params.n_subports_per_port - 1); /* Outer VLAN ID*/ *pipe = (rte_be_to_cpu_16(pdata[PIPE_OFFSET]) & 0x0FFF) & (port_params.n_pipes_per_subport - 1); /* Inner VLAN ID */ - *traffic_class = (pdata[QUEUE_OFFSET] & 0x0F) & - (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1); /* Destination IP */ - *queue = ((pdata[QUEUE_OFFSET] >> 8) & 0x0F) & - (RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS - 1) ; /* Destination IP */ + pipe_queue = active_queues[(pdata[QUEUE_OFFSET] >> 8) % n_active_queues]; /* Destination IP */ + *traffic_class = (pipe_queue > (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1) ? + (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1) : pipe_queue); + *queue = pipe_queue - *traffic_class; *color = pdata[COLOR_OFFSET] & 0x03; /* Destination IP */ return 0; diff --git a/examples/qos_sched/cfg_file.c b/examples/qos_sched/cfg_file.c index 76ffffc4b..cb8a62cac 100644 --- a/examples/qos_sched/cfg_file.c +++ b/examples/qos_sched/cfg_file.c @@ -29,6 +29,9 @@ cfg_load_port(struct rte_cfgfile *cfg, struct rte_sched_port_params *port_params if (!cfg || !port_params) return -1; + memset(active_queues, 0, sizeof(active_queues)); + n_active_queues = 0; + entry = rte_cfgfile_get_entry(cfg, "port", "frame overhead"); if (entry) port_params->frame_overhead = (uint32_t)atoi(entry); @@ -45,12 +48,25 @@ cfg_load_port(struct rte_cfgfile *cfg, struct rte_sched_port_params *port_params if (entry) { char *next; - for(j = 0; j < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; j++) { + for (j = 0; j < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; j++) { port_params->qsize[j] = (uint16_t)strtol(entry, &next, 10); if (next == NULL) break; entry = next; } + + for (j = 0; j < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1; j++) + if (port_params->qsize[j]) { + active_queues[n_active_queues] = j; + n_active_queues++; + } + + if (port_params->qsize[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1]) + for (j = 0; j < RTE_SCHED_BE_QUEUES_PER_PIPE; j++) { + active_queues[n_active_queues] = + (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1) + j; + n_active_queues++; + } } #ifdef RTE_SCHED_RED @@ -173,46 +189,50 @@ cfg_load_pipe(struct rte_cfgfile *cfg, struct rte_sched_pipe_params *pipe_params if (entry) pipe_params[j].tc_rate[3] = (uint32_t)atoi(entry); -#ifdef RTE_SCHED_SUBPORT_TC_OV - entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 3 oversubscription weight"); + entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 4 rate"); + if (entry) + pipe_params[j].tc_rate[4] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 5 rate"); + if (entry) + pipe_params[j].tc_rate[5] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 6 rate"); + if (entry) + pipe_params[j].tc_rate[6] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 7 rate"); + if (entry) + pipe_params[j].tc_rate[7] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 8 rate"); + if (entry) + pipe_params[j].tc_rate[8] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 9 rate"); + if (entry) + pipe_params[j].tc_rate[9] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 10 rate"); + if (entry) + pipe_params[j].tc_rate[10] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 11 rate"); + if (entry) + pipe_params[j].tc_rate[11] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 12 rate"); + if (entry) + pipe_params[j].tc_rate[12] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 12 oversubscription weight"); if (entry) pipe_params[j].tc_ov_weight = (uint8_t)atoi(entry); -#endif - entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 0 wrr weights"); - if (entry) { - for(i = 0; i < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; i++) { - pipe_params[j].wrr_weights[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE*0 + i] = - (uint8_t)strtol(entry, &next, 10); - if (next == NULL) - break; - entry = next; - } - } - entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 1 wrr weights"); - if (entry) { - for(i = 0; i < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; i++) { - pipe_params[j].wrr_weights[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE*1 + i] = - (uint8_t)strtol(entry, &next, 10); - if (next == NULL) - break; - entry = next; - } - } - entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 2 wrr weights"); - if (entry) { - for(i = 0; i < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; i++) { - pipe_params[j].wrr_weights[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE*2 + i] = - (uint8_t)strtol(entry, &next, 10); - if (next == NULL) - break; - entry = next; - } - } - entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 3 wrr weights"); + entry = rte_cfgfile_get_entry(cfg, pipe_name, "tc 12 wrr weights"); if (entry) { - for(i = 0; i < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; i++) { - pipe_params[j].wrr_weights[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE*3 + i] = + for (i = 0; i < RTE_SCHED_BE_QUEUES_PER_PIPE; i++) { + pipe_params[j].wrr_weights[i] = (uint8_t)strtol(entry, &next, 10); if (next == NULL) break; @@ -267,6 +287,42 @@ cfg_load_subport(struct rte_cfgfile *cfg, struct rte_sched_subport_params *subpo if (entry) subport_params[i].tc_rate[3] = (uint32_t)atoi(entry); + entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 4 rate"); + if (entry) + subport_params[i].tc_rate[4] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 5 rate"); + if (entry) + subport_params[i].tc_rate[5] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 6 rate"); + if (entry) + subport_params[i].tc_rate[6] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 7 rate"); + if (entry) + subport_params[i].tc_rate[7] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 8 rate"); + if (entry) + subport_params[i].tc_rate[8] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 9 rate"); + if (entry) + subport_params[i].tc_rate[9] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 10 rate"); + if (entry) + subport_params[i].tc_rate[10] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 11 rate"); + if (entry) + subport_params[i].tc_rate[11] = (uint32_t)atoi(entry); + + entry = rte_cfgfile_get_entry(cfg, sec_name, "tc 12 rate"); + if (entry) + subport_params[i].tc_rate[12] = (uint32_t)atoi(entry); + int n_entries = rte_cfgfile_section_num_entries(cfg, sec_name); struct rte_cfgfile_entry entries[n_entries]; diff --git a/examples/qos_sched/init.c b/examples/qos_sched/init.c index 6b63d4e0e..b05206d5a 100644 --- a/examples/qos_sched/init.c +++ b/examples/qos_sched/init.c @@ -170,17 +170,20 @@ static struct rte_sched_subport_params subport_params[MAX_SCHED_SUBPORTS] = { .tb_rate = 1250000000, .tb_size = 1000000, - .tc_rate = {1250000000, 1250000000, 1250000000, 1250000000}, + .tc_rate = {1250000000, 1250000000, 1250000000, 1250000000, + 1250000000, 1250000000, 1250000000, 1250000000, 1250000000, + 1250000000, 1250000000, 1250000000, 1250000000}, .tc_period = 10, }, }; -static struct rte_sched_pipe_params pipe_profiles[RTE_SCHED_PIPE_PROFILES_PER_PORT] = { +static struct rte_sched_pipe_params pipe_profiles[MAX_SCHED_PIPE_PROFILES] = { { /* Profile #0 */ .tb_rate = 305175, .tb_size = 1000000, - .tc_rate = {305175, 305175, 305175, 305175}, + .tc_rate = {305175, 305175, 305175, 305175, 305175, 305175, + 305175, 305175, 305175, 305175, 305175, 305175, 305175}, .tc_period = 40, #ifdef RTE_SCHED_SUBPORT_TC_OV .tc_ov_weight = 1, @@ -198,9 +201,10 @@ struct rte_sched_port_params port_params = { .frame_overhead = RTE_SCHED_FRAME_OVERHEAD_DEFAULT, .n_subports_per_port = 1, .n_pipes_per_subport = 4096, - .qsize = {64, 64, 64, 64}, + .qsize = {64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64}, .pipe_profiles = pipe_profiles, .n_pipe_profiles = sizeof(pipe_profiles) / sizeof(struct rte_sched_pipe_params), + .n_max_pipe_profiles = MAX_SCHED_PIPE_PROFILES, #ifdef RTE_SCHED_RED .red_params = { @@ -222,8 +226,53 @@ struct rte_sched_port_params port_params = { /* Traffic Class 3 - Colors Green / Yellow / Red */ [3][0] = {.min_th = 48, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, [3][1] = {.min_th = 40, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, - [3][2] = {.min_th = 32, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9} - } + [3][2] = {.min_th = 32, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + + /* Traffic Class 4 - Colors Green / Yellow / Red */ + [4][0] = {.min_th = 48, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [4][1] = {.min_th = 40, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [4][2] = {.min_th = 32, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + + /* Traffic Class 5 - Colors Green / Yellow / Red */ + [5][0] = {.min_th = 48, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [5][1] = {.min_th = 40, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [5][2] = {.min_th = 32, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + + /* Traffic Class 6 - Colors Green / Yellow / Red */ + [6][0] = {.min_th = 48, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [6][1] = {.min_th = 40, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [6][2] = {.min_th = 32, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + + /* Traffic Class 7 - Colors Green / Yellow / Red */ + [7][0] = {.min_th = 48, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [7][1] = {.min_th = 40, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [7][2] = {.min_th = 32, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + + /* Traffic Class 8 - Colors Green / Yellow / Red */ + [8][0] = {.min_th = 48, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [8][1] = {.min_th = 40, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [8][2] = {.min_th = 32, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + + /* Traffic Class 9 - Colors Green / Yellow / Red */ + [9][0] = {.min_th = 48, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [9][1] = {.min_th = 40, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [9][2] = {.min_th = 32, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + + /* Traffic Class 10 - Colors Green / Yellow / Red */ + [10][0] = {.min_th = 48, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [10][1] = {.min_th = 40, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [10][2] = {.min_th = 32, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + + /* Traffic Class 11 - Colors Green / Yellow / Red */ + [11][0] = {.min_th = 48, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [11][1] = {.min_th = 40, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [11][2] = {.min_th = 32, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + + /* Traffic Class 12 - Colors Green / Yellow / Red */ + [12][0] = {.min_th = 48, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [12][1] = {.min_th = 40, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + [12][2] = {.min_th = 32, .max_th = 64, .maxp_inv = 10, .wq_log2 = 9}, + }, #endif /* RTE_SCHED_RED */ }; @@ -255,7 +304,7 @@ app_init_sched_port(uint32_t portid, uint32_t socketid) subport, err); } - for (pipe = 0; pipe < port_params.n_pipes_per_subport; pipe ++) { + for (pipe = 0; pipe < port_params.n_pipes_per_subport; pipe++) { if (app_pipe_to_profile[subport][pipe] != -1) { err = rte_sched_pipe_config(port, subport, pipe, app_pipe_to_profile[subport][pipe]); diff --git a/examples/qos_sched/main.h b/examples/qos_sched/main.h index 8a2741c58..d8f890b64 100644 --- a/examples/qos_sched/main.h +++ b/examples/qos_sched/main.h @@ -50,6 +50,7 @@ extern "C" { #define MAX_DATA_STREAMS (APP_MAX_LCORE/2) #define MAX_SCHED_SUBPORTS 8 #define MAX_SCHED_PIPES 4096 +#define MAX_SCHED_PIPE_PROFILES 256 #ifndef APP_COLLECT_STAT #define APP_COLLECT_STAT 1 @@ -147,6 +148,9 @@ extern struct burst_conf burst_conf; extern struct ring_thresh rx_thresh; extern struct ring_thresh tx_thresh; +uint32_t active_queues[RTE_SCHED_QUEUES_PER_PIPE]; +uint32_t n_active_queues; + extern struct rte_sched_port_params port_params; int app_parse_args(int argc, char **argv); diff --git a/examples/qos_sched/profile.cfg b/examples/qos_sched/profile.cfg index f5b704cc6..df7c6d1d8 100644 --- a/examples/qos_sched/profile.cfg +++ b/examples/qos_sched/profile.cfg @@ -1,6 +1,6 @@ ; BSD LICENSE ; -; Copyright(c) 2010-2014 Intel Corporation. All rights reserved. +; Copyright(c) 2010-2019 Intel Corporation. All rights reserved. ; All rights reserved. ; ; Redistribution and use in source and binary forms, with or without @@ -33,12 +33,13 @@ ; 10GbE output port: ; * Single subport (subport 0): ; - Subport rate set to 100% of port rate -; - Each of the 4 traffic classes has rate set to 100% of port rate +; - Each of the 13 traffic classes has rate set to 100% of port rate ; * 4K pipes per subport 0 (pipes 0 .. 4095) with identical configuration: ; - Pipe rate set to 1/4K of port rate -; - Each of the 4 traffic classes has rate set to 100% of pipe rate -; - Within each traffic class, the byte-level WRR weights for the 4 queues -; are set to 1:1:1:1 +; - Each of the 13 traffic classes has rate set to 100% of pipe rate +; - Within lowest priority traffic class (best-effort), the byte-level +; WRR weights for the 4 queues of best effort traffic class are set +; to 1:1:1:1 ; ; For more details, please refer to chapter "Quality of Service (QoS) Framework" ; of Data Plane Development Kit (DPDK) Programmer's Guide. @@ -48,7 +49,7 @@ frame overhead = 24 number of subports per port = 1 number of pipes per subport = 4096 -queue sizes = 64 64 64 64 +queue sizes = 64 64 64 64 64 64 64 64 64 64 64 64 64 ; Subport configuration [subport 0] @@ -59,6 +60,16 @@ tc 0 rate = 1250000000 ; Bytes per second tc 1 rate = 1250000000 ; Bytes per second tc 2 rate = 1250000000 ; Bytes per second tc 3 rate = 1250000000 ; Bytes per second +tc 4 rate = 1250000000 ; Bytes per second +tc 5 rate = 1250000000 ; Bytes per second +tc 6 rate = 1250000000 ; Bytes per second +tc 7 rate = 1250000000 ; Bytes per second +tc 8 rate = 1250000000 ; Bytes per second +tc 9 rate = 1250000000 ; Bytes per second +tc 10 rate = 1250000000 ; Bytes per second +tc 11 rate = 1250000000 ; Bytes per second +tc 12 rate = 1250000000 ; Bytes per second + tc period = 10 ; Milliseconds pipe 0-4095 = 0 ; These pipes are configured with pipe profile 0 @@ -72,14 +83,21 @@ tc 0 rate = 305175 ; Bytes per second tc 1 rate = 305175 ; Bytes per second tc 2 rate = 305175 ; Bytes per second tc 3 rate = 305175 ; Bytes per second -tc period = 40 ; Milliseconds +tc 4 rate = 305175 ; Bytes per second +tc 5 rate = 305175 ; Bytes per second +tc 6 rate = 305175 ; Bytes per second +tc 7 rate = 305175 ; Bytes per second +tc 8 rate = 305175 ; Bytes per second +tc 9 rate = 305175 ; Bytes per second +tc 10 rate = 305175 ; Bytes per second +tc 11 rate = 305175 ; Bytes per second +tc 12 rate = 305175 ; Bytes per second + +tc period = 40 ; Milliseconds -tc 3 oversubscription weight = 1 +tc 12 oversubscription weight = 1 -tc 0 wrr weights = 1 1 1 1 -tc 1 wrr weights = 1 1 1 1 -tc 2 wrr weights = 1 1 1 1 -tc 3 wrr weights = 1 1 1 1 +tc 12 wrr weights = 1 1 1 1 ; RED params per traffic class and color (Green / Yellow / Red) [red] @@ -102,3 +120,28 @@ tc 3 wred min = 48 40 32 tc 3 wred max = 64 64 64 tc 3 wred inv prob = 10 10 10 tc 3 wred weight = 9 9 9 + +tc 4 wred min = 48 40 32 +tc 4 wred max = 64 64 64 +tc 4 wred inv prob = 10 10 10 +tc 4 wred weight = 9 9 9 + +tc 5 wred min = 48 40 32 +tc 5 wred max = 64 64 64 +tc 5 wred inv prob = 10 10 10 +tc 5 wred weight = 9 9 9 + +tc 6 wred min = 48 40 32 +tc 6 wred max = 64 64 64 +tc 6 wred inv prob = 10 10 10 +tc 6 wred weight = 9 9 9 + +tc 7 wred min = 48 40 32 +tc 7 wred max = 64 64 64 +tc 7 wred inv prob = 10 10 10 +tc 7 wred weight = 9 9 9 + +tc 8 wred min = 48 40 32 +tc 8 wred max = 64 64 64 +tc 8 wred inv prob = 10 10 10 +tc 8 wred weight = 9 9 9 diff --git a/examples/qos_sched/profile_ov.cfg b/examples/qos_sched/profile_ov.cfg index 33000df9e..c0b7b3c3d 100644 --- a/examples/qos_sched/profile_ov.cfg +++ b/examples/qos_sched/profile_ov.cfg @@ -1,6 +1,6 @@ ; BSD LICENSE ; -; Copyright(c) 2010-2014 Intel Corporation. All rights reserved. +; Copyright(c) 2010-2019 Intel Corporation. All rights reserved. ; All rights reserved. ; ; Redistribution and use in source and binary forms, with or without @@ -34,7 +34,7 @@ frame overhead = 24 number of subports per port = 1 number of pipes per subport = 32 -queue sizes = 64 64 64 64 +queue sizes = 64 64 64 64 64 64 64 64 64 64 64 64 64 ; Subport configuration [subport 0] @@ -45,6 +45,15 @@ tc 0 rate = 8400000 ; Bytes per second tc 1 rate = 8400000 ; Bytes per second tc 2 rate = 8400000 ; Bytes per second tc 3 rate = 8400000 ; Bytes per second +tc 4 rate = 8400000 ; Bytes per second +tc 5 rate = 8400000 ; Bytes per second +tc 6 rate = 8400000 ; Bytes per second +tc 7 rate = 8400000 ; Bytes per second +tc 8 rate = 8400000 ; Bytes per second +tc 9 rate = 8400000 ; Bytes per second +tc 10 rate = 8400000 ; Bytes per second +tc 11 rate = 8400000 ; Bytes per second +tc 12 rate = 8400000 ; Bytes per second tc period = 10 ; Milliseconds pipe 0-31 = 0 ; These pipes are configured with pipe profile 0 @@ -58,14 +67,20 @@ tc 0 rate = 16800000 ; Bytes per second tc 1 rate = 16800000 ; Bytes per second tc 2 rate = 16800000 ; Bytes per second tc 3 rate = 16800000 ; Bytes per second +tc 4 rate = 16800000 ; Bytes per second +tc 5 rate = 16800000 ; Bytes per second +tc 6 rate = 16800000 ; Bytes per second +tc 7 rate = 16800000 ; Bytes per second +tc 8 rate = 16800000 ; Bytes per second +tc 9 rate = 16800000 ; Bytes per second +tc 10 rate = 16800000 ; Bytes per second +tc 11 rate = 16800000 ; Bytes per second +tc 12 rate = 16800000 ; Bytes per second tc period = 28 ; Milliseconds -tc 3 oversubscription weight = 1 +tc 12 oversubscription weight = 1 -tc 0 wrr weights = 1 1 1 1 -tc 1 wrr weights = 1 1 1 1 -tc 2 wrr weights = 1 1 1 1 -tc 3 wrr weights = 1 1 1 1 +tc 12 wrr weights = 1 1 1 1 ; RED params per traffic class and color (Green / Yellow / Red) [red] @@ -88,3 +103,28 @@ tc 3 wred min = 48 40 32 tc 3 wred max = 64 64 64 tc 3 wred inv prob = 10 10 10 tc 3 wred weight = 9 9 9 + +tc 4 wred min = 48 40 32 +tc 4 wred max = 64 64 64 +tc 4 wred inv prob = 10 10 10 +tc 4 wred weight = 9 9 9 + +tc 5 wred min = 48 40 32 +tc 5 wred max = 64 64 64 +tc 5 wred inv prob = 10 10 10 +tc 5 wred weight = 9 9 9 + +tc 6 wred min = 48 40 32 +tc 6 wred max = 64 64 64 +tc 6 wred inv prob = 10 10 10 +tc 6 wred weight = 9 9 9 + +tc 7 wred min = 48 40 32 +tc 7 wred max = 64 64 64 +tc 7 wred inv prob = 10 10 10 +tc 7 wred weight = 9 9 9 + +tc 8 wred min = 48 40 32 +tc 8 wred max = 64 64 64 +tc 8 wred inv prob = 10 10 10 +tc 8 wred weight = 9 9 9 diff --git a/examples/qos_sched/stats.c b/examples/qos_sched/stats.c index 8193d964c..2dfa7f23b 100644 --- a/examples/qos_sched/stats.c +++ b/examples/qos_sched/stats.c @@ -11,278 +11,341 @@ int qavg_q(uint16_t port_id, uint32_t subport_id, uint32_t pipe_id, uint8_t tc, uint8_t q) { - struct rte_sched_queue_stats stats; - struct rte_sched_port *port; - uint16_t qlen; - uint32_t queue_id, count, i; - uint32_t average; - - for (i = 0; i < nb_pfc; i++) { - if (qos_conf[i].tx_port == port_id) - break; - } - if (i == nb_pfc || subport_id >= port_params.n_subports_per_port || pipe_id >= port_params.n_pipes_per_subport - || tc >= RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE || q >= RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS) - return -1; - - port = qos_conf[i].sched_port; - - queue_id = RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS * (subport_id * port_params.n_pipes_per_subport + pipe_id); - queue_id = queue_id + (tc * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS + q); - - average = 0; - - for (count = 0; count < qavg_ntimes; count++) { - rte_sched_queue_read_stats(port, queue_id, &stats, &qlen); - average += qlen; - usleep(qavg_period); - } - - average /= qavg_ntimes; - - printf("\nAverage queue size: %" PRIu32 " bytes.\n\n", average); - - return 0; + struct rte_sched_queue_stats stats; + struct rte_sched_port *port; + uint16_t qlen; + uint32_t count, i, queue_id = 0; + uint32_t average; + + for (i = 0; i < nb_pfc; i++) { + if (qos_conf[i].tx_port == port_id) + break; + } + + if (i == nb_pfc || + subport_id >= port_params.n_subports_per_port || + pipe_id >= port_params.n_pipes_per_subport || + tc >= RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE || + q >= RTE_SCHED_BE_QUEUES_PER_PIPE || + (tc < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1 && q > 0)) + return -1; + + port = qos_conf[i].sched_port; + for (i = 0; i < subport_id; i++) + queue_id += port_params.n_pipes_per_subport * + RTE_SCHED_QUEUES_PER_PIPE; + if (tc < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1) + queue_id += pipe_id * RTE_SCHED_QUEUES_PER_PIPE + tc; + else + queue_id += pipe_id * RTE_SCHED_QUEUES_PER_PIPE + tc + q; + + average = 0; + for (count = 0; count < qavg_ntimes; count++) { + rte_sched_queue_read_stats(port, queue_id, &stats, &qlen); + average += qlen; + usleep(qavg_period); + } + + average /= qavg_ntimes; + + printf("\nAverage queue size: %" PRIu32 " bytes.\n\n", average); + + return 0; } int qavg_tcpipe(uint16_t port_id, uint32_t subport_id, uint32_t pipe_id, - uint8_t tc) + uint8_t tc) { - struct rte_sched_queue_stats stats; - struct rte_sched_port *port; - uint16_t qlen; - uint32_t queue_id, count, i; - uint32_t average, part_average; - - for (i = 0; i < nb_pfc; i++) { - if (qos_conf[i].tx_port == port_id) - break; - } - if (i == nb_pfc || subport_id >= port_params.n_subports_per_port || pipe_id >= port_params.n_pipes_per_subport - || tc >= RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE) - return -1; - - port = qos_conf[i].sched_port; - - queue_id = RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS * (subport_id * port_params.n_pipes_per_subport + pipe_id); - - average = 0; - - for (count = 0; count < qavg_ntimes; count++) { - part_average = 0; - for (i = 0; i < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; i++) { - rte_sched_queue_read_stats(port, queue_id + (tc * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS + i), &stats, &qlen); - part_average += qlen; - } - average += part_average / RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; - usleep(qavg_period); - } - - average /= qavg_ntimes; - - printf("\nAverage queue size: %" PRIu32 " bytes.\n\n", average); - - return 0; + struct rte_sched_queue_stats stats; + struct rte_sched_port *port; + uint16_t qlen; + uint32_t count, i, queue_id = 0; + uint32_t average, part_average; + + for (i = 0; i < nb_pfc; i++) { + if (qos_conf[i].tx_port == port_id) + break; + } + + if (i == nb_pfc || subport_id >= port_params.n_subports_per_port || + pipe_id >= port_params.n_pipes_per_subport || + tc >= RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE) + return -1; + + port = qos_conf[i].sched_port; + + for (i = 0; i < subport_id; i++) + queue_id += port_params.n_pipes_per_subport * RTE_SCHED_QUEUES_PER_PIPE; + + queue_id += pipe_id * RTE_SCHED_QUEUES_PER_PIPE + tc; + + average = 0; + + for (count = 0; count < qavg_ntimes; count++) { + part_average = 0; + + if (tc < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1) { + rte_sched_queue_read_stats(port, queue_id, + &stats, &qlen); + part_average += qlen; + } else { + for (i = 0; i < RTE_SCHED_BE_QUEUES_PER_PIPE; i++) { + rte_sched_queue_read_stats(port, queue_id + i, + &stats, &qlen); + part_average += qlen; + } + average += part_average / RTE_SCHED_BE_QUEUES_PER_PIPE; + } + usleep(qavg_period); + } + + average /= qavg_ntimes; + + printf("\nAverage queue size: %" PRIu32 " bytes.\n\n", average); + + return 0; } int qavg_pipe(uint16_t port_id, uint32_t subport_id, uint32_t pipe_id) { - struct rte_sched_queue_stats stats; - struct rte_sched_port *port; - uint16_t qlen; - uint32_t queue_id, count, i; - uint32_t average, part_average; + struct rte_sched_queue_stats stats; + struct rte_sched_port *port; + uint16_t qlen; + uint32_t count, i, queue_id = 0; + uint32_t average, part_average; + + for (i = 0; i < nb_pfc; i++) { + if (qos_conf[i].tx_port == port_id) + break; + } - for (i = 0; i < nb_pfc; i++) { - if (qos_conf[i].tx_port == port_id) - break; - } - if (i == nb_pfc || subport_id >= port_params.n_subports_per_port || pipe_id >= port_params.n_pipes_per_subport) - return -1; + if (i == nb_pfc || + subport_id >= port_params.n_subports_per_port || + pipe_id >= port_params.n_pipes_per_subport) + return -1; - port = qos_conf[i].sched_port; + port = qos_conf[i].sched_port; - queue_id = RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS * (subport_id * port_params.n_pipes_per_subport + pipe_id); + for (i = 0; i < subport_id; i++) + queue_id += port_params.n_pipes_per_subport * + RTE_SCHED_QUEUES_PER_PIPE; - average = 0; + queue_id += pipe_id * RTE_SCHED_QUEUES_PER_PIPE; - for (count = 0; count < qavg_ntimes; count++) { - part_average = 0; - for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; i++) { - rte_sched_queue_read_stats(port, queue_id + i, &stats, &qlen); - part_average += qlen; - } - average += part_average / (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS); - usleep(qavg_period); - } + average = 0; - average /= qavg_ntimes; + for (count = 0; count < qavg_ntimes; count++) { + part_average = 0; + for (i = 0; i < RTE_SCHED_QUEUES_PER_PIPE; i++) { + rte_sched_queue_read_stats(port, queue_id + i, + &stats, &qlen); + part_average += qlen; + } + average += part_average / RTE_SCHED_QUEUES_PER_PIPE; + usleep(qavg_period); + } - printf("\nAverage queue size: %" PRIu32 " bytes.\n\n", average); + average /= qavg_ntimes; - return 0; + printf("\nAverage queue size: %" PRIu32 " bytes.\n\n", average); + + return 0; } int qavg_tcsubport(uint16_t port_id, uint32_t subport_id, uint8_t tc) { - struct rte_sched_queue_stats stats; - struct rte_sched_port *port; - uint16_t qlen; - uint32_t queue_id, count, i, j; - uint32_t average, part_average; - - for (i = 0; i < nb_pfc; i++) { - if (qos_conf[i].tx_port == port_id) - break; - } - if (i == nb_pfc || subport_id >= port_params.n_subports_per_port || tc >= RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE) - return -1; - - port = qos_conf[i].sched_port; - - average = 0; - - for (count = 0; count < qavg_ntimes; count++) { - part_average = 0; - for (i = 0; i < port_params.n_pipes_per_subport; i++) { - queue_id = RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS * (subport_id * port_params.n_pipes_per_subport + i); - - for (j = 0; j < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; j++) { - rte_sched_queue_read_stats(port, queue_id + (tc * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS + j), &stats, &qlen); - part_average += qlen; - } - } - - average += part_average / (port_params.n_pipes_per_subport * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS); - usleep(qavg_period); - } - - average /= qavg_ntimes; - - printf("\nAverage queue size: %" PRIu32 " bytes.\n\n", average); - - return 0; + struct rte_sched_queue_stats stats; + struct rte_sched_port *port; + uint16_t qlen; + uint32_t queue_id, count, i, j, subport_queue_id = 0; + uint32_t average, part_average; + + for (i = 0; i < nb_pfc; i++) { + if (qos_conf[i].tx_port == port_id) + break; + } + + if (i == nb_pfc || + subport_id >= port_params.n_subports_per_port || + tc >= RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE) + return -1; + + port = qos_conf[i].sched_port; + + for (i = 0; i < subport_id; i++) + subport_queue_id += port_params.n_pipes_per_subport * RTE_SCHED_QUEUES_PER_PIPE; + + average = 0; + + for (count = 0; count < qavg_ntimes; count++) { + part_average = 0; + for (i = 0; i < port_params.n_pipes_per_subport; i++) { + if (tc < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1) { + queue_id = subport_queue_id + i * RTE_SCHED_QUEUES_PER_PIPE + tc; + rte_sched_queue_read_stats(port, queue_id, + &stats, &qlen); + part_average += qlen; + } else { + for (j = 0; j < RTE_SCHED_BE_QUEUES_PER_PIPE; j++) { + queue_id = subport_queue_id + + i * RTE_SCHED_QUEUES_PER_PIPE + tc + j; + rte_sched_queue_read_stats(port, queue_id, + &stats, &qlen); + part_average += qlen; + } + } + } + + if (tc < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1) + average += part_average / (port_params.n_pipes_per_subport); + else + average += + part_average / (port_params.n_pipes_per_subport) * RTE_SCHED_BE_QUEUES_PER_PIPE; + + usleep(qavg_period); + } + + average /= qavg_ntimes; + + printf("\nAverage queue size: %" PRIu32 " bytes.\n\n", average); + + return 0; } int qavg_subport(uint16_t port_id, uint32_t subport_id) { - struct rte_sched_queue_stats stats; - struct rte_sched_port *port; - uint16_t qlen; - uint32_t queue_id, count, i, j; - uint32_t average, part_average; + struct rte_sched_queue_stats stats; + struct rte_sched_port *port; + uint16_t qlen; + uint32_t queue_id, count, i, j, subport_queue_id = 0; + uint32_t average, part_average; + + for (i = 0; i < nb_pfc; i++) { + if (qos_conf[i].tx_port == port_id) + break; + } + + if (i == nb_pfc || + subport_id >= port_params.n_subports_per_port) + return -1; - for (i = 0; i < nb_pfc; i++) { - if (qos_conf[i].tx_port == port_id) - break; - } - if (i == nb_pfc || subport_id >= port_params.n_subports_per_port) - return -1; + port = qos_conf[i].sched_port; - port = qos_conf[i].sched_port; + for (i = 0; i < subport_id; i++) + subport_queue_id += port_params.n_pipes_per_subport * RTE_SCHED_QUEUES_PER_PIPE; - average = 0; + average = 0; - for (count = 0; count < qavg_ntimes; count++) { - part_average = 0; - for (i = 0; i < port_params.n_pipes_per_subport; i++) { - queue_id = RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS * (subport_id * port_params.n_pipes_per_subport + i); + for (count = 0; count < qavg_ntimes; count++) { + part_average = 0; + for (i = 0; i < port_params.n_pipes_per_subport; i++) { + queue_id = subport_queue_id + i * RTE_SCHED_QUEUES_PER_PIPE; - for (j = 0; j < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; j++) { - rte_sched_queue_read_stats(port, queue_id + j, &stats, &qlen); - part_average += qlen; - } - } + for (j = 0; j < RTE_SCHED_QUEUES_PER_PIPE; j++) { + rte_sched_queue_read_stats(port, queue_id + j, + &stats, &qlen); + part_average += qlen; + } + } - average += part_average / (port_params.n_pipes_per_subport * RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS); - usleep(qavg_period); - } + average += part_average / (port_params.n_pipes_per_subport * RTE_SCHED_QUEUES_PER_PIPE); + usleep(qavg_period); + } - average /= qavg_ntimes; + average /= qavg_ntimes; - printf("\nAverage queue size: %" PRIu32 " bytes.\n\n", average); + printf("\nAverage queue size: %" PRIu32 " bytes.\n\n", average); - return 0; + return 0; } int subport_stat(uint16_t port_id, uint32_t subport_id) { - struct rte_sched_subport_stats stats; - struct rte_sched_port *port; - uint32_t tc_ov[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; - uint8_t i; - - for (i = 0; i < nb_pfc; i++) { - if (qos_conf[i].tx_port == port_id) - break; - } - if (i == nb_pfc || subport_id >= port_params.n_subports_per_port) - return -1; - - port = qos_conf[i].sched_port; - memset (tc_ov, 0, sizeof(tc_ov)); - - rte_sched_subport_read_stats(port, subport_id, &stats, tc_ov); - - printf("\n"); - printf("+----+-------------+-------------+-------------+-------------+-------------+\n"); - printf("| TC | Pkts OK |Pkts Dropped | Bytes OK |Bytes Dropped| OV Status |\n"); - printf("+----+-------------+-------------+-------------+-------------+-------------+\n"); - - for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { - printf("| %d | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " |\n", i, - stats.n_pkts_tc[i], stats.n_pkts_tc_dropped[i], - stats.n_bytes_tc[i], stats.n_bytes_tc_dropped[i], tc_ov[i]); - printf("+----+-------------+-------------+-------------+-------------+-------------+\n"); - } - printf("\n"); - - return 0; + struct rte_sched_subport_stats stats; + struct rte_sched_port *port; + uint32_t tc_ov[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; + uint8_t i; + + for (i = 0; i < nb_pfc; i++) { + if (qos_conf[i].tx_port == port_id) + break; + } + + if (i == nb_pfc || subport_id >= port_params.n_subports_per_port) + return -1; + + port = qos_conf[i].sched_port; + memset(tc_ov, 0, sizeof(tc_ov)); + + rte_sched_subport_read_stats(port, subport_id, &stats, tc_ov); + + printf("\n"); + printf("+----+-------------+-------------+-------------+-------------+-------------+\n"); + printf("| TC | Pkts OK |Pkts Dropped | Bytes OK |Bytes Dropped| OV Status |\n"); + printf("+----+-------------+-------------+-------------+-------------+-------------+\n"); + + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { + printf("| %d | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " |\n", i, + stats.n_pkts_tc[i], stats.n_pkts_tc_dropped[i], + stats.n_bytes_tc[i], stats.n_bytes_tc_dropped[i], tc_ov[i]); + printf("+----+-------------+-------------+-------------+-------------+-------------+\n"); + } + printf("\n"); + + return 0; } int pipe_stat(uint16_t port_id, uint32_t subport_id, uint32_t pipe_id) { - struct rte_sched_queue_stats stats; - struct rte_sched_port *port; - uint16_t qlen; - uint8_t i, j; - uint32_t queue_id; - - for (i = 0; i < nb_pfc; i++) { - if (qos_conf[i].tx_port == port_id) - break; - } - if (i == nb_pfc || subport_id >= port_params.n_subports_per_port || pipe_id >= port_params.n_pipes_per_subport) - return -1; - - port = qos_conf[i].sched_port; - - queue_id = RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS * (subport_id * port_params.n_pipes_per_subport + pipe_id); - - printf("\n"); - printf("+----+-------+-------------+-------------+-------------+-------------+-------------+\n"); - printf("| TC | Queue | Pkts OK |Pkts Dropped | Bytes OK |Bytes Dropped| Length |\n"); - printf("+----+-------+-------------+-------------+-------------+-------------+-------------+\n"); - - for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { - for (j = 0; j < RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS; j++) { - - rte_sched_queue_read_stats(port, queue_id + (i * RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS + j), &stats, &qlen); - - printf("| %d | %d | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " | %11i |\n", i, j, - stats.n_pkts, stats.n_pkts_dropped, stats.n_bytes, stats.n_bytes_dropped, qlen); - printf("+----+-------+-------------+-------------+-------------+-------------+-------------+\n"); - } - if (i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1) - printf("+----+-------+-------------+-------------+-------------+-------------+-------------+\n"); - } - printf("\n"); - - return 0; + struct rte_sched_queue_stats stats; + struct rte_sched_port *port; + uint16_t qlen; + uint8_t i, j; + uint32_t queue_id = 0; + + for (i = 0; i < nb_pfc; i++) { + if (qos_conf[i].tx_port == port_id) + break; + } + + if (i == nb_pfc || + subport_id >= port_params.n_subports_per_port || + pipe_id >= port_params.n_pipes_per_subport) + return -1; + + port = qos_conf[i].sched_port; + for (i = 0; i < subport_id; i++) + queue_id += port_params.n_pipes_per_subport * RTE_SCHED_QUEUES_PER_PIPE; + + queue_id += pipe_id * RTE_SCHED_QUEUES_PER_PIPE; + + printf("\n"); + printf("+----+-------+-------------+-------------+-------------+-------------+-------------+\n"); + printf("| TC | Queue | Pkts OK |Pkts Dropped | Bytes OK |Bytes Dropped| Length |\n"); + printf("+----+-------+-------------+-------------+-------------+-------------+-------------+\n"); + + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { + if (i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1) { + rte_sched_queue_read_stats(port, queue_id + i, &stats, &qlen); + printf("| %d | %d | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " | %11i |\n", i, 0, + stats.n_pkts, stats.n_pkts_dropped, stats.n_bytes, stats.n_bytes_dropped, qlen); + printf("+----+-------+-------------+-------------+-------------+-------------+-------------+\n"); + } else { + for (j = 0; j < RTE_SCHED_BE_QUEUES_PER_PIPE; j++) { + rte_sched_queue_read_stats(port, queue_id + i + j, &stats, &qlen); + printf("| %d | %d | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " | %11" PRIu32 " | %11i |\n", i, j, + stats.n_pkts, stats.n_pkts_dropped, stats.n_bytes, stats.n_bytes_dropped, qlen); + printf("+----+-------+-------------+-------------+-------------+-------------+-------------+\n"); + } + } + } + printf("\n"); + + return 0; } -- 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* [dpdk-dev] [PATCH v5 11/11] sched: remove redundant macros 2019-07-17 14:42 ` [dpdk-dev] [PATCH v5 00/11] sched: feature enhancements Jasvinder Singh ` (9 preceding siblings ...) 2019-07-17 14:42 ` [dpdk-dev] [PATCH v5 10/11] examples/qos_sched: add tc and queue config flexibility Jasvinder Singh @ 2019-07-17 14:42 ` Jasvinder Singh 2019-07-18 22:57 ` [dpdk-dev] [PATCH v5 00/11] sched: feature enhancements Dumitrescu, Cristian 11 siblings, 0 replies; 163+ messages in thread From: Jasvinder Singh @ 2019-07-17 14:42 UTC (permalink / raw) To: dev; +Cc: cristian.dumitrescu, Abraham Tovar, Lukasz Krakowiak Remove unused macros from the library, and update release notes. Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com> Signed-off-by: Abraham Tovar <abrahamx.tovar@intel.com> Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com> --- doc/guides/rel_notes/release_19_08.rst | 10 +++++++++- lib/librte_sched/rte_sched.h | 12 ------------ 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/doc/guides/rel_notes/release_19_08.rst b/doc/guides/rel_notes/release_19_08.rst index 4a1fd8dd8..5f6f56666 100644 --- a/doc/guides/rel_notes/release_19_08.rst +++ b/doc/guides/rel_notes/release_19_08.rst @@ -251,6 +251,14 @@ API Changes * malloc: The function ``rte_malloc_set_limit`` was never implemented is deprecated and will be removed in a future release. +* sched: Macros ``RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS`` and + ``RTE_SCHED_PIPE_PROFILES_PER_PORT`` are removed for flexible configuration + of pipe traffic classes and their queues size, and for runtime configuration + of maximum number of pipe profiles, respectively. In addtion, wrr_weights + field of struct ``rte_sched_pipe_params`` is modifed to be used only for + best-effort tc, and qsize field of struct ``rte_sched_port_params`` is + changed to allow different size of the each queue. + * eventdev: No longer marked as experimental. The eventdev functions are no longer marked as experimental, and have @@ -385,7 +393,7 @@ The libraries prepended with a plus sign were incremented in this version. librte_rcu.so.1 librte_reorder.so.1 librte_ring.so.2 - librte_sched.so.2 + + librte_sched.so.3 librte_security.so.2 librte_stack.so.1 librte_table.so.3 diff --git a/lib/librte_sched/rte_sched.h b/lib/librte_sched/rte_sched.h index caf9fa406..6074c3bfb 100644 --- a/lib/librte_sched/rte_sched.h +++ b/lib/librte_sched/rte_sched.h @@ -89,18 +89,6 @@ extern "C" { #define RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE \ (RTE_SCHED_QUEUES_PER_PIPE - RTE_SCHED_BE_QUEUES_PER_PIPE + 1) - -/** Number of queues per pipe traffic class. Cannot be changed. */ -#define RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS 4 - - -/** Maximum number of pipe profiles that can be defined per port. - * Compile-time configurable. - */ -#ifndef RTE_SCHED_PIPE_PROFILES_PER_PORT -#define RTE_SCHED_PIPE_PROFILES_PER_PORT 256 -#endif - /* * Ethernet framing overhead. Overhead fields per Ethernet frame: * 1. Preamble: 7 bytes; -- 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* Re: [dpdk-dev] [PATCH v5 00/11] sched: feature enhancements 2019-07-17 14:42 ` [dpdk-dev] [PATCH v5 00/11] sched: feature enhancements Jasvinder Singh ` (10 preceding siblings ...) 2019-07-17 14:42 ` [dpdk-dev] [PATCH v5 11/11] sched: remove redundant macros Jasvinder Singh @ 2019-07-18 22:57 ` Dumitrescu, Cristian 2019-07-19 10:41 ` Thomas Monjalon 11 siblings, 1 reply; 163+ messages in thread From: Dumitrescu, Cristian @ 2019-07-18 22:57 UTC (permalink / raw) To: Singh, Jasvinder, dev > -----Original Message----- > From: Singh, Jasvinder > Sent: Wednesday, July 17, 2019 4:43 PM > To: dev@dpdk.org > Cc: Dumitrescu, Cristian <cristian.dumitrescu@intel.com> > Subject: [PATCH v5 00/11] sched: feature enhancements > > This patchset refactors the dpdk qos sched library to allow flexibile > configuration of the pipe traffic classes and queue sizes. > > Currently, each pipe has 16 queues hardwired into 4 TCs scheduled with > strict priority, and each TC has exactly with 4 queues that are > scheduled with Weighted Fair Queuing (WFQ). > > Instead of hardwiring queues to traffic class within the specific pipe, > the new implementation allows more flexible/configurable split of pipe > queues between strict priority (SP) and best-effort (BE) traffic classes > along with the support of more number of traffic classes i.e. max 16. > > All the high priority TCs (TC1, TC2, ...) have exactly 1 queue, while > the lowest priority BE TC, has 1, 4 or 8 queues. This is justified by > the fact that all the high priority TCs are fully provisioned (small to > medium traffic rates), while most of the traffic fits into the BE class, > which is typically oversubscribed. > > Furthermore, this change allows to use less than 16 queues per pipe when > not all the 16 queues are needed. Therefore, no memory will be allocated > to the queues that are not needed. > > v5: > - fix traffic class and queue mapping in api function > - remove n_be_queues parameter from internal pipe profile and pipe struct > - replace int multiplication in grinder_schedule func with bitwise & operation > - remove TC_OV logic flag from all the configuration/initialization code > - fix traffic qsize per traffic class instead of individual queue of the pipe > > v4: > - fix build errors > - fix checkpatch errors > > v3: > - remove code related to subport level configuration of the pipe > - remove tc oversubscription flag from struct rte_sched_pipe_params > - replace RTE_SCHED_PIPE_PROFILES_PER_PORT with port param field > > v2: > - fix bug in subport parameters check > - remove redundant RTE_SCHED_SUBPORT_PER_PORT macro > - fix bug in grinder_scheduler function > - improve doxygen comments > - add error log information > > Jasvinder Singh (11): > sched: remove wrr from strict priority tc queues > sched: add config flexibility to tc queue sizes > sched: add max pipe profiles config in run time > sched: rename tc3 params to best-effort tc > sched: improve error log messages > sched: improve doxygen comments > net/softnic: add config flexibility to softnic tm > test_sched: modify tests for config flexibility > examples/ip_pipeline: add config flexibility to tm function > examples/qos_sched: add tc and queue config flexibility > sched: remove redundant macros > > app/test/test_sched.c | 15 +- > doc/guides/rel_notes/release_19_08.rst | 10 +- > drivers/net/softnic/rte_eth_softnic.c | 98 ++ > drivers/net/softnic/rte_eth_softnic_cli.c | 448 +++++++++- > .../net/softnic/rte_eth_softnic_internals.h | 6 +- > drivers/net/softnic/rte_eth_softnic_tm.c | 121 ++- > examples/ip_pipeline/cli.c | 43 +- > examples/ip_pipeline/tmgr.h | 4 +- > examples/qos_sched/app_thread.c | 11 +- > examples/qos_sched/cfg_file.c | 130 ++- > examples/qos_sched/init.c | 65 +- > examples/qos_sched/main.h | 4 + > examples/qos_sched/profile.cfg | 67 +- > examples/qos_sched/profile_ov.cfg | 54 +- > examples/qos_sched/stats.c | 517 ++++++----- > lib/librte_pipeline/rte_table_action.c | 1 - > lib/librte_pipeline/rte_table_action.h | 4 +- > lib/librte_sched/Makefile | 2 +- > lib/librte_sched/meson.build | 2 +- > lib/librte_sched/rte_sched.c | 835 +++++++++++------- > lib/librte_sched/rte_sched.h | 183 ++-- > 21 files changed, 1847 insertions(+), 773 deletions(-) > > -- > 2.21.0 Series-acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com> See the replies on some individual patches for a few details that we should fix for RC3 if we cannot get them done in time for RC2. ^ permalink raw reply [flat|nested] 163+ messages in thread
* Re: [dpdk-dev] [PATCH v5 00/11] sched: feature enhancements 2019-07-18 22:57 ` [dpdk-dev] [PATCH v5 00/11] sched: feature enhancements Dumitrescu, Cristian @ 2019-07-19 10:41 ` Thomas Monjalon 2019-07-19 11:16 ` Singh, Jasvinder 0 siblings, 1 reply; 163+ messages in thread From: Thomas Monjalon @ 2019-07-19 10:41 UTC (permalink / raw) To: Singh, Jasvinder; +Cc: dev, Dumitrescu, Cristian 19/07/2019 00:57, Dumitrescu, Cristian: > > Jasvinder Singh (11): > > sched: remove wrr from strict priority tc queues > > sched: add config flexibility to tc queue sizes > > sched: add max pipe profiles config in run time > > sched: rename tc3 params to best-effort tc > > sched: improve error log messages > > sched: improve doxygen comments > > net/softnic: add config flexibility to softnic tm > > test_sched: modify tests for config flexibility > > examples/ip_pipeline: add config flexibility to tm function > > examples/qos_sched: add tc and queue config flexibility > > sched: remove redundant macros > > Series-acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com> > > See the replies on some individual patches for a few details > that we should fix for RC3 if we cannot get them done in time for RC2. I am waiting for a v6. ^ permalink raw reply [flat|nested] 163+ messages in thread
* Re: [dpdk-dev] [PATCH v5 00/11] sched: feature enhancements 2019-07-19 10:41 ` Thomas Monjalon @ 2019-07-19 11:16 ` Singh, Jasvinder 2019-07-19 11:40 ` Thomas Monjalon 0 siblings, 1 reply; 163+ messages in thread From: Singh, Jasvinder @ 2019-07-19 11:16 UTC (permalink / raw) To: Thomas Monjalon; +Cc: dev, Dumitrescu, Cristian > -----Original Message----- > From: Thomas Monjalon [mailto:thomas@monjalon.net] > Sent: Friday, July 19, 2019 11:41 AM > To: Singh, Jasvinder <jasvinder.singh@intel.com> > Cc: dev@dpdk.org; Dumitrescu, Cristian <cristian.dumitrescu@intel.com> > Subject: Re: [dpdk-dev] [PATCH v5 00/11] sched: feature enhancements > > 19/07/2019 00:57, Dumitrescu, Cristian: > > > Jasvinder Singh (11): > > > sched: remove wrr from strict priority tc queues > > > sched: add config flexibility to tc queue sizes > > > sched: add max pipe profiles config in run time > > > sched: rename tc3 params to best-effort tc > > > sched: improve error log messages > > > sched: improve doxygen comments > > > net/softnic: add config flexibility to softnic tm > > > test_sched: modify tests for config flexibility > > > examples/ip_pipeline: add config flexibility to tm function > > > examples/qos_sched: add tc and queue config flexibility > > > sched: remove redundant macros > > > > Series-acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com> > > > > See the replies on some individual patches for a few details that we > > should fix for RC3 if we cannot get them done in time for RC2. > > I am waiting for a v6. > Can these suggestions be fixed in RC3 as separate patch as they doesn't change any functionality? Thanks. ^ permalink raw reply [flat|nested] 163+ messages in thread
* Re: [dpdk-dev] [PATCH v5 00/11] sched: feature enhancements 2019-07-19 11:16 ` Singh, Jasvinder @ 2019-07-19 11:40 ` Thomas Monjalon 2019-07-19 11:42 ` Singh, Jasvinder 0 siblings, 1 reply; 163+ messages in thread From: Thomas Monjalon @ 2019-07-19 11:40 UTC (permalink / raw) To: Singh, Jasvinder; +Cc: dev, Dumitrescu, Cristian 19/07/2019 13:16, Singh, Jasvinder: > From: Thomas Monjalon [mailto:thomas@monjalon.net] > > 19/07/2019 00:57, Dumitrescu, Cristian: > > > > Jasvinder Singh (11): > > > > sched: remove wrr from strict priority tc queues > > > > sched: add config flexibility to tc queue sizes > > > > sched: add max pipe profiles config in run time > > > > sched: rename tc3 params to best-effort tc > > > > sched: improve error log messages > > > > sched: improve doxygen comments > > > > net/softnic: add config flexibility to softnic tm > > > > test_sched: modify tests for config flexibility > > > > examples/ip_pipeline: add config flexibility to tm function > > > > examples/qos_sched: add tc and queue config flexibility > > > > sched: remove redundant macros > > > > > > Series-acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com> > > > > > > See the replies on some individual patches for a few details that we > > > should fix for RC3 if we cannot get them done in time for RC2. > > > > I am waiting for a v6. > > > Can these suggestions be fixed in RC3 as separate patch as they doesn't change any functionality? No please, I prefer avoiding having too many fixes. I already know in advance such code will have many fixes, and you are a specialist to get things at the last minute. And it is really late to close such change. I feel that it is not ready for 19.08. Please show us how you can fix things quickly. ^ permalink raw reply [flat|nested] 163+ messages in thread
* Re: [dpdk-dev] [PATCH v5 00/11] sched: feature enhancements 2019-07-19 11:40 ` Thomas Monjalon @ 2019-07-19 11:42 ` Singh, Jasvinder 0 siblings, 0 replies; 163+ messages in thread From: Singh, Jasvinder @ 2019-07-19 11:42 UTC (permalink / raw) To: Thomas Monjalon; +Cc: dev, Dumitrescu, Cristian > -----Original Message----- > From: Thomas Monjalon [mailto:thomas@monjalon.net] > Sent: Friday, July 19, 2019 12:41 PM > To: Singh, Jasvinder <jasvinder.singh@intel.com> > Cc: dev@dpdk.org; Dumitrescu, Cristian <cristian.dumitrescu@intel.com> > Subject: Re: [dpdk-dev] [PATCH v5 00/11] sched: feature enhancements > > 19/07/2019 13:16, Singh, Jasvinder: > > From: Thomas Monjalon [mailto:thomas@monjalon.net] > > > 19/07/2019 00:57, Dumitrescu, Cristian: > > > > > Jasvinder Singh (11): > > > > > sched: remove wrr from strict priority tc queues > > > > > sched: add config flexibility to tc queue sizes > > > > > sched: add max pipe profiles config in run time > > > > > sched: rename tc3 params to best-effort tc > > > > > sched: improve error log messages > > > > > sched: improve doxygen comments > > > > > net/softnic: add config flexibility to softnic tm > > > > > test_sched: modify tests for config flexibility > > > > > examples/ip_pipeline: add config flexibility to tm function > > > > > examples/qos_sched: add tc and queue config flexibility > > > > > sched: remove redundant macros > > > > > > > > Series-acked-by: Cristian Dumitrescu > > > > <cristian.dumitrescu@intel.com> > > > > > > > > See the replies on some individual patches for a few details that > > > > we should fix for RC3 if we cannot get them done in time for RC2. > > > > > > I am waiting for a v6. > > > > > Can these suggestions be fixed in RC3 as separate patch as they doesn't > change any functionality? > > No please, I prefer avoiding having too many fixes. > I already know in advance such code will have many fixes, and you are a > specialist to get things at the last minute. > And it is really late to close such change. > I feel that it is not ready for 19.08. > Please show us how you can fix things quickly. > Alright, will send you v6. ^ permalink raw reply [flat|nested] 163+ messages in thread
* [dpdk-dev] [PATCH v4 02/11] sched: add config flexibility to tc queue sizes 2019-07-12 9:57 ` [dpdk-dev] [PATCH v4 00/11] sched: feature enhancements Jasvinder Singh 2019-07-12 9:57 ` [dpdk-dev] [PATCH v4 01/11] sched: remove wrr from strict priority tc queues Jasvinder Singh @ 2019-07-12 9:57 ` Jasvinder Singh 2019-07-16 0:37 ` Dumitrescu, Cristian 2019-07-16 0:57 ` Dumitrescu, Cristian 2019-07-12 9:57 ` [dpdk-dev] [PATCH v4 03/11] sched: add max pipe profiles config in run time Jasvinder Singh ` (8 subsequent siblings) 10 siblings, 2 replies; 163+ messages in thread From: Jasvinder Singh @ 2019-07-12 9:57 UTC (permalink / raw) To: dev; +Cc: cristian.dumitrescu, Abraham Tovar, Lukasz Krakowiak Add support for zero queue sizes of the traffic classes. The queues which are not used can be set to zero size. This helps in reducing memory footprint of the hierarchical scheduler. Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com> Signed-off-by: Abraham Tovar <abrahamx.tovar@intel.com> Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com> --- lib/librte_sched/rte_sched.c | 354 +++++++++++++++++++---------------- lib/librte_sched/rte_sched.h | 12 +- 2 files changed, 198 insertions(+), 168 deletions(-) diff --git a/lib/librte_sched/rte_sched.c b/lib/librte_sched/rte_sched.c index b1f521794..411924c36 100644 --- a/lib/librte_sched/rte_sched.c +++ b/lib/librte_sched/rte_sched.c @@ -149,15 +149,15 @@ struct rte_sched_grinder { struct rte_sched_pipe_profile *pipe_params; /* TC cache */ - uint8_t tccache_qmask[4]; - uint32_t tccache_qindex[4]; + uint8_t tccache_qmask[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; + uint32_t tccache_qindex[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; uint32_t tccache_w; uint32_t tccache_r; /* Current TC */ uint32_t tc_index; - struct rte_sched_queue *queue[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; - struct rte_mbuf **qbase[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; + struct rte_sched_queue *queue[RTE_SCHED_MAX_QUEUES_PER_TC]; + struct rte_mbuf **qbase[RTE_SCHED_MAX_QUEUES_PER_TC]; uint32_t qindex[RTE_SCHED_MAX_QUEUES_PER_TC]; uint16_t qsize[RTE_SCHED_MAX_QUEUES_PER_TC]; uint32_t qmask; @@ -178,7 +178,7 @@ struct rte_sched_port { uint32_t rate; uint32_t mtu; uint32_t frame_overhead; - uint16_t qsize[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; + uint16_t qsize[RTE_SCHED_QUEUES_PER_PIPE]; uint32_t n_pipe_profiles; uint32_t pipe_tc3_rate_max; #ifdef RTE_SCHED_RED @@ -260,14 +260,13 @@ rte_sched_port_qbase(struct rte_sched_port *port, uint32_t qindex) static inline uint16_t rte_sched_port_qsize(struct rte_sched_port *port, uint32_t qindex) { - uint32_t tc = (qindex >> 2) & 0x3; - - return port->qsize[tc]; + uint32_t qpos = qindex & 0xF; + return port->qsize[qpos]; } static int pipe_profile_check(struct rte_sched_pipe_params *params, - uint32_t rate) + uint32_t rate, uint16_t *qsize) { uint32_t i; @@ -285,12 +284,17 @@ pipe_profile_check(struct rte_sched_pipe_params *params, return -12; /* TC rate: non-zero, less than pipe rate */ - for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { - if (params->tc_rate[i] == 0 || - params->tc_rate[i] > params->tb_rate) + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASS_BE; i++) { + if ((qsize[i] == 0 && params->tc_rate[i] != 0) || + (qsize[i] != 0 && (params->tc_rate[i] == 0 || + params->tc_rate[i] > params->tb_rate))) return -13; + } + if (params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE] == 0) + return -13; + /* TC period: non-zero */ if (params->tc_period == 0) return -14; @@ -302,8 +306,10 @@ pipe_profile_check(struct rte_sched_pipe_params *params, #endif /* Queue WRR weights: non-zero */ - for (i = 0; i < RTE_SCHED_QUEUES_PER_PIPE; i++) { - if (params->wrr_weights[i] == 0) + for (i = 0; i < RTE_SCHED_BE_QUEUES_PER_PIPE; i++) { + uint32_t qindex = RTE_SCHED_TRAFFIC_CLASS_BE + i; + if ((qsize[qindex] != 0 && params->wrr_weights[i] == 0) || + (qsize[qindex] == 0 && params->wrr_weights[i] != 0)) return -16; } return 0; @@ -343,10 +349,10 @@ rte_sched_port_check_params(struct rte_sched_port_params *params) /* qsize: non-zero, power of 2, * no bigger than 32K (due to 16-bit read/write pointers) */ - for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { + for (i = 0; i < RTE_SCHED_QUEUES_PER_PIPE; i++) { uint16_t qsize = params->qsize[i]; - - if (qsize == 0 || !rte_is_power_of_2(qsize)) + if ((qsize != 0 && !rte_is_power_of_2(qsize)) || + ((i == RTE_SCHED_TRAFFIC_CLASS_BE) && (qsize == 0))) return -8; } @@ -360,7 +366,7 @@ rte_sched_port_check_params(struct rte_sched_port_params *params) struct rte_sched_pipe_params *p = params->pipe_profiles + i; int status; - status = pipe_profile_check(p, params->rate); + status = pipe_profile_check(p, params->rate, ¶ms->qsize[0]); if (status != 0) return status; } @@ -389,9 +395,9 @@ rte_sched_port_get_array_base(struct rte_sched_port_params *params, enum rte_sch uint32_t base, i; size_per_pipe_queue_array = 0; - for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { - size_per_pipe_queue_array += RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS - * params->qsize[i] * sizeof(struct rte_mbuf *); + for (i = 0; i < RTE_SCHED_QUEUES_PER_PIPE; i++) { + size_per_pipe_queue_array += + params->qsize[i] * sizeof(struct rte_mbuf *); } size_queue_array = n_pipes_per_port * size_per_pipe_queue_array; @@ -451,31 +457,12 @@ rte_sched_port_get_memory_footprint(struct rte_sched_port_params *params) static void rte_sched_port_config_qsize(struct rte_sched_port *port) { - /* TC 0 */ + uint32_t i; port->qsize_add[0] = 0; - port->qsize_add[1] = port->qsize_add[0] + port->qsize[0]; - port->qsize_add[2] = port->qsize_add[1] + port->qsize[0]; - port->qsize_add[3] = port->qsize_add[2] + port->qsize[0]; - - /* TC 1 */ - port->qsize_add[4] = port->qsize_add[3] + port->qsize[0]; - port->qsize_add[5] = port->qsize_add[4] + port->qsize[1]; - port->qsize_add[6] = port->qsize_add[5] + port->qsize[1]; - port->qsize_add[7] = port->qsize_add[6] + port->qsize[1]; - - /* TC 2 */ - port->qsize_add[8] = port->qsize_add[7] + port->qsize[1]; - port->qsize_add[9] = port->qsize_add[8] + port->qsize[2]; - port->qsize_add[10] = port->qsize_add[9] + port->qsize[2]; - port->qsize_add[11] = port->qsize_add[10] + port->qsize[2]; - - /* TC 3 */ - port->qsize_add[12] = port->qsize_add[11] + port->qsize[2]; - port->qsize_add[13] = port->qsize_add[12] + port->qsize[3]; - port->qsize_add[14] = port->qsize_add[13] + port->qsize[3]; - port->qsize_add[15] = port->qsize_add[14] + port->qsize[3]; - - port->qsize_sum = port->qsize_add[15] + port->qsize[3]; + for (i = 1; i < RTE_SCHED_QUEUES_PER_PIPE; i++) + port->qsize_add[i] = port->qsize_add[i-1] + port->qsize[i-1]; + + port->qsize_sum = port->qsize_add[15] + port->qsize[15]; } static void @@ -484,10 +471,11 @@ rte_sched_port_log_pipe_profile(struct rte_sched_port *port, uint32_t i) struct rte_sched_pipe_profile *p = port->pipe_profiles + i; RTE_LOG(DEBUG, SCHED, "Low level config for pipe profile %u:\n" - " Token bucket: period = %u, credits per period = %u, size = %u\n" - " Traffic classes: period = %u, credits per period = [%u, %u, %u, %u]\n" - " Traffic class 3 oversubscription: weight = %hhu\n" - " WRR cost: [%hhu, %hhu, %hhu, %hhu]\n", + " Token bucket: period = %u, credits per period = %u, size = %u\n" + " Traffic classes: period = %u,\n" + " credits per period = [%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u]\n" + " Best-effort traffic class oversubscription: weight = %hhu\n" + " WRR cost: [%hhu, %hhu, %hhu, %hhu]\n", i, /* Token bucket */ @@ -501,8 +489,17 @@ 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], - - /* Traffic class 3 oversubscription */ + 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], + + /* Best-effort traffic class oversubscription */ p->tc_ov_weight, /* WRR */ @@ -548,9 +545,10 @@ rte_sched_pipe_profile_convert(struct rte_sched_port *port, 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]); + if (port->qsize[i]) + dst->tc_credits_per_period[i] + = rte_sched_time_ms_to_bytes(src->tc_period, + src->tc_rate[i]); #ifdef RTE_SCHED_SUBPORT_TC_OV dst->tc_ov_weight = src->tc_ov_weight; @@ -558,7 +556,7 @@ rte_sched_pipe_profile_convert(struct rte_sched_port *port, /* WRR queues */ for (i = 0; i < RTE_SCHED_BE_QUEUES_PER_PIPE; i++) - if (port->qsize[i]) + if (port->qsize[RTE_SCHED_TRAFFIC_CLASS_BE + i]) dst->n_be_queues++; if (dst->n_be_queues == 1) @@ -620,7 +618,7 @@ rte_sched_port_config_pipe_profile_table(struct rte_sched_port *port, 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]; + uint32_t pipe_tc3_rate = src->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE]; if (port->pipe_tc3_rate_max < pipe_tc3_rate) port->pipe_tc3_rate_max = pipe_tc3_rate; @@ -762,12 +760,14 @@ rte_sched_port_free(struct rte_sched_port *port) for (qindex = 0; qindex < n_queues_per_port; qindex++) { struct rte_mbuf **mbufs = rte_sched_port_qbase(port, qindex); uint16_t qsize = rte_sched_port_qsize(port, qindex); - struct rte_sched_queue *queue = port->queue + qindex; - uint16_t qr = queue->qr & (qsize - 1); - uint16_t qw = queue->qw & (qsize - 1); + if (qsize != 0) { + struct rte_sched_queue *queue = port->queue + qindex; + uint16_t qr = queue->qr & (qsize - 1); + uint16_t qw = queue->qw & (qsize - 1); - for (; qr != qw; qr = (qr + 1) & (qsize - 1)) - rte_pktmbuf_free(mbufs[qr]); + for (; qr != qw; qr = (qr + 1) & (qsize - 1)) + rte_pktmbuf_free(mbufs[qr]); + } } rte_bitmap_free(port->bmp); @@ -780,9 +780,10 @@ rte_sched_port_log_subport_config(struct rte_sched_port *port, uint32_t i) struct rte_sched_subport *s = port->subport + i; RTE_LOG(DEBUG, SCHED, "Low level config for subport %u:\n" - " Token bucket: period = %u, credits per period = %u, size = %u\n" - " Traffic classes: period = %u, credits per period = [%u, %u, %u, %u]\n" - " Traffic class 3 oversubscription: wm min = %u, wm max = %u\n", + " Token bucket: period = %u, credits per period = %u, size = %u\n" + " Traffic classes: period = %u\n" + " credits per period = [%u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u, %u]\n" + " Best effort traffic class oversubscription: wm min = %u, wm max = %u\n", i, /* Token bucket */ @@ -796,8 +797,17 @@ 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], - - /* Traffic class 3 oversubscription */ + s->tc_credits_per_period[4], + s->tc_credits_per_period[5], + s->tc_credits_per_period[6], + s->tc_credits_per_period[7], + s->tc_credits_per_period[8], + s->tc_credits_per_period[9], + s->tc_credits_per_period[10], + s->tc_credits_per_period[11], + s->tc_credits_per_period[12], + + /* Best effort traffic class oversubscription */ s->tc_ov_wm_min, s->tc_ov_wm_max); } @@ -808,7 +818,7 @@ rte_sched_subport_config(struct rte_sched_port *port, struct rte_sched_subport_params *params) { struct rte_sched_subport *s; - uint32_t i; + uint32_t i, j; /* Check user parameters */ if (port == NULL || @@ -822,12 +832,24 @@ rte_sched_subport_config(struct rte_sched_port *port, if (params->tb_size == 0) return -3; - for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { - if (params->tc_rate[i] == 0 || - params->tc_rate[i] > params->tb_rate) - return -4; + for (i = 0, j = 0; i < RTE_SCHED_QUEUES_PER_PIPE; i++) { + uint32_t tc_rate = params->tc_rate[j]; + uint16_t qsize = port->qsize[i]; + + if (((qsize == 0) && + ((tc_rate != 0) && (j != RTE_SCHED_TRAFFIC_CLASS_BE))) || + ((qsize != 0) && (tc_rate == 0)) || + (tc_rate > params->tb_rate)) + return -3; + + if (j < RTE_SCHED_TRAFFIC_CLASS_BE) + j++; } + if (port->qsize[RTE_SCHED_TRAFFIC_CLASS_BE] == 0 || + params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE] == 0) + return -3; + if (params->tc_period == 0) return -5; @@ -851,13 +873,16 @@ rte_sched_subport_config(struct rte_sched_port *port, /* Traffic Classes (TCs) */ s->tc_period = rte_sched_time_ms_to_bytes(params->tc_period, port->rate); for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { - s->tc_credits_per_period[i] - = rte_sched_time_ms_to_bytes(params->tc_period, - params->tc_rate[i]); + if (port->qsize[i]) + s->tc_credits_per_period[i] + = rte_sched_time_ms_to_bytes(params->tc_period, + params->tc_rate[i]); + } s->tc_time = port->time + s->tc_period; for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) - s->tc_credits[i] = s->tc_credits_per_period[i]; + if (port->qsize[i]) + s->tc_credits[i] = s->tc_credits_per_period[i]; #ifdef RTE_SCHED_SUBPORT_TC_OV /* TC oversubscription */ @@ -910,9 +935,9 @@ 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 subport_tc3_rate = (double) s->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] / (double) s->tc_period; - double pipe_tc3_rate = (double) params->tc_credits_per_period[3] + double pipe_tc3_rate = (double) params->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] / (double) params->tc_period; uint32_t tc3_ov = s->tc_ov; @@ -945,15 +970,19 @@ rte_sched_pipe_config(struct rte_sched_port *port, /* Traffic Classes (TCs) */ p->tc_time = port->time + params->tc_period; + p->n_be_queues = params->n_be_queues; for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) - p->tc_credits[i] = params->tc_credits_per_period[i]; + if (port->qsize[i]) + p->tc_credits[i] = params->tc_credits_per_period[i]; #ifdef RTE_SCHED_SUBPORT_TC_OV { /* Subport TC3 oversubscription */ - double subport_tc3_rate = (double) s->tc_credits_per_period[3] + double subport_tc3_rate = + (double) s->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] / (double) s->tc_period; - double pipe_tc3_rate = (double) params->tc_credits_per_period[3] + double pipe_tc3_rate = + (double) params->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] / (double) params->tc_period; uint32_t tc3_ov = s->tc_ov; @@ -992,7 +1021,7 @@ rte_sched_port_pipe_profile_add(struct rte_sched_port *port, return -2; /* Pipe params */ - status = pipe_profile_check(params, port->rate); + status = pipe_profile_check(params, port->rate, &port->qsize[0]); if (status != 0) return status; @@ -1008,8 +1037,8 @@ rte_sched_port_pipe_profile_add(struct rte_sched_port *port, *pipe_profile_id = port->n_pipe_profiles; port->n_pipe_profiles++; - if (port->pipe_tc3_rate_max < params->tc_rate[3]) - port->pipe_tc3_rate_max = params->tc_rate[3]; + if (port->pipe_tc3_rate_max < params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE]) + port->pipe_tc3_rate_max = params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE]; rte_sched_port_log_pipe_profile(port, *pipe_profile_id); @@ -1020,15 +1049,12 @@ static inline uint32_t rte_sched_port_qindex(struct rte_sched_port *port, uint32_t subport, uint32_t pipe, - uint32_t traffic_class, uint32_t queue) { return ((subport & (port->n_subports_per_port - 1)) << (port->n_pipes_per_subport_log2 + 4)) | ((pipe & (port->n_pipes_per_subport - 1)) << 4) | - ((traffic_class & - (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1)) << 2) | - (queue & (RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS - 1)); + (queue & (RTE_SCHED_QUEUES_PER_PIPE - 1)); } void @@ -1038,8 +1064,8 @@ rte_sched_port_pkt_write(struct rte_sched_port *port, uint32_t traffic_class, uint32_t queue, enum rte_color color) { - uint32_t queue_id = rte_sched_port_qindex(port, subport, pipe, - traffic_class, queue); + uint32_t queue_id = rte_sched_port_qindex(port, subport, pipe, queue); + rte_mbuf_sched_set(pkt, queue_id, traffic_class, (uint8_t)color); } @@ -1050,12 +1076,12 @@ rte_sched_port_pkt_read_tree_path(struct rte_sched_port *port, uint32_t *traffic_class, uint32_t *queue) { uint32_t queue_id = rte_mbuf_sched_queue_get(pkt); + uint32_t tc_id = rte_mbuf_sched_traffic_class_get(pkt); *subport = queue_id >> (port->n_pipes_per_subport_log2 + 4); *pipe = (queue_id >> 4) & (port->n_pipes_per_subport - 1); - *traffic_class = (queue_id >> 2) & - (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1); - *queue = queue_id & (RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS - 1); + *traffic_class = tc_id; + *queue = queue_id & (RTE_SCHED_QUEUES_PER_PIPE - 1); } enum rte_color @@ -1136,7 +1162,7 @@ static inline void rte_sched_port_update_subport_stats(struct rte_sched_port *port, uint32_t qindex, struct rte_mbuf *pkt) { struct rte_sched_subport *s = port->subport + (qindex / rte_sched_port_queues_per_subport(port)); - uint32_t tc_index = (qindex >> 2) & 0x3; + uint32_t tc_index = rte_mbuf_sched_traffic_class_get(pkt); uint32_t pkt_len = pkt->pkt_len; s->stats.n_pkts_tc[tc_index] += 1; @@ -1156,7 +1182,7 @@ rte_sched_port_update_subport_stats_on_drop(struct rte_sched_port *port, #endif { struct rte_sched_subport *s = port->subport + (qindex / rte_sched_port_queues_per_subport(port)); - uint32_t tc_index = (qindex >> 2) & 0x3; + uint32_t tc_index = rte_mbuf_sched_traffic_class_get(pkt); uint32_t pkt_len = pkt->pkt_len; s->stats.n_pkts_tc_dropped[tc_index] += 1; @@ -1211,7 +1237,7 @@ rte_sched_port_red_drop(struct rte_sched_port *port, struct rte_mbuf *pkt, uint3 uint32_t tc_index; enum rte_color color; - tc_index = (qindex >> 2) & 0x3; + tc_index = rte_mbuf_sched_traffic_class_get(pkt); color = rte_sched_port_pkt_read_color(pkt); red_cfg = &port->red_config[tc_index][color]; @@ -1528,6 +1554,7 @@ grinder_credits_update(struct rte_sched_port *port, uint32_t pos) struct rte_sched_pipe *pipe = grinder->pipe; struct rte_sched_pipe_profile *params = grinder->pipe_params; uint64_t n_periods; + uint32_t i; /* Subport TB */ n_periods = (port->time - subport->tb_time) / subport->tb_period; @@ -1543,19 +1570,17 @@ grinder_credits_update(struct rte_sched_port *port, uint32_t pos) /* Subport TCs */ 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]; + for (i = 0; i <= RTE_SCHED_TRAFFIC_CLASS_BE; i++) + subport->tc_credits[i] = subport->tc_credits_per_period[i]; + subport->tc_time = port->time + subport->tc_period; } /* Pipe TCs */ if (unlikely(port->time >= pipe->tc_time)) { - pipe->tc_credits[0] = params->tc_credits_per_period[0]; - pipe->tc_credits[1] = params->tc_credits_per_period[1]; - pipe->tc_credits[2] = params->tc_credits_per_period[2]; - pipe->tc_credits[3] = params->tc_credits_per_period[3]; + for (i = 0; i <= RTE_SCHED_TRAFFIC_CLASS_BE; i++) + pipe->tc_credits[i] = params->tc_credits_per_period[i]; + pipe->tc_time = port->time + params->tc_period; } } @@ -1568,21 +1593,29 @@ 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_consumption = 0, tc_ov_consumption_max; uint32_t tc_ov_wm = subport->tc_ov_wm; + uint32_t i; 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]; + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASS_BE; i++) { + tc_ov_consumption[i] = + subport->tc_credits_per_period[i] - subport->tc_credits[i]; + tc_consumption += tc_ov_consumption[i]; + } + + tc_ov_consumption[RTE_SCHED_TRAFFIC_CLASS_BE] = + subport->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] - + subport->tc_credits[RTE_SCHED_TRAFFIC_CLASS_BE]; + - tc_ov_consumption_max = subport->tc_credits_per_period[3] - - (tc_ov_consumption[0] + tc_ov_consumption[1] + tc_ov_consumption[2]); + tc_ov_consumption_max = + subport->tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] - tc_consumption; - if (tc_ov_consumption[3] > (tc_ov_consumption_max - port->mtu)) { + if (tc_ov_consumption[RTE_SCHED_TRAFFIC_CLASS_BE] > + (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; @@ -1605,6 +1638,7 @@ grinder_credits_update(struct rte_sched_port *port, uint32_t pos) struct rte_sched_pipe *pipe = grinder->pipe; struct rte_sched_pipe_profile *params = grinder->pipe_params; uint64_t n_periods; + uint32_t i; /* Subport TB */ n_periods = (port->time - subport->tb_time) / subport->tb_period; @@ -1622,10 +1656,8 @@ grinder_credits_update(struct rte_sched_port *port, uint32_t pos) 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]; + for (i = 0; i <= RTE_SCHED_TRAFFIC_CLASS_BE; i++) + subport->tc_credits[i] = subport->tc_credits_per_period[i]; subport->tc_time = port->time + subport->tc_period; subport->tc_ov_period_id++; @@ -1633,10 +1665,8 @@ grinder_credits_update(struct rte_sched_port *port, uint32_t pos) /* Pipe TCs */ if (unlikely(port->time >= pipe->tc_time)) { - pipe->tc_credits[0] = params->tc_credits_per_period[0]; - pipe->tc_credits[1] = params->tc_credits_per_period[1]; - pipe->tc_credits[2] = params->tc_credits_per_period[2]; - pipe->tc_credits[3] = params->tc_credits_per_period[3]; + for (i = 0; i <= RTE_SCHED_TRAFFIC_CLASS_BE; i++) + pipe->tc_credits[i] = params->tc_credits_per_period[i]; pipe->tc_time = port->time + params->tc_period; } @@ -1701,11 +1731,18 @@ 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_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]; + uint32_t pipe_tc_ov_mask1[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; + uint32_t pipe_tc_ov_mask2[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE] = {0}; + uint32_t pipe_tc_ov_credits, i; int enough_credits; + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) + pipe_tc_ov_mask1[i] = UINT32_MAX; + + pipe_tc_ov_mask1[RTE_SCHED_TRAFFIC_CLASS_BE] = pipe->tc_ov_credits; + pipe_tc_ov_mask2[RTE_SCHED_TRAFFIC_CLASS_BE] = UINT32_MAX; + pipe_tc_ov_credits = pipe_tc_ov_mask1[tc_index]; + /* Check pipe and subport credits */ enough_credits = (pkt_len <= subport_tb_credits) && (pkt_len <= subport_tc_credits) && @@ -1860,68 +1897,65 @@ static inline void grinder_tccache_populate(struct rte_sched_port *port, uint32_t pos, uint32_t qindex, uint16_t qmask) { struct rte_sched_grinder *grinder = port->grinder + pos; - uint8_t b[4]; + uint8_t b, i; grinder->tccache_w = 0; grinder->tccache_r = 0; - b[0] = (uint8_t) (qmask & 0xF); - b[1] = (uint8_t) ((qmask >> 4) & 0xF); - b[2] = (uint8_t) ((qmask >> 8) & 0xF); - b[3] = (uint8_t) ((qmask >> 12) & 0xF); - - grinder->tccache_qmask[grinder->tccache_w] = b[0]; - grinder->tccache_qindex[grinder->tccache_w] = qindex; - grinder->tccache_w += (b[0] != 0); - - grinder->tccache_qmask[grinder->tccache_w] = b[1]; - grinder->tccache_qindex[grinder->tccache_w] = qindex + 4; - grinder->tccache_w += (b[1] != 0); - - grinder->tccache_qmask[grinder->tccache_w] = b[2]; - grinder->tccache_qindex[grinder->tccache_w] = qindex + 8; - grinder->tccache_w += (b[2] != 0); + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASS_BE; i++) { + b = (uint8_t) ((qmask >> i) & 0x1); + grinder->tccache_qmask[grinder->tccache_w] = b; + grinder->tccache_qindex[grinder->tccache_w] = qindex + i; + grinder->tccache_w += (b != 0); + } - grinder->tccache_qmask[grinder->tccache_w] = b[3]; - grinder->tccache_qindex[grinder->tccache_w] = qindex + 12; - grinder->tccache_w += (b[3] != 0); + b = (uint8_t) (qmask >> (RTE_SCHED_TRAFFIC_CLASS_BE)); + grinder->tccache_qmask[grinder->tccache_w] = b; + grinder->tccache_qindex[grinder->tccache_w] = qindex + + RTE_SCHED_TRAFFIC_CLASS_BE; + grinder->tccache_w += (b != 0); } static inline int grinder_next_tc(struct rte_sched_port *port, uint32_t pos) { struct rte_sched_grinder *grinder = port->grinder + pos; + struct rte_sched_pipe *pipe = grinder->pipe; struct rte_mbuf **qbase; - uint32_t qindex; + uint32_t qindex, qpos = 0; uint16_t qsize; if (grinder->tccache_r == grinder->tccache_w) return 0; qindex = grinder->tccache_qindex[grinder->tccache_r]; + grinder->tc_index = qindex & 0xf; qbase = rte_sched_port_qbase(port, qindex); - qsize = rte_sched_port_qsize(port, qindex); - - grinder->tc_index = (qindex >> 2) & 0x3; - grinder->qmask = grinder->tccache_qmask[grinder->tccache_r]; - grinder->qsize[grinder->tc_index] = qsize; - grinder->qindex[0] = qindex; - grinder->qindex[1] = qindex + 1; - grinder->qindex[2] = qindex + 2; - grinder->qindex[3] = qindex + 3; + if (grinder->tc_index < RTE_SCHED_TRAFFIC_CLASS_BE) { + qsize = rte_sched_port_qsize(port, qindex); - grinder->queue[0] = port->queue + qindex; - grinder->queue[1] = port->queue + qindex + 1; - grinder->queue[2] = port->queue + qindex + 2; - grinder->queue[3] = port->queue + qindex + 3; + grinder->queue[qpos] = port->queue + qindex; + grinder->qbase[qpos] = qbase; + grinder->qindex[qpos] = qindex; + grinder->qsize[qpos] = qsize; + grinder->qmask = grinder->tccache_qmask[grinder->tccache_r]; + grinder->tccache_r++; - grinder->qbase[0] = qbase; - grinder->qbase[1] = qbase + qsize; - grinder->qbase[2] = qbase + 2 * qsize; - grinder->qbase[3] = qbase + 3 * qsize; + return 1; + } + for ( ; qpos < pipe->n_be_queues; qpos++) { + qsize = rte_sched_port_qsize(port, qindex + qpos); + grinder->queue[qpos] = port->queue + qindex + qpos; + grinder->qbase[qpos] = qbase + qpos * qsize; + grinder->qindex[qpos] = qindex + qpos; + grinder->qsize[qpos] = qsize; + } + grinder->tc_index = RTE_SCHED_TRAFFIC_CLASS_BE; + grinder->qmask = grinder->tccache_qmask[grinder->tccache_r]; grinder->tccache_r++; + return 1; } diff --git a/lib/librte_sched/rte_sched.h b/lib/librte_sched/rte_sched.h index 2a935998a..ae4dfb311 100644 --- a/lib/librte_sched/rte_sched.h +++ b/lib/librte_sched/rte_sched.h @@ -83,9 +83,9 @@ extern "C" { #define RTE_SCHED_BE_QUEUES_PER_PIPE 4 /** Number of traffic classes per pipe (as well as subport). - * Cannot be changed. */ -#define RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE 4 +#define RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE \ +(RTE_SCHED_QUEUES_PER_PIPE - RTE_SCHED_BE_QUEUES_PER_PIPE + 1) /** Number of queues per pipe traffic class. Cannot be changed. */ #define RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS 4 @@ -171,9 +171,7 @@ struct rte_sched_pipe_params { /**< Traffic class rates (measured in bytes per second) */ uint32_t tc_period; /**< Enforcement period (measured in milliseconds) */ -#ifdef RTE_SCHED_SUBPORT_TC_OV uint8_t tc_ov_weight; /**< Weight Traffic class 3 oversubscription */ -#endif /* Pipe queues */ uint8_t wrr_weights[RTE_SCHED_BE_QUEUES_PER_PIPE]; /**< WRR weights */ @@ -206,11 +204,9 @@ struct rte_sched_port_params { * (measured in bytes) */ uint32_t n_subports_per_port; /**< Number of subports */ uint32_t n_pipes_per_subport; /**< Number of pipes per subport */ - uint16_t qsize[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; + uint16_t qsize[RTE_SCHED_QUEUES_PER_PIPE]; /**< Packet queue size for each traffic class. - * All queues within the same pipe traffic class have the same - * size. Queues from different pipes serving the same traffic - * class have the same size. */ + * Queues which are not needed are allowed to have zero size. */ struct rte_sched_pipe_params *pipe_profiles; /**< Pipe profile table. * Every pipe is configured using one of the profiles from this table. */ -- 2.21.0 ^ permalink raw reply [flat|nested] 163+ messages in thread
* Re: [dpdk-dev] [PATCH v4 02/11] sched: add config flexibility to tc queue sizes 2019-07-12 9:57 ` [dpdk-dev] [PATCH v4 02/11] sched: add config flexibility to tc queue sizes Jasvinder Singh @ 2019-07-16 0:37 ` Dumitrescu, Cristian 2019-07-17 14:57 ` Singh, Jasvinder 2019-07-16 0:57 ` Dumitrescu, Cristian 1 sibling, 1 reply; 163+ messages in thread From: Dumitrescu, Cristian @ 2019-07-16 0:37 UTC (permalink / raw) To: Singh, Jasvinder, dev; +Cc: Tovar, AbrahamX, Krakowiak, LukaszX > -----Original Message----- > From: Singh, Jasvinder > Sent: Friday, July 12, 2019 11:57 AM > To: dev@dpdk.org > Cc: Dumitrescu, Cristian <cristian.dumitrescu@intel.com>; Tovar, AbrahamX > <abrahamx.tovar@intel.com>; Krakowiak, LukaszX > <lukaszx.krakowiak@intel.com> > Subject: [PATCH v4 02/11] sched: add config flexibility to tc queue sizes > > Add support for zero queue sizes of the traffic classes. The queues > which are not used can be set to zero size. This helps in reducing > memory footprint of the hierarchical scheduler. > > Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com> > Signed-off-by: Abraham Tovar <abrahamx.tovar@intel.com> > Signed-off-by: Lukasz Krakowiak <lukaszx.krakowiak@intel.com> > --- > lib/librte_sched/rte_sched.c | 354 +++++++++++++++++++---------------- > lib/librte_sched/rte_sched.h | 12 +- > 2 files changed, 198 insertions(+), 168 deletions(-) > > diff --git a/lib/librte_sched/rte_sched.c b/lib/librte_sched/rte_sched.c > index b1f521794..411924c36 100644 > --- a/lib/librte_sched/rte_sched.c > +++ b/lib/librte_sched/rte_sched.c > @@ -149,15 +149,15 @@ struct rte_sched_grinder { > struct rte_sched_pipe_profile *pipe_params; > > /* TC cache */ > - uint8_t tccache_qmask[4]; > - uint32_t tccache_qindex[4]; > + uint8_t tccache_qmask[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; > + uint32_t tccache_qindex[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; > uint32_t tccache_w; > uint32_t tccache_r; > > /* Current TC */ > uint32_t tc_index; > - struct rte_sched_queue > *queue[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; > - struct rte_mbuf **qbase[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; > + struct rte_sched_queue > *queue[RTE_SCHED_MAX_QUEUES_PER_TC]; > + struct rte_mbuf **qbase[RTE_SCHED_MAX_QUEUES_PER_TC]; > uint32_t qindex[RTE_SCHED_MAX_QUEUES_PER_TC]; > uint16_t qsize[RTE_SCHED_MAX_QUEUES_PER_TC]; > uint32_t qmask; > @@ -178,7 +178,7 @@ struct rte_sched_port { > uint32_t rate; > uint32_t mtu; > uint32_t frame_overhead; > - uint16_t qsize[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; > + uint16_t qsize[RTE_SCHED_QUEUES_PER_PIPE]; > uint32_t n_pipe_profiles; > uint32_t pipe_tc3_rate_max; > #ifdef RTE_SCHED_RED > @@ -260,14 +260,13 @@ rte_sched_port_qbase(struct rte_sched_port > *port, uint32_t qindex) > static inline uint16_t > rte_sched_port_qsize(struct rte_sched_port *port, uint32_t qindex) > { > - uint32_t tc = (qindex >> 2) & 0x3; > - > - return port->qsize[tc]; > + uint32_t qpos = qindex & 0xF; > + return port->qsize[qpos]; > } > > static int > pipe_profile_check(struct rte_sched_pipe_params *params, > - uint32_t rate) > + uint32_t rate, uint16_t *qsize) > { > uint32_t i; > > @@ -285,12 +284,17 @@ pipe_profile_check(struct rte_sched_pipe_params > *params, > return -12; > > /* TC rate: non-zero, less than pipe rate */ > - for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { > - if (params->tc_rate[i] == 0 || > - params->tc_rate[i] > params->tb_rate) > + for (i = 0; i < RTE_SCHED_TRAFFIC_CLASS_BE; i++) { > + if ((qsize[i] == 0 && params->tc_rate[i] != 0) || > + (qsize[i] != 0 && (params->tc_rate[i] == 0 || > + params->tc_rate[i] > params->tb_rate))) > return -13; > + > } > > + if (params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE] == 0) > + return -13; You forgot to check that pipe BE TC rate is not bigger than the pipe rate, which is a check that is enforced for the other higher priority traffic classes. > + > /* TC period: non-zero */ > if (params->tc_period == 0) > return -14; > @@ -302,8 +306,10 @@ pipe_profile_check(struct rte_sched_pipe_params > *params, > #endif > > /* Queue WRR weights: non-zero */ > - for (i = 0; i < RTE_SCHED_QUEUES_PER_PIPE; i++) { > - if (params->wrr_weights[i] == 0) > + for (i = 0; i < RTE_SCHED_BE_QUEUES_PER_PIPE; i++) { > + uint32_t qindex = RTE_SCHED_TRAFFIC_CLASS_BE + i; > + if ((qsize[qindex] != 0 && params->wrr_weights[i] == 0) || > + (qsize[qindex] == 0 && params->wrr_weights[i] != > 0)) > return -16; > } > return 0; > @@ -343,10 +349,10 @@ rte_sched_port_check_params(struct > rte_sched_port_params *params) > /* qsize: non-zero, power of 2, > * no bigger than 32K (due to 16-bit read/write pointers) > */ > - for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { > + for (i = 0; i < RTE_SCHED_QUEUES_PER_PIPE; i++) { > uint16_t qsize = params->qsize[i]; > - > - if (qsize == 0 || !rte_is_power_of_2(qsize)) > + if ((qsize != 0 && !rte_is_power_of_2(qsize)) || > + ((i == RTE_SCHED_TRAFFIC_CLASS_BE) && (qsize == > 0))) > return -8; > } > > @@ -360,7 +366,7 @@ rte_sched_port_check_params(struct > rte_sched_port_params *params) > struct rte_sched_pipe_params *p = params->pipe_profiles + > i; > int status; > > - status = pipe_profile_check(p, params->rate); > + status = pipe_profile_check(p, params->rate, ¶ms- > >qsize[0]); > if (status != 0) > return status; > } > @@ -389,9 +395,9 @@ rte_sched_port_get_array_base(struct > rte_sched_port_params *params, enum rte_sch > uint32_t base, i; > > size_per_pipe_queue_array = 0; > - for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { > - size_per_pipe_queue_array += > RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS > - * params->qsize[i] * sizeof(struct rte_mbuf *); > + for (i = 0; i < RTE_SCHED_QUEUES_PER_PIPE; i++) { > + size_per_pipe_queue_array += > + params->qsize[i] * sizeof(struct rte_mbuf *); > } > size_queue_array = n_pipes_per_port * > size_per_pipe_queue_array; > > @@ -451,31 +457,12 @@ rte_sched_port_get_memory_footprint(struct > rte_sched_port_params *params) > static void > rte_sched_port_config_qsize(struct rte_sched_port *port) > { > - /* TC 0 */ > + uint32_t i; > port->qsize_add[0] = 0; > - port->qsize_add[1] = port->qsize_add[0] + port->qsize[0]; > - port->qsize_add[2] = port->qsize_add[1] + port->qsize[0]; > - port->qsize_add[3] = port->qsize_add[2] + port->qsize[0]; > - > - /* TC 1 */ > - port->qsize_add[4] = port->qsize_add[3] + port->qsize[0]; > - port->qsize_add[5] = port->qsize_add[4] + port->qsize[1]; > - port->qsize_add[6] = port->qsize_add[5] + port->qsize[1]; > - port->qsize_add[7] = port->qsize_add[6] + port->qsize[1]; > - > - /* TC 2 */ > - port->qsize_add[8] = port->qsize_add[7] + port->qsize[1]; > - port->qsize_add[9] = port->qsize_add[8] + port->qsize[2]; > - port->qsize_add[10] = port->qsize_add[9] + port->qsize[2]; > - port->qsize_add[11] = port->qsize_add[10] + port->qsize[2]; > - > - /* TC 3 */ > - port->qsize_add[12] = port->qsize_add[11] + port->qsize[2]; > - port->qsize_add[13] = port->qsize_add[12] + port->qsize[3]; > - port->qsize_add[14] = port->qsize_add[13] + port->qsize[3]; > - port->qsize_add[15] = port->qsize_add[14] + port->qsize[3]; > - > - port->qsize_sum = port->qsize_add[15] + port->qsize[3]; > + for (i = 1; i < RTE_SCHED_QUEUES_PER_PIPE; i++) > + port->qsize_add[i] = port->qsize_add[i-1] + port->qsize[i-1]; > + > + port->qsize_sum = port->qsize_add[15] + port->qsize[15]; > } > > static void > @@ -484,10 +471,11 @@ rte_sched_port_log_pipe_profile(struct > rte_sched_port *port, uint32_t i) > struct rte_sched_pipe_profile *p = port->pipe_profiles + i; > > RTE_LOG(DEBUG, SCHED, "Low level config for pipe profile %u:\n" > - " Token bucket: period = %u, credits per period = %u, size = > %u\n" > - " Traffic classes: period = %u, credits per period = [%u, %u, > %u, %u]\n" > - " Traffic class 3 oversubscription: weight = %hhu\n" > - " WRR cost: [%hhu, %hhu, %hhu, %hhu]\n", > + " Token bucket: period = %u, credits per period = %u, > size = %u\n" > + " Traffic classes: period = %u,\n" > + " credits per period = [%u, %u, %u, %u, %u, %u, %u, > %u, %u, %u, %u, %u, %u]\n" > + " Best-effort traffic class oversubscription: weight = > %hhu\n" > + " WRR cost: [%hhu, %hhu, %hhu, %hhu]\n", > i, > > /* Token bucket */ > @@ -501,8 +489,17 @@ 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], > - > - /* Traffic class 3 oversubscription */ > + 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], > + > + /* Best-effort traffic class oversubscription */ > p->tc_ov_weight, > > /* WRR */ > @@ -548,9 +545,10 @@ rte_sched_pipe_profile_convert(struct > rte_sched_port *port, > 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]); > + if (port->qsize[i]) > + dst->tc_credits_per_period[i] > + = rte_sched_time_ms_to_bytes(src- > >tc_period, > + src->tc_rate[i]); > > #ifdef RTE_SCHED_SUBPORT_TC_OV The TC_OV logic should be enabled for all the configuration/initialization code; the only place it should be conditionally enabled is the run-time code (e.g. grinder update/schedule), so no need for this #ifdef here. Same in many other places, should be easy to change for a consistent approach. > dst->tc_ov_weight = src->tc_ov_weight; > @@ -558,7 +556,7 @@ rte_sched_pipe_profile_convert(struct > rte_sched_port *port, > > /* WRR queues */ > for (i = 0; i < RTE_SCHED_BE_QUEUES_PER_PIPE; i++) > - if (port->qsize[i]) > + if (port->qsize[RTE_SCHED_TRAFFIC_CLASS_BE + i]) > dst->n_be_queues++; > > if (dst->n_be_queues == 1) > @@ -620,7 +618,7 @@ rte_sched_port_config_pipe_profile_table(struct > rte_sched_port *port, > 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]; > + uint32_t pipe_tc3_rate = src- > >tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE]; > > if (port->pipe_tc3_rate_max < pipe_tc3_rate) > port->pipe_tc3_rate_max = pipe_tc3_rate; > @@ -762,12 +760,14 @@ rte_sched_port_free(struct rte_sched_port *port) > for (qindex = 0; qindex < n_queues_per_port; qindex++) { > struct rte_mbuf **mbufs = rte_sched_port_qbase(port, > qindex); > uint16_t qsize = rte_sched_port_qsize(port, qindex); > - struct rte_sched_queue *queue = port->queue + qindex; > - uint16_t qr = queue->qr & (qsize - 1); > - uint16_t qw = queue->qw & (qsize - 1); > + if (qsize != 0) { > + struct rte_sched_queue *queue = port->queue + > qindex; > + uint16_t qr = queue->qr & (qsize - 1); > + uint16_t qw = queue->qw & (qsize - 1); > > - for (; qr != qw; qr = (qr + 1) & (qsize - 1)) > - rte_pktmbuf_free(mbufs[qr]); > + for (; qr != qw; qr = (qr + 1) & (qsize - 1)) > + rte_pktmbuf_free(mbufs[qr]); > + } > } > > rte_bitmap_free(port->bmp); > @@ -780,9 +780,10 @@ rte_sched_port_log_subport_config(struct > rte_sched_port *port, uint32_t i) > struct rte_sched_subport *s = port->subport + i; > > RTE_LOG(DEBUG, SCHED, "Low level config for subport %u:\n" > - " Token bucket: period = %u, credits per period = %u, size = > %u\n" > - " Traffic classes: period = %u, credits per period = [%u, %u, > %u, %u]\n" > - " Traffic class 3 oversubscription: wm min = %u, wm max = > %u\n", > + " Token bucket: period = %u, credits per period = %u, > size = %u\n" > + " Traffic classes: period = %u\n" > + " credits per period = [%u, %u, %u, %u, %u, %u, %u, > %u, %u, %u, %u, %u, %u]\n" > + " Best effort traffic class oversubscription: wm min = > %u, wm max = %u\n", > i, > > /* Token bucket */ > @@ -796,8 +797,17 @@ 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], > - > - /* Traffic class 3 oversubscription */ > + s->tc_credits_per_period[4], > + s->tc_credits_per_period[5], > + s->tc_credits_per_period[6], > + s->tc_credits_per_period[7], > + s->tc_credits_per_period[8], > + s->tc_credits_per_period[9], > + s->tc_credits_per_period[10], > + s->tc_credits_per_period[11], > + s->tc_credits_per_period[12], > + > + /* Best effort traffic class oversubscription */ > s->tc_ov_wm_min, > s->tc_ov_wm_max); > } > @@ -808,7 +818,7 @@ rte_sched_subport_config(struct rte_sched_port > *port, > struct rte_sched_subport_params *params) > { > struct rte_sched_subport *s; > - uint32_t i; > + uint32_t i, j; > > /* Check user parameters */ > if (port == NULL || > @@ -822,12 +832,24 @@ rte_sched_subport_config(struct rte_sched_port > *port, > if (params->tb_size == 0) > return -3; > > - for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { > - if (params->tc_rate[i] == 0 || > - params->tc_rate[i] > params->tb_rate) > - return -4; > + for (i = 0, j = 0; i < RTE_SCHED_QUEUES_PER_PIPE; i++) { > + uint32_t tc_rate = params->tc_rate[j]; > + uint16_t qsize = port->qsize[i]; > + > + if (((qsize == 0) && > + ((tc_rate != 0) && (j != > RTE_SCHED_TRAFFIC_CLASS_BE))) || > + ((qsize != 0) && (tc_rate == 0)) || > + (tc_rate > params->tb_rate)) > + return -3; > + > + if (j < RTE_SCHED_TRAFFIC_CLASS_BE) > + j++; > } > > + if (port->qsize[RTE_SCHED_TRAFFIC_CLASS_BE] == 0 || > + params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE] == 0) > + return -3; > + > if (params->tc_period == 0) > return -5; > > @@ -851,13 +873,16 @@ rte_sched_subport_config(struct rte_sched_port > *port, > /* Traffic Classes (TCs) */ > s->tc_period = rte_sched_time_ms_to_bytes(params->tc_period, > port->rate); > for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { > - s->tc_credits_per_period[i] > - = rte_sched_time_ms_to_bytes(params->tc_period, > - params->tc_rate[i]); > + if (port->qsize[i]) > + s->tc_credits_per_period[i] > + = rte_sched_time_ms_to_bytes(params- > >tc_period, > + params- > >tc_rate[i]); > + > } > s->tc_time = port->time + s->tc_period; > for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) > - s->tc_credits[i] = s->tc_credits_per_period[i]; > + if (port->qsize[i]) > + s->tc_credits[i] = s->tc_credits_per_period[i]; > > #ifdef RTE_SCHED_SUBPORT_TC_OV > /* TC oversubscription */ > @@ -910,9 +935,9 @@ 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 subport_tc3_rate = (double) s- > >tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] > / (double) s->tc_period; > - double pipe_tc3_rate = (double) params- > >tc_credits_per_period[3] > + double pipe_tc3_rate = (double) params- > >tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] > / (double) params->tc_period; > uint32_t tc3_ov = s->tc_ov; > > @@ -945,15 +970,19 @@ rte_sched_pipe_config(struct rte_sched_port > *port, > > /* Traffic Classes (TCs) */ > p->tc_time = port->time + params->tc_period; > + p->n_be_queues = params->n_be_queues; > for (i = 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) > - p->tc_credits[i] = params->tc_credits_per_period[i]; > + if (port->qsize[i]) > + p->tc_credits[i] = params->tc_credits_per_period[i]; > > #ifdef RTE_SCHED_SUBPORT_TC_OV > { > /* Subport TC3 oversubscription */ > - double subport_tc3_rate = (double) s- > >tc_credits_per_period[3] > + double subport_tc3_rate = > + (double) s- > >tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] > / (double) s->tc_period; > - double pipe_tc3_rate = (double) params- > >tc_credits_per_period[3] > + double pipe_tc3_rate = > + (double) params- > >tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] > / (double) params->tc_period; > uint32_t tc3_ov = s->tc_ov; > > @@ -992,7 +1021,7 @@ rte_sched_port_pipe_profile_add(struct > rte_sched_port *port, > return -2; > > /* Pipe params */ > - status = pipe_profile_check(params, port->rate); > + status = pipe_profile_check(params, port->rate, &port->qsize[0]); > if (status != 0) > return status; > > @@ -1008,8 +1037,8 @@ rte_sched_port_pipe_profile_add(struct > rte_sched_port *port, > *pipe_profile_id = port->n_pipe_profiles; > port->n_pipe_profiles++; > > - if (port->pipe_tc3_rate_max < params->tc_rate[3]) > - port->pipe_tc3_rate_max = params->tc_rate[3]; > + if (port->pipe_tc3_rate_max < params- > >tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE]) > + port->pipe_tc3_rate_max = params- > >tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE]; > > rte_sched_port_log_pipe_profile(port, *pipe_profile_id); > > @@ -1020,15 +1049,12 @@ static inline uint32_t > rte_sched_port_qindex(struct rte_sched_port *port, > uint32_t subport, > uint32_t pipe, > - uint32_t traffic_class, > uint32_t queue) > { > return ((subport & (port->n_subports_per_port - 1)) << > (port->n_pipes_per_subport_log2 + 4)) | > ((pipe & (port->n_pipes_per_subport - 1)) << 4) | > - ((traffic_class & > - (RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE - 1)) << > 2) | > - (queue & > (RTE_SCHED_QUEUES_PER_TRAFFIC_CLASS - 1)); > + (queue & (RTE_SCHED_QUEUES_PER_PIPE - 1)); > } > > void > @@ -1038,8 +1064,8 @@ rte_sched_port_pkt_write(struct rte_sched_port > *port, > uint32_t traffic_class, > uint32_t queue, enum rte_color color) > { > - uint32_t queue_id = rte_sched_port_qindex(port, subport, pipe, > - traffic_class, queue); > + uint32_t queue_id = rte_sched_port_qindex(port, subport, pipe, > q