From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id 10A70A0577; Tue, 14 Apr 2020 10:49:45 +0200 (CEST) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id A2D401C205; Tue, 14 Apr 2020 10:49:44 +0200 (CEST) Received: from EUR04-VI1-obe.outbound.protection.outlook.com (mail-eopbgr80075.outbound.protection.outlook.com [40.107.8.75]) by dpdk.org (Postfix) with ESMTP id 1C86D1C194 for ; Tue, 14 Apr 2020 10:49:43 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=nkkvZodP/xB1jj6Hk2Zz1mDV2X5g0vxIsEnaMARyl8JcTgoqDU9uuSwotf5EWJ3yNeCmUTUnAtf64a/HAB3KCv/qNt0s/Zy9UBOuHaTv+hbp1BtE0DyOqtntFU1pSIQNiJl2Ghagh43BYX2sV3vr0GgI8mA0RsG3eVsb1kN4r4xENG3RX7fwL3X58ljcO9hlB7GsopdwOAhujnFdC63ksSfTLTxYGRk7QQ4zVf53Y8fg22Gsc6q6/XohgPPJOPfDLNAdbw8aIaqojVm/kTRjodEWPAu0nqsLyMJbEjAuVgWQvUTa6/T0Ib8IVvEK1loJ2V9PIqVOflmj7d9dJHl4tg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=ZDxprkpmCSObpEnSJZW5CJDIfXlQBik/bDsWn7/wzy8=; b=h2bJPeHXuNvb0cazAIPFQI1GOHzOOC46Hih4AYc2ub68qiDqdnCRNTeAfvt4izymVT4RO/S6BHTMY5an7aJ9lT37zpDHZGnO0QCC6P322Cje6nORkfP5FtwmIgzmJdVTVJp3H+nuPLbXg2H1XdqHJ2bqbIWVyAMS6AaQmcSk1M/SeShzFlzMVkPlxvk3pObQU6bMK/lMJNpM2tlLxK4zj05f4QRXBumeBASySfjRtNOFf7K3YaIf717orBf9ZWuLXhbmph2UlT+9t8s1F4LysTDozIQBB5YbWNyQFVML8Vm5jHxufFc6fZ6FBH3XjXQf6GRVVqz1H1A3yv+vo+40gg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=mellanox.com; dmarc=pass action=none header.from=mellanox.com; dkim=pass header.d=mellanox.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Mellanox.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=ZDxprkpmCSObpEnSJZW5CJDIfXlQBik/bDsWn7/wzy8=; b=L+Z2vX8rAH0H9TPtuNHbOn6tfSxOvNLxH0uKSuH2fU93BJoP9e2b6S+J7PLHAxKcfLYlLwcEvyEdIxtuiKPaV38LY5H6KFooNIDjL+QNKwVwU6HOEOdSk3R5+vjJK1qG1UvUH8UOjBDqQZN+1W78KWFrbNjv56LtGzEYhyvWtgI= Received: from AM6PR05MB5176.eurprd05.prod.outlook.com (2603:10a6:20b:63::30) by AM6PR05MB4360.eurprd05.prod.outlook.com (2603:10a6:209:4a::26) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2900.15; Tue, 14 Apr 2020 08:49:42 +0000 Received: from AM6PR05MB5176.eurprd05.prod.outlook.com ([fe80::f5cd:b10f:5f1b:4b22]) by AM6PR05MB5176.eurprd05.prod.outlook.com ([fe80::f5cd:b10f:5f1b:4b22%7]) with mapi id 15.20.2900.028; Tue, 14 Apr 2020 08:49:42 +0000 From: Ori Kam To: Bill Zhou , Matan Azrad , "wenzhuo.lu@intel.com" , "jingjing.wu@intel.com" , "bernard.iremonger@intel.com" , "john.mcnamara@intel.com" , "marko.kovacevic@intel.com" , Thomas Monjalon , "ferruh.yigit@intel.com" , "arybchenko@solarflare.com" CC: "dev@dpdk.org" Thread-Topic: [PATCH v2] ethdev: support flow aging Thread-Index: AQHWEjdOKpTkfmpQB0u4LW1P44fBX6h4Tl+g Date: Tue, 14 Apr 2020 08:49:41 +0000 Message-ID: References: <20200410094631.31330-1-dongz@mellanox.com> <20200414083255.14014-1-dongz@mellanox.com> In-Reply-To: <20200414083255.14014-1-dongz@mellanox.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: spf=none (sender IP is ) smtp.mailfrom=orika@mellanox.com; x-originating-ip: [185.149.253.12] x-ms-publictraffictype: Email x-ms-office365-filtering-ht: Tenant x-ms-office365-filtering-correlation-id: 23fb7657-fddd-46e2-d5f2-08d7e050c600 x-ms-traffictypediagnostic: AM6PR05MB4360:|AM6PR05MB4360: x-ld-processed: a652971c-7d2e-4d9b-a6a4-d149256f461b,ExtAddr x-ms-exchange-transport-forked: True x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:3631; x-forefront-prvs: 0373D94D15 x-forefront-antispam-report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:AM6PR05MB5176.eurprd05.prod.outlook.com; PTR:; CAT:NONE; SFTY:; SFS:(10009020)(4636009)(396003)(376002)(39850400004)(136003)(366004)(346002)(66946007)(66476007)(66556008)(64756008)(66446008)(26005)(316002)(7696005)(76116006)(2906002)(71200400001)(33656002)(478600001)(6506007)(30864003)(53546011)(86362001)(55016002)(52536014)(8936002)(8676002)(110136005)(186003)(5660300002)(4326008)(81156014)(9686003)(921003)(1121003); DIR:OUT; SFP:1101; received-spf: None (protection.outlook.com: mellanox.com does not designate permitted sender hosts) x-ms-exchange-senderadcheck: 1 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: sbKcmxdF/9+XS7o2kVMI06KC9oC9A6p/QAurgNQEiII7tvYui6U5cREnK9jwhHs+xmZjCqpBWql1E1ZxcXsQNj6R0C4v0kmzYS0hPJBeRJ2W67oewB6UC6EerygSn3Zire3aip5B3AprwvuG+EmVIEccSEhPxHMG4J29DT6KmRUHa8qKTAJfGg3lmTPxUXeGblUWEZrXV2RStTq/AFupprWRCQ0GktYV+SYZ9XnUvB1UAkOWOxeIeK7aWIggIA4n+0GSqvofD1JjUKjjl2WEt0/wclv8iaxh54OfYxSWsDW9ac8nkviloXqXJ2ks9e3Up4Jl9VY5fmRzNrJhhQvDaIBk2VkhxbvjN9hW3HUM1F5UAV0cdXI0PkaET+fcYpxBU34m/dno29xgLVIEKJ9tFVj3TPaVUbYGmA+JxcV+s1OZDky96+C0G50Hk3hlliQXlwmCBY4PMQfjTZKdsNpySxBPdDqwLu9wuh9Kai97fhA6eTMUQTOvtocN1SAVhcz8 x-ms-exchange-antispam-messagedata: 4+ylhyHL7U/FNhUX2qMfBs40GS004PJYY7ZD036B5u4au3Pb2NmiuirFrvhh8SQPyaFGM6Yr7bUkXqQ0RrdLZK2Ak/NvNYMTSFVcCtjqndUO5WrbXHZKRW9t264l2L0Pc1oPMPt1eezf8RadAzo3Bw== Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-OriginatorOrg: Mellanox.com X-MS-Exchange-CrossTenant-Network-Message-Id: 23fb7657-fddd-46e2-d5f2-08d7e050c600 X-MS-Exchange-CrossTenant-originalarrivaltime: 14 Apr 2020 08:49:41.8784 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: a652971c-7d2e-4d9b-a6a4-d149256f461b X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: 3dIGXBO8nYcuUs1S6yt8ix3Dmpfff+E19fNfu57OgZyBmA3rdQghxhYvrBsiIWp+qZC9luDe4F1k2/Nj1Jn8Xg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM6PR05MB4360 Subject: Re: [dpdk-dev] [PATCH v2] ethdev: support flow aging X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" > -----Original Message----- > From: Dong Zhou > Sent: Tuesday, April 14, 2020 11:33 AM > To: Ori Kam ; Matan Azrad ; > wenzhuo.lu@intel.com; jingjing.wu@intel.com; bernard.iremonger@intel.com; > john.mcnamara@intel.com; marko.kovacevic@intel.com; Thomas Monjalon > ; ferruh.yigit@intel.com; arybchenko@solarflare.com > Cc: dev@dpdk.org > Subject: [PATCH v2] ethdev: support flow aging >=20 > One of the reasons to destroy a flow is the fact that no packet matches t= he > flow for "timeout" time. > For example, when TCP\UDP sessions are suddenly closed. >=20 > Currently, there is not any DPDK mechanism for flow aging and the > applications use their own ways to detect and destroy aged-out flows. >=20 > The flow aging implementation need include: > - A new rte_flow action: RTE_FLOW_ACTION_TYPE_AGE to set the timeout and > the application flow context for each flow. > - A new ethdev event: RTE_ETH_EVENT_FLOW_AGED for the driver to report > that there are new aged-out flows. > - A new rte_flow API: rte_flow_get_aged_flows to get the aged-out flows > contexts from the port. > - Support input flow aging command line in Testpmd. >=20 > Signed-off-by: Dong Zhou > --- Like said before nice patch and hope to see more patches from you. Just a small nit please next time add change log. Acked-by: Ori Kam Thanks, Ori > app/test-pmd/cmdline_flow.c | 26 ++++++++++ > doc/guides/prog_guide/rte_flow.rst | 22 +++++++++ > doc/guides/rel_notes/release_20_05.rst | 11 +++++ > lib/librte_ethdev/rte_ethdev.h | 1 + > lib/librte_ethdev/rte_ethdev_version.map | 3 ++ > lib/librte_ethdev/rte_flow.c | 18 +++++++ > lib/librte_ethdev/rte_flow.h | 62 ++++++++++++++++++++++++ > lib/librte_ethdev/rte_flow_driver.h | 6 +++ > 8 files changed, 149 insertions(+) >=20 > diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c > index e6ab8ff2f7..45bcff3cf5 100644 > --- a/app/test-pmd/cmdline_flow.c > +++ b/app/test-pmd/cmdline_flow.c > @@ -343,6 +343,8 @@ enum index { > ACTION_SET_IPV4_DSCP_VALUE, > ACTION_SET_IPV6_DSCP, > ACTION_SET_IPV6_DSCP_VALUE, > + ACTION_AGE, > + ACTION_AGE_TIMEOUT, > }; >=20 > /** Maximum size for pattern in struct rte_flow_item_raw. */ > @@ -1145,6 +1147,7 @@ static const enum index next_action[] =3D { > ACTION_SET_META, > ACTION_SET_IPV4_DSCP, > ACTION_SET_IPV6_DSCP, > + ACTION_AGE, > ZERO, > }; >=20 > @@ -1370,6 +1373,13 @@ static const enum index action_set_ipv6_dscp[] =3D= { > ZERO, > }; >=20 > +static const enum index action_age[] =3D { > + ACTION_AGE, > + ACTION_AGE_TIMEOUT, > + ACTION_NEXT, > + ZERO, > +}; > + > static int parse_set_raw_encap_decap(struct context *, const struct toke= n *, > const char *, unsigned int, > void *, unsigned int); > @@ -3694,6 +3704,22 @@ static const struct token token_list[] =3D { > (struct rte_flow_action_set_dscp, dscp)), > .call =3D parse_vc_conf, > }, > + [ACTION_AGE] =3D { > + .name =3D "age", > + .help =3D "set a specific metadata header", > + .next =3D NEXT(action_age), > + .priv =3D PRIV_ACTION(AGE, > + sizeof(struct rte_flow_action_age)), > + .call =3D parse_vc, > + }, > + [ACTION_AGE_TIMEOUT] =3D { > + .name =3D "timeout", > + .help =3D "flow age timeout value", > + .args =3D ARGS(ARGS_ENTRY_BF(struct rte_flow_action_age, > + timeout, 24)), > + .next =3D NEXT(action_age, NEXT_ENTRY(UNSIGNED)), > + .call =3D parse_vc_conf, > + }, > }; >=20 > /** Remove and return last entry from argument stack. */ > diff --git a/doc/guides/prog_guide/rte_flow.rst > b/doc/guides/prog_guide/rte_flow.rst > index 41c147913c..cf4368e1c4 100644 > --- a/doc/guides/prog_guide/rte_flow.rst > +++ b/doc/guides/prog_guide/rte_flow.rst > @@ -2616,6 +2616,28 @@ Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error > will be returned. > | ``dscp`` | DSCP in low 6 bits, rest ignore | > +-----------+---------------------------------+ >=20 > +Action: ``AGE`` > +^^^^^^^^^^^^^^^^^^^^^^^^^ > + > +Set ageing timeout configuration to a flow. > + > +Event RTE_ETH_EVENT_FLOW_AGED will be reported if > +timeout passed without any matching on the flow. > + > +.. _table_rte_flow_action_age: > + > +.. table:: AGE > + > + +--------------+---------------------------------+ > + | Field | Value | > + +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D+=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= + > + | ``timeout`` | 24 bits timeout value | > + +--------------+---------------------------------+ > + | ``reserved`` | 8 bits reserved, must be zero | > + +--------------+---------------------------------+ > + | ``context`` | user input flow context | > + +--------------+---------------------------------+ > + > Negative types > ~~~~~~~~~~~~~~ >=20 > diff --git a/doc/guides/rel_notes/release_20_05.rst > b/doc/guides/rel_notes/release_20_05.rst > index db885f3609..6b3cd8cda7 100644 > --- a/doc/guides/rel_notes/release_20_05.rst > +++ b/doc/guides/rel_notes/release_20_05.rst > @@ -100,6 +100,17 @@ New Features >=20 > * Added generic filter support. >=20 > +* **Added flow Aging Support.** > + > + Added flow Aging support to detect and report aged-out flows, includin= g: > + > + * Added new action: RTE_FLOW_ACTION_TYPE_AGE to set the timeout and > the > + application flow context for each flow. > + * Added new event: RTE_ETH_EVENT_FLOW_AGED for the driver to report > that > + there are new aged-out flows. > + * Added new API: rte_flow_get_aged_flows to get the aged-out flows > contexts > + from the port. > + > Removed Items > ------------- >=20 > diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethde= v.h > index d1a593ad11..74c9d00f36 100644 > --- a/lib/librte_ethdev/rte_ethdev.h > +++ b/lib/librte_ethdev/rte_ethdev.h > @@ -3015,6 +3015,7 @@ enum rte_eth_event_type { > RTE_ETH_EVENT_NEW, /**< port is probed */ > RTE_ETH_EVENT_DESTROY, /**< port is released */ > RTE_ETH_EVENT_IPSEC, /**< IPsec offload related event */ > + RTE_ETH_EVENT_FLOW_AGED,/**< New aged-out flows is detected */ > RTE_ETH_EVENT_MAX /**< max value of this enum */ > }; >=20 > diff --git a/lib/librte_ethdev/rte_ethdev_version.map > b/lib/librte_ethdev/rte_ethdev_version.map > index 3f32fdecf7..fa4b5816be 100644 > --- a/lib/librte_ethdev/rte_ethdev_version.map > +++ b/lib/librte_ethdev/rte_ethdev_version.map > @@ -230,4 +230,7 @@ EXPERIMENTAL { >=20 > # added in 20.02 > rte_flow_dev_dump; > + > + # added in 20.05 > + rte_flow_get_aged_flows; > }; > diff --git a/lib/librte_ethdev/rte_flow.c b/lib/librte_ethdev/rte_flow.c > index a5ac1c7fbd..3699edce49 100644 > --- a/lib/librte_ethdev/rte_flow.c > +++ b/lib/librte_ethdev/rte_flow.c > @@ -172,6 +172,7 @@ static const struct rte_flow_desc_data > rte_flow_desc_action[] =3D { > MK_FLOW_ACTION(SET_META, sizeof(struct > rte_flow_action_set_meta)), > MK_FLOW_ACTION(SET_IPV4_DSCP, sizeof(struct > rte_flow_action_set_dscp)), > MK_FLOW_ACTION(SET_IPV6_DSCP, sizeof(struct > rte_flow_action_set_dscp)), > + MK_FLOW_ACTION(AGE, sizeof(struct rte_flow_action_age)), > }; >=20 > int > @@ -1232,3 +1233,20 @@ rte_flow_dev_dump(uint16_t port_id, FILE *file, > struct rte_flow_error *error) > RTE_FLOW_ERROR_TYPE_UNSPECIFIED, > NULL, rte_strerror(ENOSYS)); > } > + > +int > +rte_flow_get_aged_flows(uint16_t port_id, void **contexts, > + uint32_t nb_contexts, struct rte_flow_error *error) > +{ > + struct rte_eth_dev *dev =3D &rte_eth_devices[port_id]; > + const struct rte_flow_ops *ops =3D rte_flow_ops_get(port_id, error); > + > + if (unlikely(!ops)) > + return -rte_errno; > + if (likely(!!ops->get_aged_flows)) > + return flow_err(port_id, ops->get_aged_flows(dev, contexts, > + nb_contexts, error), error); > + return rte_flow_error_set(error, ENOTSUP, > + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, > + NULL, rte_strerror(ENOTSUP)); > +} > diff --git a/lib/librte_ethdev/rte_flow.h b/lib/librte_ethdev/rte_flow.h > index 7f3e08fad3..fab44f6c0b 100644 > --- a/lib/librte_ethdev/rte_flow.h > +++ b/lib/librte_ethdev/rte_flow.h > @@ -2081,6 +2081,16 @@ enum rte_flow_action_type { > * See struct rte_flow_action_set_dscp. > */ > RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP, > + > + /** > + * Report as aged flow if timeout passed without any matching on the > + * flow. > + * > + * See struct rte_flow_action_age. > + * See function rte_flow_get_aged_flows > + * see enum RTE_ETH_EVENT_FLOW_AGED > + */ > + RTE_FLOW_ACTION_TYPE_AGE, > }; >=20 > /** > @@ -2122,6 +2132,25 @@ struct rte_flow_action_queue { > uint16_t index; /**< Queue index to use. */ > }; >=20 > +/** > + * @warning > + * @b EXPERIMENTAL: this structure may change without prior notice > + * > + * RTE_FLOW_ACTION_TYPE_AGE > + * > + * Report flow as aged-out if timeout passed without any matching > + * on the flow. RTE_ETH_EVENT_FLOW_AGED event is triggered when a > + * port detects new aged-out flows. > + * > + * The flow context and the flow handle will be reported by the > + * rte_flow_get_aged_flows API. > + */ > +struct rte_flow_action_age { > + uint32_t timeout:24; /**< Time in seconds. */ > + uint32_t reserved:8; /**< Reserved, must be zero. */ > + void *context; > + /**< The user flow context, NULL means the rte_flow pointer. > */ > +}; >=20 > /** > * @warning > @@ -3254,6 +3283,39 @@ rte_flow_conv(enum rte_flow_conv_op op, > const void *src, > struct rte_flow_error *error); >=20 > +/** > + * Get aged-out flows of a given port. > + * > + * RTE_ETH_EVENT_FLOW_AGED event will be triggered when at least one > new aged > + * out flow was detected after the last call to rte_flow_get_aged_flows. > + * This function can be called to get the aged flows usynchronously from= the > + * event callback or synchronously regardless the event. > + * This is not safe to call rte_flow_get_aged_flows function with other = flow > + * functions from multiple threads simultaneously. > + * > + * @param port_id > + * Port identifier of Ethernet device. > + * @param[in, out] contexts > + * The address of an array of pointers to the aged-out flows contexts. > + * @param[in] nb_contexts > + * The length of context array pointers. > + * @param[out] error > + * Perform verbose error reporting if not NULL. Initialized in case of > + * error only. > + * > + * @return > + * if nb_contexts is 0, return the amount of all aged contexts. > + * if nb_contexts is not 0 , return the amount of aged flows reported > + * in the context array, otherwise negative errno value. > + * > + * @see rte_flow_action_age > + * @see RTE_ETH_EVENT_FLOW_AGED > + */ > +__rte_experimental > +int > +rte_flow_get_aged_flows(uint16_t port_id, void **contexts, > + uint32_t nb_contexts, struct rte_flow_error *error); > + > #ifdef __cplusplus > } > #endif > diff --git a/lib/librte_ethdev/rte_flow_driver.h > b/lib/librte_ethdev/rte_flow_driver.h > index 51a9a57a0f..881cc469b7 100644 > --- a/lib/librte_ethdev/rte_flow_driver.h > +++ b/lib/librte_ethdev/rte_flow_driver.h > @@ -101,6 +101,12 @@ struct rte_flow_ops { > (struct rte_eth_dev *dev, > FILE *file, > struct rte_flow_error *error); > + /** See rte_flow_get_aged_flows() */ > + int (*get_aged_flows) > + (struct rte_eth_dev *dev, > + void **context, > + uint32_t nb_contexts, > + struct rte_flow_error *err); > }; >=20 > /** > -- > 2.21.0