From cecfaf9bede9665d6a10f1e575cd5d575450cff7 Mon Sep 17 00:00:00 2001 From: Kristof Provost Date: Wed, 10 Mar 2021 22:56:11 +0100 Subject: [PATCH] pf: Fully remove interrupt events on vnet cleanup swi_remove() removes the software interrupt handler but does not remove the associated interrupt event. This is visible when creating and remove a vnet jail in `procstat -t 12`. We can remove it manually with intr_event_destroy(). PR: 254171 MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D29211 --- sys/net/pfvar.h | 2 ++ sys/netpfil/pf/if_pfsync.c | 10 ++++++++-- sys/netpfil/pf/pf.c | 1 + sys/netpfil/pf/pf_ioctl.c | 8 ++++++-- 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index 31be6b7a833d..6102d6186cd2 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -1390,6 +1390,8 @@ VNET_DECLARE(struct pf_srchash *, pf_srchash); VNET_DECLARE(void *, pf_swi_cookie); #define V_pf_swi_cookie VNET(pf_swi_cookie) +VNET_DECLARE(struct intr_event *, pf_swi_ie); +#define V_pf_swi_ie VNET(pf_swi_ie) VNET_DECLARE(uint64_t, pf_stateid[MAXCPU]); #define V_pf_stateid VNET(pf_stateid) diff --git a/sys/netpfil/pf/if_pfsync.c b/sys/netpfil/pf/if_pfsync.c index 059300f6a6a7..cf2ff2ef0926 100644 --- a/sys/netpfil/pf/if_pfsync.c +++ b/sys/netpfil/pf/if_pfsync.c @@ -254,6 +254,8 @@ VNET_DEFINE_STATIC(struct pfsync_softc *, pfsyncif) = NULL; #define V_pfsyncif VNET(pfsyncif) VNET_DEFINE_STATIC(void *, pfsync_swi_cookie) = NULL; #define V_pfsync_swi_cookie VNET(pfsync_swi_cookie) +VNET_DEFINE_STATIC(struct intr_event *, pfsync_swi_ie); +#define V_pfsync_swi_ie VNET(pfsync_swi_ie) VNET_DEFINE_STATIC(struct pfsyncstats, pfsyncstats); #define V_pfsyncstats VNET(pfsyncstats) VNET_DEFINE_STATIC(int, pfsync_carp_adj) = CARP_MAXSKEW; @@ -2472,7 +2474,7 @@ vnet_pfsync_init(const void *unused __unused) V_pfsync_cloner = if_clone_simple(pfsyncname, pfsync_clone_create, pfsync_clone_destroy, 1); - error = swi_add(NULL, pfsyncname, pfsyncintr, V_pfsyncif, + error = swi_add(&V_pfsync_swi_ie, pfsyncname, pfsyncintr, V_pfsyncif, SWI_NET, INTR_MPSAFE, &V_pfsync_swi_cookie); if (error) { if_clone_detach(V_pfsync_cloner); @@ -2487,11 +2489,15 @@ VNET_SYSINIT(vnet_pfsync_init, SI_SUB_PROTO_FIREWALL, SI_ORDER_ANY, static void vnet_pfsync_uninit(const void *unused __unused) { + int ret; pfsync_pointers_uninit(); if_clone_detach(V_pfsync_cloner); - swi_remove(V_pfsync_swi_cookie); + ret = swi_remove(V_pfsync_swi_cookie); + MPASS(ret == 0); + ret = intr_event_destroy(V_pfsync_swi_ie); + MPASS(ret == 0); } VNET_SYSUNINIT(vnet_pfsync_uninit, SI_SUB_PROTO_FIREWALL, SI_ORDER_FOURTH, diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index f088f117b8e8..752e8a7eef1a 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -388,6 +388,7 @@ SYSCTL_ULONG(_net_pf, OID_AUTO, request_maxcount, CTLFLAG_RWTUN, &pf_ioctl_maxcount, 0, "Maximum number of tables, addresses, ... in a single ioctl() call"); VNET_DEFINE(void *, pf_swi_cookie); +VNET_DEFINE(struct intr_event *, pf_swi_ie); VNET_DEFINE(uint32_t, pf_hashseed); #define V_pf_hashseed VNET(pf_hashseed) diff --git a/sys/netpfil/pf/pf_ioctl.c b/sys/netpfil/pf/pf_ioctl.c index 977f0debacaa..c930a67ecf80 100644 --- a/sys/netpfil/pf/pf_ioctl.c +++ b/sys/netpfil/pf/pf_ioctl.c @@ -331,7 +331,7 @@ pfattach_vnet(void) for (int i = 0; i < SCNT_MAX; i++) V_pf_status.scounters[i] = counter_u64_alloc(M_WAITOK); - if (swi_add(NULL, "pf send", pf_intr, curvnet, SWI_NET, + if (swi_add(&V_pf_swi_ie, "pf send", pf_intr, curvnet, SWI_NET, INTR_MPSAFE, &V_pf_swi_cookie) != 0) /* XXXGL: leaked all above. */ return; @@ -4670,6 +4670,7 @@ pf_load(void) static void pf_unload_vnet(void) { + int ret; V_pf_vnet_active = 0; V_pf_status.running = 0; @@ -4679,7 +4680,10 @@ pf_unload_vnet(void) shutdown_pf(); PF_RULES_WUNLOCK(); - swi_remove(V_pf_swi_cookie); + ret = swi_remove(V_pf_swi_cookie); + MPASS(ret == 0); + ret = intr_event_destroy(V_pf_swi_ie); + MPASS(ret == 0); pf_unload_vnet_purge();