Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F157019522
D39180.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D39180.diff
View Options
diff --git a/sys/netlink/netlink_domain.c b/sys/netlink/netlink_domain.c
--- a/sys/netlink/netlink_domain.c
+++ b/sys/netlink/netlink_domain.c
@@ -46,6 +46,8 @@
#include <sys/syslog.h>
#include <sys/priv.h> /* priv_check */
+#include <sys/syscallsubr.h>
+
#include <netlink/netlink.h>
#include <netlink/netlink_ctl.h>
#include <netlink/netlink_var.h>
@@ -268,6 +270,18 @@
return (0);
}
+static int
+nlp_thread_init(struct thread *td, void *thunk)
+{
+ struct nlpcb *nlp = thunk;
+
+ nlp->nl_thread = td;
+
+ cpu_fork_kthread_handler(td, nl_taskqueue_handler, nlp);
+
+ return (0);
+}
+
static int
nl_pru_attach(struct socket *so, int proto, struct thread *td)
{
@@ -312,11 +326,20 @@
refcount_init(&nlp->nl_refcount, 1);
nl_init_io(nlp);
+ error = thread_create(td, NULL, nlp_thread_init, nlp);
+ if (error != 0) {
+ free(nlp, M_PCB);
+ return (error);
+ }
+ NL_LOG(LOG_DEBUG2, "thread %p created", nlp->nl_thread);
+
+#if 0
nlp->nl_taskqueue = taskqueue_create("netlink_socket", M_WAITOK,
taskqueue_thread_enqueue, &nlp->nl_taskqueue);
TASK_INIT(&nlp->nl_task, 0, nl_taskqueue_handler, nlp);
- taskqueue_start_threads(&nlp->nl_taskqueue, 1, PWAIT,
- "netlink_socket (PID %u)", nlp->nl_process_id);
+ taskqueue_start_threads_in_proc(&nlp->nl_taskqueue, 1, PWAIT,
+ td->td_proc, "netlink_socket (PID %u)", nlp->nl_process_id);
+#endif
NLCTL_WLOCK(ctl);
/* XXX: check ctl is still alive */
@@ -477,9 +500,26 @@
nlp->nl_active = false;
NLP_UNLOCK(nlp);
+ NL_LOG(LOG_DEBUG2, "Waking up thread %p", nlp->nl_thread);
+ wakeup_any(nlp);
+
+ NLP_LOCK(nlp);
+ if (!nlp->nl_dead) {
+ NL_LOG(LOG_DEBUG2, "Waiting till the thread dies");
+ mtx_sleep(&nlp->nl_epoch_ctx, &nlp->nl_lock, 0, "dying", 0);
+ }
+ NL_LOG(LOG_DEBUG2, "Thread %p set dead to %s", nlp->nl_thread, nlp->nl_dead ? "true" : "false");
+ MPASS(nlp->nl_dead);
+ NLP_UNLOCK(nlp);
+
+ int error = kern_thr_exit(nlp->nl_thread);
+ NL_LOG(LOG_DEBUG2, "thread_exit(%p) returned %d", nlp->nl_thread, error);
+
+#if 0
/* Wait till all scheduled work has been completed */
taskqueue_drain_all(nlp->nl_taskqueue);
taskqueue_free(nlp->nl_taskqueue);
+#endif
NLCTL_WLOCK(ctl);
NLP_LOCK(nlp);
diff --git a/sys/netlink/netlink_io.c b/sys/netlink/netlink_io.c
--- a/sys/netlink/netlink_io.c
+++ b/sys/netlink/netlink_io.c
@@ -129,7 +129,7 @@
{
if (!nlp->nl_task_pending) {
nlp->nl_task_pending = true;
- taskqueue_enqueue(nlp->nl_taskqueue, &nlp->nl_task);
+ wakeup_any(nlp);
NL_LOG(LOG_DEBUG3, "taskqueue scheduled");
} else {
NL_LOG(LOG_DEBUG3, "taskqueue schedule skipped");
@@ -301,13 +301,33 @@
}
void
-nl_taskqueue_handler(void *_arg, int pending)
+nl_taskqueue_handler(void *_arg)
{
struct nlpcb *nlp = (struct nlpcb *)_arg;
CURVNET_SET(nlp->nl_socket->so_vnet);
- nl_process_received(nlp);
+
+ NL_LOG(LOG_DEBUG2, "work thread %p for nlp %p started", nlp->nl_thread, nlp);
+
+ NLP_LOCK(nlp);
+ while (true) {
+ NL_LOG(LOG_DEBUG2, "sleeping / waiting for work");
+ mtx_sleep(nlp, &nlp->nl_lock, 0, "nlp sleep", 0);
+ NL_LOG(LOG_DEBUG2, "worken up, socket is %s", nlp->nl_active ? "active":"dying");
+ if (__predict_false(!nlp->nl_active))
+ break;
+ NLP_UNLOCK(nlp);
+ nl_process_received(nlp);
+ NLP_LOCK(nlp);
+ }
+ nlp->nl_dead = true;
+ NL_LOG(LOG_DEBUG2, "SET dead to true");
+ NLP_UNLOCK(nlp);
+
CURVNET_RESTORE();
+
+ wakeup_one(&nlp->nl_epoch_ctx);
+ NL_LOG(LOG_DEBUG2, "work thread %p for nlp %p ended", nlp->nl_thread, nlp);
}
static __noinline void
diff --git a/sys/netlink/netlink_var.h b/sys/netlink/netlink_var.h
--- a/sys/netlink/netlink_var.h
+++ b/sys/netlink/netlink_var.h
@@ -61,10 +61,10 @@
bool nl_task_pending;
bool nl_tx_blocked; /* No new requests accepted */
bool nl_linux; /* true if running under compat */
+ bool nl_dead;
struct nl_io_queue rx_queue;
struct nl_io_queue tx_queue;
- struct taskqueue *nl_taskqueue;
- struct task nl_task;
+ struct thread *nl_thread;
struct ucred *nl_cred; /* Copy of nl_socket->so_cred */
uint64_t nl_dropped_bytes;
uint64_t nl_dropped_messages;
@@ -139,7 +139,7 @@
void nl_init_io(struct nlpcb *nlp);
void nl_free_io(struct nlpcb *nlp);
-void nl_taskqueue_handler(void *_arg, int pending);
+void nl_taskqueue_handler(void *_arg);
int nl_receive_async(struct mbuf *m, struct socket *so);
void nl_process_receive_locked(struct nlpcb *nlp);
diff --git a/sys/netlink/route/iface.c b/sys/netlink/route/iface.c
--- a/sys/netlink/route/iface.c
+++ b/sys/netlink/route/iface.c
@@ -928,14 +928,11 @@
}
static void
-rtnl_handle_ifevent(struct ifnet *ifp, int nlmsg_type, bool modify, int if_flags_mask)
+rtnl_handle_ifevent(struct ifnet *ifp, int nlmsg_type, int if_flags_mask)
{
struct nlmsghdr hdr = { .nlmsg_type = nlmsg_type };
struct nl_writer nw = {};
- if (modify)
- hdr.nlmsg_flags |= NLM_F_REPLACE;
-
if (!nl_has_listeners(NETLINK_ROUTE, RTNLGRP_LINK))
return;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, May 18, 11:52 PM (11 h, 40 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
33277536
Default Alt Text
D39180.diff (4 KB)
Attached To
Mode
D39180: netlink: use process threads
Attached
Detach File
Event Timeline
Log In to Comment