c-taylor commented on code in PR #13086:
URL: https://github.com/apache/trafficserver/pull/13086#discussion_r3083382360


##########
src/iocore/net/UnixNet.cc:
##########
@@ -200,3 +205,54 @@ initialize_thread_for_net(EThread *thread)
 #endif
   thread->ep = ep;
 }
+
+// Late-initialization continuation for ET_NET threads.  Runs on each
+// thread after start_HttpProxyServer() has created all listen sockets
+// and all initialization FDs (eventfds, cache disks, DNS sockets, log
+// files, plugin FDs) are in place.
+//
+// On Linux, when accept is performed directly on ET_NET threads
+// (accept_threads == 0), this calls unshare(CLONE_FILES) to give each
+// thread its own private kernel FD table, eliminating spinlock
+// contention on accept4/close.  The underlying kernel objects
+// (struct file) are shared, so cross-thread eventfd signalling and
+// shared cache-disk FDs keep working.
+//
+// This is NOT safe with dedicated accept threads (accept_threads > 0)
+// because accepted sockets are created on the accept thread and handed
+// off to ET_NET by FD number — after unshare those FDs would not exist
+// in the ET_NET thread's private table.
+
+namespace
+{
+struct ExecThrLateCont : public Continuation {
+  int
+  mainEvent(int /* event ATS_UNUSED */, Event * /* e ATS_UNUSED */)
+  {
+#if defined(__linux__)
+    int accept_threads = 
RecGetRecordInt("proxy.config.accept_threads").value_or(0);
+    if (accept_threads > 0) {
+      Dbg(dbg_ctl_iocore_net, "ET_NET thread %d: skipping unshare 
(accept_threads=%d)", this_ethread()->id, accept_threads);
+    } else if (unshare(CLONE_FILES) < 0) {
+      Warning("ET_NET thread %d: unshare(CLONE_FILES) failed: %s", 
this_ethread()->id, strerror(errno));
+    } else {
+      Dbg(dbg_ctl_iocore_net, "ET_NET thread %d: FD table unshared", 
this_ethread()->id);
+    }
+#endif
+    delete this;
+    return EVENT_DONE;
+  }
+
+  ExecThrLateCont() : Continuation(nullptr) { 
SET_HANDLER(&ExecThrLateCont::mainEvent); }
+};
+} // end anonymous namespace
+
+void
+exec_thr_late_init()
+{
+  int n = eventProcessor.thread_group[ET_NET]._count;
+  for (int i = 0; i < n; i++) {
+    eventProcessor.thread_group[ET_NET]._thread[i]->schedule_imm(new 
ExecThrLateCont());
+  }
+  Note("Scheduled exec_thr_late_init() on %d ET_NET threads", n);

Review Comment:
   Agree



##########
src/iocore/net/UnixNet.cc:
##########
@@ -200,3 +205,54 @@ initialize_thread_for_net(EThread *thread)
 #endif
   thread->ep = ep;
 }
+
+// Late-initialization continuation for ET_NET threads.  Runs on each
+// thread after start_HttpProxyServer() has created all listen sockets
+// and all initialization FDs (eventfds, cache disks, DNS sockets, log
+// files, plugin FDs) are in place.
+//
+// On Linux, when accept is performed directly on ET_NET threads
+// (accept_threads == 0), this calls unshare(CLONE_FILES) to give each
+// thread its own private kernel FD table, eliminating spinlock
+// contention on accept4/close.  The underlying kernel objects
+// (struct file) are shared, so cross-thread eventfd signalling and
+// shared cache-disk FDs keep working.
+//
+// This is NOT safe with dedicated accept threads (accept_threads > 0)
+// because accepted sockets are created on the accept thread and handed
+// off to ET_NET by FD number — after unshare those FDs would not exist
+// in the ET_NET thread's private table.
+
+namespace
+{
+struct ExecThrLateCont : public Continuation {
+  int
+  mainEvent(int /* event ATS_UNUSED */, Event * /* e ATS_UNUSED */)
+  {
+#if defined(__linux__)
+    int accept_threads = 
RecGetRecordInt("proxy.config.accept_threads").value_or(0);
+    if (accept_threads > 0) {
+      Dbg(dbg_ctl_iocore_net, "ET_NET thread %d: skipping unshare 
(accept_threads=%d)", this_ethread()->id, accept_threads);
+    } else if (unshare(CLONE_FILES) < 0) {
+      Warning("ET_NET thread %d: unshare(CLONE_FILES) failed: %s", 
this_ethread()->id, strerror(errno));
+    } else {
+      Dbg(dbg_ctl_iocore_net, "ET_NET thread %d: FD table unshared", 
this_ethread()->id);
+    }

Review Comment:
   Agree



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to