Skip to content

Commit 1c7a08e

Browse files
committed
affinity
Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
1 parent 6bec161 commit 1c7a08e

File tree

1 file changed

+60
-1
lines changed

1 file changed

+60
-1
lines changed

examples/zcrx.c

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,14 @@
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+
4755
enum {
4856
RQ_ALLOC_USER,
4957
RQ_ALLOC_KERNEL,
@@ -81,6 +89,7 @@ static const char *cfg_ifname;
8189
static int cfg_queue_id = -1;
8290
static bool cfg_verify_data = false;
8391
static size_t cfg_size = 0;
92+
static unsigned cfg_affinity_mode = AFFINITY_MODE_NONE;
8493
static unsigned cfg_rq_alloc_mode = RQ_ALLOC_USER;
8594
static unsigned cfg_area_type = AREA_TYPE_NORMAL;
8695
static struct sockaddr_in6 cfg_addr;
@@ -99,6 +108,51 @@ static int dmabuf_fd;
99108
static int memfd;
100109

101110
static 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

103157
static 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

Comments
 (0)