From: Joe Stringer Date: Thu, 24 Dec 2015 18:41:35 +0000 (-0800) Subject: compat: Detect and use inet_frag_queue->list_evictor. X-Git-Url: http://git.cascardo.eti.br/?p=cascardo%2Fovs.git;a=commitdiff_plain;h=e0d45da35ec70f2224826a5a62ce66e505ee1962 compat: Detect and use inet_frag_queue->list_evictor. 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 Acked-by: Pravin B Shelar --- diff --git a/acinclude.m4 b/acinclude.m4 index 7ed464c14..e99420e5f 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -355,10 +355,13 @@ 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_GREP_IFELSE([$KSRC/include/net/inet_frag.h], [inet_frag_evicting]) OVS_FIND_FIELD_IFELSE([$KSRC/include/net/inet_frag.h], [inet_frags], [frags_work]) OVS_FIND_FIELD_IFELSE([$KSRC/include/net/inet_frag.h], [inet_frags], [rwlock]) + OVS_FIND_FIELD_IFELSE([$KSRC/include/net/inet_frag.h], [inet_frag_queue], + [list_evictor]) OVS_GREP_IFELSE([$KSRC/include/net/inetpeer.h], [vif], [OVS_DEFINE([HAVE_INETPEER_VIF_SUPPORT])]) diff --git a/datapath/linux/compat/include/net/inet_frag.h b/datapath/linux/compat/include/net/inet_frag.h index 2708cddf2..64edffa2b 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,15 @@ static inline bool rpl_inet_frag_evicting(struct inet_frag_queue *q) #endif } #define inet_frag_evicting rpl_inet_frag_evicting +#else /* HAVE_INET_FRAG_QUEUE_WITH_LIST_EVICTOR */ +#ifndef HAVE_INET_FRAG_EVICTING +static inline bool rpl_inet_frag_evicting(struct inet_frag_queue *q) +{ + return !hlist_unhashed(&q->list_evictor); +} +#define inet_frag_evicting rpl_inet_frag_evicting +#endif +#endif 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 741a05554..0b9b9515e 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 1841c49b9..4fa50193b 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 };