From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 433E9A0C47; Tue, 12 Oct 2021 20:34:32 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 0D018410E5; Tue, 12 Oct 2021 20:34:32 +0200 (CEST) Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by mails.dpdk.org (Postfix) with ESMTP id A38FF410DC for ; Tue, 12 Oct 2021 20:34:30 +0200 (CEST) X-IronPort-AV: E=McAfee;i="6200,9189,10135"; a="214387143" X-IronPort-AV: E=Sophos;i="5.85,368,1624345200"; d="scan'208";a="214387143" Received: from orsmga003.jf.intel.com ([10.7.209.27]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Oct 2021 11:34:29 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.85,368,1624345200"; d="scan'208";a="441977102" Received: from fmsmsx604.amr.corp.intel.com ([10.18.126.84]) by orsmga003.jf.intel.com with ESMTP; 12 Oct 2021 11:34:29 -0700 Received: from fmsmsx605.amr.corp.intel.com (10.18.126.85) by fmsmsx604.amr.corp.intel.com (10.18.126.84) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2242.12; Tue, 12 Oct 2021 11:34:29 -0700 Received: from fmsedg601.ED.cps.intel.com (10.1.192.135) by fmsmsx605.amr.corp.intel.com (10.18.126.85) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2242.12 via Frontend Transport; Tue, 12 Oct 2021 11:34:29 -0700 Received: from NAM02-BN1-obe.outbound.protection.outlook.com (104.47.51.43) by edgegateway.intel.com (192.55.55.70) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2242.12; Tue, 12 Oct 2021 11:34:28 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=aown6RgFa/JiVUU3lllMP7AeaPFsP2RgtjpHfWE2cT1Zs7/fBB+Of//wwN/oVBuqkORi6uXGA8HPjlDlxuF3u5IFPuCPrVTh8Z9Ov/6KyS5NX7tgPbnNSEaKepflHw0VvE0G1bsrJqI/5o6sP5V25ff0Dx8siFZwXZo71Cp7PnE+l9DW29NlrKZUrJ8NnzftLuX3LKLLBjdGaAbeFKNOc1NmYlQMPFFX3JgXb5V1eIpuYJxYJUyKECGF6lgsPDPU3ei8lEJ+ZukbfMh1kFvOb2v7w7So3DtK/6NZgs3JVIahEU1kjlESuUXLN/9nVrquAdRSpKH1hLb0bjpIKQJr6w== 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-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=3TToL7sFwOEbFQYUjnWC3ANBKQf9ljzZFGsmbqpjOrU=; b=hIHNlIeY7cFtm0D67Pokqy5GWZExFBNzbiTduLbQu92Ow9p/wFMnNNEmhBOzes718L2+ARHBhuWY/HR0YCjIZQbG/plCauYBTi7Oplg+ohc4+RsXmxK2hOcXHpffdcGSUspWh7OLtsQKD0vu9eBWN0qwbSwv8Es4Y2sncNL1kopCMyxhSH7F/TpwQrlI4Wztehvc6yneKk0fIdGIJE9qWEE4jFZUNNRlHn4pPJIfoezlyDvYmYbq2OUe7Ek+uSk27J8cnq113tQ4nB7VUYIIuw47u9luB8aH7nmQcE1bbBXZ0+c3UeMlJvts2Bv1iv+s2WJAJh7bCSdHpSNbFgtT3w== 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=3TToL7sFwOEbFQYUjnWC3ANBKQf9ljzZFGsmbqpjOrU=; b=Sl1W3EHxrRHJCF9NWnqrksJIjjoCvjI3Hixwp1jdIcBXY7J0cUd4ltoBmzMHxprDJxzJB9HScegjTvsUeeJZDa5AzKOI3K7aM11DgKsQRnapwI7GhtuczwwatakmEy5v63PW4HwII1tHj6nEqwJI57AViBiu8WoJbRAUddqLlKM= Received: from BN9PR11MB5372.namprd11.prod.outlook.com (2603:10b6:408:105::5) by BN9PR11MB5353.namprd11.prod.outlook.com (2603:10b6:408:11a::6) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4587.19; Tue, 12 Oct 2021 18:34:27 +0000 Received: from BN9PR11MB5372.namprd11.prod.outlook.com ([fe80::9ef:5965:3a7e:7b8c]) by BN9PR11MB5372.namprd11.prod.outlook.com ([fe80::9ef:5965:3a7e:7b8c%9]) with mapi id 15.20.4587.026; Tue, 12 Oct 2021 18:34:26 +0000 From: "Liguzinski, WojciechX" To: "Dumitrescu, Cristian" , "dev@dpdk.org" , "Singh, Jasvinder" CC: "Ajmera, Megha" , "Cybura, LukaszX" , "Zegota, AnnaX" Thread-Topic: [PATCH v9 1/5] sched: add PIE based congestion management Thread-Index: AQHXv4IoyMrm6DTszESHOG2VKSwh8qvPqTqw Date: Tue, 12 Oct 2021 18:34:26 +0000 Message-ID: References: <20210923094533.939757-1-wojciechx.liguzinski@intel.com> <20211011075541.1182775-1-wojciechx.liguzinski@intel.com> <20211011075541.1182775-2-wojciechx.liguzinski@intel.com> In-Reply-To: Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: dlp-product: dlpe-windows dlp-version: 11.6.200.16 dlp-reaction: no-action authentication-results: intel.com; dkim=none (message not signed) header.d=none;intel.com; dmarc=none action=none header.from=intel.com; x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 1d9b7882-c362-49de-7c60-08d98daeebd0 x-ms-traffictypediagnostic: BN9PR11MB5353: x-ms-exchange-transport-forked: True x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:669; x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: wm867GVwpVxCbgKvRMDzRDMedJPIYYHOuz73QKH7cSC8Dv1YHvcMF31n+hKd0AtML0UZoDi8zg6qcELW2R75ek7EL/y5trpVKh6wtjp9okvL6Ir18urjkXxJr8whWJU2hFAdsxfeR1zUOymLeUzVf8otBnazFOZVFwiM/m001TVEZfdug3TN3lkBVLcXzQIJX2s9HXYGEH8dL0cb5vhzMmp9AuAcpANjdWiDFq7HxUQ5weMna+VOYx7CxFqxg5013xIIpxNTBQfZBmBjtiyaZo900sh/paTEXkgL5/XP0bAb+M2vzFSfP42/S8C8NXd0uWvrJwWLxSpbzocgqM4l1c1GImh4j9hVoXIrYeB0dcEFeIWp7jQxdcjmscpEvhLSfoATh6hqjp5c6aQIRl4jjtApDHG+tipko2m2H1ceuDLU/SKAqG7+ziTWIN2bhlZu+ElRdp0WBrSAdpRA/W8weXon7P6k3PBVvAit94B5+HwBufeslp01El3Ozj0XHcGo37A4RZjZVTDTrd8u2Sxnk+W5xZ1yTSiHDtYsJ3LqpJTBgEF3ft17sm1c36nvVHVKVXdGW/8DH2G1LhGTFAo9oU0nuBDctkKcrdvoRLCV7x6/P/KNMWfqtyJDZTvYRE3iyQXE3f8+Nqvk9uAVwzRX6jFvVdQDi1Gamy0KeiUSiPuqd4ufHZxk3ClzlChrHq2Ohy1a28UFqkUdkj75QhxCe3smK1pyLDa6miZp6732kIDA+K4froA4sx75jits/kiQN+ARLhU8nlT2jPmD1yOjpnSih8boCdlgluckdFZ5o1w= x-forefront-antispam-report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:BN9PR11MB5372.namprd11.prod.outlook.com; PTR:; CAT:NONE; SFS:(4636009)(366004)(38100700002)(52536014)(316002)(86362001)(54906003)(55016002)(122000001)(110136005)(966005)(6506007)(5660300002)(33656002)(4326008)(7696005)(26005)(53546011)(38070700005)(9686003)(508600001)(6636002)(66476007)(66556008)(8676002)(186003)(83380400001)(64756008)(66446008)(8936002)(66946007)(71200400001)(30864003)(2906002)(107886003)(76116006)(559001)(579004); DIR:OUT; SFP:1102; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?us-ascii?Q?VKBDJaj1hE/PdPX9IEr0NGowbtSC0r6XyJMwDaJi/Uuv+KVmM/6y/wNx4FQz?= =?us-ascii?Q?lKleuoJTstIG7AoDP+lACPKyRbxUhU6/02794Z9gy97Y/njiprvwK/FfYDut?= =?us-ascii?Q?f8AeFhX0wY/VFxvqQtP3ObK15oG/J5dDT/jZNBaWX1cf3FPh5fF8mWiKjRIv?= =?us-ascii?Q?iaiXysRRUtCpxcYZHM8vBUwe75ocTuUnQaMgYvzEbUNPcEi4+p4aGdz6wXRG?= =?us-ascii?Q?yvpNh0FYBxBIPpPz5VPSYm9Bgt8gY4KCtJ5QTC/j0lbMnyA4QTrKY8D/iUZL?= =?us-ascii?Q?KJrnLHPg3kXSkeiWuKL+i0tvKb/7E4THb1AZEevoqW1APn/IcLtywgGjJXQV?= =?us-ascii?Q?7McfddbZgFC86rNoC2h0I5BJFy5c9Sr9cASpomiOgrIEC1wA1dZsYUqKXM8d?= =?us-ascii?Q?mDc2ILwxITC06idxJe4YyM1tY95OXwXS93slTV7lx9sdNxF3or8pYscwvP2I?= =?us-ascii?Q?sW+wngpAmRQneanvjdZkckY19I9mvaxb/teSbBDdz2XGTWhCGPjGUlDJs2dJ?= =?us-ascii?Q?Da6tbGq5jqszE0P2QRMobbPgTTFlg7i74VxTOdVLYHJQjnrwX+qVLrMpRmHa?= =?us-ascii?Q?aD/i5hXYTj1zZ5TRXtuxM2+StyxCzVT10eeFGxzuhYuM/rzdfkqWIBRWzYV6?= =?us-ascii?Q?UusXhsgHgWuYZS75eQR1ZkSYtoOOQKmSvFwRgA9uabQKowpVMvfi3Af6BjM7?= =?us-ascii?Q?cxefTBUQlik/ydGoFzAFXbPC5qs+R2UNOGm7qzWRfonDCAeYY3QIDyttgR3Y?= =?us-ascii?Q?XAtUsDsspVGjJjW2246PQgdat/OW7xPtICCgdlFg5XeE70U8KDb4SVr+lOrI?= =?us-ascii?Q?ibAhGYNtLwTH+5Yz2O9djTnxA8RJNt7QPmU0s6lRFwskMr5y7o/6/qMODrnM?= =?us-ascii?Q?Y07mx8EaMby41XwUz/PkCHo8y7SFHPH+7ufasTkgLSyyzDECrQN+hQmTqdEO?= =?us-ascii?Q?IRwIgjVaLi6nw7qjoj7m/CJKBSflFeq6zBi7YduvYN1L7owwjA20VTXUIxNw?= =?us-ascii?Q?AgwsGI3+tARjqZh/sAL82J3n3OjEV1e5RzpUMuLDOYIqc530uAwmfDEKZ5Og?= =?us-ascii?Q?+8d+9v5ym6InKtmVF1+WDDto5xkEEeNRZzmLa94KB8mQQXqvV5oDo+0o/sjX?= =?us-ascii?Q?Hgt2TCT7b21ZfnrCVDeB8pyQ442GWYJUdCqtXfWNY2e8NGLEEzSWsLvkBJ6M?= =?us-ascii?Q?7F+9tW3erE3j+6tlJmtcye8+ULmZE4hzkCBhtJurvkPPFr9OqQqJrDv2ROF3?= =?us-ascii?Q?gKUsqkxAob6hTcJFSWQ47n9Erb2SX1JJF8u13u7LPi5ZuvNFzTSYg2wJkW0v?= =?us-ascii?Q?nTqUPICwjta1JsAOAdNHY4wR?= 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: BN9PR11MB5372.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 1d9b7882-c362-49de-7c60-08d98daeebd0 X-MS-Exchange-CrossTenant-originalarrivaltime: 12 Oct 2021 18:34:26.7530 (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: WI5lrUC7CtyBX6hIaAUyj2QC9D1a07dAtxtK1xlz+R+hqwy9dljb3E6Mmf+u2rQJWY99KwUPCZpxPN/+DBDqSsUclUXfLm+idj8WlibBp4M= X-MS-Exchange-Transport-CrossTenantHeadersStamped: BN9PR11MB5353 X-OriginatorOrg: intel.com Subject: Re: [dpdk-dev] [PATCH v9 1/5] sched: add PIE based congestion management X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 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" Hi Cristian, -----Original Message----- From: Dumitrescu, Cristian =20 Sent: Tuesday, October 12, 2021 6:00 PM To: Liguzinski, WojciechX ; dev@dpdk.org; S= ingh, Jasvinder Cc: Ajmera, Megha Subject: RE: [PATCH v9 1/5] sched: add PIE based congestion management Hi Wojchech, > -----Original Message----- > From: Liguzinski, WojciechX > Sent: Monday, October 11, 2021 8:56 AM > To: dev@dpdk.org; Singh, Jasvinder ;=20 > Dumitrescu, Cristian > Cc: Ajmera, Megha > Subject: [PATCH v9 1/5] sched: add PIE based congestion management >=20 > Implement PIE based congestion management based on rfc8033 >=20 > Signed-off-by: Liguzinski, WojciechX > --- > drivers/net/softnic/rte_eth_softnic_tm.c | 6 +- > lib/sched/meson.build | 10 +- > lib/sched/rte_pie.c | 82 +++++ > lib/sched/rte_pie.h | 393 +++++++++++++++++++++++ > lib/sched/rte_sched.c | 228 +++++++++---- > lib/sched/rte_sched.h | 53 ++- > lib/sched/version.map | 3 + > 7 files changed, 685 insertions(+), 90 deletions(-) create mode=20 > 100644 lib/sched/rte_pie.c create mode 100644 lib/sched/rte_pie.h >=20 > diff --git a/drivers/net/softnic/rte_eth_softnic_tm.c > b/drivers/net/softnic/rte_eth_softnic_tm.c > index 90baba15ce..5b6c4e6d4b 100644 > --- a/drivers/net/softnic/rte_eth_softnic_tm.c > +++ b/drivers/net/softnic/rte_eth_softnic_tm.c > @@ -420,7 +420,7 @@ pmd_tm_node_type_get(struct rte_eth_dev *dev, > return 0; > } >=20 > -#ifdef RTE_SCHED_RED > +#ifdef RTE_SCHED_AQM > #define WRED_SUPPORTED 1 > #else > #define WRED_SUPPORTED 0 > @@ -2306,7 +2306,7 @@ tm_tc_wred_profile_get(struct rte_eth_dev *dev,=20 > uint32_t tc_id) > return NULL; > } >=20 > -#ifdef RTE_SCHED_RED > +#ifdef RTE_SCHED_AQM >=20 > static void > wred_profiles_set(struct rte_eth_dev *dev, uint32_t subport_id) @@=20 > -2321,7 +2321,7 @@ wred_profiles_set(struct rte_eth_dev *dev, uint32_t=20 > subport_id) > for (tc_id =3D 0; tc_id < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; > tc_id++) > for (color =3D RTE_COLOR_GREEN; color < RTE_COLORS; > color++) { > struct rte_red_params *dst =3D > - &pp->red_params[tc_id][color]; > + &pp->wred_params[tc_id][color]; > struct tm_wred_profile *src_wp =3D > tm_tc_wred_profile_get(dev, tc_id); > struct rte_tm_red_params *src =3D > diff --git a/lib/sched/meson.build b/lib/sched/meson.build index=20 > b24f7b8775..e7ae9bcf19 100644 > --- a/lib/sched/meson.build > +++ b/lib/sched/meson.build > @@ -1,11 +1,7 @@ > # SPDX-License-Identifier: BSD-3-Clause # Copyright(c) 2017 Intel=20 > Corporation >=20 > -sources =3D files('rte_sched.c', 'rte_red.c', 'rte_approx.c') -headers=20 > =3D files( > - 'rte_approx.h', > - 'rte_red.h', > - 'rte_sched.h', > - 'rte_sched_common.h', > -) > +sources =3D files('rte_sched.c', 'rte_red.c', 'rte_approx.c',=20 > +'rte_pie.c') headers =3D files('rte_sched.h', 'rte_sched_common.h', > + 'rte_red.h', 'rte_approx.h', 'rte_pie.h') > deps +=3D ['mbuf', 'meter'] > diff --git a/lib/sched/rte_pie.c b/lib/sched/rte_pie.c new file mode=20 > 100644 index 0000000000..2fcecb2db4 > --- /dev/null > +++ b/lib/sched/rte_pie.c > @@ -0,0 +1,82 @@ > +/* SPDX-License-Identifier: BSD-3-Clause > + * Copyright(c) 2020 Intel Corporation */ > + > +#include > + > +#include "rte_pie.h" > +#include > +#include > +#include > + > +#ifdef __INTEL_COMPILER > +#pragma warning(disable:2259) /* conversion may lose significant bits=20 > +*/ #endif > + > +void > +rte_pie_rt_data_init(struct rte_pie *pie) { > + if (pie =3D=3D NULL) { > + /* Allocate memory to use the PIE data structure */ > + pie =3D rte_malloc(NULL, sizeof(struct rte_pie), 0); > + > + if (pie =3D=3D NULL) > + RTE_LOG(ERR, SCHED, "%s: Memory allocation > fails\n", __func__); > + } > + > + pie->active =3D 0; > + pie->in_measurement =3D 0; > + pie->departed_bytes_count =3D 0; > + pie->start_measurement =3D 0; > + pie->last_measurement =3D 0; > + pie->qlen =3D 0; > + pie->avg_dq_time =3D 0; > + pie->burst_allowance =3D 0; > + pie->qdelay_old =3D 0; > + pie->drop_prob =3D 0; > + pie->accu_prob =3D 0; > +} > + > +int > +rte_pie_config_init(struct rte_pie_config *pie_cfg, > + const uint16_t qdelay_ref, > + const uint16_t dp_update_interval, > + const uint16_t max_burst, > + const uint16_t tailq_th) > +{ > + uint64_t tsc_hz =3D rte_get_tsc_hz(); > + > + if (pie_cfg =3D=3D NULL) > + return -1; > + > + if (qdelay_ref <=3D 0) { > + RTE_LOG(ERR, SCHED, > + "%s: Incorrect value for qdelay_ref\n", __func__); > + return -EINVAL; > + } > + > + if (dp_update_interval <=3D 0) { > + RTE_LOG(ERR, SCHED, > + "%s: Incorrect value for dp_update_interval\n", > __func__); > + return -EINVAL; > + } > + > + if (max_burst <=3D 0) { > + RTE_LOG(ERR, SCHED, > + "%s: Incorrect value for max_burst\n", __func__); > + return -EINVAL; > + } > + > + if (tailq_th <=3D 0) { > + RTE_LOG(ERR, SCHED, > + "%s: Incorrect value for tailq_th\n", __func__); > + return -EINVAL; > + } > + > + pie_cfg->qdelay_ref =3D (tsc_hz * qdelay_ref) / 1000; > + pie_cfg->dp_update_interval =3D (tsc_hz * dp_update_interval) / > 1000; > + pie_cfg->max_burst =3D (tsc_hz * max_burst) / 1000; > + pie_cfg->tailq_th =3D tailq_th; > + > + return 0; > +} > diff --git a/lib/sched/rte_pie.h b/lib/sched/rte_pie.h new file mode=20 > 100644 index 0000000000..f83c95664f > --- /dev/null > +++ b/lib/sched/rte_pie.h > @@ -0,0 +1,393 @@ > +/* SPDX-License-Identifier: BSD-3-Clause > + * Copyright(c) 2020 Intel Corporation */ > + > +#ifndef __RTE_PIE_H_INCLUDED__ > +#define __RTE_PIE_H_INCLUDED__ > + > +#ifdef __cplusplus > +extern "C" { > +#endif > + > +/** > + * @file > + * RTE Proportional Integral controller Enhanced (PIE) > + * > + * > + ***/ > + > +#include > + > +#include > +#include > + > +#define RTE_DQ_THRESHOLD 16384 /**< Queue length threshold (2^14) > + * to start measurement cycle (bytes) > + */ > +#define RTE_DQ_WEIGHT 0.25 /**< Weight > (RTE_DQ_THRESHOLD/2^16) to compute dequeue rate */ > +#define RTE_ALPHA 0.125 /**< Weights in drop probability > calculations */ > +#define RTE_BETA 1.25 /**< Weights in drop probability calc= ulations > */ > +#define RTE_RAND_MAX ~0LLU /**< Max value of the random number > */ > + > + > +/** > + * PIE configuration parameters passed by user > + * > + */ > +struct rte_pie_params { > + uint16_t qdelay_ref; /**< Latency Target (milliseconds) */ > + uint16_t dp_update_interval; /**< Update interval for drop > probability (milliseconds) */ > + uint16_t max_burst; /**< Max Burst Allowance (milliseconds) > */ > + uint16_t tailq_th; /**< Tailq drop threshold (packet counts= ) */ > +}; > + > +/** > + * PIE configuration parameters > + * > + */ > +struct rte_pie_config { > + uint64_t qdelay_ref; /**< Latency Target (in CPU cycles.) */ > + uint64_t dp_update_interval; /**< Update interval for drop > probability (in CPU cycles) */ > + uint64_t max_burst; /**< Max Burst Allowance (in CPU cycles.= ) > */ > + uint16_t tailq_th; /**< Tailq drop threshold (packet counts= ) */ > +}; > + > +/** > + * RED run-time data > + */ > +struct rte_pie { > + uint16_t active; /**< Flag for activating/deactivating pi= e */ > + uint16_t in_measurement; /**< Flag for activation of > measurement cycle */ > + uint32_t departed_bytes_count; /**< Number of bytes departed in > current measurement cycle */ > + uint64_t start_measurement; /**< Time to start to measurement > cycle (in cpu cycles) */ > + uint64_t last_measurement; /**< Time of last measurement (in > cpu cycles) */ > + uint64_t qlen; /**< Queue length (packets count) */ > + uint64_t qlen_bytes; /**< Queue length (bytes count) */ > + uint64_t avg_dq_time; /**< Time averaged dequeue rate (in > cpu cycles) */ > + uint32_t burst_allowance; /**< Current burst allowance (bytes) */ > + uint64_t qdelay_old; /**< Old queue delay (bytes) */ > + double drop_prob; /**< Current packet drop probability */ > + double accu_prob; /**< Accumulated packet drop probability > */ > +}; > + > +/** > + * @brief Initialises run-time data > + * > + * @param pie [in,out] data pointer to PIE runtime data */ void=20 > +__rte_experimental rte_pie_rt_data_init(struct rte_pie *pie); > + > +/** > + * @brief Configures a single PIE configuration parameter structure. > + * > + * @param pie_cfg [in,out] config pointer to a PIE configuration=20 > +parameter > structure > + * @param qdelay_ref [in] latency target(milliseconds) > + * @param dp_update_interval [in] update interval for drop=20 > + probability > (milliseconds) > + * @param max_burst [in] maximum burst allowance (milliseconds) > + * @param tailq_th [in] tail drop threshold for the queue (number of > packets) > + * > + * @return Operation status > + * @retval 0 success > + * @retval !0 error > + */ > +int > +__rte_experimental > +rte_pie_config_init(struct rte_pie_config *pie_cfg, > + const uint16_t qdelay_ref, > + const uint16_t dp_update_interval, > + const uint16_t max_burst, > + const uint16_t tailq_th); > + > +/** > + * @brief Decides packet enqueue when queue is empty > + * > + * Note: packet is never dropped in this particular case. > + * > + * @param pie_cfg [in] config pointer to a PIE configuration=20 > +parameter > structure > + * @param pie [in, out] data pointer to PIE runtime data > + * @param pkt_len [in] packet length in bytes > + * > + * @return Operation status > + * @retval 0 enqueue the packet > + * @retval !0 drop the packet > + */ > +static inline int > +__rte_experimental > +rte_pie_enqueue_empty(const struct rte_pie_config *pie_cfg, > + struct rte_pie *pie, > + uint32_t pkt_len) > +{ > + RTE_ASSERT(pkt_len !=3D NULL); > + > + /* Update the PIE qlen parameter */ > + pie->qlen++; > + pie->qlen_bytes +=3D pkt_len; > + > + /** > + * If the queue has been idle for a while, turn off PIE and Reset > counters > + */ > + if ((pie->active =3D=3D 1) && > + (pie->qlen < (pie_cfg->tailq_th * 0.1))) { > + pie->active =3D 0; > + pie->in_measurement =3D 0; > + } > + > + return 0; > +} > + > +/** > + * @brief make a decision to drop or enqueue a packet based on probabili= ty > + * criteria > + * > + * @param pie_cfg [in] config pointer to a PIE configuration=20 > +parameter > structure > + * @param pie [in, out] data pointer to PIE runtime data > + * @param time [in] current time (measured in cpu cycles) */ static=20 > +inline void __rte_experimental _calc_drop_probability(const struct=20 > +rte_pie_config *pie_cfg, > + struct rte_pie *pie, uint64_t time) > +{ > + uint64_t qdelay_ref =3D pie_cfg->qdelay_ref; > + > + /* Note: can be implemented using integer multiply. > + * DQ_THRESHOLD is power of 2 value. > + */ > + double current_qdelay =3D pie->qlen * (pie->avg_dq_time / > RTE_DQ_THRESHOLD); > + > + double p =3D RTE_ALPHA * (current_qdelay - qdelay_ref) + > + RTE_BETA * (current_qdelay - pie->qdelay_old); > + > + if (pie->drop_prob < 0.000001) > + p =3D p * 0.00048828125; /* (1/2048) =3D 0.00048828125 */ > + else if (pie->drop_prob < 0.00001) > + p =3D p * 0.001953125; /* (1/512) =3D 0.001953125 */ > + else if (pie->drop_prob < 0.0001) > + p =3D p * 0.0078125; /* (1/128) =3D 0.0078125 */ > + else if (pie->drop_prob < 0.001) > + p =3D p * 0.03125; /* (1/32) =3D 0.03125 */ > + else if (pie->drop_prob < 0.01) > + p =3D p * 0.125; /* (1/8) =3D 0.125 */ > + else if (pie->drop_prob < 0.1) > + p =3D p * 0.5; /* (1/2) =3D 0.5 */ > + > + if (pie->drop_prob >=3D 0.1 && p > 0.02) > + p =3D 0.02; > + > + pie->drop_prob +=3D p; > + > + double qdelay =3D qdelay_ref * 0.5; > + > + /* Exponentially decay drop prob when congestion goes away */ > + if (current_qdelay < qdelay && pie->qdelay_old < qdelay) > + pie->drop_prob *=3D 0.98; /* 1 - 1/64 is sufficient */ > + > + /* Bound drop probability */ > + if (pie->drop_prob < 0) > + pie->drop_prob =3D 0; > + if (pie->drop_prob > 1) > + pie->drop_prob =3D 1; > + > + pie->qdelay_old =3D current_qdelay; > + pie->last_measurement =3D time; > + > + uint64_t burst_allowance =3D pie->burst_allowance - pie_cfg- > >dp_update_interval; > + > + pie->burst_allowance =3D (burst_allowance > 0) ? burst_allowance : 0;=20 > +} > + > +/** > + * @brief make a decision to drop or enqueue a packet based on probabili= ty > + * criteria > + * > + * @param pie_cfg [in] config pointer to a PIE configuration=20 > +parameter > structure > + * @param pie [in, out] data pointer to PIE runtime data > + * > + * @return operation status > + * @retval 0 enqueue the packet > + * @retval 1 drop the packet > + */ > +static inline int > +__rte_experimental > +_rte_pie_drop(const struct rte_pie_config *pie_cfg, > + struct rte_pie *pie) > +{ > + uint64_t rand_value; > + double qdelay =3D pie_cfg->qdelay_ref * 0.5; > + > + /* PIE is active but the queue is not congested: return 0 */ > + if (((pie->qdelay_old < qdelay) && (pie->drop_prob < 0.2)) || > + (pie->qlen <=3D (pie_cfg->tailq_th * 0.1))) > + return 0; > + > + if (pie->drop_prob =3D=3D 0) > + pie->accu_prob =3D 0; > + > + /* For practical reasons, drop probability can be further scaled > according > + * to packet size, but one needs to set a bound to avoid unnecessary > bias > + * Random drop > + */ > + pie->accu_prob +=3D pie->drop_prob; > + > + if (pie->accu_prob < 0.85) > + return 0; > + > + if (pie->accu_prob >=3D 8.5) > + return 1; > + > + rand_value =3D rte_rand()/RTE_RAND_MAX; > + > + if ((double)rand_value < pie->drop_prob) { > + pie->accu_prob =3D 0; > + return 1; > + } > + > + /* No drop */ > + return 0; > +} > + > +/** > + * @brief Decides if new packet should be enqeued or dropped for non- > empty queue > + * > + * @param pie_cfg [in] config pointer to a PIE configuration=20 > + parameter > structure > + * @param pie [in,out] data pointer to PIE runtime data > + * @param pkt_len [in] packet length in bytes > + * @param time [in] current time (measured in cpu cycles) > + * > + * @return Operation status > + * @retval 0 enqueue the packet > + * @retval 1 drop the packet based on max threshold criterion > + * @retval 2 drop the packet based on mark probability criterion */=20 > +static inline int __rte_experimental rte_pie_enqueue_nonempty(const=20 > +struct rte_pie_config *pie_cfg, > + struct rte_pie *pie, > + uint32_t pkt_len, > + const uint64_t time) > +{ > + /* Check queue space against the tail drop threshold */ > + if (pie->qlen >=3D pie_cfg->tailq_th) { > + > + pie->accu_prob =3D 0; > + return 1; > + } > + > + if (pie->active) { > + /* Update drop probability after certain interval */ > + if ((time - pie->last_measurement) >=3D pie_cfg- > >dp_update_interval) > + _calc_drop_probability(pie_cfg, pie, time); > + > + /* Decide whether packet to be dropped or enqueued */ > + if (_rte_pie_drop(pie_cfg, pie) && pie->burst_allowance =3D=3D > 0) > + return 2; > + } > + > + /* When queue occupancy is over a certain threshold, turn on PIE */ > + if ((pie->active =3D=3D 0) && > + (pie->qlen >=3D (pie_cfg->tailq_th * 0.1))) { > + pie->active =3D 1; > + pie->qdelay_old =3D 0; > + pie->drop_prob =3D 0; > + pie->in_measurement =3D 1; > + pie->departed_bytes_count =3D 0; > + pie->avg_dq_time =3D 0; > + pie->last_measurement =3D time; > + pie->burst_allowance =3D pie_cfg->max_burst; > + pie->accu_prob =3D 0; > + pie->start_measurement =3D time; > + } > + > + /* when queue has been idle for a while, turn off PIE and Reset > counters */ > + if (pie->active =3D=3D 1 && > + pie->qlen < (pie_cfg->tailq_th * 0.1)) { > + pie->active =3D 0; > + pie->in_measurement =3D 0; > + } > + > + /* Update PIE qlen parameter */ > + pie->qlen++; > + pie->qlen_bytes +=3D pkt_len; > + > + /* No drop */ > + return 0; > +} > + > +/** > + * @brief Decides if new packet should be enqeued or dropped > + * Updates run time data and gives verdict whether to enqueue or drop=20 > +the > packet. > + * > + * @param pie_cfg [in] config pointer to a PIE configuration=20 > + parameter > structure > + * @param pie [in,out] data pointer to PIE runtime data > + * @param qlen [in] queue length > + * @param pkt_len [in] packet length in bytes > + * @param time [in] current time stamp (measured in cpu cycles) > + * > + * @return Operation status > + * @retval 0 enqueue the packet > + * @retval 1 drop the packet based on drop probility criteria */=20 > +static inline int __rte_experimental rte_pie_enqueue(const struct=20 > +rte_pie_config *pie_cfg, > + struct rte_pie *pie, > + const unsigned int qlen, > + uint32_t pkt_len, > + const uint64_t time) > +{ > + RTE_ASSERT(pie_cfg !=3D NULL); > + RTE_ASSERT(pie !=3D NULL); > + > + if (qlen !=3D 0) > + return rte_pie_enqueue_nonempty(pie_cfg, pie, pkt_len, > time); > + else > + return rte_pie_enqueue_empty(pie_cfg, pie, pkt_len); } > + > +/** > + * @brief PIE rate estimation method > + * Called on each packet departure. > + * > + * @param pie [in] data pointer to PIE runtime data > + * @param pkt_len [in] packet length in bytes > + * @param time [in] current time stamp in cpu cycles */ static=20 > +inline void __rte_experimental rte_pie_dequeue(struct rte_pie *pie, > + uint32_t pkt_len, > + uint64_t time) > +{ > + /* Dequeue rate estimation */ > + if (pie->in_measurement) { > + pie->departed_bytes_count +=3D pkt_len; > + > + /* Start a new measurement cycle when enough packets */ > + if (pie->departed_bytes_count >=3D RTE_DQ_THRESHOLD) { > + uint64_t dq_time =3D time - pie->start_measurement; > + > + if (pie->avg_dq_time =3D=3D 0) > + pie->avg_dq_time =3D dq_time; > + else > + pie->avg_dq_time =3D dq_time * > RTE_DQ_WEIGHT + pie->avg_dq_time > + * (1 - RTE_DQ_WEIGHT); > + > + pie->in_measurement =3D 0; > + } > + } > + > + /* Start measurement cycle when enough data in the queue */ > + if ((pie->qlen_bytes >=3D RTE_DQ_THRESHOLD) && (pie- > >in_measurement =3D=3D 0)) { > + pie->in_measurement =3D 1; > + pie->start_measurement =3D time; > + pie->departed_bytes_count =3D 0; > + } > +} > + > +#ifdef __cplusplus > +} > +#endif > + > +#endif /* __RTE_PIE_H_INCLUDED__ */ > diff --git a/lib/sched/rte_sched.c b/lib/sched/rte_sched.c index=20 > a858f61f95..320435ed91 100644 > --- a/lib/sched/rte_sched.c > +++ b/lib/sched/rte_sched.c > @@ -89,8 +89,12 @@ struct rte_sched_queue { >=20 > struct rte_sched_queue_extra { > struct rte_sched_queue_stats stats; > -#ifdef RTE_SCHED_RED > - struct rte_red red; > +#ifdef RTE_SCHED_AQM > + RTE_STD_C11 > + union { > + struct rte_red red; > + struct rte_pie pie; > + }; > #endif > }; >=20 > @@ -183,8 +187,13 @@ struct rte_sched_subport { > /* Pipe queues size */ > uint16_t qsize[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; >=20 > -#ifdef RTE_SCHED_RED > - struct rte_red_config > red_config[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE][RTE_COLORS]; > + enum rte_sched_aqm_mode aqm; > +#ifdef RTE_SCHED_AQM > + RTE_STD_C11 > + union { > + struct rte_red_config > wred_config[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE][RTE_COLORS]; > + struct rte_pie_config > pie_config[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; > + }; > #endif >=20 > /* Scheduling loop detection */ > @@ -1078,6 +1087,91 @@ rte_sched_free_memory(struct rte_sched_port=20 > *port, uint32_t n_subports) > rte_free(port); > } >=20 > +#ifdef RTE_SCHED_AQM > + > +static int > +rte_sched_red_config(struct rte_sched_port *port, > + struct rte_sched_subport *s, > + struct rte_sched_subport_params *params, > + uint32_t n_subports) > +{ > + uint32_t i; > + > + for (i =3D 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { > + > + uint32_t j; > + > + for (j =3D 0; j < RTE_COLORS; j++) { > + /* if min/max are both zero, then RED is disabled */ > + if ((params->wred_params[i][j].min_th | > + params->wred_params[i][j].max_th) =3D=3D 0) { > + continue; > + } > + > + if (rte_red_config_init(&s->wred_config[i][j], > + params->wred_params[i][j].wq_log2, > + params->wred_params[i][j].min_th, > + params->wred_params[i][j].max_th, > + params->wred_params[i][j].maxp_inv) !=3D 0) { > + rte_sched_free_memory(port, n_subports); > + > + RTE_LOG(NOTICE, SCHED, > + "%s: RED configuration init fails\n", > __func__); > + return -EINVAL; > + } > + } > + } > + s->aqm =3D RTE_SCHED_AQM_WRED; > + return 0; > +} > + > +static int > +rte_sched_pie_config(struct rte_sched_port *port, > + struct rte_sched_subport *s, > + struct rte_sched_subport_params *params, > + uint32_t n_subports) > +{ > + uint32_t i; > + > + for (i =3D 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { > + if (params->pie_params[i].tailq_th > params->qsize[i]) { > + RTE_LOG(NOTICE, SCHED, > + "%s: PIE tailq threshold incorrect\n", __func__); > + return -EINVAL; > + } > + > + if (rte_pie_config_init(&s->pie_config[i], > + params->pie_params[i].qdelay_ref, > + params->pie_params[i].dp_update_interval, > + params->pie_params[i].max_burst, > + params->pie_params[i].tailq_th) !=3D 0) { > + rte_sched_free_memory(port, n_subports); > + > + RTE_LOG(NOTICE, SCHED, > + "%s: PIE configuration init fails\n", __func__); > + return -EINVAL; > + } > + } > + s->aqm =3D RTE_SCHED_AQM_PIE; > + return 0; > +} > + > +static int > +rte_sched_aqm_config(struct rte_sched_port *port, > + struct rte_sched_subport *s, > + struct rte_sched_subport_params *params, > + uint32_t n_subports) > +{ > + if (params->aqm =3D=3D RTE_SCHED_AQM_WRED) > + return rte_sched_red_config(port, s, params, n_subports); > + > + else if (params->aqm =3D=3D RTE_SCHED_AQM_PIE) > + return rte_sched_pie_config(port, s, params, n_subports); > + > + return -EINVAL; > +} > +#endif > + > int > rte_sched_subport_config(struct rte_sched_port *port, > uint32_t subport_id, > @@ -1167,29 +1261,11 @@ rte_sched_subport_config(struct rte_sched_port=20 > *port, > s->n_pipe_profiles =3D params->n_pipe_profiles; > s->n_max_pipe_profiles =3D params->n_max_pipe_profiles; >=20 > -#ifdef RTE_SCHED_RED > - for (i =3D 0; i < RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE; i++) { > - uint32_t j; > - > - for (j =3D 0; j < RTE_COLORS; j++) { > - /* if min/max are both zero, then RED is disabled */ > - if ((params->red_params[i][j].min_th | > - params->red_params[i][j].max_th) =3D=3D 0) { > - continue; > - } > - > - if (rte_red_config_init(&s->red_config[i][j], > - params->red_params[i][j].wq_log2, > - params->red_params[i][j].min_th, > - params->red_params[i][j].max_th, > - params->red_params[i][j].maxp_inv) !=3D 0) > { > - RTE_LOG(NOTICE, SCHED, > - "%s: RED configuration init fails\n", > - __func__); > - ret =3D -EINVAL; > - goto out; > - } > - } > +#ifdef RTE_SCHED_AQM > + status =3D rte_sched_aqm_config(port, s, params, > n_subports); > + if (status) { > + RTE_LOG(NOTICE, SCHED, "%s: AQM configuration > fails\n", __func__); > + return status; > } > #endif >=20 > @@ -1718,29 +1794,20 @@ rte_sched_port_update_subport_stats(struct > rte_sched_port *port, > subport->stats.n_bytes_tc[tc_index] +=3D pkt_len; } >=20 > -#ifdef RTE_SCHED_RED > -static inline void > -rte_sched_port_update_subport_stats_on_drop(struct rte_sched_port=20 > *port, > - struct rte_sched_subport *subport, > - uint32_t qindex, > - struct rte_mbuf *pkt, > - uint32_t red) > -#else > static inline void > rte_sched_port_update_subport_stats_on_drop(struct rte_sched_port=20 > *port, > struct rte_sched_subport *subport, > uint32_t qindex, > struct rte_mbuf *pkt, > - __rte_unused uint32_t red) > -#endif > + __rte_unused uint32_t drops) > { > uint32_t tc_index =3D rte_sched_port_pipe_tc(port, qindex); > uint32_t pkt_len =3D pkt->pkt_len; >=20 > subport->stats.n_pkts_tc_dropped[tc_index] +=3D 1; > subport->stats.n_bytes_tc_dropped[tc_index] +=3D pkt_len; -#ifdef=20 > RTE_SCHED_RED > - subport->stats.n_pkts_red_dropped[tc_index] +=3D red; > +#ifdef RTE_SCHED_AQM > + subport->stats.n_pkts_aqm_dropped[tc_index] +=3D drops; > #endif > } >=20 > @@ -1756,58 +1823,61 @@ rte_sched_port_update_queue_stats(struct > rte_sched_subport *subport, > qe->stats.n_bytes +=3D pkt_len; > } >=20 > -#ifdef RTE_SCHED_RED > -static inline void > -rte_sched_port_update_queue_stats_on_drop(struct rte_sched_subport=20 > *subport, > - uint32_t qindex, > - struct rte_mbuf *pkt, > - uint32_t red) > -#else > static inline void > rte_sched_port_update_queue_stats_on_drop(struct rte_sched_subport=20 > *subport, > uint32_t qindex, > struct rte_mbuf *pkt, > - __rte_unused uint32_t red) > -#endif > + __rte_unused uint32_t drops) > { > struct rte_sched_queue_extra *qe =3D subport->queue_extra + qindex; > uint32_t pkt_len =3D pkt->pkt_len; >=20 > qe->stats.n_pkts_dropped +=3D 1; > qe->stats.n_bytes_dropped +=3D pkt_len; -#ifdef RTE_SCHED_RED > - qe->stats.n_pkts_red_dropped +=3D red; > +#ifdef RTE_SCHED_AQM > + qe->stats.n_pkts_aqm_dropped +=3D drops; > #endif > } >=20 > #endif /* RTE_SCHED_COLLECT_STATS */ >=20 > -#ifdef RTE_SCHED_RED > +#ifdef RTE_SCHED_AQM >=20 > static inline int > -rte_sched_port_red_drop(struct rte_sched_port *port, > +rte_sched_port_aqm_drop(struct rte_sched_port *port, > struct rte_sched_subport *subport, > struct rte_mbuf *pkt, > uint32_t qindex, > uint16_t qlen) > { > struct rte_sched_queue_extra *qe; > - struct rte_red_config *red_cfg; > - struct rte_red *red; > uint32_t tc_index; > - enum rte_color color; >=20 > tc_index =3D rte_sched_port_pipe_tc(port, qindex); > - color =3D rte_sched_port_pkt_read_color(pkt); > - red_cfg =3D &subport->red_config[tc_index][color]; > + qe =3D subport->queue_extra + qindex; >=20 > - if ((red_cfg->min_th | red_cfg->max_th) =3D=3D 0) > - return 0; > + /* WRED */ > + if (subport->aqm =3D=3D RTE_SCHED_AQM_WRED) { > + struct rte_red_config *red_cfg; > + struct rte_red *red; > + enum rte_color color; >=20 > - qe =3D subport->queue_extra + qindex; > - red =3D &qe->red; > + color =3D rte_sched_port_pkt_read_color(pkt); > + red_cfg =3D &subport->wred_config[tc_index][color]; > + > + if ((red_cfg->min_th | red_cfg->max_th) =3D=3D 0) > + return 0; >=20 > - return rte_red_enqueue(red_cfg, red, qlen, port->time); > + red =3D &qe->red; > + > + return rte_red_enqueue(red_cfg, red, qlen, port->time); > + } > + > + /* PIE */ > + struct rte_pie_config *pie_cfg =3D &subport->pie_config[tc_index]; > + struct rte_pie *pie =3D &qe->pie; > + > + return rte_pie_enqueue(pie_cfg, pie, pkt->pkt_len, qlen, port- > >time_cpu_cycles); > } >=20 > static inline void > @@ -1815,14 +1885,29 @@ > rte_sched_port_set_queue_empty_timestamp(struct rte_sched_port *port, > struct rte_sched_subport *subport, uint32_t qindex) { > struct rte_sched_queue_extra *qe =3D subport->queue_extra + qindex; > - struct rte_red *red =3D &qe->red; > + if (subport->aqm =3D=3D RTE_SCHED_AQM_WRED) { > + struct rte_red *red =3D &qe->red; > + > + rte_red_mark_queue_empty(red, port->time); > + } > +} > + > +static inline void > +rte_sched_port_pie_dequeue(struct rte_sched_subport *subport,=20 > +uint32_t qindex, uint32_t pkt_len, uint64_t time) { > + struct rte_sched_queue_extra *qe =3D subport->queue_extra + > qindex; > + struct rte_pie *pie =3D &qe->pie; >=20 > - rte_red_mark_queue_empty(red, port->time); > + /* Update queue length */ > + pie->qlen -=3D 1; > + pie->qlen_bytes -=3D pkt_len; > + > + rte_pie_dequeue(pie, pkt_len, time); > } >=20 > #else >=20 > -static inline int rte_sched_port_red_drop(struct rte_sched_port *port=20 > __rte_unused, > +static inline int rte_sched_port_aqm_drop(struct rte_sched_port *port > __rte_unused, > struct rte_sched_subport *subport __rte_unused, > struct rte_mbuf *pkt __rte_unused, > uint32_t qindex __rte_unused, > @@ -1833,7 +1918,7 @@ static inline int rte_sched_port_red_drop(struct=20 > rte_sched_port *port __rte_unus >=20 > #define rte_sched_port_set_queue_empty_timestamp(port, subport, > qindex) >=20 > -#endif /* RTE_SCHED_RED */ > +#endif /* RTE_SCHED_AQM */ >=20 > #ifdef RTE_SCHED_DEBUG >=20 > @@ -1929,7 +2014,7 @@ rte_sched_port_enqueue_qwa(struct rte_sched_port=20 > *port, > qlen =3D q->qw - q->qr; >=20 > /* Drop the packet (and update drop stats) when queue is full */ > - if (unlikely(rte_sched_port_red_drop(port, subport, pkt, qindex, > qlen) || > + if (unlikely(rte_sched_port_aqm_drop(port, subport, pkt, qindex, > qlen) || > (qlen >=3D qsize))) { > rte_pktmbuf_free(pkt); > #ifdef RTE_SCHED_COLLECT_STATS > @@ -2402,6 +2487,7 @@ grinder_schedule(struct rte_sched_port *port, { > struct rte_sched_grinder *grinder =3D subport->grinder + pos; > struct rte_sched_queue *queue =3D grinder->queue[grinder->qpos]; > + uint32_t qindex =3D grinder->qindex[grinder->qpos]; > struct rte_mbuf *pkt =3D grinder->pkt; > uint32_t pkt_len =3D pkt->pkt_len + port->frame_overhead; > uint32_t be_tc_active; > @@ -2421,15 +2507,19 @@ grinder_schedule(struct rte_sched_port *port, > (pkt_len * grinder->wrr_cost[grinder->qpos]) & be_tc_active; >=20 > if (queue->qr =3D=3D queue->qw) { > - uint32_t qindex =3D grinder->qindex[grinder->qpos]; > - > rte_bitmap_clear(subport->bmp, qindex); > grinder->qmask &=3D ~(1 << grinder->qpos); > if (be_tc_active) > grinder->wrr_mask[grinder->qpos] =3D 0; > + > rte_sched_port_set_queue_empty_timestamp(port, > subport, qindex); > } >=20 > +#ifdef RTE_SCHED_AQM > + if (subport->aqm =3D=3D RTE_SCHED_AQM_PIE) > + rte_sched_port_pie_dequeue(subport, qindex, pkt_len, > port->time_cpu_cycles); > +#endif > + > /* Reset pipe loop detection */ > subport->pipe_loop =3D RTE_SCHED_PIPE_INVALID; > grinder->productive =3D 1; > diff --git a/lib/sched/rte_sched.h b/lib/sched/rte_sched.h index=20 > c1a772b70c..a5fe6266cd 100644 > --- a/lib/sched/rte_sched.h > +++ b/lib/sched/rte_sched.h > @@ -61,9 +61,10 @@ extern "C" { > #include > #include >=20 > -/** Random Early Detection (RED) */ > -#ifdef RTE_SCHED_RED > +/** Active Queue Management */ > +#ifdef RTE_SCHED_AQM > #include "rte_red.h" > +#include "rte_pie.h" > #endif >=20 > /** Maximum number of queues per pipe. > @@ -110,6 +111,28 @@ extern "C" { > #define RTE_SCHED_FRAME_OVERHEAD_DEFAULT 24 > #endif >=20 > +/** > + * Active Queue Management (AQM) mode > + * > + * This is used for controlling the admission of packets into a=20 > +packet queue > or > + * group of packet queues on congestion. > + * > + * The *Random Early Detection (RED)* algorithm works by proactively > dropping > + * more and more input packets as the queue occupancy builds up. When > the queue > + * is full or almost full, RED effectively works as *tail drop*. The=20 > + *Weighted > + * RED* algorithm uses a separate set of RED thresholds for each=20 > + packet > color. > + * > + * Similar to RED, Proportional Integral Controller Enhanced (PIE)=20 > + randomly > + * drops a packet at the onset of the congestion and tries to control=20 > + the > + * latency around the target value. The congestion detection,=20 > + however, is > based > + * on the queueing latency instead of the queue length like RED. For=20 > +more > + * information, refer RFC8033. > + */ > +enum rte_sched_aqm_mode { > + RTE_SCHED_AQM_WRED, /**< Weighted Random Early Detection > (WRED) */ > + RTE_SCHED_AQM_PIE, /**< Proportional Integral Controller > Enhanced (PIE) */ > +}; > + > /* > * Pipe configuration parameters. The period and credits_per_period > * parameters are measured in bytes, with one byte meaning the time=20 > @@ -174,9 +197,17 @@ struct rte_sched_subport_params { > /** Max allowed profiles in the pipe profile table */ > uint32_t n_max_pipe_profiles; >=20 > -#ifdef RTE_SCHED_RED > - /** RED parameters */ > - struct rte_red_params > red_params[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE][RTE_COLORS]; > +#ifdef RTE_SCHED_AQM > + /** Active Queue Management mode */ > + enum rte_sched_aqm_mode aqm; > + > + RTE_STD_C11 > + union { > + /** WRED parameters */ > + struct rte_red_params > wred_params[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE][RTE_COLORS]; > + /** PIE parameters */ > + struct rte_pie_params > pie_params[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; > + }; > #endif > }; >=20 > @@ -208,9 +239,9 @@ struct rte_sched_subport_stats { > /** Number of bytes dropped for each traffic class */ > uint64_t > n_bytes_tc_dropped[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; >=20 > -#ifdef RTE_SCHED_RED > - /** Number of packets dropped by red */ > - uint64_t > n_pkts_red_dropped[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; > +#ifdef RTE_SCHED_AQM > + /** Number of packets dropped by active queue management > scheme */ > + uint64_t > n_pkts_aqm_dropped[RTE_SCHED_TRAFFIC_CLASSES_PER_PIPE]; > #endif > }; >=20 > @@ -222,9 +253,9 @@ struct rte_sched_queue_stats { > /** Packets dropped */ > uint64_t n_pkts_dropped; >=20 > -#ifdef RTE_SCHED_RED > - /** Packets dropped by RED */ > - uint64_t n_pkts_red_dropped; > +#ifdef RTE_SCHED_AQM > + /** Packets dropped by active queue management scheme */ > + uint64_t n_pkts_aqm_dropped; > #endif >=20 > /** Bytes successfully written */ > diff --git a/lib/sched/version.map b/lib/sched/version.map index=20 > ace284b7de..3422821ac8 100644 > --- a/lib/sched/version.map > +++ b/lib/sched/version.map > @@ -30,4 +30,7 @@ EXPERIMENTAL { > rte_sched_subport_pipe_profile_add; > # added in 20.11 > rte_sched_port_subport_profile_add; > + > + rte_pie_rt_data_init; > + rte_pie_config_init; > }; > -- > 2.25.1 NACK I see that none of my previous comments from the V4 review got implemented,= is there any reason to silently discard all of them? https://patches.dpdk.org/project/dpdk/patch/20210705080421.18736-2-wojciech= x.liguzinski@intel.com/ I did not see any reply from you on my comments, so I assumed that you acce= pted and implemented most of them, but I see that none of them were picked = up. Also, I don't see any revision history, just the version counter gets incre= mented, so reviewing a new version of your patch requires re-reading every = line of code, which is time consuming. Could you please add a revision hist= ory? Thanks, Cristian ------------------------------------ First thing - I'm very sorry that I haven't replied to your comments. It wa= s not my intention to ignore them. I was going through them and I was a bit confused that most of your suggest= ions would actually revert majority of my changes suggested by other commun= ity members, e.g. by Stephen Hemminger. I wanted to get some opinion how to proceed but I got some additional tasks= on the way, so - my fault that I was postponing that. Again - apologies. I will go through them again and implement/respond to them as quickly as po= ssible. I was uploading the patches following the procedure that were presented to = me (rebasing the changes so the new ones are applied to existing commits), = so honestly I was not aware that I need to do a revision history when apply= ing anther version of patches. Let me think of a way to provide you with such revision history. Thanks, Wojtek