Fix LOCKDEBUG kernel panic when many(about 200) tunnel interfaces is created.
The tunnel interfaces are gif(4), l2tp(4), and ipsecif(4). They use mutex itself in percpu area. When percpu_cpu_enlarge() run, the address of the mutex in percpu area becomes different from the address which lockdebug saved. That can cause "already initialized" false detection.
This commit is contained in:
parent
d4593e87a1
commit
b0c61d654b
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: if_gif.c,v 1.139 2018/02/12 15:38:14 maxv Exp $ */
|
||||
/* $NetBSD: if_gif.c,v 1.140 2018/04/27 09:55:27 knakahara Exp $ */
|
||||
/* $KAME: if_gif.c,v 1.76 2001/08/20 02:01:02 kjc Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -31,7 +31,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_gif.c,v 1.139 2018/02/12 15:38:14 maxv Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_gif.c,v 1.140 2018/04/27 09:55:27 knakahara Exp $");
|
||||
|
||||
#ifdef _KERNEL_OPT
|
||||
#include "opt_inet.h"
|
||||
|
@ -319,7 +319,7 @@ gif_ro_init_pc(void *p, void *arg __unused, struct cpu_info *ci __unused)
|
|||
{
|
||||
struct gif_ro *gro = p;
|
||||
|
||||
mutex_init(&gro->gr_lock, MUTEX_DEFAULT, IPL_NONE);
|
||||
gro->gr_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -329,7 +329,7 @@ gif_ro_fini_pc(void *p, void *arg __unused, struct cpu_info *ci __unused)
|
|||
|
||||
rtcache_free(&gro->gr_ro);
|
||||
|
||||
mutex_destroy(&gro->gr_lock);
|
||||
mutex_obj_free(gro->gr_lock);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: if_gif.h,v 1.30 2018/04/19 21:20:43 christos Exp $ */
|
||||
/* $NetBSD: if_gif.h,v 1.31 2018/04/27 09:55:27 knakahara Exp $ */
|
||||
/* $KAME: if_gif.h,v 1.23 2001/07/27 09:21:42 itojun Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -56,7 +56,7 @@ struct encaptab;
|
|||
|
||||
struct gif_ro {
|
||||
struct route gr_ro;
|
||||
kmutex_t gr_lock;
|
||||
kmutex_t *gr_lock;
|
||||
};
|
||||
|
||||
struct gif_variant {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: if_ipsec.c,v 1.12 2018/04/27 00:06:40 knakahara Exp $ */
|
||||
/* $NetBSD: if_ipsec.c,v 1.13 2018/04/27 09:55:27 knakahara Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2017 Internet Initiative Japan Inc.
|
||||
|
@ -27,7 +27,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_ipsec.c,v 1.12 2018/04/27 00:06:40 knakahara Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_ipsec.c,v 1.13 2018/04/27 09:55:27 knakahara Exp $");
|
||||
|
||||
#ifdef _KERNEL_OPT
|
||||
#include "opt_inet.h"
|
||||
|
@ -220,7 +220,7 @@ if_ipsec_ro_init_pc(void *p, void *arg __unused, struct cpu_info *ci __unused)
|
|||
{
|
||||
struct ipsec_ro *iro = p;
|
||||
|
||||
mutex_init(&iro->ir_lock, MUTEX_DEFAULT, IPL_NONE);
|
||||
iro->ir_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -230,7 +230,7 @@ if_ipsec_ro_fini_pc(void *p, void *arg __unused, struct cpu_info *ci __unused)
|
|||
|
||||
rtcache_free(&iro->ir_ro);
|
||||
|
||||
mutex_destroy(&iro->ir_lock);
|
||||
mutex_obj_free(iro->ir_lock);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: if_ipsec.h,v 1.2 2018/04/19 21:20:43 christos Exp $ */
|
||||
/* $NetBSD: if_ipsec.h,v 1.3 2018/04/27 09:55:27 knakahara Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2017 Internet Initiative Japan Inc.
|
||||
|
@ -87,7 +87,7 @@ struct ipsec_variant {
|
|||
|
||||
struct ipsec_ro {
|
||||
struct route ir_ro;
|
||||
kmutex_t ir_lock;
|
||||
kmutex_t *ir_lock;
|
||||
};
|
||||
|
||||
struct ipsec_softc {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: if_l2tp.c,v 1.23 2018/04/10 11:44:13 knakahara Exp $ */
|
||||
/* $NetBSD: if_l2tp.c,v 1.24 2018/04/27 09:55:27 knakahara Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2017 Internet Initiative Japan Inc.
|
||||
|
@ -31,7 +31,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_l2tp.c,v 1.23 2018/04/10 11:44:13 knakahara Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: if_l2tp.c,v 1.24 2018/04/27 09:55:27 knakahara Exp $");
|
||||
|
||||
#ifdef _KERNEL_OPT
|
||||
#include "opt_inet.h"
|
||||
|
@ -298,7 +298,7 @@ l2tp_ro_init_pc(void *p, void *arg __unused, struct cpu_info *ci __unused)
|
|||
{
|
||||
struct l2tp_ro *lro = p;
|
||||
|
||||
mutex_init(&lro->lr_lock, MUTEX_DEFAULT, IPL_NONE);
|
||||
lro->lr_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -308,7 +308,7 @@ l2tp_ro_fini_pc(void *p, void *arg __unused, struct cpu_info *ci __unused)
|
|||
|
||||
rtcache_free(&lro->lr_ro);
|
||||
|
||||
mutex_destroy(&lro->lr_lock);
|
||||
mutex_obj_free(lro->lr_lock);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: if_l2tp.h,v 1.4 2018/04/19 21:20:43 christos Exp $ */
|
||||
/* $NetBSD: if_l2tp.h,v 1.5 2018/04/27 09:55:27 knakahara Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2017 Internet Initiative Japan Inc.
|
||||
|
@ -92,7 +92,7 @@ struct l2tp_variant {
|
|||
|
||||
struct l2tp_ro {
|
||||
struct route lr_ro;
|
||||
kmutex_t lr_lock;
|
||||
kmutex_t *lr_lock;
|
||||
};
|
||||
|
||||
struct l2tp_softc {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: in_gif.c,v 1.92 2018/01/10 11:13:26 knakahara Exp $ */
|
||||
/* $NetBSD: in_gif.c,v 1.93 2018/04/27 09:55:28 knakahara Exp $ */
|
||||
/* $KAME: in_gif.c,v 1.66 2001/07/29 04:46:09 itojun Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -31,7 +31,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: in_gif.c,v 1.92 2018/01/10 11:13:26 knakahara Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: in_gif.c,v 1.93 2018/04/27 09:55:28 knakahara Exp $");
|
||||
|
||||
#ifdef _KERNEL_OPT
|
||||
#include "opt_inet.h"
|
||||
|
@ -176,10 +176,10 @@ in_gif_output(struct gif_variant *var, int family, struct mbuf *m)
|
|||
|
||||
sc = var->gv_softc;
|
||||
gro = percpu_getref(sc->gif_ro_percpu);
|
||||
mutex_enter(&gro->gr_lock);
|
||||
mutex_enter(gro->gr_lock);
|
||||
ro = &gro->gr_ro;
|
||||
if ((rt = rtcache_lookup(ro, var->gv_pdst)) == NULL) {
|
||||
mutex_exit(&gro->gr_lock);
|
||||
mutex_exit(gro->gr_lock);
|
||||
percpu_putref(sc->gif_ro_percpu);
|
||||
m_freem(m);
|
||||
return ENETUNREACH;
|
||||
|
@ -189,7 +189,7 @@ in_gif_output(struct gif_variant *var, int family, struct mbuf *m)
|
|||
if (rt->rt_ifp == ifp) {
|
||||
rtcache_unref(rt, ro);
|
||||
rtcache_free(ro);
|
||||
mutex_exit(&gro->gr_lock);
|
||||
mutex_exit(gro->gr_lock);
|
||||
percpu_putref(sc->gif_ro_percpu);
|
||||
m_freem(m);
|
||||
return ENETUNREACH; /*XXX*/
|
||||
|
@ -197,7 +197,7 @@ in_gif_output(struct gif_variant *var, int family, struct mbuf *m)
|
|||
rtcache_unref(rt, ro);
|
||||
|
||||
error = ip_output(m, NULL, ro, 0, NULL, NULL);
|
||||
mutex_exit(&gro->gr_lock);
|
||||
mutex_exit(gro->gr_lock);
|
||||
percpu_putref(sc->gif_ro_percpu);
|
||||
return (error);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: in_l2tp.c,v 1.12 2018/01/26 07:49:15 maxv Exp $ */
|
||||
/* $NetBSD: in_l2tp.c,v 1.13 2018/04/27 09:55:28 knakahara Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2017 Internet Initiative Japan Inc.
|
||||
|
@ -27,7 +27,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: in_l2tp.c,v 1.12 2018/01/26 07:49:15 maxv Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: in_l2tp.c,v 1.13 2018/04/27 09:55:28 knakahara Exp $");
|
||||
|
||||
#ifdef _KERNEL_OPT
|
||||
#include "opt_l2tp.h"
|
||||
|
@ -209,9 +209,9 @@ in_l2tp_output(struct l2tp_variant *var, struct mbuf *m)
|
|||
memcpy(mtod(m, struct ip *), &iphdr, sizeof(struct ip));
|
||||
|
||||
lro = percpu_getref(sc->l2tp_ro_percpu);
|
||||
mutex_enter(&lro->lr_lock);
|
||||
mutex_enter(lro->lr_lock);
|
||||
if ((rt = rtcache_lookup(&lro->lr_ro, var->lv_pdst)) == NULL) {
|
||||
mutex_exit(&lro->lr_lock);
|
||||
mutex_exit(lro->lr_lock);
|
||||
percpu_putref(sc->l2tp_ro_percpu);
|
||||
m_freem(m);
|
||||
error = ENETUNREACH;
|
||||
|
@ -221,7 +221,7 @@ in_l2tp_output(struct l2tp_variant *var, struct mbuf *m)
|
|||
if (rt->rt_ifp == ifp) {
|
||||
rtcache_unref(rt, &lro->lr_ro);
|
||||
rtcache_free(&lro->lr_ro);
|
||||
mutex_exit(&lro->lr_lock);
|
||||
mutex_exit(lro->lr_lock);
|
||||
percpu_putref(sc->l2tp_ro_percpu);
|
||||
m_freem(m);
|
||||
error = ENETUNREACH; /*XXX*/
|
||||
|
@ -236,7 +236,7 @@ in_l2tp_output(struct l2tp_variant *var, struct mbuf *m)
|
|||
m->m_pkthdr.csum_flags = 0;
|
||||
|
||||
error = ip_output(m, NULL, &lro->lr_ro, 0, NULL, NULL);
|
||||
mutex_exit(&lro->lr_lock);
|
||||
mutex_exit(lro->lr_lock);
|
||||
percpu_putref(sc->l2tp_ro_percpu);
|
||||
return error;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: in6_gif.c,v 1.91 2018/03/14 07:56:32 knakahara Exp $ */
|
||||
/* $NetBSD: in6_gif.c,v 1.92 2018/04/27 09:55:28 knakahara Exp $ */
|
||||
/* $KAME: in6_gif.c,v 1.62 2001/07/29 04:27:25 itojun Exp $ */
|
||||
|
||||
/*
|
||||
|
@ -31,7 +31,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: in6_gif.c,v 1.91 2018/03/14 07:56:32 knakahara Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: in6_gif.c,v 1.92 2018/04/27 09:55:28 knakahara Exp $");
|
||||
|
||||
#ifdef _KERNEL_OPT
|
||||
#include "opt_inet.h"
|
||||
|
@ -182,11 +182,11 @@ in6_gif_output(struct gif_variant *var, int family, struct mbuf *m)
|
|||
|
||||
sc = ifp->if_softc;
|
||||
gro = percpu_getref(sc->gif_ro_percpu);
|
||||
mutex_enter(&gro->gr_lock);
|
||||
mutex_enter(gro->gr_lock);
|
||||
ro = &gro->gr_ro;
|
||||
rt = rtcache_lookup(ro, var->gv_pdst);
|
||||
if (rt == NULL) {
|
||||
mutex_exit(&gro->gr_lock);
|
||||
mutex_exit(gro->gr_lock);
|
||||
percpu_putref(sc->gif_ro_percpu);
|
||||
m_freem(m);
|
||||
return ENETUNREACH;
|
||||
|
@ -196,7 +196,7 @@ in6_gif_output(struct gif_variant *var, int family, struct mbuf *m)
|
|||
if (rt->rt_ifp == ifp) {
|
||||
rtcache_unref(rt, ro);
|
||||
rtcache_free(ro);
|
||||
mutex_exit(&gro->gr_lock);
|
||||
mutex_exit(gro->gr_lock);
|
||||
percpu_putref(sc->gif_ro_percpu);
|
||||
m_freem(m);
|
||||
return ENETUNREACH; /* XXX */
|
||||
|
@ -213,7 +213,7 @@ in6_gif_output(struct gif_variant *var, int family, struct mbuf *m)
|
|||
#else
|
||||
error = ip6_output(m, 0, ro, 0, NULL, NULL, NULL);
|
||||
#endif
|
||||
mutex_exit(&gro->gr_lock);
|
||||
mutex_exit(gro->gr_lock);
|
||||
percpu_putref(sc->gif_ro_percpu);
|
||||
return (error);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: in6_l2tp.c,v 1.14 2018/01/26 07:49:15 maxv Exp $ */
|
||||
/* $NetBSD: in6_l2tp.c,v 1.15 2018/04/27 09:55:28 knakahara Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2017 Internet Initiative Japan Inc.
|
||||
|
@ -27,7 +27,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: in6_l2tp.c,v 1.14 2018/01/26 07:49:15 maxv Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: in6_l2tp.c,v 1.15 2018/04/27 09:55:28 knakahara Exp $");
|
||||
|
||||
#ifdef _KERNEL_OPT
|
||||
#include "opt_l2tp.h"
|
||||
|
@ -202,9 +202,9 @@ in6_l2tp_output(struct l2tp_variant *var, struct mbuf *m)
|
|||
memcpy(mtod(m, struct ip6_hdr *), &ip6hdr, sizeof(struct ip6_hdr));
|
||||
|
||||
lro = percpu_getref(sc->l2tp_ro_percpu);
|
||||
mutex_enter(&lro->lr_lock);
|
||||
mutex_enter(lro->lr_lock);
|
||||
if ((rt = rtcache_lookup(&lro->lr_ro, var->lv_pdst)) == NULL) {
|
||||
mutex_exit(&lro->lr_lock);
|
||||
mutex_exit(lro->lr_lock);
|
||||
percpu_putref(sc->l2tp_ro_percpu);
|
||||
m_freem(m);
|
||||
return ENETUNREACH;
|
||||
|
@ -214,7 +214,7 @@ in6_l2tp_output(struct l2tp_variant *var, struct mbuf *m)
|
|||
if (rt->rt_ifp == ifp) {
|
||||
rtcache_unref(rt, &lro->lr_ro);
|
||||
rtcache_free(&lro->lr_ro);
|
||||
mutex_exit(&lro->lr_lock);
|
||||
mutex_exit(lro->lr_lock);
|
||||
percpu_putref(sc->l2tp_ro_percpu);
|
||||
m_freem(m);
|
||||
return ENETUNREACH; /* XXX */
|
||||
|
@ -228,7 +228,7 @@ in6_l2tp_output(struct l2tp_variant *var, struct mbuf *m)
|
|||
m->m_pkthdr.csum_flags = 0;
|
||||
|
||||
error = ip6_output(m, 0, &lro->lr_ro, 0, NULL, NULL, NULL);
|
||||
mutex_exit(&lro->lr_lock);
|
||||
mutex_exit(lro->lr_lock);
|
||||
percpu_putref(sc->l2tp_ro_percpu);
|
||||
return(error);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: ipsecif.c,v 1.7 2018/04/06 10:38:53 knakahara Exp $ */
|
||||
/* $NetBSD: ipsecif.c,v 1.8 2018/04/27 09:55:28 knakahara Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2017 Internet Initiative Japan Inc.
|
||||
|
@ -27,7 +27,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: ipsecif.c,v 1.7 2018/04/06 10:38:53 knakahara Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: ipsecif.c,v 1.8 2018/04/27 09:55:28 knakahara Exp $");
|
||||
|
||||
#ifdef _KERNEL_OPT
|
||||
#include "opt_inet.h"
|
||||
|
@ -570,9 +570,9 @@ ipsecif6_output(struct ipsec_variant *var, int family, struct mbuf *m)
|
|||
sockaddr_in6_init(&u.dst6, &sin6_dst->sin6_addr, 0, 0, 0);
|
||||
|
||||
iro = percpu_getref(sc->ipsec_ro_percpu);
|
||||
mutex_enter(&iro->ir_lock);
|
||||
mutex_enter(iro->ir_lock);
|
||||
if ((rt = rtcache_lookup(&iro->ir_ro, &u.dst)) == NULL) {
|
||||
mutex_exit(&iro->ir_lock);
|
||||
mutex_exit(iro->ir_lock);
|
||||
percpu_putref(sc->ipsec_ro_percpu);
|
||||
m_freem(m);
|
||||
return ENETUNREACH;
|
||||
|
@ -581,7 +581,7 @@ ipsecif6_output(struct ipsec_variant *var, int family, struct mbuf *m)
|
|||
if (rt->rt_ifp == ifp) {
|
||||
rtcache_unref(rt, &iro->ir_ro);
|
||||
rtcache_free(&iro->ir_ro);
|
||||
mutex_exit(&iro->ir_lock);
|
||||
mutex_exit(iro->ir_lock);
|
||||
percpu_putref(sc->ipsec_ro_percpu);
|
||||
m_freem(m);
|
||||
return ENETUNREACH;
|
||||
|
@ -598,7 +598,7 @@ ipsecif6_output(struct ipsec_variant *var, int family, struct mbuf *m)
|
|||
if (error)
|
||||
rtcache_free(&iro->ir_ro);
|
||||
|
||||
mutex_exit(&iro->ir_lock);
|
||||
mutex_exit(iro->ir_lock);
|
||||
percpu_putref(sc->ipsec_ro_percpu);
|
||||
|
||||
return error;
|
||||
|
@ -906,9 +906,9 @@ ipsecif6_rtcache_free_pc(void *p, void *arg __unused, struct cpu_info *ci __unus
|
|||
{
|
||||
struct ipsec_ro *iro = p;
|
||||
|
||||
mutex_enter(&iro->ir_lock);
|
||||
mutex_enter(iro->ir_lock);
|
||||
rtcache_free(&iro->ir_ro);
|
||||
mutex_exit(&iro->ir_lock);
|
||||
mutex_exit(iro->ir_lock);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -960,7 +960,7 @@ ipsecif6_ctlinput(int cmd, const struct sockaddr *sa, void *d, void *eparg)
|
|||
return NULL;
|
||||
|
||||
iro = percpu_getref(sc->ipsec_ro_percpu);
|
||||
mutex_enter(&iro->ir_lock);
|
||||
mutex_enter(iro->ir_lock);
|
||||
dst6 = satocsin6(rtcache_getdst(&iro->ir_ro));
|
||||
/* XXX scope */
|
||||
if (dst6 == NULL)
|
||||
|
@ -969,7 +969,7 @@ ipsecif6_ctlinput(int cmd, const struct sockaddr *sa, void *d, void *eparg)
|
|||
/* flush route cache */
|
||||
rtcache_free(&iro->ir_ro);
|
||||
|
||||
mutex_exit(&iro->ir_lock);
|
||||
mutex_exit(iro->ir_lock);
|
||||
percpu_putref(sc->ipsec_ro_percpu);
|
||||
|
||||
return NULL;
|
||||
|
|
Loading…
Reference in New Issue