git: cd7306bb1fd1 - main - ip_mroute: split mrouter interface deactivation and if_free
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 04 Feb 2022 09:25:26 UTC
The branch main has been updated by wma:
URL: https://cgit.FreeBSD.org/src/commit/?id=cd7306bb1fd1c4f2b2875bb7947ef5ee905f5f26
commit cd7306bb1fd1c4f2b2875bb7947ef5ee905f5f26
Author: Sylvian Meygret <sylvain.meygret.external@stormshield.eu>
AuthorDate: 2022-02-04 09:19:55 +0000
Commit: Wojciech Macek <wma@FreeBSD.org>
CommitDate: 2022-02-04 09:25:07 +0000
ip_mroute: split mrouter interface deactivation and if_free
Move if_free outside MRW_LOCK. This will silence LOR message
which might appere during deinitialization.
---
sys/netinet/ip_mroute.c | 29 +++++++++++++++++++++++------
1 file changed, 23 insertions(+), 6 deletions(-)
diff --git a/sys/netinet/ip_mroute.c b/sys/netinet/ip_mroute.c
index c678acd650c0..99ec2952de88 100644
--- a/sys/netinet/ip_mroute.c
+++ b/sys/netinet/ip_mroute.c
@@ -316,7 +316,7 @@ static void bw_upcalls_send(void);
static int del_bw_upcall(struct bw_upcall *);
static int del_mfc(struct mfcctl2 *);
static int del_vif(vifi_t);
-static int del_vif_locked(vifi_t);
+static int del_vif_locked(vifi_t, struct ifnet **);
static void expire_bw_upcalls_send(void *);
static void expire_mfc(struct mfc *);
static void expire_upcalls(void *);
@@ -621,7 +621,8 @@ static void
if_detached_event(void *arg __unused, struct ifnet *ifp)
{
vifi_t vifi;
- u_long i;
+ u_long i, vifi_cnt = 0;
+ struct ifnet *free_ptr;
MRW_WLOCK();
@@ -650,10 +651,20 @@ if_detached_event(void *arg __unused, struct ifnet *ifp)
}
}
}
- del_vif_locked(vifi);
+ del_vif_locked(vifi, &free_ptr);
+ if (free_ptr != NULL)
+ vifi_cnt++;
}
MRW_WUNLOCK();
+
+ /*
+ * Free IFP. We don't have to use free_ptr here as it is the same
+ * that ifp. Perform free as many times as required in case
+ * refcount is greater than 1.
+ */
+ for (i = 0; i < vifi_cnt; i++)
+ if_free(ifp);
}
static void
@@ -982,10 +993,12 @@ add_vif(struct vifctl *vifcp)
* Delete a vif from the vif table
*/
static int
-del_vif_locked(vifi_t vifi)
+del_vif_locked(vifi_t vifi, struct ifnet **ifp_free)
{
struct vif *vifp;
+ *ifp_free = NULL;
+
MRW_WLOCK_ASSERT();
if (vifi >= V_numvifs) {
@@ -1004,7 +1017,7 @@ del_vif_locked(vifi_t vifi)
if (vifp->v_ifp) {
if (vifp->v_ifp == V_multicast_register_if)
V_multicast_register_if = NULL;
- if_free(vifp->v_ifp);
+ *ifp_free = vifp->v_ifp;
}
}
@@ -1027,11 +1040,15 @@ static int
del_vif(vifi_t vifi)
{
int cc;
+ struct ifnet *free_ptr;
MRW_WLOCK();
- cc = del_vif_locked(vifi);
+ cc = del_vif_locked(vifi, &free_ptr);
MRW_WUNLOCK();
+ if (free_ptr)
+ if_free(free_ptr);
+
return cc;
}