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 A8B71A0C4B; Thu, 14 Oct 2021 18:08:18 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 2221541100; Thu, 14 Oct 2021 18:08:18 +0200 (CEST) Received: from mga01.intel.com (mga01.intel.com [192.55.52.88]) by mails.dpdk.org (Postfix) with ESMTP id 4E4CC410F8 for ; Thu, 14 Oct 2021 18:08:15 +0200 (CEST) X-IronPort-AV: E=McAfee;i="6200,9189,10137"; a="251148321" X-IronPort-AV: E=Sophos;i="5.85,372,1624345200"; d="scan'208";a="251148321" Received: from orsmga001.jf.intel.com ([10.7.209.18]) by fmsmga101.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Oct 2021 09:02:58 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.85,372,1624345200"; d="scan'208";a="525108875" Received: from fmsmsx604.amr.corp.intel.com ([10.18.126.84]) by orsmga001.jf.intel.com with ESMTP; 14 Oct 2021 09:02:57 -0700 Received: from fmsmsx612.amr.corp.intel.com (10.18.126.92) 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; Thu, 14 Oct 2021 09:02:57 -0700 Received: from fmsmsx605.amr.corp.intel.com (10.18.126.85) by fmsmsx612.amr.corp.intel.com (10.18.126.92) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2242.12; Thu, 14 Oct 2021 09:02:57 -0700 Received: from fmsedg602.ED.cps.intel.com (10.1.192.136) 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; Thu, 14 Oct 2021 09:02:57 -0700 Received: from NAM10-MW2-obe.outbound.protection.outlook.com (104.47.55.103) by edgegateway.intel.com (192.55.55.71) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2242.12; Thu, 14 Oct 2021 09:02:56 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=CEvlDsnljfvhSYAGv1kLLG9awMHUMYdAEepbGaIdzOYSmVB3x7Tl36epXcV7JEL0pIN5zGZlSetPQQAS513XQ249GQgHH2SSUxc3K0sAW03Vvi1MAoESq5CVgl+ApH5wdHbZ8zNfb9Rqv8kwczwKRfKEVTXLD2w13OdZpGJzQDMlGXZp65T+d+gyj26ASDiENTNhAYeXC7vfQd9sPMaKENjAEV4S/74p5eQldw3F2RFraBH+VDKg31fYcizSjLSnQUEYlI2TQZ6f5G0d2GNC48PwzN5aL7Yh1xpbiGLOcLVTHpSs7xLdAw+vvRZG214vT7zvkiKQSOcpl+gL3OD2oQ== 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=iKD1HfX3uU6cLhEwbZsiq09OiSyyVVGE2+YvT4KS4R4=; b=Bz/DXkBporbstKznimg0WXNRiAKIUjv+E+3b1pdaArUvrYn3a9IU4M0utLjitwsilPjNfU4aYrQR3455ts/DlUvmyZ4HrTGve2wOvovR/oNoyvVh6C3CU1EUJAWuqT6njlK00XE994B4owm4+5q6RFMHw5pRrJ02ubZZd6qZ6J4SGUx1ZbNgHQN8VntxueDV3z8UrUcB7o2IU8G8vNGg7eUQfnHLgd4XxW2FCpyPOYPrHSMsJkUB9XCyHJwOVnZ9HGSXkm3NA0kQ5kHOvD3Cf5n4KkxYcTk+SVYuzM3Koc2SEbb7yoYO3/X/b5cXzEUGAuQZ/zXIGYb1TcGKJVlrrw== 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=iKD1HfX3uU6cLhEwbZsiq09OiSyyVVGE2+YvT4KS4R4=; b=PBONhcAHoUOh7LGojWbHPO1N+TYIS5NditNZA1Ep25B7M5YxSx9tVATPKZjD1+BGb8cvZ3G6dGppQs7fPvYQMHrozEdOV4uOy1Un1vtxabiUOkdU+DmUxbq5lORloocolxtMmtV15dCCkJxAMGb/D5wd/RPagvaCtoXTyUEt05U= Received: from CH0PR11MB5363.namprd11.prod.outlook.com (2603:10b6:610:ba::12) by CH2PR11MB4293.namprd11.prod.outlook.com (2603:10b6:610:40::25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.4587.20; Thu, 14 Oct 2021 16:02:54 +0000 Received: from CH0PR11MB5363.namprd11.prod.outlook.com ([fe80::90cf:5b59:eef2:1128]) by CH0PR11MB5363.namprd11.prod.outlook.com ([fe80::90cf:5b59:eef2:1128%8]) with mapi id 15.20.4608.016; Thu, 14 Oct 2021 16:02:54 +0000 From: "Liguzinski, WojciechX" To: "Dumitrescu, Cristian" , "dev@dpdk.org" , "Singh, Jasvinder" CC: "Ajmera, Megha" , "Zegota, AnnaX" Thread-Topic: [PATCH v9 1/5] sched: add PIE based congestion management Thread-Index: AQHXv4IoyMrm6DTszESHOG2VKSwh8qvPqTqwgAL7l6A= Date: Thu, 14 Oct 2021 16:02:54 +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: 5d36fa4c-f089-4dae-ca0f-08d98f2c1539 x-ms-traffictypediagnostic: CH2PR11MB4293: 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: 3tq4G6vjLXwVdLZBWIzPmNrbn73u7+NRNQNagoFO2PxVKcJuIhdvUPLqfqaRYk6rO1R/jDo8E4yeFsYr7+mMM8KcMYaR02z3g+RNVxU3B2m48Jsx1RVKcNWeiB3HBlABo/xATGdr7HSd98ofhyRhmqs9foiUxSPGr1NIyXmpUjU8w92pFiDAvi3m7qfYSF93vaXhcHBVmK6t4lT0HkDpvDUOsX/HJbFMEXaOS0MJj9R/vnasN0Lmkw1WstpbYZr11uQMiyS+/J61rytRUeblOERyjw1zXpAikuRZw7q3U8GWKp6m1hNzCSkYc1NLGzfLUbHUUEl38MY5u9hdqQ8UB5sHmybEzPBTmuV07bYgFyaAM2DOhxpkd2IrMrvx07m58rWMfKuJwrht699qVrbU7CmwMTh0MS8bYEUYANT1OYsG9kHhDKwzrr1KjgYG4zlhv31VPj0LKOeDWdhCsRaZ5UcP0D1918QGj6TWrn9SAcU3mqXcHdqsmY+VvD8V72zQ71gRPVu9z5jiBjGhoFM7LHeimewN4id+v89L6UNAbg0UmKcIdgtS4Ut+NcFxfsKd5uOSV8hdkWdA7dc0DNYLv3ctmHGihSme6NjVsLL3AHElCzDmVCb+/gJypcTueuP5YHJy2vyLPaKOkQDtqgvtZSpsyv/fHOESI9zGFpRCEap10Ya+SJVrZhUdMRWHiD0CZw/2xOdW+KqtIQxfV5LsyWmvsebcrJK22W9E0QdGDWARh0kQtCFa0oVE0jC5fbD3ltZnbM04R75rfO66FDIZgb8H5896G5jMVx+K46ubh3JhT+S9JrfRHQOhKnGHMkxaOzde+R9RSnwtM2QmbC7VoQ== x-forefront-antispam-report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:CH0PR11MB5363.namprd11.prod.outlook.com; PTR:; CAT:NONE; SFS:(366004)(55016002)(52536014)(7696005)(54906003)(110136005)(53546011)(2906002)(66446008)(66476007)(5660300002)(107886003)(4326008)(64756008)(6636002)(76116006)(8936002)(6506007)(83380400001)(66946007)(8676002)(186003)(26005)(316002)(9686003)(66556008)(71200400001)(508600001)(966005)(122000001)(33656002)(38070700005)(38100700002)(82960400001)(30864003)(86362001)(559001)(579004); DIR:OUT; SFP:1102; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?us-ascii?Q?5Mvt/3BnQ683JcSXSqqnpRrpyh3w0y40VZeg/E4B+JK5g7VV/z3hsNyuBzpX?= =?us-ascii?Q?l5gcY8qvFhg6iiRQOs62eO3HlHKofyaRDqeaIMKRbR8deaO22PAHJ91wX275?= =?us-ascii?Q?0b1xSRX9p+lOaH1MVcwQwd0nbMaHSGZOa3zgd28sLG6aUh4oKaxfgpAY9xGf?= =?us-ascii?Q?KQtI7RbMqotQOBS23kTPShXwWr9GzwXqIyscgLy0LtQI+yp30gcp8CUY1fp9?= =?us-ascii?Q?yRIs3/dp5uCICRu1I6u9kzbzkIlav0WG6vbemVxppHy79f6WJIRlprGcj1fy?= =?us-ascii?Q?wLiUC5A1HdAcmlYklh+/cKEJzCy7vKNUokfu1PSLprlM1fFf8cOYiNe3IiYN?= =?us-ascii?Q?pcFsbmJxcxcKIP7WRySGMOzBjUD7JCtb6rRK7I/vNktSdwor2+rTwCp0TUsk?= =?us-ascii?Q?qV42VTf2uKH4k4D9QpL59WzaWfij/45wEGLWfwsq3tIL6zOHvD/X20QqxOln?= =?us-ascii?Q?mRFfjlVFZcTGXMWZVynh3VYE70QaNAhjlhz2VEY+/nEbk6v1j9ZRejZTYdQ5?= =?us-ascii?Q?74+t52w5f+42IBwykFsFxJGUfU7I/T7Ic5t66HOVlFDPjm7464LjvcJO9oJg?= =?us-ascii?Q?6DMcLiPoKN3IM0cv9lctivqzfB+vzZOC6NdPVFdsQ2quCC033OwgiWu5sWuD?= =?us-ascii?Q?grFJkTqCpKjww4CvEGWtj4x4nibrKsv2lf9Vmi+IB2qepOjs5rlWeWPc3PkN?= =?us-ascii?Q?qTqQ1UgqrruwzLE0YpbOeq9xAlP3ltAM30nAbMgJk7l56yW8cfVwpll6mjHN?= =?us-ascii?Q?GihwbE8pJcsoZ03dOrpYLW15Tqx3L62fJCe8cASCHZmd1zkYVaCjIEDguTJz?= =?us-ascii?Q?raLPCWXedX8PWMr0q1bfafw5+wBMA4e479CGE/eAv30ZQJLEGPTw3Y3l+imb?= =?us-ascii?Q?qOk/TjVnz9+iKVkYgGdA39TiQlGvMzxjmyWFy5bMxWCoT31e+xhW74FBIi62?= =?us-ascii?Q?7eOe8hEIg4tWKUzHRx0DSBkFVnpnOM51KVs4+oQ/UMzH8bO5D0F8kp+d5xdf?= =?us-ascii?Q?lfe7Z46X26a86iGBKRP8PvF6o52/zTvbTnKGaWCZwNWbSQqrGzTiIsSpumOs?= =?us-ascii?Q?0Kpwu2wYwrKbEhwwMEqgGongC/LqYySFaOgyRQP6IGV/OcZr9REvIbXYGweM?= =?us-ascii?Q?JpaoMV60vgENlCCVNfJWJKGDxpGt1ksvGuBRhpdJp6QtZY7Mbz6h/LJSr5S5?= =?us-ascii?Q?dCn+txDx29/6jsRTsqmoxZfioXP960+aA8JrpRyQvEMNYWgo0OUAtAqn8ueC?= =?us-ascii?Q?iQ+HCnWXp5HdrJSKPjTt9X5VMfvI88noAPH0M/hSv2Hyi1kFJIzPblHC8daI?= =?us-ascii?Q?kNZjZ/V5eS0xSMHPJYV+uv6K?= 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: CH0PR11MB5363.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 5d36fa4c-f089-4dae-ca0f-08d98f2c1539 X-MS-Exchange-CrossTenant-originalarrivaltime: 14 Oct 2021 16:02:54.5136 (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: 8nyYlyfoSE6Trsu5vt9ptNLJoRmhTCgL7is9yPrwoiEd7DuU5nLKty8rBEhkT1ZeHnkEauIiFQff17lJjJp6WZAyQkCjci1N47p45isaXxw= X-MS-Exchange-Transport-CrossTenantHeadersStamped: CH2PR11MB4293 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: Liguzinski, WojciechX=20 Sent: Tuesday, October 12, 2021 8:34 PM To: Dumitrescu, Cristian ; dev@dpdk.org; Sin= gh, Jasvinder Cc: Ajmera, Megha ; Cybura, LukaszX ; Zegota, AnnaX Subject: RE: [PATCH v9 1/5] sched: add PIE based congestion management Hi Cristian, -----Original Message----- From: Dumitrescu, Cristian 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 > 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) @@ > -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=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', > +'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=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 > 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 > 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 > 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 ---------------------- Thanks for your review comments. Replying to them: - The majority of them I have implemented/added to the code, - Adding this one else statement for the "declaring new variables in the mi= ddle of the function" had to be rejected as it was in conflict with chechpa= tch and resulted in a warning, - Another thing that I needed to omit is using this generic struct rte_sche= d_cman_params in struct rte_sched_subport (rte_sched.c) as config structure= s for red an pie are used there, and I thought that with limited time I don= 't want to risk with the implementation, - Introducing rte_sched_cman_params structure changed a bit the code, but I= hope that I didn't break anything - Some changes (like in cfg_file.c & cfg_file.h) where the result of previo= us point + exceeding the line length So now, I'd like to ask you for a review. Unfortunately, I haven't found a neat way to show you the revision history,= but please have a look here: https://patchwork.dpdk.org/project/dpdk/list/= ?submitter=3D2195&state=3D%2A&archive=3Dboth Thanks, Wojtek