From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <konstantin.ananyev@intel.com>
Received: from mga17.intel.com (mga17.intel.com [192.55.52.151])
 by dpdk.org (Postfix) with ESMTP id 5E5981B5E7
 for <dev@dpdk.org>; Fri, 29 Jun 2018 18:37:09 +0200 (CEST)
X-Amp-Result: SKIPPED(no attachment in message)
X-Amp-File-Uploaded: False
Received: from fmsmga006.fm.intel.com ([10.253.24.20])
 by fmsmga107.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384;
 29 Jun 2018 09:37:07 -0700
X-ExtLoop1: 1
X-IronPort-AV: E=Sophos;i="5.51,286,1526367600"; d="scan'208";a="241747373"
Received: from irsmsx107.ger.corp.intel.com ([163.33.3.99])
 by fmsmga006.fm.intel.com with ESMTP; 29 Jun 2018 09:37:06 -0700
Received: from irsmsx156.ger.corp.intel.com (10.108.20.68) by
 IRSMSX107.ger.corp.intel.com (163.33.3.99) with Microsoft SMTP Server (TLS)
 id 14.3.319.2; Fri, 29 Jun 2018 17:37:05 +0100
Received: from irsmsx105.ger.corp.intel.com ([169.254.7.126]) by
 IRSMSX156.ger.corp.intel.com ([169.254.3.252]) with mapi id 14.03.0319.002;
 Fri, 29 Jun 2018 17:37:05 +0100
From: "Ananyev, Konstantin" <konstantin.ananyev@intel.com>
To: Alex Kiselev <alex@therouter.net>, "dev@dpdk.org" <dev@dpdk.org>,
 "Burakov, Anatoly" <anatoly.burakov@intel.com>
Thread-Topic: [dpdk-dev] [PATCH v2 1/2] librte_ip_frag: add function to
 delete expired entries
Thread-Index: AQHT++y16bNiAWgtSEOVYJhgU/0MjKR3lseQ
Date: Fri, 29 Jun 2018 16:37:04 +0000
Message-ID: <2601191342CEEE43887BDE71AB977258C0C44FD9@irsmsx105.ger.corp.intel.com>
References: <79375b5b-5429-482e-bf87-fa2d7b811527@orsmsx101.amr.corp.intel.com>
In-Reply-To: <79375b5b-5429-482e-bf87-fa2d7b811527@orsmsx101.amr.corp.intel.com>
Accept-Language: en-IE, en-US
Content-Language: en-US
X-MS-Has-Attach: 
X-MS-TNEF-Correlator: 
x-titus-metadata-40: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiMGIzYTBiZGUtYWRmZi00MGMwLThlZGQtYzNkNjUxMDI1MmQ3IiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX05UIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE3LjEwLjE4MDQuNDkiLCJUcnVzdGVkTGFiZWxIYXNoIjoib3FLSU53MDJrUUhzcW1lSlJ3bmpGaU9COXhtdTFKOXFYQjBBM2lWSFlpWHdydFQ4XC9IeTh4MzFWWjRwUnNlZmEifQ==
x-ctpclassification: CTP_NT
dlp-product: dlpe-windows
dlp-version: 11.0.200.100
dlp-reaction: no-action
x-originating-ip: [163.33.239.180]
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: quoted-printable
MIME-Version: 1.0
Subject: Re: [dpdk-dev] [PATCH v2 1/2] librte_ip_frag: add function to
 delete expired entries
X-BeenThere: dev@dpdk.org
X-Mailman-Version: 2.1.15
Precedence: list
List-Id: DPDK patches and discussions <dev.dpdk.org>
List-Unsubscribe: <https://mails.dpdk.org/options/dev>,
 <mailto:dev-request@dpdk.org?subject=unsubscribe>
List-Archive: <http://mails.dpdk.org/archives/dev/>
List-Post: <mailto:dev@dpdk.org>
List-Help: <mailto:dev-request@dpdk.org?subject=help>
List-Subscribe: <https://mails.dpdk.org/listinfo/dev>,
 <mailto:dev-request@dpdk.org?subject=subscribe>
X-List-Received-Date: Fri, 29 Jun 2018 16:37:10 -0000



> -----Original Message-----
> From: Alex Kiselev [mailto:alex@therouter.net]
> Sent: Monday, June 4, 2018 11:13 AM
> To: Ananyev, Konstantin <konstantin.ananyev@intel.com>; dev@dpdk.org; Bur=
akov, Anatoly <anatoly.burakov@intel.com>
> Subject: [dpdk-dev] [PATCH v2 1/2] librte_ip_frag: add function to delete=
 expired entries
