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 830D9A0C47; Tue, 12 Oct 2021 17:59:42 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 20C01411AE; Tue, 12 Oct 2021 17:59:42 +0200 (CEST) Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by mails.dpdk.org (Postfix) with ESMTP id 6D7784113A for ; Tue, 12 Oct 2021 17:59:39 +0200 (CEST) X-IronPort-AV: E=McAfee;i="6200,9189,10135"; a="214341161" X-IronPort-AV: E=Sophos;i="5.85,368,1624345200"; d="scan'208";a="214341161" Received: from orsmga004.jf.intel.com ([10.7.209.38]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Oct 2021 08:59:38 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.85,368,1624345200"; d="scan'208";a="591819928" Received: from orsmsx605.amr.corp.intel.com ([10.22.229.18]) by orsmga004.jf.intel.com with ESMTP; 12 Oct 2021 08:59:38 -0700 Received: from orsmsx606.amr.corp.intel.com (10.22.229.19) by ORSMSX605.amr.corp.intel.com (10.22.229.18) 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 08:59:37 -0700 Received: from ORSEDG601.ED.cps.intel.com (10.7.248.6) by orsmsx606.amr.corp.intel.com (10.22.229.19) 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 08:59:37 -0700 Received: from NAM12-MW2-obe.outbound.protection.outlook.com (104.47.66.44) by edgegateway.intel.com (134.134.137.102) 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 08:59:37 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=cbHNhB3aUzKucCJdHef0rTDo65TjEGgKj/y/j3eUPPOzNqY8zVarzeRtwbAvFeX27LcL/o9OMfQiWnLDZiXG5/BrkLokF+oBvXF638sYp0lC6BDykb+H1czr4au2v87/DqT7MmxyZ4HP30SP+VqXLN/PRvR44vCzKV6WLYbYDk0BwRN4w34lz5adVOJu4kN2IA2tByxuybUAMcEWgsPQXwcFYlTNbvnMkqc9sG/2Bl0cf5/rpmjxD7fjVkuFTDH+KHdiiovsbHrIW6hMGQx2oXsmNiK0nEJc68RSwhx/WfHr+3IhFCKyRVf/XHF09hGvdefUxMp3I2dh3iCh0J3drQ== 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=/OK1FIamQVAXirM23oR1yGFaGzTgQ8SeNwcIqzUYVhA=; b=WNWWGbOr17SZEzBtP51hV0uLMqdYUbWxr7qaT2b7SN3nu/yjbhs7ZUClwiPe2LOzN9ddotJHk1q6tjNzPJ1n6hhHsazI/PYoDE0c3wnYZNOaSi5CKOGb5+bR/7jcJ43akNMErw6WV2KXTbObeWoMLzD6MVuTu7qPsF1Ef44pW4qIZaUDSNqalUVSXDPaE408JYTjpVVCrIOXIkyHQKE9bw9HTkirBYQjkvS/MdUsX03f/gmk7HBshHTdmdBEA5ms3tywTl7VOyhERILEAe9Tf2WZ99kgo8zD9+mgMp4DeVOXP6jy+Lxo28er8dijcPfN2utjNvNGiHMSfjXscQpRLQ== 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=/OK1FIamQVAXirM23oR1yGFaGzTgQ8SeNwcIqzUYVhA=; b=F8rH30MJF1okovI9BsN0K4blH+Zind2JdOBcVYg3sqFK9twJcmXk7eJBE39asbjd0MoIjSWWywiaeDxRem8xob0FH0n/OAo3aqwguA7rp6sVyCQgee2zIPRfd5ZFzVdl79NR5jprLZEKqm6Shb3reN804klPN1d+nsW3Q/0JXdg= Received: from DM8PR11MB5670.namprd11.prod.outlook.com (2603:10b6:8:37::12) by DM8PR11MB5605.namprd11.prod.outlook.com (2603:10b6:8:26::11) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4608.14; Tue, 12 Oct 2021 15:59:36 +0000 Received: from DM8PR11MB5670.namprd11.prod.outlook.com ([fe80::c0f1:1135:ceb5:ac10]) by DM8PR11MB5670.namprd11.prod.outlook.com ([fe80::c0f1:1135:ceb5:ac10%8]) with mapi id 15.20.4587.026; Tue, 12 Oct 2021 15:59:36 +0000 From: "Dumitrescu, Cristian" To: "Liguzinski, WojciechX" , "dev@dpdk.org" , "Singh, Jasvinder" CC: "Ajmera, Megha" Thread-Topic: [PATCH v9 1/5] sched: add PIE based congestion management Thread-Index: AQHXvnVqLT3T6Zva3E6lVy3Hq0+/DqvPhfUg Date: Tue, 12 Oct 2021 15:59:35 +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: <20211011075541.1182775-2-wojciechx.liguzinski@intel.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: dlp-version: 11.6.200.16 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-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 5c6699e4-d552-4719-c2bf-08d98d9949f7 x-ms-traffictypediagnostic: DM8PR11MB5605: 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: YMoX3TikB8wc8fEbjNR7TLoNrgj82aTA5viiV1gOhGIm4X9G7i0ONmoOzzc30TDGkycNGHXTgSZ+ZYWyCCLiXQR3doNO+WjgK8J7EM4RHivdCQrgI1rcZ7hm+KRy32SRDrVqZl6YNtyAyfiGEOZQMf583EsXSpnuQ1diKVt6BOKUaPEqq5LYJGvD+av734pNmSoxR4XC3AU8hsUua0qVIu/l534PrLrL0v0Apt94TR9/wF8LrdpGmMnaNIRvRMODFSZhSyxLAcSp5GlRQARjCK2Uq72SSzNPIi9dLTBWSYNK8YRqfiim3dOPetGF7OCjLb2KpLWD+x5oKVZptNsyMehM2bI5cp+0iI8sNZ+zwBejFlUTpq5tFjNXRQxnLob7Lyuf/zyCv5z7a8FDJC11YNHe29HlqhGDNakVToYFWduNQgAzXE1MXub0FovztlpzZ0ZhhRjeI71Cad+Rog9Fj4A+2kRGcE2ofN6k7VwXGacHBV8/P1s029zFV5yqj4+hQCf4dEBVOUwRCabwMLJ2FboPHLYNuSK8FMNrl3LFEcKS+J5APwBn7/GybGdFLHVxHGP9DZt8gRL5zkJhJ9nOBmyZ6hgJjuLhaQEO+vJQUncUoqL1qkKHqHwM2dyJf7M7xQO9FE/hQSB9efiRljMu6PDYGl99u0dzNeSTVNw+a6MgEekU+NxyMfLH5ISvRozbUvJBH9KotDU2mzh9+xVvv18YvLFUO+Yk1KX4zouyAtuS7arkECjlFFGNKpdJ2quH0lLnS02D4+iBLQLMpjl0GkzV1R5arRXisS+pfr6/sig= x-forefront-antispam-report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:DM8PR11MB5670.namprd11.prod.outlook.com; PTR:; CAT:NONE; SFS:(4636009)(366004)(107886003)(6506007)(316002)(110136005)(55016002)(30864003)(33656002)(9686003)(71200400001)(8936002)(7696005)(83380400001)(8676002)(4326008)(2906002)(53546011)(86362001)(76116006)(38100700002)(66476007)(66556008)(66446008)(64756008)(52536014)(5660300002)(6636002)(122000001)(66946007)(508600001)(966005)(186003)(38070700005)(26005)(579004)(559001); DIR:OUT; SFP:1102; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?us-ascii?Q?MoVSCLiI7dQ3iYD9P7DMGBku4Wpqt6q+7zzBF9lgVYHyM+vHOhC7gGvuF6Nl?= =?us-ascii?Q?8xh5wX4lOjHwbLVTgmaniDlpj8idH+k2ve0xeWfEIMfDo/NFstGuyVoaEnlw?= =?us-ascii?Q?U2ejjmyOcQJEKLl8cRwT+gAgZJv4c+ChHJIWfiP2dC8rk+QNskWZW5J9QbcH?= =?us-ascii?Q?OLrBvOVl+6/W0o655U8WVhIrbBmUjhild0btESzbI7kTKs0MLmsgJlquoQOC?= =?us-ascii?Q?FW6UHSPiWmZrnugifLdl3Jyeu/yUe668n7t5frsQOX7kw8hwAaGjzUeqkm7C?= =?us-ascii?Q?3DM7iGEzcRk/oTuNr0TYKzdC57XnvuedeglrHyluq24Gj92GFIwvViE7Xhxf?= =?us-ascii?Q?jrEMyWySf2tJbiPsVl858HWunNxzhaG0ddLo9MXN3xWaTq2tyd4oP6QAYmWr?= =?us-ascii?Q?nBy5QNzAtDJ/zTm/N6oeQRZb/JpB0EMtlOE/3nXD/rheCZwUsdbedEP7aHjn?= =?us-ascii?Q?3kcRmMOxtfxcRb3c9yj6Ec1uC7yYCrtwB4QQqVqt3dg18DcO9F4JHEC5MRPE?= =?us-ascii?Q?d882iLFmgBpk9Lgj9UYugCbI+4On1M5CNlmQKK8RIzINY37nPNXVbI3DSwHC?= =?us-ascii?Q?bmntODtz0AECSew9Kyc1662YDCq9fEp/PV107NDfad4aDh94FVXnGPCYC4ZI?= =?us-ascii?Q?UFgRjCD17y7qAylzFWEJDXPjdSxDacfQLrYM5qRtWGA0j1meajgc9Yz8iyjr?= =?us-ascii?Q?PmcU2v1DgneepOoJbt1e6L+F7nv2iVREqyfMIZ81gUfQzY4DaUvZNsHPIC5u?= =?us-ascii?Q?+TXXQ8/0xjemmfDuV2Jf8PhFcpoO+UhA4XHKZ0FgyzF4agrJexVBfdZseXBN?= =?us-ascii?Q?nK5UeWXWRWDWUy2ighOM6ErCAwCVmEdnJySTzKDKCwxM/A8xT9/zBgPyhDVt?= =?us-ascii?Q?C3GaLEpa8Asn6Dk+tMhme8JZRuVVbp+x4JpJ4UO+VsJfo75J0XKGgnDUhNuK?= =?us-ascii?Q?Nyuf2aftk3fukoCiGJaZ8TgC2yK6QwgjVk5+C6Pj58zN/iAoz3DozwSewWD0?= =?us-ascii?Q?trGx7r3v4vNnpRZBD91pfS9R8J+dYP0bcRNl6bsUIUy7l4Zf1CJN1PpGRZbU?= =?us-ascii?Q?QFRFodPS0SzGwe+wSfZwKKQayNp0Yae2RBTZPvaXJRiYaZivnZu0pi1wl5jU?= =?us-ascii?Q?+de2Nuu/9+FzJEGiiEiUaT8e2EY0szSsKCDpAkbPZiNG056RYy8TAz9Lag0l?= =?us-ascii?Q?NctJz4+3qArmzfMFNbY9Auehn8+y6AbJj8rkADNyY54q88rg9x/8YNNDZQ+I?= =?us-ascii?Q?ZiW6xRgwFWeYw9QiK4TNebC1XhZgQy/FCGjwSaAH5jVxyliGKglGSkbOU3xL?= =?us-ascii?Q?GzwfosctNlDa3uZe5CYRCtdu?= 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: DM8PR11MB5670.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 5c6699e4-d552-4719-c2bf-08d98d9949f7 X-MS-Exchange-CrossTenant-originalarrivaltime: 12 Oct 2021 15:59:35.9116 (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: 2Pjx5s/AjyFrDGSJOI13bVwkCIIpTY2hrje6J1ICTjRAcOBGHSZdK8t0uDKXD9Z1osXz443aPdGAFqdle3xVAnFudWySCYiXebhH7N/M+qA= X-MS-Exchange-Transport-CrossTenantHeadersStamped: DM8PR11MB5605 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 Wojchech, > -----Original Message----- > From: Liguzinski, WojciechX > Sent: Monday, October 11, 2021 8:56 AM > To: dev@dpdk.org; Singh, Jasvinder ; > 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 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, > 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) > @@ -2321,7 +2321,7 @@ wred_profiles_set(struct rte_eth_dev *dev, > uint32_t 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 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 Corporation >=20 > -sources =3D files('rte_sched.c', 'rte_red.c', 'rte_approx.c') > -headers =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', '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 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 */ > +#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 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 > +__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 paramet= er > structure > + * @param qdelay_ref [in] latency target(milliseconds) > + * @param dp_update_interval [in] update interval for drop 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 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 parameter > structure > + * @param pie [in, out] data pointer to PIE runtime data > + * @param time [in] current time (measured in cpu cycles) > + */ > +static inline void > +__rte_experimental > +_calc_drop_probability(const struct 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; > +} > + > +/** > + * @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 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 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 > + */ > +static inline int > +__rte_experimental > +rte_pie_enqueue_nonempty(const 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 th= e > packet. > + * > + * @param pie_cfg [in] config pointer to a PIE configuration 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 > + */ > +static inline int > +__rte_experimental > +rte_pie_enqueue(const struct 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 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 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 > *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 *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 > *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 > *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 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 > *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 > *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, > +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 > __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 > 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 *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 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 packet q= ueue > 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 *We= ighted > + * RED* algorithm uses a separate set of RED thresholds for each packet > color. > + * > + * Similar to RED, Proportional Integral Controller Enhanced (PIE) rando= mly > + * drops a packet at the onset of the congestion and tries to control th= e > + * latency around the target value. The congestion detection, however, i= s > based > + * on the queueing latency instead of the queue length like RED. For mor= e > + * 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 > @@ -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 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