Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/netipsec Fix a deadlock happening if !NET_MPSAFE
details: https://anonhg.NetBSD.org/src/rev/f2e49f158edc
branches: trunk
changeset: 357848:f2e49f158edc
user: ozaki-r <ozaki-r%NetBSD.org@localhost>
date: Thu Nov 30 02:45:12 2017 +0000
description:
Fix a deadlock happening if !NET_MPSAFE
If NET_MPSAFE isn't set, key_timehandler_work is executed with holding
softnet_lock. This means that localcount_drain can be called with holding
softnet_lock resulting in a deadlock that localcount_drain waits for packet
processing to release a reference to SP/SA while network processing is prevented
by softnet_lock.
Fix the deadlock by not taking softnet_lock in key_timehandler_work. It's okay
because IPsec is MP-safe even if !NET_MPSAFE. Note that the change also needs
to enable pserialize_perform because the IPsec code can be run in parallel now.
Reported by christos@
diffstat:
sys/netipsec/key.c | 20 ++------------------
1 files changed, 2 insertions(+), 18 deletions(-)
diffs (116 lines):
diff -r f04422a354de -r f2e49f158edc sys/netipsec/key.c
--- a/sys/netipsec/key.c Thu Nov 30 02:43:49 2017 +0000
+++ b/sys/netipsec/key.c Thu Nov 30 02:45:12 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: key.c,v 1.244 2017/11/30 02:43:49 ozaki-r Exp $ */
+/* $NetBSD: key.c,v 1.245 2017/11/30 02:45:12 ozaki-r Exp $ */
/* $FreeBSD: src/sys/netipsec/key.c,v 1.3.2.3 2004/02/14 22:23:23 bms Exp $ */
/* $KAME: key.c,v 1.191 2001/06/27 10:46:49 sakane Exp $ */
@@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.244 2017/11/30 02:43:49 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.245 2017/11/30 02:45:12 ozaki-r Exp $");
/*
* This code is referred to RFC 2367
@@ -800,7 +800,6 @@
return 0;
}
-#ifdef NET_MPSAFE
static void
key_spd_pserialize_perform(void)
{
@@ -818,7 +817,6 @@
key_spd.psz_performing = false;
cv_broadcast(&key_spd.cv_psz);
}
-#endif
/*
* Remove the sp from the key_spd.splist and wait for references to the sp
@@ -836,10 +834,8 @@
/* Invalidate all cached SPD pointers in the PCBs. */
ipsec_invalpcbcacheall();
-#ifdef NET_MPSAFE
KDASSERT(mutex_ownable(softnet_lock));
key_spd_pserialize_perform();
-#endif
localcount_drain(&sp->localcount, &key_spd.cv_lc, &key_spd.lock);
}
@@ -1493,7 +1489,6 @@
}
#endif
-#ifdef NET_MPSAFE
static void
key_sad_pserialize_perform(void)
{
@@ -1511,7 +1506,6 @@
key_sad.psz_performing = false;
cv_broadcast(&key_sad.cv_psz);
}
-#endif
/*
* Remove the sav from the savlist of its sah and wait for references to the sav
@@ -1525,10 +1519,8 @@
SAVLIST_WRITER_REMOVE(sav);
-#ifdef NET_MPSAFE
KDASSERT(mutex_ownable(softnet_lock));
key_sad_pserialize_perform();
-#endif
localcount_drain(&sav->localcount, &key_sad.cv_lc, &key_sad.lock);
}
@@ -1567,10 +1559,8 @@
KEY_SA_UNREF(&sav);
mutex_enter(&key_sad.lock);
-#ifdef NET_MPSAFE
KDASSERT(mutex_ownable(softnet_lock));
key_sad_pserialize_perform();
-#endif
localcount_drain(&sav->localcount, &key_sad.cv_lc, &key_sad.lock);
mutex_exit(&key_sad.lock);
@@ -3048,10 +3038,8 @@
/* Remove from the sah list */
SAHLIST_WRITER_REMOVE(sah);
-#ifdef NET_MPSAFE
KDASSERT(mutex_ownable(softnet_lock));
key_sad_pserialize_perform();
-#endif
localcount_drain(&sah->localcount, &key_sad.cv_lc, &key_sad.lock);
}
@@ -4862,13 +4850,10 @@
key_timehandler_work(struct work *wk, void *arg)
{
time_t now = time_uptime;
- IPSEC_DECLARE_LOCK_VARIABLE;
/* We can allow enqueuing another work at this point */
atomic_swap_uint(&key_timehandler_work_enqueued, 0);
- IPSEC_ACQUIRE_GLOBAL_LOCKS();
-
key_timehandler_spd(now);
key_timehandler_sad(now);
key_timehandler_acq(now);
@@ -4879,7 +4864,6 @@
/* do exchange to tick time !! */
callout_reset(&key_timehandler_ch, hz, key_timehandler, NULL);
- IPSEC_RELEASE_GLOBAL_LOCKS();
return;
}
Home |
Main Index |
Thread Index |
Old Index