From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from relay-out4.mail.masterhost.ru (relay-out4.mail.masterhost.ru [83.222.12.14]) by dpdk.org (Postfix) with ESMTP id F217C1B219 for ; Wed, 16 May 2018 13:04:18 +0200 (CEST) Received: from [37.139.80.50] (helo=h5.therouter.net) by relay4.mail.masterhost.ru with esmtpa envelope from authenticated with alex@therouter.net message id 1fIuE7-00065v-59; Wed, 16 May 2018 14:04:12 +0300 Received: by h5.therouter.net (sSMTP sendmail emulation); Wed, 16 May 2018 14:04:08 +0300 Date: Wed, 16 May 2018 14:04:08 +0300 To: dev@dpdk.org, "Burakov, Anatoly" From: Alex Kiselev X-KLMS-Rule-ID: 1 X-KLMS-Message-Action: clean X-KLMS-AntiSpam-Lua-Profiles: 124716 [May 16 2018] X-KLMS-AntiSpam-Version: 5.8.1.0 X-KLMS-AntiSpam-Envelope-From: alex@therouter.net X-KLMS-AntiSpam-Rate: 0 X-KLMS-AntiSpam-Status: not_detected X-KLMS-AntiSpam-Method: none X-KLMS-AntiSpam-Info: LuaCore: 132 132 c42434f570c3b5f0f81dbaf86c1c08e92ebc85af, {msgid_missed_heavy}, DmarcAF: none X-MS-Exchange-Organization-SCL: -1 X-KLMS-AntiSpam-Interceptor-Info: scan successful X-KLMS-AntiPhishing: not scanned, disabled by settings X-KLMS-AntiVirus: Kaspersky Security for Linux Mail Server, version 8.0.2.16, not scanned, license restriction Subject: [dpdk-dev] [PATCH 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 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 16 May 2018 11:04:19 -0000 Content-Type: text/plain; charset="UTF-8" Message-ID: <20180516110408.-s8ENTL4d-Tx6PLpK54Pl-SpoJAMuy1Gq3M_PTmkAcw@z> add new function rte_frag_table_del_expired_entries() that scans the list of recently used packets and delete the expired ones. 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 --- 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 | 46 ++++++++++++++++++++++++++++++ lib/librte_ip_frag/rte_ip_frag_version.map | 6 ++++ 5 files changed, 88 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..3c694df92 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..f62b5d169 100644 --- a/lib/librte_ip_frag/rte_ip_frag_common.c +++ b/lib/librte_ip_frag/rte_ip_frag_common.c @@ -121,3 +121,49 @@ 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; +} + +#ifdef RTE_IP_FRAG_DEBUG + +void +rte_frag_table_print(struct rte_ip_frag_tbl *tbl) +{ + uint32_t i, cnt; + printf("entries in use: %u, mbuf holded %u\n", tbl->use_entries, + tbl->nb_mbufs); + struct ip_frag_pkt *fp; + TAILQ_FOREACH(fp, &tbl->lru, lru) + if (!ip_frag_key_is_empty(&fp->key)) { + + /* cnt mbufs in the packet */ + cnt = 0; + for (i=0; i!=fp->last_idx; i++) + if (fp->frags[i].mb != NULL) + cnt++; + + printf("start %"PRIu64", mbuf cnt %u\n", fp->start, cnt); + } +} + +#endif /* RTE_IP_FRAG_DEBUG */ 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