diff --git a/doc/admin-guide/files/records.yaml.en.rst b/doc/admin-guide/files/records.yaml.en.rst index ba94d190b7e..0069fe72f3b 100644 --- a/doc/admin-guide/files/records.yaml.en.rst +++ b/doc/admin-guide/files/records.yaml.en.rst @@ -5055,9 +5055,11 @@ Sockets PACKET_MARK (16) PACKET_TOS (32) TCP_NOTSENT_LOWAT (64) + INCOMING_CPU (128) Note: If MPTCP is enabled, TCP_NODELAY is only supported on Linux kernels 5.17+. TCP_FASTOPEN and TCP_NOTSENT_LOWAT socket options are currently not supported. + .. note:: This is a bitmask and you need to decide what bits to set. Therefore, @@ -5069,6 +5071,20 @@ Sockets To allow TCP Fast Open for client sockets on Linux, bit 2 of the ``net.ipv4.tcp_fastopen`` sysctl must be set. +.. note:: + + As for SO_INCOMING_CPU, using it with SO_REUSEPORT and exec_thread affinity 4 is recommended. + + .. code-block:: yaml + + ts: + accept_threads: 0 + exec_thread: + listen: 1 + affinity: 4 + net: + sock_option_flag_in: 0x80 + .. ts:cv:: CONFIG proxy.config.net.sock_send_buffer_size_out INT 0 :overridable: diff --git a/include/iocore/eventsystem/EThread.h b/include/iocore/eventsystem/EThread.h index 9353580e4d7..8e404e7540b 100644 --- a/include/iocore/eventsystem/EThread.h +++ b/include/iocore/eventsystem/EThread.h @@ -34,6 +34,11 @@ #include "iocore/eventsystem/ProtectedQueue.h" #include "tsutil/Histogram.h" +#if TS_USE_HWLOC +struct hwloc_obj; +using hwloc_obj_t = hwloc_obj *; +#endif + // TODO: This would be much nicer to have "run-time" configurable (or something) #define PER_THREAD_DATA (1024 * 1024) @@ -333,9 +338,15 @@ class EThread : public Thread static constexpr int NO_ETHREAD_ID = -1; int id = NO_ETHREAD_ID; - unsigned int event_types = 0; - bool is_event_type(EventType et); - void set_event_type(EventType et); + +#if TS_USE_HWLOC + hwloc_obj_t hwloc_obj = nullptr; +#endif + + unsigned int event_types = 0; + + bool is_event_type(EventType et); + void set_event_type(EventType et); // Private Interface diff --git a/include/iocore/net/NetVCOptions.h b/include/iocore/net/NetVCOptions.h index 07e8007b53d..bdb74481a1e 100644 --- a/include/iocore/net/NetVCOptions.h +++ b/include/iocore/net/NetVCOptions.h @@ -145,6 +145,8 @@ struct NetVCOptions { static uint32_t const SOCK_OPT_PACKET_TOS = 32; /// Value for TCP_NOTSENT_LOWAT @c sockopt_flags static uint32_t const SOCK_OPT_TCP_NOTSENT_LOWAT = 64; + /// Value for SO_INCOMING_CPU @c sockopt_flags + static uint32_t const SOCK_OPT_INCOMING_CPU = 128; uint32_t packet_mark; uint32_t packet_tos; diff --git a/src/iocore/eventsystem/UnixEventProcessor.cc b/src/iocore/eventsystem/UnixEventProcessor.cc index fd8dfa53458..aae8e76f4c8 100644 --- a/src/iocore/eventsystem/UnixEventProcessor.cc +++ b/src/iocore/eventsystem/UnixEventProcessor.cc @@ -266,6 +266,8 @@ ThreadAffinityInitializer::set_affinity(int, Event *) if (obj_count > 0) { // Get our `obj` instance with index based on the thread number we are on. hwloc_obj_t obj = hwloc_get_obj_by_type(ink_get_topology(), obj_type, t->id % obj_count); + t->hwloc_obj = obj; + #if HWLOC_API_VERSION >= 0x00010100 int cpu_mask_len = hwloc_bitmap_snprintf(nullptr, 0, obj->cpuset) + 1; char *cpu_mask = static_cast(alloca(cpu_mask_len)); diff --git a/src/iocore/net/Connection.cc b/src/iocore/net/Connection.cc index 2b77dfd1694..8af918dd759 100644 --- a/src/iocore/net/Connection.cc +++ b/src/iocore/net/Connection.cc @@ -27,11 +27,17 @@ Commonality across all platforms -- move out as required. **************************************************************************/ -#include "tscore/ink_platform.h" -#include "tscore/ink_defs.h" #include "P_Net.h" +#include "tscore/ink_defs.h" +#include "tscore/ink_platform.h" +#include "tscore/ink_sock.h" + +#if TS_USE_HWLOC +#include +#endif + #ifdef SO_ACCEPTFILTER #include #include @@ -49,6 +55,7 @@ DbgCtl dbg_ctl_http_tproxy{"http_tproxy"}; DbgCtl dbg_ctl_proxyprotocol{"proxyprotocol"}; DbgCtl dbg_ctl_iocore_net_server{"iocore_net_server"}; DbgCtl dbg_ctl_connection{"connection"}; +DbgCtl dbg_ctl_iocore_thread{"iocore_thread"}; } // end anonymous namespace @@ -238,6 +245,23 @@ Server::setup_fd_for_listen(bool non_blocking, const NetProcessor::AcceptOptions #endif } +#ifdef SO_INCOMING_CPU + if (opt.sockopt_flags & NetVCOptions::SOCK_OPT_INCOMING_CPU) { + int cpu = 0; + EThread *ethread = this_ethread(); + +#ifdef TS_USE_HWLOC + cpu = ethread->hwloc_obj->os_index; +#else + cpu = ethread->id; +#endif + if (safe_setsockopt(fd, SOL_SOCKET, SO_INCOMING_CPU, &cpu, sizeof(cpu)) < 0) { + goto Lerror; + } + Dbg(dbg_ctl_iocore_thread, "SO_INCOMING_CPU - fd=%d cpu=%d", fd, cpu); + } +#endif + if ((opt.sockopt_flags & NetVCOptions::SOCK_OPT_NO_DELAY) && setsockopt_on(fd, IPPROTO_TCP, TCP_NODELAY) < 0) { goto Lerror; }