From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 84E1AA0549; Thu, 16 Jul 2020 10:14:37 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 5D6CC1BEB1; Thu, 16 Jul 2020 10:14:37 +0200 (CEST) Received: from mga11.intel.com (mga11.intel.com [192.55.52.93]) by dpdk.org (Postfix) with ESMTP id CB0384F9A for ; Thu, 16 Jul 2020 10:14:34 +0200 (CEST) IronPort-SDR: oMSRtX9QYTiu1DsrFLuUU2o9O98O0ZVddvtkBZ9t7YetWsW5BhELALI0olgtuDISktx3cwAw/y 6gRl7SL+XwgQ== X-IronPort-AV: E=McAfee;i="6000,8403,9683"; a="147333547" X-IronPort-AV: E=Sophos;i="5.75,358,1589266800"; d="scan'208";a="147333547" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga007.fm.intel.com ([10.253.24.52]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Jul 2020 01:14:33 -0700 IronPort-SDR: i7ZpEOWRZGOl+gEAxuUo5Tga3SYIrz6yxFetiwwuJOihkJoeD6tP2nYfxOkGQo0RKJAhmcj27K pzBn2pMBNfOA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.75,358,1589266800"; d="scan'208";a="269189942" Received: from orsmsx105.amr.corp.intel.com ([10.22.225.132]) by fmsmga007.fm.intel.com with ESMTP; 16 Jul 2020 01:14:33 -0700 Received: from orsmsx612.amr.corp.intel.com (10.22.229.25) by ORSMSX105.amr.corp.intel.com (10.22.225.132) with Microsoft SMTP Server (TLS) id 14.3.439.0; Thu, 16 Jul 2020 01:14:33 -0700 Received: from orsmsx603.amr.corp.intel.com (10.22.229.16) by ORSMSX612.amr.corp.intel.com (10.22.229.25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1713.5; Thu, 16 Jul 2020 01:14:33 -0700 Received: from ORSEDG001.ED.cps.intel.com (10.7.248.4) by orsmsx603.amr.corp.intel.com (10.22.229.16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256) id 15.1.1713.5 via Frontend Transport; Thu, 16 Jul 2020 01:14:33 -0700 Received: from NAM11-DM6-obe.outbound.protection.outlook.com (104.47.57.170) by edgegateway.intel.com (134.134.137.100) with Microsoft SMTP Server (TLS) id 14.3.439.0; Thu, 16 Jul 2020 01:14:31 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Yg+ydzh++WsCHYWUdqojFd5hltT1vWg/at8SkkwN8IxkbreqMKDa6eZcI88WkOdn65lbgP/1weXDpnzG08OAafF1gS1rVZbK05kcz9w3PMZ9n1mHP0I3pIWKZW+aPGx7W4GYE/GTGvLNPHIqvUv80VBWQiHxXtTql/MYeU2A/3OvoAzNu6pVacjStMdUWmH8AHU975Cfj4LPwRTczCbAZBz1QPKva2pb0N0odzAM4ifMrFCZ1BJ/n5W0m9aJ/q+ChkuTc4Qswrcr4Dyks+KkOutkmo/UMdE9ZVpd4Z6tHH2oY86+rBK7dpzs6A/3VFsoL+S39C3vy1m16EQ3G7vLcQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=UMPJCupNyRsnArkd9OMQ0kjgsU7oTe7eNR5lq+u9h5E=; b=RPjtuEFdhL9hfIw815RpI5J4J4GGzrVHuJiXTSSWudPdZvyd19gvPCfLJ5wHet8u+mkIjp00OOator3MDvmH0dIoalmeBMBDSC4L/yQxpPGjqBLrjcaZjAMg3Ik9OMHraZ3QQrBfRtlCTG51CoHCbV5sSCTyrEM5kOSAqSAlx5VLA8h2Q7OBnCW444bODOx9kHZDYekDITG45DawozF6iEPacrf4djCY86MfE2OvHFUtncEq4fCCdfRGCW3pwhx1gbNL5yTeR8oi5XbvsgFAQbbbBRU4oe9d58haGC0g+zX8ZGUfZLf3XlzclA1OAuyKGAoamE7jA9oqc4zoGIo32Q== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=intel.com; dmarc=pass action=none header.from=intel.com; dkim=pass header.d=intel.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=intel.onmicrosoft.com; s=selector2-intel-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=UMPJCupNyRsnArkd9OMQ0kjgsU7oTe7eNR5lq+u9h5E=; b=Y9RmpqjbLLRhCBu6UMlKM58Pe+x/SBlws3qKobKW6ua+sg87xX7FN0WuVzstM/RoWYIfTkuJGUOqnmyF75qZ5ZIbHwJrznhqnhdVdCx8FXnsTmSLUR4mmtM3zPjqzTNqqgO8eABrx9g34YJxnXhNHhK1FiG/IEungHp/19V/36M= Received: from CY4PR11MB0072.namprd11.prod.outlook.com (2603:10b6:910:76::27) by CY4PR11MB1526.namprd11.prod.outlook.com (2603:10b6:910:7::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3174.21; Thu, 16 Jul 2020 08:14:28 +0000 Received: from CY4PR11MB0072.namprd11.prod.outlook.com ([fe80::e979:a537:4a97:afd5]) by CY4PR11MB0072.namprd11.prod.outlook.com ([fe80::e979:a537:4a97:afd5%5]) with mapi id 15.20.3195.018; Thu, 16 Jul 2020 08:14:28 +0000 From: "Singh, Jasvinder" To: "Dharmappa, Savinay" , "dev@dpdk.org" , "Dumitrescu, Cristian" Thread-Topic: [RFC PATCH 1/2] sched: add dynamic config of subport bandwidth profile Thread-Index: AQHWWtXEe7Ur2pGIWEqsw/hyR54MhqkJ3H0w Date: Thu, 16 Jul 2020 08:14:28 +0000 Message-ID: References: <1594837677-313175-1-git-send-email-savinay.dharmappa@intel.com> <1594837677-313175-2-git-send-email-savinay.dharmappa@intel.com> In-Reply-To: <1594837677-313175-2-git-send-email-savinay.dharmappa@intel.com> Accept-Language: en-GB, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: dlp-version: 11.5.1.3 dlp-reaction: no-action dlp-product: dlpe-windows authentication-results: intel.com; dkim=none (message not signed) header.d=none;intel.com; dmarc=none action=none header.from=intel.com; x-originating-ip: [51.37.210.122] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 83789662-780d-453c-7070-08d8296042e7 x-ms-traffictypediagnostic: CY4PR11MB1526: x-ms-exchange-transport-forked: True x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:110; x-ms-exchange-senderadcheck: 1 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: J/Px3r7lt0UMl/AUuIws2p0PsrWfZvpQX/Zyz7B3J8oAaFH13eqK9XDvy9K8g/evvanN7pNMw6yot4+0oeToPpvTmi//aU406+LrQBfiC6O/KwHVkQe2I4ESwjywjWt52pImaLVBqDbf2VvnwAkCWGQ8GVRa9TUsyNRusAtAlYIYQ9+M40LVFUaiSwWYZewUN+tJNPz1nb7d+5CmlmgFdixD2EBGtcXEbPYGFkLSwmzb5IoAfCG2LUCmL47b1YT4QJlNXvY8lFIJNnFa8lCZ2waUCqEikLNs+SAyWsvQy77HPU8j4ZQ6swk33M46RXbK x-forefront-antispam-report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:CY4PR11MB0072.namprd11.prod.outlook.com; PTR:; CAT:NONE; SFTY:; SFS:(4636009)(396003)(366004)(136003)(39860400002)(376002)(346002)(86362001)(53546011)(6636002)(6506007)(30864003)(64756008)(71200400001)(66946007)(66446008)(66556008)(316002)(478600001)(186003)(2906002)(7696005)(9686003)(66476007)(8676002)(55016002)(26005)(8936002)(33656002)(76116006)(110136005)(83380400001)(5660300002)(52536014)(559001)(579004); DIR:OUT; SFP:1102; x-ms-exchange-antispam-messagedata: 99j58qCUZBUK/H/yh51xY2b6VbcNRdUfeAU9jsDRkkI8Nqof924pQV+lluKUVL7l8mBciueHGqC0PjVsVbReT9/CLkZIsVj7YTSHOBK4z8Thr3McX+pBb5ED1gAgjU2INyBMePEEMpuxwG/pe6uqVS8jf0r5L/N4xAm/8JZTAHfYYbD0luuTJ28iJUU1F8hyC/3k6wCV2/DFsEC70SuW4RReq8AqkePdcQ4vkZGe882ozIVrHH7MoudZeftFznm/knN+EUY04CHL+qCu+j/PiLsgeGZWav+0RicLFqlRUZmvDCsNhKjIN4QgcL9ZybfyxszSFNyeqEeTCglqumuxJG3ODcicpUPtaS8tlW5WefCmJQ+2OzVANq4Ajjd/bzmJAWrfXdfAE9VGn/vTlsv/QVxTu4h7BUuOetEYUlMcHtQ56yk0wTd3UiLfq4ZLyWUvNBPxmIb+IgwQYE7mW354Rd1xDSpvuS/3ccIIAchuKf4= Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: CY4PR11MB0072.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 83789662-780d-453c-7070-08d8296042e7 X-MS-Exchange-CrossTenant-originalarrivaltime: 16 Jul 2020 08:14:28.7908 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 46c98d88-e344-4ed4-8496-4ed7712e255d X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: Luf82YSq3YGAmtrD4BbTfCFihb9V7NJruopnJIlbATNFOoNSZHLcgqEyWcf3DzkQccHnZNdKaxsoDtesQ1tGW7G+3X1+NTJ13aTmGBw3NCo= X-MS-Exchange-Transport-CrossTenantHeadersStamped: CY4PR11MB1526 X-OriginatorOrg: intel.com Subject: Re: [dpdk-dev] [RFC PATCH 1/2] sched: add dynamic config of subport bandwidth profile X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" > -----Original Message----- > From: Dharmappa, Savinay > Sent: Wednesday, July 15, 2020 7:28 PM > To: Dharmappa, Savinay ; Singh, Jasvinder > ; dev@dpdk.org > Subject: [RFC PATCH 1/2] sched: add dynamic config of subport bandwidth > profile >=20 > This patch modifies the subport level data structures and add new API to > allow dynamic configuration of the subport bandwidth profile. >=20 > Signed-off-by: Savinay Dharmappa > Signed-off-by: Jasvinder Singh > --- > lib/librte_sched/rte_sched.c | 486 ++++++++++++++++++++++++---= ------ > lib/librte_sched/rte_sched.h | 82 +++++- > lib/librte_sched/rte_sched_version.map | 2 + > 3 files changed, 424 insertions(+), 146 deletions(-) >=20 > diff --git a/lib/librte_sched/rte_sched.c b/lib/librte_sched/rte_sched.c = index > c0983dd..5bb0d2b 100644 > --- a/lib/librte_sched/rte_sched.c > +++ b/lib/librte_sched/rte_sched.c > @@ -2,6 +2,7 @@ > * Copyright(c) 2010-2014 Intel Corporation > */ >=20 > +#include > #include > #include >=20 > @@ -101,6 +102,16 @@ enum grinder_state { > e_GRINDER_READ_MBUF > }; >=20 > +struct rte_sched_subport_profile { > + /* Token bucket (TB) */ > + uint64_t tb_period; > + uint64_t tb_credits_per_period; > + uint64_t tb_size; > + > + uint64_t > tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; > + uint64_t tc_period; > +}; > + > struct rte_sched_grinder { > /* Pipe cache */ > uint16_t pcache_qmask[RTE_SCHED_GRINDER_PCACHE_SIZE]; > @@ -113,6 +124,7 @@ struct rte_sched_grinder { > uint32_t productive; > uint32_t pindex; > struct rte_sched_subport *subport; > + struct rte_sched_subport_profile *subport_params; > struct rte_sched_pipe *pipe; > struct rte_sched_pipe_profile *pipe_params; >=20 > @@ -139,18 +151,13 @@ struct rte_sched_grinder { }; >=20 > struct rte_sched_subport { > - /* Token bucket (TB) */ > + > uint64_t tb_time; /* time of last update */ > - uint64_t tb_period; > - uint64_t tb_credits_per_period; > - uint64_t tb_size; > uint64_t tb_credits; >=20 > /* Traffic classes (TCs) */ > uint64_t tc_time; /* time of next update */ > - uint64_t > tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; > uint64_t tc_credits[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; > - uint64_t tc_period; >=20 > /* TC oversubscription */ > uint64_t tc_ov_wm; > @@ -164,6 +171,8 @@ struct rte_sched_subport { > /* Statistics */ > struct rte_sched_subport_stats stats __rte_cache_aligned; >=20 > + /* subport profile flag */ > + uint32_t profile; > /* Subport pipes */ > uint32_t n_pipes_per_subport_enabled; > uint32_t n_pipe_profiles; > @@ -212,6 +221,8 @@ struct rte_sched_port { > uint16_t pipe_queue[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; > uint8_t pipe_tc[RTE_SCHED_QUEUES_PER_PIPE]; > uint8_t tc_queue[RTE_SCHED_QUEUES_PER_PIPE]; > + uint32_t n_subport_profiles; > + uint32_t n_max_subport_profiles; > uint64_t rate; > uint32_t mtu; > uint32_t frame_overhead; > @@ -229,6 +240,7 @@ struct rte_sched_port { > uint32_t subport_id; >=20 > /* Large data structures */ > + struct rte_sched_subport_profile *subport_profiles; > struct rte_sched_subport *subports[0] __rte_cache_aligned; } > __rte_cache_aligned; >=20 > @@ -375,8 +387,60 @@ pipe_profile_check(struct rte_sched_pipe_params > *params, } >=20 > static int > +subport_profile_check(struct rte_sched_subport_profile_params *params, > + uint64_t rate) > +{ > + uint32_t i; > + > + /* Check user parameters */ > + if (params =3D=3D NULL) { > + RTE_LOG(ERR, SCHED, > + "%s: Incorrect value for parameter params\n", > __func__); > + return -EINVAL; > + } > + > + if (params->tb_rate =3D=3D 0 || params->tb_rate > rate) { > + RTE_LOG(ERR, SCHED, > + "%s: Incorrect value for tb rate\n", __func__); > + return -EINVAL; > + } > + > + if (params->tb_size =3D=3D 0) { > + RTE_LOG(ERR, SCHED, > + "%s: Incorrect value for tb size\n", __func__); > + return -EINVAL; > + } > + > + for (i =3D 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { > + uint64_t tc_rate =3D params->tc_rate[i]; > + > + if (tc_rate =3D=3D 0 || (tc_rate > params->tb_rate)) { > + RTE_LOG(ERR, SCHED, > + "%s: Incorrect value for tc rate\n", __func__); > + return -EINVAL; > + } > + } > + > + if (params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE] =3D=3D 0) { > + RTE_LOG(ERR, SCHED, > + "%s: Incorrect tc rate(best effort)\n", __func__); > + return -EINVAL; > + } > + > + if (params->tc_period =3D=3D 0) { > + RTE_LOG(ERR, SCHED, > + "%s: Incorrect value for tc period\n", __func__); > + return -EINVAL; > + } > + > + return 0; > +} > + > +static int > rte_sched_port_check_params(struct rte_sched_port_params *params) { > + uint32_t i; > + > if (params =3D=3D NULL) { > RTE_LOG(ERR, SCHED, > "%s: Incorrect value for parameter params\n", > __func__); @@ -413,6 +477,29 @@ rte_sched_port_check_params(struct > rte_sched_port_params *params) > return -EINVAL; > } >=20 > + if (params->subport_profiles =3D=3D NULL || > + params->n_subport_profiles =3D=3D 0 || > + params->n_max_subport_profiles =3D=3D 0 || > + params->n_subport_profiles > params- > >n_max_subport_profiles) { > + RTE_LOG(ERR, SCHED, > + "%s: Incorrect value for subport profiles\n", __func__); > + return -EINVAL; > + } > + > + for (i =3D 0; i < params->n_subport_profiles; i++) { > + struct rte_sched_subport_profile_params *p =3D > + params->subport_profiles + i; > + int status; > + > + status =3D subport_profile_check(p, params->rate); > + if (status !=3D 0) { > + RTE_LOG(ERR, SCHED, > + "%s: subport profile check failed(%d)\n", > + __func__, status); > + return -EINVAL; > + } > + } > + > /* n_pipes_per_subport: non-zero, power of 2 */ > if (params->n_pipes_per_subport =3D=3D 0 || > !rte_is_power_of_2(params->n_pipes_per_subport)) { @@ -554,6 > +641,42 @@ rte_sched_port_log_pipe_profile(struct rte_sched_subport > *subport, uint32_t i) > p->wrr_cost[0], p->wrr_cost[1], p->wrr_cost[2], p- > >wrr_cost[3]); } >=20 > +static void > +rte_sched_port_log_subport_profile(struct rte_sched_port *port, > +uint32_t i) { > + struct rte_sched_subport_profile *p =3D port->subport_profiles + i; > + > + RTE_LOG(DEBUG, SCHED, "Low level config for subport profile > %u:\n" > + "Token bucket: period =3D %"PRIu64", credits per period =3D %"PRIu64",\ > + size =3D %"PRIu64"\n" > + "Traffic classes: period =3D %"PRIu64",\n" > + "credits per period =3D [%"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64 > + " %"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64", > %"PRIu64 > + " %"PRIu64", %"PRIu64", %"PRIu64"]\n", > + i, > + > + /* Token bucket */ > + p->tb_period, > + p->tb_credits_per_period, > + p->tb_size, > + > + /* Traffic classes */ > + p->tc_period, > + p->tc_credits_per_period[0], > + p->tc_credits_per_period[1], > + p->tc_credits_per_period[2], > + p->tc_credits_per_period[3], > + p->tc_credits_per_period[4], > + p->tc_credits_per_period[5], > + p->tc_credits_per_period[6], > + p->tc_credits_per_period[7], > + p->tc_credits_per_period[8], > + p->tc_credits_per_period[9], > + p->tc_credits_per_period[10], > + p->tc_credits_per_period[11], > + p->tc_credits_per_period[12]); > +} > + > static inline uint64_t > rte_sched_time_ms_to_bytes(uint64_t time_ms, uint64_t rate) { @@ -623,6 > +746,37 @@ rte_sched_pipe_profile_convert(struct rte_sched_subport > *subport, } >=20 > static void > +rte_sched_subport_profile_convert(struct > rte_sched_subport_profile_params *src, > + struct rte_sched_subport_profile *dst, > + uint64_t rate) > +{ > + uint32_t i; > + > + /* Token Bucket */ > + if (src->tb_rate =3D=3D rate) { > + dst->tb_credits_per_period =3D 1; > + dst->tb_period =3D 1; > + } else { > + double tb_rate =3D (double) src->tb_rate > + / (double) rate; > + double d =3D RTE_SCHED_TB_RATE_CONFIG_ERR; > + > + rte_approx_64(tb_rate, d, &dst->tb_credits_per_period, > + &dst->tb_period); > + } > + > + dst->tb_size =3D src->tb_size; > + > + /* Traffic Classes */ > + dst->tc_period =3D rte_sched_time_ms_to_bytes(src->tc_period, rate); > + > + for (i =3D 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) > + dst->tc_credits_per_period[i] > + =3D rte_sched_time_ms_to_bytes(src->tc_period, > + src->tc_rate[i]); > +} > + > +static void > rte_sched_subport_config_pipe_profile_table(struct rte_sched_subport > *subport, > struct rte_sched_subport_params *params, uint32_t rate) { @@ - > 646,6 +800,24 @@ rte_sched_subport_config_pipe_profile_table(struct > rte_sched_subport *subport, > } > } >=20 > +static void > +rte_sched_port_config_subport_profile_table(struct rte_sched_port *port, > + struct rte_sched_port_params *params, > + uint64_t rate) > +{ > + uint32_t i; > + > + for (i =3D 0; i < port->n_subport_profiles; i++) { > + struct rte_sched_subport_profile_params *src > + =3D params->subport_profiles + i; > + struct rte_sched_subport_profile *dst > + =3D port->subport_profiles + i; > + > + rte_sched_subport_profile_convert(src, dst, rate); > + rte_sched_port_log_subport_profile(port, i); > + } > +} > + > static int > rte_sched_subport_check_params(struct rte_sched_subport_params > *params, > uint32_t n_max_pipes_per_subport, > @@ -660,18 +832,6 @@ rte_sched_subport_check_params(struct > rte_sched_subport_params *params, > return -EINVAL; > } >=20 > - if (params->tb_rate =3D=3D 0 || params->tb_rate > rate) { > - RTE_LOG(ERR, SCHED, > - "%s: Incorrect value for tb rate\n", __func__); > - return -EINVAL; > - } > - > - if (params->tb_size =3D=3D 0) { > - RTE_LOG(ERR, SCHED, > - "%s: Incorrect value for tb size\n", __func__); > - return -EINVAL; > - } > - > /* qsize: if non-zero, power of 2, > * no bigger than 32K (due to 16-bit read/write pointers) > */ > @@ -685,32 +845,12 @@ rte_sched_subport_check_params(struct > rte_sched_subport_params *params, > } > } >=20 > - for (i =3D 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { > - uint64_t tc_rate =3D params->tc_rate[i]; > - uint16_t qsize =3D params->qsize[i]; > - > - if ((qsize =3D=3D 0 && tc_rate !=3D 0) || > - (qsize !=3D 0 && tc_rate =3D=3D 0) || > - (tc_rate > params->tb_rate)) { > - RTE_LOG(ERR, SCHED, > - "%s: Incorrect value for tc rate\n", __func__); > - return -EINVAL; > - } > - } > - > - if (params->qsize[RTE_SCHED_TRAFFIC_CLASS_BE] =3D=3D 0 || > - params->tc_rate[RTE_SCHED_TRAFFIC_CLASS_BE] =3D=3D 0) { > + if (params->qsize[RTE_SCHED_TRAFFIC_CLASS_BE] =3D=3D 0) { > RTE_LOG(ERR, SCHED, > "%s: Incorrect qsize or tc rate(best effort)\n", > __func__); > return -EINVAL; > } >=20 > - if (params->tc_period =3D=3D 0) { > - RTE_LOG(ERR, SCHED, > - "%s: Incorrect value for tc period\n", __func__); > - return -EINVAL; > - } > - > /* n_pipes_per_subport: non-zero, power of 2 */ > if (params->n_pipes_per_subport_enabled =3D=3D 0 || > params->n_pipes_per_subport_enabled > > n_max_pipes_per_subport || @@ -792,7 +932,7 @@ struct rte_sched_port > * rte_sched_port_config(struct rte_sched_port_params *params) { > struct rte_sched_port *port =3D NULL; > - uint32_t size0, size1; > + uint32_t size0, size1, size2; > uint32_t cycles_per_byte; > uint32_t i, j; > int status; > @@ -807,10 +947,21 @@ rte_sched_port_config(struct > rte_sched_port_params *params) >=20 > size0 =3D sizeof(struct rte_sched_port); > size1 =3D params->n_subports_per_port * sizeof(struct > rte_sched_subport *); > + size2 =3D params->n_max_subport_profiles * > + sizeof(struct rte_sched_subport_profile); >=20 > /* Allocate memory to store the data structures */ > - port =3D rte_zmalloc_socket("qos_params", size0 + size1, > RTE_CACHE_LINE_SIZE, > - params->socket); > + port =3D rte_zmalloc_socket("qos_params", size0 + size1, > + RTE_CACHE_LINE_SIZE, params->socket); > + if (port =3D=3D NULL) { > + RTE_LOG(ERR, SCHED, "%s: Memory allocation fails\n", > __func__); > + > + return NULL; > + } > + > + /* Allocate memory to store the subport profile */ > + port->subport_profiles =3D rte_zmalloc_socket("subport_profile", > size2, > + RTE_CACHE_LINE_SIZE, params- > >socket); > if (port =3D=3D NULL) { > RTE_LOG(ERR, SCHED, "%s: Memory allocation fails\n", > __func__); >=20 > @@ -819,6 +970,8 @@ rte_sched_port_config(struct > rte_sched_port_params *params) >=20 > /* User parameters */ > port->n_subports_per_port =3D params->n_subports_per_port; > + port->n_subport_profiles =3D params->n_subport_profiles; > + port->n_max_subport_profiles =3D params->n_max_subport_profiles; > port->n_pipes_per_subport =3D params->n_pipes_per_subport; > port->n_pipes_per_subport_log2 =3D > __builtin_ctz(params->n_pipes_per_subport); > @@ -849,6 +1002,9 @@ rte_sched_port_config(struct > rte_sched_port_params *params) > port->time_cpu_bytes =3D 0; > port->time =3D 0; >=20 > + /* Subport profile table */ > + rte_sched_port_config_subport_profile_table(port, params, port- > >rate); > + > cycles_per_byte =3D (rte_get_tsc_hz() << RTE_SCHED_TIME_SHIFT) > / params->rate; > port->inv_cycles_per_byte =3D rte_reciprocal_value(cycles_per_byte); > @@ -907,48 +1063,6 @@ rte_sched_port_free(struct rte_sched_port *port) > } >=20 > static void > -rte_sched_port_log_subport_config(struct rte_sched_port *port, uint32_t = i) > -{ > - struct rte_sched_subport *s =3D port->subports[i]; > - > - RTE_LOG(DEBUG, SCHED, "Low level config for subport %u:\n" > - " Token bucket: period =3D %"PRIu64", credits per period > =3D %"PRIu64 > - ", size =3D %"PRIu64"\n" > - " Traffic classes: period =3D %"PRIu64"\n" > - " credits per period =3D [%"PRIu64", %"PRIu64", > %"PRIu64", %"PRIu64 > - ", %"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64", %"PRIu64", > %"PRIu64 > - ", %"PRIu64", %"PRIu64", %"PRIu64"]\n" > - " Best effort traffic class oversubscription: wm min =3D > %"PRIu64 > - ", wm max =3D %"PRIu64"\n", > - i, > - > - /* Token bucket */ > - s->tb_period, > - s->tb_credits_per_period, > - s->tb_size, > - > - /* Traffic classes */ > - s->tc_period, > - s->tc_credits_per_period[0], > - 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], > - > - /* Best effort traffic class oversubscription */ > - s->tc_ov_wm_min, > - s->tc_ov_wm_max); > -} > - > -static void > rte_sched_free_memory(struct rte_sched_port *port, uint32_t n_subports) > { > uint32_t i; > @@ -1021,33 +1135,7 @@ rte_sched_subport_config(struct rte_sched_port > *port, > /* Port */ > port->subports[subport_id] =3D s; >=20 > - /* Token Bucket (TB) */ > - if (params->tb_rate =3D=3D port->rate) { > - s->tb_credits_per_period =3D 1; > - s->tb_period =3D 1; > - } else { > - double tb_rate =3D ((double) params->tb_rate) / ((double) > port->rate); > - double d =3D RTE_SCHED_TB_RATE_CONFIG_ERR; > - > - rte_approx_64(tb_rate, d, &s->tb_credits_per_period, &s- > >tb_period); > - } > - > - s->tb_size =3D params->tb_size; > s->tb_time =3D port->time; > - s->tb_credits =3D s->tb_size / 2; > - > - /* Traffic Classes (TCs) */ > - s->tc_period =3D rte_sched_time_ms_to_bytes(params->tc_period, > port->rate); > - for (i =3D 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { > - if (params->qsize[i]) > - s->tc_credits_per_period[i] > - =3D rte_sched_time_ms_to_bytes(params- > >tc_period, > - params->tc_rate[i]); > - } > - s->tc_time =3D port->time + s->tc_period; > - for (i =3D 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) > - if (params->qsize[i]) > - s->tc_credits[i] =3D s->tc_credits_per_period[i]; >=20 > /* compile time checks */ > RTE_BUILD_BUG_ON(RTE_SCHED_PORT_N_GRINDERS =3D=3D 0); @@ - > 1137,8 +1225,6 @@ rte_sched_subport_config(struct rte_sched_port *port, > #ifdef RTE_SCHED_SUBPORT_TC_OV > /* TC oversubscription */ > s->tc_ov_wm_min =3D port->mtu; > - s->tc_ov_wm_max =3D rte_sched_time_ms_to_bytes(params- > >tc_period, > - s->pipe_tc_be_rate_max); > s->tc_ov_wm =3D s->tc_ov_wm_max; > s->tc_ov_period_id =3D 0; > s->tc_ov =3D 0; > @@ -1146,7 +1232,54 @@ rte_sched_subport_config(struct rte_sched_port > *port, > s->tc_ov_rate =3D 0; > #endif >=20 > - rte_sched_port_log_subport_config(port, subport_id); > + return 0; > +} > + > +int > +rte_sched_subport_profile_config(struct rte_sched_port *port, > + uint32_t subport_id, > + uint32_t profile_id) > +{ > + int i; > + struct rte_sched_subport_profile *params; > + uint32_t n_subports =3D subport_id + 1; > + struct rte_sched_subport *s; > + > + if (port =3D=3D NULL) { > + RTE_LOG(ERR, SCHED, > + "%s: Incorrect value for parameter port\n", > __func__); > + return -EINVAL; > + } > + > + if (subport_id >=3D port->n_subports_per_port) { > + RTE_LOG(ERR, SCHED, > + "%s: Incorrect value for parameter subport id\n", > __func__); > + > + rte_sched_free_memory(port, n_subports); > + return -EINVAL; > + } > + > + params =3D port->subport_profiles + profile_id; > + > + s =3D port->subports[subport_id]; > + > + s->tb_credits =3D params->tb_size / 2; > + > + s->tc_time =3D port->time + params->tc_period; > + > + for (i =3D 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) > + if (s->qsize[i]) > + s->tc_credits[i] =3D params->tc_credits_per_period[i]; > + else > + params->tc_credits_per_period[i] =3D 0; > + > +#ifdef RTE_SCHED_SUBPORT_TC_OV > + s->tc_ov_wm_max =3D rte_sched_time_ms_to_bytes(params- > >tc_period, > + s->pipe_tc_be_rate_max); > +#endif > + s->profile =3D profile_id; > + > + rte_sched_port_log_subport_profile(port, profile_id); >=20 > return 0; > } > @@ -1158,6 +1291,7 @@ rte_sched_pipe_config(struct rte_sched_port > *port, > int32_t pipe_profile) > { > struct rte_sched_subport *s; > + struct rte_sched_subport_profile *sp; > struct rte_sched_pipe *p; > struct rte_sched_pipe_profile *params; > uint32_t n_subports =3D subport_id + 1; > @@ -1198,14 +1332,16 @@ rte_sched_pipe_config(struct rte_sched_port > *port, > return -EINVAL; > } >=20 > + sp =3D port->subport_profiles + s->profile; > + > /* Handle the case when pipe already has a valid configuration */ > p =3D s->pipe + pipe_id; > if (p->tb_time) { > params =3D s->pipe_profiles + p->profile; >=20 > double subport_tc_be_rate =3D > - (double) s- > >tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] > - / (double) s->tc_period; > + (double) sp- > >tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] > + / (double) sp->tc_period; > double pipe_tc_be_rate =3D > (double) params- > >tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] > / (double) params->tc_period; > @@ -1247,8 +1383,8 @@ rte_sched_pipe_config(struct rte_sched_port > *port, > { > /* Subport best effort tc oversubscription */ > double subport_tc_be_rate =3D > - (double) s- > >tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] > - / (double) s->tc_period; > + (double) sp- > >tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] > + / (double) sp->tc_period; > double pipe_tc_be_rate =3D > (double) params- > >tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] > / (double) params->tc_period; > @@ -1260,8 +1396,9 @@ rte_sched_pipe_config(struct rte_sched_port > *port, >=20 > if (s->tc_ov !=3D tc_be_ov) { > RTE_LOG(DEBUG, SCHED, > - "Subport %u Best effort TC oversubscription > is ON (%.4lf < %.4lf)\n", > - subport_id, subport_tc_be_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 =3D s->tc_ov_period_id; > p->tc_ov_credits =3D s->tc_ov_wm; > @@ -1335,6 +1472,72 @@ rte_sched_subport_pipe_profile_add(struct > rte_sched_port *port, > return 0; > } >=20 > +int > +rte_sched_port_subport_profile_add(struct rte_sched_port *port, > + struct rte_sched_subport_profile_params *params, > + uint32_t *subport_profile_id) > +{ > + int status; > + uint32_t i; > + struct rte_sched_subport_profile *dst; > + > + /* Port */ > + if (port =3D=3D NULL) { > + RTE_LOG(ERR, SCHED, > + "%s: Incorrect value for parameter port\n", __func__); > + return -EINVAL; > + } > + > + if (params =3D=3D NULL) { > + RTE_LOG(ERR, SCHED, > + "%s: Incorrect value for parameter profile\n", __func__); > + return -EINVAL; > + } > + > + if (subport_profile_id =3D=3D NULL) { > + RTE_LOG(ERR, SCHED, > + "%s: Incorrect value for parameter \ > + subport_profile_id\n", __func__); > + return -EINVAL; > + } > + > + dst =3D port->subport_profiles + port->n_subport_profiles; > + > + /* Subport profiles exceeds the max limit */ > + if (port->n_subport_profiles >=3D port->n_max_subport_profiles) { > + RTE_LOG(ERR, SCHED, > + "%s: Number of subport profiles exceeds \ > + the max limit\n", __func__); > + return -EINVAL; > + } > + > + status =3D subport_profile_check(params, port->rate); > + if (status !=3D 0) { > + RTE_LOG(ERR, SCHED, > + "%s: subport profile check failed(%d)\n", __func__, status); > + return -EINVAL; > + } > + > + rte_sched_subport_profile_convert(params, dst, port->rate); > + > + /* Subport profile should not exists */ > + for (i =3D 0; i < port->n_subport_profiles; i++) > + if (memcmp(port->subport_profiles + i, > + params, sizeof(*params)) =3D=3D 0) { > + RTE_LOG(ERR, SCHED, > + "%s: subport profile exists\n", __func__); > + return -EINVAL; > + } > + > + /* Subport profile commit */ > + *subport_profile_id =3D port->n_subport_profiles; > + port->n_subport_profiles++; > + > + rte_sched_port_log_subport_profile(port, *subport_profile_id); > + > + return 0; > +} > + > static inline uint32_t > rte_sched_port_qindex(struct rte_sched_port *port, > uint32_t subport, > @@ -1970,14 +2173,18 @@ grinder_credits_update(struct rte_sched_port > *port, > struct rte_sched_grinder *grinder =3D subport->grinder + pos; > struct rte_sched_pipe *pipe =3D grinder->pipe; > struct rte_sched_pipe_profile *params =3D grinder->pipe_params; > + struct rte_sched_subport_profile *subport_params =3D > + grinder->subport_params; > uint64_t n_periods; > uint32_t i; >=20 > /* Subport TB */ > - n_periods =3D (port->time - subport->tb_time) / subport->tb_period; > - subport->tb_credits +=3D n_periods * subport->tb_credits_per_period; > - subport->tb_credits =3D RTE_MIN(subport->tb_credits, subport- > >tb_size); > - subport->tb_time +=3D n_periods * subport->tb_period; > + n_periods =3D (port->time - subport->tb_time) / subport_params- > >tb_period; > + subport->tb_credits +=3D n_periods * > + subport_params->tb_credits_per_period; > + subport->tb_credits =3D RTE_MIN(subport->tb_credits, > + subport_params->tb_size); > + subport->tb_time +=3D n_periods * subport_params->tb_period; >=20 > /* Pipe TB */ > n_periods =3D (port->time - pipe->tb_time) / params->tb_period; @@ - > 1988,9 +2195,10 @@ grinder_credits_update(struct rte_sched_port *port, > /* Subport TCs */ > if (unlikely(port->time >=3D subport->tc_time)) { > for (i =3D 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) > - subport->tc_credits[i] =3D subport- > >tc_credits_per_period[i]; > + subport->tc_credits[i] =3D > + subport_params->tc_credits_per_period[i]; >=20 > - subport->tc_time =3D port->time + subport->tc_period; > + subport->tc_time =3D port->time + subport_params->tc_period; > } >=20 > /* Pipe TCs */ > @@ -2008,6 +2216,8 @@ static inline uint64_t > grinder_tc_ov_credits_update(struct rte_sched_port *port, > struct rte_sched_subport *subport) > { > + struct rte_sched_subport_profile *subport_params =3D > + grinder->subport_params; > uint64_t > tc_ov_consumption[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; > uint64_t tc_consumption =3D 0, tc_ov_consumption_max; > uint64_t tc_ov_wm =3D subport->tc_ov_wm; @@ -2018,16 +2228,17 > @@ grinder_tc_ov_credits_update(struct rte_sched_port *port, >=20 > for (i =3D 0; i < RTE_SCHED_TRAFFIC_CLASS_BE; i++) { > tc_ov_consumption[i] =3D > - subport->tc_credits_per_period[i] - subport- > >tc_credits[i]; > + subport_params->tc_credits_per_period[i] - > + subport->tc_credits[i]; > tc_consumption +=3D tc_ov_consumption[i]; > } >=20 > tc_ov_consumption[RTE_SCHED_TRAFFIC_CLASS_BE] =3D > - subport- > >tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] - > + subport_params- > >tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] - > subport->tc_credits[RTE_SCHED_TRAFFIC_CLASS_BE]; >=20 > tc_ov_consumption_max =3D > - subport- > >tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] - > + subport_params- > >tc_credits_per_period[RTE_SCHED_TRAFFIC_CLASS_BE] - > tc_consumption; >=20 > if (tc_ov_consumption[RTE_SCHED_TRAFFIC_CLASS_BE] > @@ - > 2053,14 +2264,18 @@ grinder_credits_update(struct rte_sched_port *port, > struct rte_sched_grinder *grinder =3D subport->grinder + pos; > struct rte_sched_pipe *pipe =3D grinder->pipe; > struct rte_sched_pipe_profile *params =3D grinder->pipe_params; > + struct rte_sched_subport_profile *subport_params =3D > + grinder->subport_params; > uint64_t n_periods; > uint32_t i; >=20 > /* Subport TB */ > - n_periods =3D (port->time - subport->tb_time) / subport->tb_period; > - subport->tb_credits +=3D n_periods * subport->tb_credits_per_period; > - subport->tb_credits =3D RTE_MIN(subport->tb_credits, subport- > >tb_size); > - subport->tb_time +=3D n_periods * subport->tb_period; > + n_periods =3D (port->time - subport->tb_time) / subport_params- > >tb_period; > + subport->tb_credits +=3D n_periods * > + subport_params->tb_credits_per_period; > + subport->tb_credits =3D RTE_MIN(subport->tb_credits, > + subport_params->tb_size); > + subport->tb_time +=3D n_periods * subport_params->tb_period; >=20 > /* Pipe TB */ > n_periods =3D (port->time - pipe->tb_time) / params->tb_period; @@ - > 2073,9 +2288,10 @@ grinder_credits_update(struct rte_sched_port *port, > subport->tc_ov_wm =3D grinder_tc_ov_credits_update(port, > subport); >=20 > for (i =3D 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) > - subport->tc_credits[i] =3D subport- > >tc_credits_per_period[i]; > + subport->tc_credits[i] =3D > + subport_params->tc_credits_per_period[i]; >=20 > - subport->tc_time =3D port->time + subport->tc_period; > + subport->tc_time =3D port->time + subport_params->tc_period; > subport->tc_ov_period_id++; > } >=20 > @@ -2598,6 +2814,8 @@ grinder_handle(struct rte_sched_port *port, > struct rte_sched_pipe *pipe =3D grinder->pipe; >=20 > grinder->pipe_params =3D subport->pipe_profiles + pipe- > >profile; > + grinder->subport_params =3D port->subport_profiles + > + subport->profile; > grinder_prefetch_tc_queue_arrays(subport, pos); > grinder_credits_update(port, subport, pos); >=20 > diff --git a/lib/librte_sched/rte_sched.h b/lib/librte_sched/rte_sched.h = index > 8a5a93c..7623919 100644 > --- a/lib/librte_sched/rte_sched.h > +++ b/lib/librte_sched/rte_sched.h > @@ -149,18 +149,6 @@ struct rte_sched_pipe_params { > * byte. > */ > struct rte_sched_subport_params { > - /** Token bucket rate (measured in bytes per second) */ > - uint64_t tb_rate; > - > - /** Token bucket size (measured in credits) */ > - uint64_t tb_size; > - > - /** Traffic class rates (measured in bytes per second) */ > - uint64_t tc_rate[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; > - > - /** Enforcement period for rates (measured in milliseconds) */ > - uint64_t tc_period; > - > /** Number of subport pipes. > * The subport can enable/allocate fewer pipes than the maximum > * number set through struct > port_params::n_max_pipes_per_subport, > @@ -192,6 +180,20 @@ struct rte_sched_subport_params { #endif }; >=20 > +struct rte_sched_subport_profile_params { > + /** Token bucket rate (measured in bytes per second) */ > + uint64_t tb_rate; > + > + /** Token bucket size (measured in credits) */ > + uint64_t tb_size; > + > + /** Traffic class rates (measured in bytes per second) */ > + uint64_t tc_rate[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; > + > + /** Enforcement period for rates (measured in milliseconds) */ > + uint64_t tc_period; > +}; > + > /** Subport statistics */ > struct rte_sched_subport_stats { > /** Number of packets successfully written */ @@ -254,6 +256,17 > @@ struct rte_sched_port_params { > /** Number of subports */ > uint32_t n_subports_per_port; >=20 > + /** subport profile table. > + * Every pipe is configured using one of the profiles from this table. > + */ > + struct rte_sched_subport_profile_params *subport_profiles; > + > + /** Profiles in the pipe profile table */ > + uint32_t n_subport_profiles; > + > + /** Max allowed profiles in the pipe profile table */ > + uint32_t n_max_subport_profiles; > + > /** Maximum number of subport pipes. > * This parameter is used to reserve a fixed number of bits > * in struct rte_mbuf::sched.queue_id for the pipe_id for all @@ - > 312,6 +325,29 @@ rte_sched_subport_pipe_profile_add(struct > rte_sched_port *port, > uint32_t *pipe_profile_id); >=20 > /** > + * @warning > + * @b EXPERIMENTAL: this API may change without prior notice. > + * > + * Hierarchical scheduler subport bandwidth profile add > + * Note that this function is safe to use in runtime for adding new > + * subport bandwidth profile as it doesn't have any impact on > +hiearchical > + * structure of the scheduler. > + * @param port > + * Handle to port scheduler instance > + * @param struct rte_sched_subport_profile > + * Subport bandwidth profile > + * @param subport_profile_d > + * Subport profile id > + * @return > + * 0 upon success, error code otherwise > + */ > +__rte_experimental > +int > +rte_sched_port_subport_profile_add(struct rte_sched_port *port, > + struct rte_sched_subport_profile_params *profile, > + uint32_t *subport_profile_id); > + > +/** > * Hierarchical scheduler subport configuration > * > * @param port > @@ -329,6 +365,28 @@ rte_sched_subport_config(struct rte_sched_port > *port, > struct rte_sched_subport_params *params); >=20 > /** > + * @warning > + * @b EXPERIMENTAL: this API may change without prior notice. > + * > + * Hierarchical scheduler subport profile configuration > + * Note that this function is safe to use in runtime for applying any > +specific > + * subport bandwidth profile as it doesn't have any impact on > +hiearchical > + * structure of the scheduler. > + * @param port > + * Handle to port scheduler instance > + * @param subport_id > + * Subport ID > + * @param profile_d > + * Subport profile id > + * @return > + * 0 upon success, error code otherwise > + */ > +__rte_experimental > +int > +rte_sched_subport_profile_config(struct rte_sched_port *port, > + uint32_t subport_id, > + uint32_t profile_id); > +/** > * Hierarchical scheduler pipe configuration > * > * @param port > diff --git a/lib/librte_sched/rte_sched_version.map > b/lib/librte_sched/rte_sched_version.map > index cefd990..c02a223 100644 > --- a/lib/librte_sched/rte_sched_version.map > +++ b/lib/librte_sched/rte_sched_version.map > @@ -28,4 +28,6 @@ EXPERIMENTAL { > global: >=20 > rte_sched_subport_pipe_profile_add; > + rte_sched_port_subport_profile_add; > + rte_sched_subport_profile_config; > }; > -- > 2.7.4 + Cristian