28 #include <sys/epoll.h> 29 #include <sys/eventfd.h> 37 static void slowpath_block(uint32_t cur_ts);
38 static void timeout_trigger(
struct timeout *to, uint8_t type,
void *opaque);
39 static void signal_tas_ready(
void);
40 void flexnic_loadmon(uint32_t cur_ts);
43 static int exited = 0;
46 int kernel_notifyfd = 0;
49 int slowpath_main(
void)
52 uint32_t last_print = 0;
53 uint32_t loadmon_ts = 0;
55 kernel_notifyfd = eventfd(0, EFD_NONBLOCK);
56 assert(kernel_notifyfd != -1);
58 struct epoll_event ev = {
60 .data.fd = kernel_notifyfd,
63 epfd = epoll_create1(0);
66 int r = epoll_ctl(
epfd, EPOLL_CTL_ADD, kernel_notifyfd, &ev);
71 fprintf(stderr,
"timeout_init failed\n");
77 fprintf(stderr,
"kni_init failed\n");
83 fprintf(stderr,
"routing_init failed\n");
89 fprintf(stderr,
"nicif_init failed\n");
95 fprintf(stderr,
"cc_init failed\n");
101 fprintf(stderr,
"appif_init failed\n");
106 fprintf(stderr,
"arp_init failed\n");
112 fprintf(stderr,
"tcp_init failed\n");
118 notify_canblock_reset(&nbs);
119 while (exited == 0) {
130 if (config.
fp_autoscale && cur_ts - loadmon_ts >= 10000) {
131 flexnic_loadmon(cur_ts);
135 if (notify_canblock(&nbs, n != 0, util_rdtsc())) {
136 slowpath_block(cur_ts);
137 notify_canblock_reset(&nbs);
140 if (cur_ts - last_print >= 1000000) {
142 printf(
"stats: drops=%"PRIu64
" k_rexmit=%"PRIu64
" ecn=%"PRIu64
" acks=%" 154 static void slowpath_block(uint32_t cur_ts)
156 int n, i, ret, timeout_ms;
157 struct epoll_event event[2];
159 uint32_t cc_timeout = cc_next_ts(cur_ts),
160 util_timeout = util_timeout_next(&timeout_mgr, cur_ts),
163 if(cc_timeout != -1U && util_timeout != -1U) {
164 timeout_us = MIN(cc_timeout, util_timeout);
165 }
else if(cc_timeout != -1U) {
166 timeout_us = util_timeout;
168 timeout_us = cc_timeout;
170 if(timeout_us != -1U) {
171 timeout_ms = timeout_us / 1000;
177 if(timeout_ms == -1 || timeout_ms > 1000) {
182 n = epoll_wait(
epfd, event, 2, timeout_ms);
183 if(n == -1 && errno == EINTR) {
186 }
else if (n == -1) {
187 perror(
"slowpath_block: epoll_wait failed");
191 for(i = 0; i < n; i++) {
192 assert(event[i].data.fd == kernel_notifyfd);
193 ret = read(kernel_notifyfd, &val,
sizeof(uint64_t));
194 if ((ret > 0 && ret !=
sizeof(uint64_t)) ||
195 (ret < 0 && errno != EAGAIN && errno != EWOULDBLOCK))
197 perror(
"slowpath_block: read failed");
203 static void timeout_trigger(
struct timeout *to, uint8_t type,
void *opaque)
210 case TO_TCP_HANDSHAKE:
211 case TO_TCP_RETRANSMIT:
217 fprintf(stderr,
"Unknown timeout type: %u\n", type);
222 static void signal_tas_ready(
void)
226 printf(
"TAS ready\n");
231 write(config.
ready_fd, &x,
sizeof(x)) < 0)
233 perror(
"TAS signal: ready fd write failed");
unsigned cc_poll(uint32_t cur_ts)
void tcp_timeout(struct timeout *to, enum timeout_type type)
uint32_t util_timeout_time_us(void)
void arp_timeout(struct timeout *to, enum timeout_type type)
int util_timeout_init(struct timeout_manager *mgr, void(*handler)(struct timeout *, uint8_t, void *), void *handler_opaque)
unsigned nicif_poll(void)
void util_timeout_poll_ts(struct timeout_manager *mgr, uint32_t cur_ts)
unsigned appif_poll(void)