Kernels 3.17 to 4.2 have a work queue to evict old fragments, but do not track these fragments in an eviction list. On these kernels, we detect the absence of the list_evictor and provide one. This commit fixes the reliance on kernel versions in the case that this functionality is backported.
Signed-off-by: Joe Stringer <j...@ovn.org> --- acinclude.m4 | 2 ++ datapath/linux/compat/include/net/inet_frag.h | 2 ++ datapath/linux/compat/inet_fragment.c | 16 ++++++++-------- datapath/linux/compat/ip_fragment.c | 2 +- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index b78244d6bf4f..1da00288d67f 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -354,6 +354,8 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [ [OVS_DEFINE([HAVE_INET_FRAGS_CONST])]) OVS_GREP_IFELSE([$KSRC/include/net/inet_frag.h], [last_in], [OVS_DEFINE([HAVE_INET_FRAGS_LAST_IN])]) + OVS_FIND_FIELD_IFELSE([$KSRC/include/net/inet_frag.h], [inet_frag_queue], + [list_evictor]) OVS_GREP_IFELSE([$KSRC/include/net/dst_metadata.h], [metadata_dst]) diff --git a/datapath/linux/compat/include/net/inet_frag.h b/datapath/linux/compat/include/net/inet_frag.h index 0c0c07619126..147435af6ae7 100644 --- a/datapath/linux/compat/include/net/inet_frag.h +++ b/datapath/linux/compat/include/net/inet_frag.h @@ -22,6 +22,7 @@ #define qp_flags(qp) (qp->q.flags) #endif +#ifndef HAVE_INET_FRAG_QUEUE_WITH_LIST_EVICTOR /** * struct ovs_inet_frag_queue - fragment queue * @@ -44,6 +45,7 @@ static inline bool rpl_inet_frag_evicting(struct inet_frag_queue *q) #endif } #define inet_frag_evicting rpl_inet_frag_evicting +#endif /* HAVE_INET_FRAG_QUEUE_WITH_LIST_EVICTOR */ static unsigned int rpl_frag_percpu_counter_batch = 130000; #define frag_percpu_counter_batch rpl_frag_percpu_counter_batch diff --git a/datapath/linux/compat/inet_fragment.c b/datapath/linux/compat/inet_fragment.c index 323226880f3d..1e335bc68c55 100644 --- a/datapath/linux/compat/inet_fragment.c +++ b/datapath/linux/compat/inet_fragment.c @@ -130,7 +130,7 @@ static bool inet_fragq_should_evict(const struct inet_frag_queue *q) static unsigned int inet_evict_bucket(struct inet_frags *f, struct inet_frag_bucket *hb) { -#if LINUX_VERSION_CODE < KERNEL_VERSION(4,2,0) +#ifndef HAVE_INET_FRAG_QUEUE_WITH_LIST_EVICTOR struct ovs_inet_frag_queue *ofq; #endif struct inet_frag_queue *fq; @@ -147,23 +147,23 @@ inet_evict_bucket(struct inet_frags *f, struct inet_frag_bucket *hb) if (!del_timer(&fq->timer)) continue; -#if LINUX_VERSION_CODE < KERNEL_VERSION(4,2,0) +#ifdef HAVE_INET_FRAG_QUEUE_WITH_LIST_EVICTOR + hlist_add_head(&fq->list_evictor, &expired); +#else ofq = (struct ovs_inet_frag_queue *)fq; hlist_add_head(&ofq->list_evictor, &expired); -#else - hlist_add_head(&fq->list_evictor, &expired); #endif ++evicted; } spin_unlock(&hb->chain_lock); -#if LINUX_VERSION_CODE < KERNEL_VERSION(4,2,0) - hlist_for_each_entry_safe(ofq, n, &expired, list_evictor) - f->frag_expire((unsigned long) &ofq->fq); -#else +#ifdef HAVE_INET_FRAG_QUEUE_WITH_LIST_EVICTOR hlist_for_each_entry_safe(fq, n, &expired, list_evictor) f->frag_expire((unsigned long) fq); +#else + hlist_for_each_entry_safe(ofq, n, &expired, list_evictor) + f->frag_expire((unsigned long) &ofq->fq); #endif return evicted; diff --git a/datapath/linux/compat/ip_fragment.c b/datapath/linux/compat/ip_fragment.c index 418134928114..b683aaffedde 100644 --- a/datapath/linux/compat/ip_fragment.c +++ b/datapath/linux/compat/ip_fragment.c @@ -78,7 +78,7 @@ struct ipfrag_skb_cb struct ipq { union { struct inet_frag_queue q; -#if LINUX_VERSION_CODE < KERNEL_VERSION(4,2,0) +#ifndef HAVE_INET_FRAG_QUEUE_WITH_LIST_EVICTOR struct ovs_inet_frag_queue oq; #endif }; -- 2.1.4 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev