Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F105560110
D24914.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D24914.diff
View Options
Index: head/sys/netinet/in.c
===================================================================
--- head/sys/netinet/in.c
+++ head/sys/netinet/in.c
@@ -998,6 +998,13 @@
in_pcbpurgeif0(&V_ulitecbinfo, ifp);
in_purgemaddrs(ifp);
IN_MULTI_UNLOCK();
+
+ /*
+ * Make sure all multicast deletions invoking if_ioctl() are
+ * completed before returning. Else we risk accessing a freed
+ * ifnet structure pointer.
+ */
+ inm_release_wait(NULL);
}
/*
Index: head/sys/netinet/in_mcast.c
===================================================================
--- head/sys/netinet/in_mcast.c
+++ head/sys/netinet/in_mcast.c
@@ -224,18 +224,37 @@
}
#endif
-static struct task free_task;
+/*
+ * Interface detach can happen in a taskqueue thread context, so we must use a
+ * dedicated thread to avoid deadlocks when draining inm_release tasks.
+ */
+TASKQUEUE_DEFINE_THREAD(inm_free);
+static struct task inm_free_task;
static struct in_multi_head inm_free_list = SLIST_HEAD_INITIALIZER();
static void inm_release_task(void *arg __unused, int pending __unused);
static void
inm_init(void *arg __unused)
{
- TASK_INIT(&free_task, 0, inm_release_task, NULL);
+ TASK_INIT(&inm_free_task, 0, inm_release_task, NULL);
}
SYSINIT(inm_init, SI_SUB_TASKQ, SI_ORDER_ANY, inm_init, NULL);
void
+inm_release_wait(void *arg __unused)
+{
+
+ /*
+ * Make sure all pending multicast addresses are freed before
+ * the VNET or network device is destroyed:
+ */
+ taskqueue_drain(taskqueue_inm_free, &inm_free_task);
+}
+#ifdef VIMAGE
+VNET_SYSUNINIT(inm_release_wait, SI_SUB_PROTO_DOMAIN, SI_ORDER_FIRST, inm_release_wait, NULL);
+#endif
+
+void
inm_release_list_deferred(struct in_multi_head *inmh)
{
@@ -244,7 +263,7 @@
mtx_lock(&in_multi_free_mtx);
SLIST_CONCAT(&inm_free_list, inmh, in_multi, inm_nrele);
mtx_unlock(&in_multi_free_mtx);
- taskqueue_enqueue(taskqueue_thread, &free_task);
+ taskqueue_enqueue(taskqueue_inm_free, &inm_free_task);
}
void
Index: head/sys/netinet/in_var.h
===================================================================
--- head/sys/netinet/in_var.h
+++ head/sys/netinet/in_var.h
@@ -450,6 +450,7 @@
int inm_record_source(struct in_multi *inm, const in_addr_t);
void inm_release_deferred(struct in_multi *);
void inm_release_list_deferred(struct in_multi_head *);
+void inm_release_wait(void *);
struct in_multi *
in_addmulti(struct in_addr *, struct ifnet *);
int in_joingroup(struct ifnet *, const struct in_addr *,
Index: head/sys/netinet6/in6_ifattach.c
===================================================================
--- head/sys/netinet6/in6_ifattach.c
+++ head/sys/netinet6/in6_ifattach.c
@@ -871,7 +871,7 @@
* completed before returning. Else we risk accessing a freed
* ifnet structure pointer.
*/
- in6m_release_wait();
+ in6m_release_wait(NULL);
}
void
Index: head/sys/netinet6/in6_mcast.c
===================================================================
--- head/sys/netinet6/in6_mcast.c
+++ head/sys/netinet6/in6_mcast.c
@@ -539,10 +539,18 @@
}
void
-in6m_release_wait(void)
+in6m_release_wait(void *arg __unused)
{
+
+ /*
+ * Make sure all pending multicast addresses are freed before
+ * the VNET or network device is destroyed:
+ */
taskqueue_drain_all(taskqueue_in6m_free);
}
+#ifdef VIMAGE
+VNET_SYSUNINIT(in6m_release_wait, SI_SUB_PROTO_DOMAIN, SI_ORDER_FIRST, in6m_release_wait, NULL);
+#endif
void
in6m_disconnect_locked(struct in6_multi_head *inmh, struct in6_multi *inm)
Index: head/sys/netinet6/in6_var.h
===================================================================
--- head/sys/netinet6/in6_var.h
+++ head/sys/netinet6/in6_var.h
@@ -870,7 +870,7 @@
void in6m_print(const struct in6_multi *);
int in6m_record_source(struct in6_multi *, const struct in6_addr *);
void in6m_release_list_deferred(struct in6_multi_head *);
-void in6m_release_wait(void);
+void in6m_release_wait(void *);
void ip6_freemoptions(struct ip6_moptions *);
int ip6_getmoptions(struct inpcb *, struct sockopt *);
int ip6_setmoptions(struct inpcb *, struct sockopt *);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Dec 18, 4:27 PM (18 h, 20 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15490259
Default Alt Text
D24914.diff (3 KB)
Attached To
Mode
D24914: Make sure the multicast release tasks are properly drained when destroying VNET and IFNET
Attached
Detach File
Event Timeline
Log In to Comment