* Re: [dpdk-dev] [PATCH v2 1/2] librte_ip_frag: add function to delete expired entries
@ 2018-08-24 11:34 Ananyev, Konstantin
2018-09-19 17:49 ` Thomas Monjalon
0 siblings, 1 reply; 5+ messages in thread
From: Ananyev, Konstantin @ 2018-08-24 11:34 UTC (permalink / raw)
To: dev; +Cc: Alex Kiselev
> -----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; Burakov, Anatoly <anatoly.burakov@intel.com>
> Subject: [dpdk-dev] [PATCH v2 1/2] librte_ip_frag: add function to delete expired entries
>
> 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.
>
> 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(-)
>
> 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
>
> +#ifdef RTE_LIBRTE_IP_FRAG_TBL_STAT
> +#define IP_FRAG_TBL_STAT_UPDATE(s, f, v) ((s)->f += (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] = zero_frag;
> }
>
> +/* local frag table helper functions */
> +static inline void
> +ip_frag_tbl_del(struct rte_ip_frag_tbl *tbl, struct rte_ip_frag_death_row *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/ip_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))
>
> -#ifdef RTE_LIBRTE_IP_FRAG_TBL_STAT
> -#define IP_FRAG_TBL_STAT_UPDATE(s, f, v) ((s)->f += (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_row *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 {
>
> #define IP_FRAG_DEATH_ROW_LEN 32 /**< death row size (in packets) */
>
> +/* 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 */
> };
>
> @@ -325,6 +328,20 @@ void rte_ip_frag_free_death_row(struct rte_ip_frag_death_row *dr,
> void
> rte_ip_frag_table_statistics_dump(FILE * f, const struct rte_ip_frag_tbl *tbl);
>
> +/**
> + * 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 struct 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 = 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 >= 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_frag/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;
>
> } DPDK_2.0;
> +
> +EXPERIMENTAL {
> + global:
> +
> + rte_frag_table_del_expired_entries;
> +};
> --
> 2.16.1.windows.1
Seems my previous ack for that patch was lost somewhere:
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [dpdk-dev] [PATCH v2 1/2] librte_ip_frag: add function to delete expired entries
2018-08-24 11:34 [dpdk-dev] [PATCH v2 1/2] librte_ip_frag: add function to delete expired entries Ananyev, Konstantin
@ 2018-09-19 17:49 ` Thomas Monjalon
0 siblings, 0 replies; 5+ messages in thread
From: Thomas Monjalon @ 2018-09-19 17:49 UTC (permalink / raw)
To: Alex Kiselev; +Cc: dev, Ananyev, Konstantin
> > 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.
> >
> > Signed-off-by: Alex Kiselev <alex@therouter.net>
>
> Seems my previous ack for that patch was lost somewhere:
> Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Applied, thanks
Note: the second patch of this series is marked as rejected.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [dpdk-dev] [PATCH v2 1/2] librte_ip_frag: add function to delete expired entries
[not found] <79375b5b-5429-482e-bf87-fa2d7b811527@orsmsx101.amr.corp.intel.com>
2018-06-08 13:28 ` Ananyev, Konstantin
@ 2018-06-29 16:37 ` Ananyev, Konstantin
1 sibling, 0 replies; 5+ messages in thread
From: Ananyev, Konstantin @ 2018-06-29 16:37 UTC (permalink / raw)
To: Alex Kiselev, dev, Burakov, Anatoly
> -----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; Burakov, Anatoly <anatoly.burakov@intel.com>
> Subject: [dpdk-dev] [PATCH v2 1/2] librte_ip_frag: add function to delete expired entries
>
> 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.
>
> 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(-)
>
> 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
>
> +#ifdef RTE_LIBRTE_IP_FRAG_TBL_STAT
> +#define IP_FRAG_TBL_STAT_UPDATE(s, f, v) ((s)->f += (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] = zero_frag;
> }
>
> +/* local frag table helper functions */
> +static inline void
> +ip_frag_tbl_del(struct rte_ip_frag_tbl *tbl, struct rte_ip_frag_death_row *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/ip_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))
>
> -#ifdef RTE_LIBRTE_IP_FRAG_TBL_STAT
> -#define IP_FRAG_TBL_STAT_UPDATE(s, f, v) ((s)->f += (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_row *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 {
>
> #define IP_FRAG_DEATH_ROW_LEN 32 /**< death row size (in packets) */
>
> +/* 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 */
> };
>
> @@ -325,6 +328,20 @@ void rte_ip_frag_free_death_row(struct rte_ip_frag_death_row *dr,
> void
> rte_ip_frag_table_statistics_dump(FILE * f, const struct rte_ip_frag_tbl *tbl);
>
> +/**
> + * 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 struct 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 = 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 >= 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_frag/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;
>
> } DPDK_2.0;
> +
> +EXPERIMENTAL {
> + global:
> +
> + rte_frag_table_del_expired_entries;
> +};
> --
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
> 2.16.1.windows.1
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [dpdk-dev] [PATCH v2 1/2] librte_ip_frag: add function to delete expired entries
[not found] <79375b5b-5429-482e-bf87-fa2d7b811527@orsmsx101.amr.corp.intel.com>
@ 2018-06-08 13:28 ` Ananyev, Konstantin
2018-06-29 16:37 ` Ananyev, Konstantin
1 sibling, 0 replies; 5+ messages in thread
From: Ananyev, Konstantin @ 2018-06-08 13:28 UTC (permalink / raw)
To: Alex Kiselev, dev, Burakov, Anatoly
>
> 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.
>
> 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(-)
>
> 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
>
> +#ifdef RTE_LIBRTE_IP_FRAG_TBL_STAT
> +#define IP_FRAG_TBL_STAT_UPDATE(s, f, v) ((s)->f += (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] = zero_frag;
> }
>
> +/* local frag table helper functions */
> +static inline void
> +ip_frag_tbl_del(struct rte_ip_frag_tbl *tbl, struct rte_ip_frag_death_row *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/ip_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))
>
> -#ifdef RTE_LIBRTE_IP_FRAG_TBL_STAT
> -#define IP_FRAG_TBL_STAT_UPDATE(s, f, v) ((s)->f += (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_row *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 {
>
> #define IP_FRAG_DEATH_ROW_LEN 32 /**< death row size (in packets) */
>
> +/* 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 */
> };
>
> @@ -325,6 +328,20 @@ void rte_ip_frag_free_death_row(struct rte_ip_frag_death_row *dr,
> void
> rte_ip_frag_table_statistics_dump(FILE * f, const struct rte_ip_frag_tbl *tbl);
>
> +/**
> + * 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 struct 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 = 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 >= fp->last_idx)
Just as a nit: s/ IP_FRAG_DEATH_ROW_MBUF_LEN/RTE_DIM(dr->row).
Apart from that - looks good.
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
^ permalink raw reply [flat|nested] 5+ messages in thread
* [dpdk-dev] [PATCH v2 1/2] librte_ip_frag: add function to delete expired entries
@ 2018-06-04 10:13 Alex Kiselev
0 siblings, 0 replies; 5+ messages in thread
From: Alex Kiselev @ 2018-06-04 10:13 UTC (permalink / raw)
To: Ananyev, Konstantin, dev, Burakov, Anatoly
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.
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(-)
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
+#ifdef RTE_LIBRTE_IP_FRAG_TBL_STAT
+#define IP_FRAG_TBL_STAT_UPDATE(s, f, v) ((s)->f += (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] = zero_frag;
}
+/* local frag table helper functions */
+static inline void
+ip_frag_tbl_del(struct rte_ip_frag_tbl *tbl, struct rte_ip_frag_death_row *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/ip_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))
-#ifdef RTE_LIBRTE_IP_FRAG_TBL_STAT
-#define IP_FRAG_TBL_STAT_UPDATE(s, f, v) ((s)->f += (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_row *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 {
#define IP_FRAG_DEATH_ROW_LEN 32 /**< death row size (in packets) */
+/* 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 */
};
@@ -325,6 +328,20 @@ void rte_ip_frag_free_death_row(struct rte_ip_frag_death_row *dr,
void
rte_ip_frag_table_statistics_dump(FILE * f, const struct rte_ip_frag_tbl *tbl);
+/**
+ * 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 struct 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 = 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 >= 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_frag/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;
} DPDK_2.0;
+
+EXPERIMENTAL {
+ global:
+
+ rte_frag_table_del_expired_entries;
+};
--
2.16.1.windows.1
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2018-09-19 17:49 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-08-24 11:34 [dpdk-dev] [PATCH v2 1/2] librte_ip_frag: add function to delete expired entries Ananyev, Konstantin
2018-09-19 17:49 ` Thomas Monjalon
[not found] <79375b5b-5429-482e-bf87-fa2d7b811527@orsmsx101.amr.corp.intel.com>
2018-06-08 13:28 ` Ananyev, Konstantin
2018-06-29 16:37 ` Ananyev, Konstantin
-- strict thread matches above, loose matches on Subject: below --
2018-06-04 10:13 Alex Kiselev
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).