>=20
> A fragmented packets is supposed to live no longer than max_cycles,
> but the lib deletes an expired packet only occasionally when it scans
> a bucket to find an empty slot while adding a new packet.
> Therefore a fragment might sit in the table forever.
>=20
> Signed-off-by: Alex Kiselev <alex@therouter.net>
> ---
>  lib/librte_ip_frag/ip_frag_common.h        | 18 ++++++++++++++++++
>  lib/librte_ip_frag/ip_frag_internal.c      | 18 ------------------
>  lib/librte_ip_frag/rte_ip_frag.h           | 19 ++++++++++++++++++-
>  lib/librte_ip_frag/rte_ip_frag_common.c    | 21 +++++++++++++++++++++
>  lib/librte_ip_frag/rte_ip_frag_version.map |  6 ++++++
>  5 files changed, 63 insertions(+), 19 deletions(-)
>=20
> diff --git a/lib/librte_ip_frag/ip_frag_common.h b/lib/librte_ip_frag/ip_=
frag_common.h
> index 197acf8d8..0fdcc7d0f 100644
> --- a/lib/librte_ip_frag/ip_frag_common.h
> +++ b/lib/librte_ip_frag/ip_frag_common.h
> @@ -25,6 +25,12 @@
>  #define IPv6_KEY_BYTES_FMT \
>  	"%08" PRIx64 "%08" PRIx64 "%08" PRIx64 "%08" PRIx64
>=20
> +#ifdef RTE_LIBRTE_IP_FRAG_TBL_STAT
> +#define	IP_FRAG_TBL_STAT_UPDATE(s, f, v)	((s)->f +=3D (v))
> +#else
> +#define	IP_FRAG_TBL_STAT_UPDATE(s, f, v)	do {} while (0)
> +#endif /* IP_FRAG_TBL_STAT */
> +
>  /* internal functions declarations */
>  struct rte_mbuf * ip_frag_process(struct ip_frag_pkt *fp,
>  		struct rte_ip_frag_death_row *dr, struct rte_mbuf *mb,
> @@ -149,4 +155,16 @@ ip_frag_reset(struct ip_frag_pkt *fp, uint64_t tms)
>  	fp->frags[IP_FIRST_FRAG_IDX] =3D zero_frag;
>  }
>=20
> +/* local frag table helper functions */
> +static inline void
> +ip_frag_tbl_del(struct rte_ip_frag_tbl *tbl, struct rte_ip_frag_death_ro=
w *dr,
> +	struct ip_frag_pkt *fp)
> +{
> +	ip_frag_free(fp, dr);
> +	ip_frag_key_invalidate(&fp->key);
> +	TAILQ_REMOVE(&tbl->lru, fp, lru);
> +	tbl->use_entries--;
> +	IP_FRAG_TBL_STAT_UPDATE(&tbl->stat, del_num, 1);
> +}
> +
>  #endif /* _IP_FRAG_COMMON_H_ */
> diff --git a/lib/librte_ip_frag/ip_frag_internal.c b/lib/librte_ip_frag/i=
p_frag_internal.c
> index 2560c7713..97470a872 100644
> --- a/lib/librte_ip_frag/ip_frag_internal.c
> +++ b/lib/librte_ip_frag/ip_frag_internal.c
> @@ -14,24 +14,6 @@
>  #define	IP_FRAG_TBL_POS(tbl, sig)	\
>  	((tbl)->pkt + ((sig) & (tbl)->entry_mask))
>=20
> -#ifdef RTE_LIBRTE_IP_FRAG_TBL_STAT
> -#define	IP_FRAG_TBL_STAT_UPDATE(s, f, v)	((s)->f +=3D (v))
> -#else
> -#define	IP_FRAG_TBL_STAT_UPDATE(s, f, v)	do {} while (0)
> -#endif /* IP_FRAG_TBL_STAT */
> -
> -/* local frag table helper functions */
> -static inline void
> -ip_frag_tbl_del(struct rte_ip_frag_tbl *tbl, struct rte_ip_frag_death_ro=
w *dr,
> -	struct ip_frag_pkt *fp)
> -{
> -	ip_frag_free(fp, dr);
> -	ip_frag_key_invalidate(&fp->key);
> -	TAILQ_REMOVE(&tbl->lru, fp, lru);
> -	tbl->use_entries--;
> -	IP_FRAG_TBL_STAT_UPDATE(&tbl->stat, del_num, 1);
> -}
> -
>  static inline void
>  ip_frag_tbl_add(struct rte_ip_frag_tbl *tbl,  struct ip_frag_pkt *fp,
>  	const struct ip_frag_key *key, uint64_t tms)
> diff --git a/lib/librte_ip_frag/rte_ip_frag.h b/lib/librte_ip_frag/rte_ip=
_frag.h
> index b3f3f78df..7f425f610 100644
> --- a/lib/librte_ip_frag/rte_ip_frag.h
> +++ b/lib/librte_ip_frag/rte_ip_frag.h
> @@ -65,10 +65,13 @@ struct ip_frag_pkt {
>=20
>  #define IP_FRAG_DEATH_ROW_LEN 32 /**< death row size (in packets) */
>=20
> +/* death row size in mbufs */
> +#define IP_FRAG_DEATH_ROW_MBUF_LEN (IP_FRAG_DEATH_ROW_LEN * (IP_MAX_FRAG=
_NUM + 1))
> +
>  /** mbuf death row (packets to be freed) */
>  struct rte_ip_frag_death_row {
>  	uint32_t cnt;          /**< number of mbufs currently on death row */
> -	struct rte_mbuf *row[IP_FRAG_DEATH_ROW_LEN * (IP_MAX_FRAG_NUM + 1)];
> +	struct rte_mbuf *row[IP_FRAG_DEATH_ROW_MBUF_LEN];
>  	/**< mbufs to be freed */
>  };
>=20
> @@ -325,6 +328,20 @@ void rte_ip_frag_free_death_row(struct rte_ip_frag_d=
eath_row *dr,
>  void
>  rte_ip_frag_table_statistics_dump(FILE * f, const struct rte_ip_frag_tbl=
 *tbl);
>=20
> +/**
> + * Delete expired fragments
> + *
> + * @param tbl
> + *   Table to delete expired fragments from
> + * @param dr
> + *   Death row to free buffers to
> + * @param tms
> + *   Current timestamp
> + */
> +void __rte_experimental
> +rte_frag_table_del_expired_entries(struct rte_ip_frag_tbl *tbl,
> +	struct rte_ip_frag_death_row *dr, uint64_t tms);
> +
>  #ifdef __cplusplus
>  }
>  #endif
> diff --git a/lib/librte_ip_frag/rte_ip_frag_common.c b/lib/librte_ip_frag=
/rte_ip_frag_common.c
> index 659a17951..a23f6f24f 100644
> --- a/lib/librte_ip_frag/rte_ip_frag_common.c
> +++ b/lib/librte_ip_frag/rte_ip_frag_common.c
> @@ -121,3 +121,24 @@ rte_ip_frag_table_statistics_dump(FILE *f, const str=
uct rte_ip_frag_tbl *tbl)
>  		fail_nospace,
>  		fail_total - fail_nospace);
>  }
> +
> +/* Delete expired fragments */
> +void __rte_experimental
> +rte_frag_table_del_expired_entries(struct rte_ip_frag_tbl *tbl,
> +	struct rte_ip_frag_death_row *dr, uint64_t tms)
> +{
> +	uint64_t max_cycles;
> +	struct ip_frag_pkt *fp;
> +
> +	max_cycles =3D tbl->max_cycles;
> +
> +	TAILQ_FOREACH(fp, &tbl->lru, lru)
> +		if (max_cycles + fp->start < tms) {
> +			/* check that death row has enough space */
> +			if (IP_FRAG_DEATH_ROW_MBUF_LEN - dr->cnt >=3D fp->last_idx)
> +				ip_frag_tbl_del(tbl, dr, fp);
> +			else
> +				return;
> +		} else
> +			return;
> +}
> diff --git a/lib/librte_ip_frag/rte_ip_frag_version.map b/lib/librte_ip_f=
rag/rte_ip_frag_version.map
> index d1acf07cb..d40d5515f 100644
> --- a/lib/librte_ip_frag/rte_ip_frag_version.map
> +++ b/lib/librte_ip_frag/rte_ip_frag_version.map
> @@ -18,3 +18,9 @@ DPDK_17.08 {
>      rte_ip_frag_table_destroy;
>=20
>  } DPDK_2.0;
> +
> +EXPERIMENTAL {
> +	global:
> +
> +	rte_frag_table_del_expired_entries;
> +};
> --

Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>

> 2.16.1.windows.1