4444#include "liburing.h"
4545#include "helpers.h"
4646
47+ enum {
48+ AFFINITY_MODE_NONE ,
49+ AFFINITY_MODE_SAME ,
50+ AFFINITY_MODE_DIFFERENT ,
51+
52+ __AFFINITY_MODE_MAX ,
53+ };
54+
4755enum {
4856 RQ_ALLOC_USER ,
4957 RQ_ALLOC_KERNEL ,
@@ -81,6 +89,7 @@ static const char *cfg_ifname;
8189static int cfg_queue_id = -1 ;
8290static bool cfg_verify_data = false;
8391static size_t cfg_size = 0 ;
92+ static unsigned cfg_affinity_mode = AFFINITY_MODE_NONE ;
8493static unsigned cfg_rq_alloc_mode = RQ_ALLOC_USER ;
8594static unsigned cfg_area_type = AREA_TYPE_NORMAL ;
8695static struct sockaddr_in6 cfg_addr ;
@@ -99,6 +108,51 @@ static int dmabuf_fd;
99108static int memfd ;
100109
101110static int listen_fd ;
111+ static int target_cpu = -1 ;
112+
113+ static int get_sock_cpu (int sockfd )
114+ {
115+ int cpu ;
116+ socklen_t len = sizeof (cpu );
117+
118+ if (getsockopt (sockfd , SOL_SOCKET , SO_INCOMING_CPU , & cpu , & len ))
119+ t_error (1 , errno , "getsockopt failed\n" );
120+ return cpu ;
121+ }
122+
123+ static void set_affinity (int sockfd )
124+ {
125+ int new_cpu = -1 ;
126+ int sock_cpu ;
127+ cpu_set_t mask ;
128+
129+ if (cfg_affinity_mode == AFFINITY_MODE_NONE )
130+ return ;
131+
132+ sock_cpu = get_sock_cpu (sockfd );
133+ if (sock_cpu == -1 )
134+ t_error (1 , 0 , "Can't socket's CPU" );
135+
136+ if (cfg_affinity_mode == AFFINITY_MODE_SAME ) {
137+ new_cpu = sock_cpu ;
138+ } else if (cfg_affinity_mode == AFFINITY_MODE_DIFFERENT ) {
139+ if (target_cpu != -1 && target_cpu != sock_cpu )
140+ new_cpu = target_cpu ;
141+ else
142+ new_cpu = sock_cpu ^ 1 ;
143+ }
144+
145+ if (target_cpu != -1 && new_cpu != target_cpu ) {
146+ printf ("Couldn't set affinity for multi socket setup\n" );
147+ return ;
148+ }
149+
150+ CPU_ZERO (& mask );
151+ CPU_SET (new_cpu , & mask );
152+ if (sched_setaffinity (0 , sizeof (mask ), & mask ))
153+ t_error (1 , errno , "sched_setaffinity() failed\n" );
154+ target_cpu = new_cpu ;
155+ }
102156
103157static struct zc_conn * get_connection (__u64 user_data )
104158{
@@ -309,6 +363,7 @@ static void process_accept(struct io_uring *ring, struct io_uring_cqe *cqe)
309363 memset (conn , 0 , sizeof (* conn ));
310364 conn -> sockfd = cqe -> res ;
311365 print_socket_info (conn -> sockfd );
366+ set_affinity (conn -> sockfd );
312367 add_recvzc (ring , conn , cfg_size );
313368
314369 add_accept (ring , listen_fd );
@@ -504,7 +559,7 @@ static void parse_opts(int argc, char **argv)
504559 if (argc <= 1 )
505560 usage (argv [0 ]);
506561
507- while ((c = getopt (argc , argv , "vp:i:q:s:r:A:S:C:R:" )) != -1 ) {
562+ while ((c = getopt (argc , argv , "vp:i:q:s:r:A:S:C:R:c: " )) != -1 ) {
508563 switch (c ) {
509564 case 'p' :
510565 cfg_port = strtoul (optarg , NULL , 0 );
@@ -540,6 +595,10 @@ static void parse_opts(int argc, char **argv)
540595 case 'R' :
541596 cfg_rq_entries = strtoul (optarg , NULL , 0 );
542597 break ;
598+ case 'c' :
599+ cfg_affinity_mode = strtoul (optarg , NULL , 0 );
600+ if (cfg_affinity_mode >= __AFFINITY_MODE_MAX )
601+ t_error (1 , 0 , "Invalid affinity mode" );
543602 }
544603 }
545604
0 commit comments