Message ID | cd710487a34149654a5ff73a8c0df9b1d3fc73a9.1717087015.git.pabeni@redhat.com (mailing list archive) |
---|---|
State | Changes Requested |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | dst_cache: cope with device removal | expand |
On Thu, May 30, 2024 at 7:21 PM Paolo Abeni <pabeni@redhat.com> wrote: > > Eric reported that dst_cache don't cope correctly with device removal, > keeping the cached dst unmodified even when the underlining device is > deleted and the dst itself is not uncached. > > The above causes the infamous 'unregistering netdevice' hangup. > > Address the issue by adding each entry held by the dst_caches to the > 'uncached' list, so that the dst core will cleanup the device reference > at device removal time. > > Reported-by: Eric Dumazet <edumazet@google.com> > Suggested-by: Eric Dumazet <edumazet@google.com> > Fixes: 911362c70df5 ("net: add dst_cache support") > Signed-off-by: Paolo Abeni <pabeni@redhat.com> > --- > net/core/dst_cache.c | 8 ++++++++ > 1 file changed, 8 insertions(+) > > diff --git a/net/core/dst_cache.c b/net/core/dst_cache.c > index 6a0482e676d3..d1cb852d5748 100644 > --- a/net/core/dst_cache.c > +++ b/net/core/dst_cache.c > @@ -11,6 +11,7 @@ > #include <net/route.h> > #if IS_ENABLED(CONFIG_IPV6) > #include <net/ip6_fib.h> > +#include <net/ip6_route.h> > #endif > #include <uapi/linux/in.h> > > @@ -28,6 +29,7 @@ static void dst_cache_per_cpu_dst_set(struct dst_cache_pcpu *dst_cache, > struct dst_entry *dst, u32 cookie) > { > dst_release(dst_cache->dst); > + > if (dst) > dst_hold(dst); > > @@ -98,6 +100,9 @@ void dst_cache_set_ip4(struct dst_cache *dst_cache, struct dst_entry *dst, > > idst = this_cpu_ptr(dst_cache->cache); > dst_cache_per_cpu_dst_set(idst, dst, 0); > + if (dst && list_empty(&dst->rt_uncached)) > + rt_add_uncached_list(dst_rtable(dst)); > + > idst->in_saddr.s_addr = saddr; > } > EXPORT_SYMBOL_GPL(dst_cache_set_ip4); > @@ -114,6 +119,9 @@ void dst_cache_set_ip6(struct dst_cache *dst_cache, struct dst_entry *dst, > idst = this_cpu_ptr(dst_cache->cache); > dst_cache_per_cpu_dst_set(idst, dst, > rt6_get_cookie(dst_rt6_info(dst))); > + if (dst && list_empty(&dst->rt_uncached)) > + rt6_uncached_list_add(dst_rt6_info(dst)); This probably will not compile if CONFIG_IPV6=m ?
Hi Paolo, kernel test robot noticed the following build errors: [auto build test ERROR on net-next/main] url: https://github.com/intel-lab-lkp/linux/commits/Paolo-Abeni/ipv6-use-a-new-flag-to-indicate-elevated-refcount/20240531-012716 base: net-next/main patch link: https://lore.kernel.org/r/cd710487a34149654a5ff73a8c0df9b1d3fc73a9.1717087015.git.pabeni%40redhat.com patch subject: [PATCH net-next 3/3] dst_cache: let rt_uncached cope with dst_cache cleanup config: arm64-defconfig (https://download.01.org/0day-ci/archive/20240531/202405311808.vqBTwxEf-lkp@intel.com/config) compiler: aarch64-linux-gcc (GCC) 13.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240531/202405311808.vqBTwxEf-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202405311808.vqBTwxEf-lkp@intel.com/ All errors (new ones prefixed by >>): aarch64-linux-ld: Unexpected GOT/PLT entries detected! aarch64-linux-ld: Unexpected run-time procedure linkages detected! aarch64-linux-ld: net/core/dst_cache.o: in function `dst_cache_set_ip6': >> net/core/dst_cache.c:123:(.text+0x240): undefined reference to `rt6_uncached_list_add' vim +123 net/core/dst_cache.c 109 110 #if IS_ENABLED(CONFIG_IPV6) 111 void dst_cache_set_ip6(struct dst_cache *dst_cache, struct dst_entry *dst, 112 const struct in6_addr *saddr) 113 { 114 struct dst_cache_pcpu *idst; 115 116 if (!dst_cache->cache) 117 return; 118 119 idst = this_cpu_ptr(dst_cache->cache); 120 dst_cache_per_cpu_dst_set(idst, dst, 121 rt6_get_cookie(dst_rt6_info(dst))); 122 if (dst && list_empty(&dst->rt_uncached)) > 123 rt6_uncached_list_add(dst_rt6_info(dst)); 124 125 idst->in6_saddr = *saddr; 126 } 127 EXPORT_SYMBOL_GPL(dst_cache_set_ip6); 128
Hi Paolo,
kernel test robot noticed the following build errors:
[auto build test ERROR on net-next/main]
url: https://github.com/intel-lab-lkp/linux/commits/Paolo-Abeni/ipv6-use-a-new-flag-to-indicate-elevated-refcount/20240531-012716
base: net-next/main
patch link: https://lore.kernel.org/r/cd710487a34149654a5ff73a8c0df9b1d3fc73a9.1717087015.git.pabeni%40redhat.com
patch subject: [PATCH net-next 3/3] dst_cache: let rt_uncached cope with dst_cache cleanup
config: m68k-defconfig (https://download.01.org/0day-ci/archive/20240601/202406010139.PSZGIJkQ-lkp@intel.com/config)
compiler: m68k-linux-gcc (GCC) 13.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20240601/202406010139.PSZGIJkQ-lkp@intel.com/reproduce)
If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202406010139.PSZGIJkQ-lkp@intel.com/
All errors (new ones prefixed by >>):
m68k-linux-ld: net/core/dst_cache.o: in function `dst_cache_set_ip6':
>> dst_cache.c:(.text+0x21e): undefined reference to `rt6_uncached_list_add'
diff --git a/net/core/dst_cache.c b/net/core/dst_cache.c index 6a0482e676d3..d1cb852d5748 100644 --- a/net/core/dst_cache.c +++ b/net/core/dst_cache.c @@ -11,6 +11,7 @@ #include <net/route.h> #if IS_ENABLED(CONFIG_IPV6) #include <net/ip6_fib.h> +#include <net/ip6_route.h> #endif #include <uapi/linux/in.h> @@ -28,6 +29,7 @@ static void dst_cache_per_cpu_dst_set(struct dst_cache_pcpu *dst_cache, struct dst_entry *dst, u32 cookie) { dst_release(dst_cache->dst); + if (dst) dst_hold(dst); @@ -98,6 +100,9 @@ void dst_cache_set_ip4(struct dst_cache *dst_cache, struct dst_entry *dst, idst = this_cpu_ptr(dst_cache->cache); dst_cache_per_cpu_dst_set(idst, dst, 0); + if (dst && list_empty(&dst->rt_uncached)) + rt_add_uncached_list(dst_rtable(dst)); + idst->in_saddr.s_addr = saddr; } EXPORT_SYMBOL_GPL(dst_cache_set_ip4); @@ -114,6 +119,9 @@ void dst_cache_set_ip6(struct dst_cache *dst_cache, struct dst_entry *dst, idst = this_cpu_ptr(dst_cache->cache); dst_cache_per_cpu_dst_set(idst, dst, rt6_get_cookie(dst_rt6_info(dst))); + if (dst && list_empty(&dst->rt_uncached)) + rt6_uncached_list_add(dst_rt6_info(dst)); + idst->in6_saddr = *saddr; } EXPORT_SYMBOL_GPL(dst_cache_set_ip6);
Eric reported that dst_cache don't cope correctly with device removal, keeping the cached dst unmodified even when the underlining device is deleted and the dst itself is not uncached. The above causes the infamous 'unregistering netdevice' hangup. Address the issue by adding each entry held by the dst_caches to the 'uncached' list, so that the dst core will cleanup the device reference at device removal time. Reported-by: Eric Dumazet <edumazet@google.com> Suggested-by: Eric Dumazet <edumazet@google.com> Fixes: 911362c70df5 ("net: add dst_cache support") Signed-off-by: Paolo Abeni <pabeni@redhat.com> --- net/core/dst_cache.c | 8 ++++++++ 1 file changed, 8 insertions(+)