29 #include <sys/socket.h> 30 #include <sys/types.h> 32 #include <kernel_appif.h> 33 #include <utils_timeout.h> 36 #define NIC_RXQ_LEN (64 * 32 * 1024) 37 #define NIC_TXQ_LEN (64 * 8192) 39 static int ksock_fd = -1;
40 static int kernel_evfd = 0;
42 void flextcp_kernel_kick(
void)
44 static uint64_t __thread last_ts = 0;
45 uint64_t now = util_rdtsc();
52 assert(kernel_evfd != 0);
54 int r = write(kernel_evfd, &val,
sizeof(uint64_t));
55 assert(r ==
sizeof(uint64_t));
61 int flextcp_kernel_connect(
void)
66 uint32_t num_fds, off, i, n;
67 struct sockaddr_un saun;
71 memset(&saun, 0,
sizeof(saun));
72 saun.sun_family = AF_UNIX;
73 memcpy(saun.sun_path, KERNEL_SOCKET_PATH,
sizeof(KERNEL_SOCKET_PATH));
75 if ((fd =
socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0)) == -1) {
76 perror(
"flextcp_kernel_connect: socket failed");
80 if (connect(fd, (
struct sockaddr *) &saun,
sizeof(saun)) != 0) {
81 perror(
"flextcp_kernel_connect: connect failed");
87 .iov_len =
sizeof(uint32_t),
90 char buf[CMSG_SPACE(
sizeof(
int) * 4)];
99 .msg_controllen =
sizeof(u.buf),
105 if ((r = recvmsg(fd, &msg, 0)) !=
sizeof(uint32_t)) {
106 fprintf(stderr,
"flextcp_kernel_connect: recvmsg failed (%zd)\n", r);
111 cmsg = CMSG_FIRSTHDR(&msg);
112 pfd = (
int *) CMSG_DATA(cmsg);
113 if (msg.msg_controllen <= 0 || cmsg->cmsg_len != CMSG_LEN(
sizeof(
int))) {
114 fprintf(stderr,
"flextcp_kernel_connect: accessing ancillary data " 122 for (off = 0 ; off < num_fds; ) {
126 memset(&msg, 0,
sizeof(msg));
129 msg.msg_control = u.buf;
130 msg.msg_controllen =
sizeof(u);
133 if ((r = recvmsg(fd, &msg, 0)) != 1) {
134 fprintf(stderr,
"flextcp_kernel_connect: recvmsg fd failed (%zd)\n", r);
138 n = (num_fds - off >= 4 ? 4 : num_fds - off);
141 cmsg = CMSG_FIRSTHDR(&msg);
142 pfd = (
int *) CMSG_DATA(cmsg);
143 if (msg.msg_controllen <= 0 || cmsg->cmsg_len != CMSG_LEN(
sizeof(
int) * n)) {
144 fprintf(stderr,
"flextcp_kernel_connect: accessing ancillary data fds " 149 for (i = 0; i < n; i++) {
150 flexnic_evfd[off++] = pfd[i];
160 ssize_t sz, off, total_sz;
162 uint8_t resp_buf[
sizeof(*resp) +
163 FLEXTCP_MAX_FTCPCORES *
sizeof(resp->flexnic_qs[0])];
165 .rxq_len = NIC_RXQ_LEN,
166 .txq_len = NIC_TXQ_LEN,
173 .iov_len =
sizeof(req),
176 char buf[CMSG_SPACE(
sizeof(
int))];
177 struct cmsghdr align;
179 struct msghdr msg = {
184 .msg_control = u.buf,
185 .msg_controllen =
sizeof(u.buf),
188 struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
189 cmsg->cmsg_level = SOL_SOCKET;
190 cmsg->cmsg_type = SCM_RIGHTS;
191 cmsg->cmsg_len = CMSG_LEN(
sizeof(
int));
192 int *myfd = (
int *)CMSG_DATA(cmsg);
194 sz = sendmsg(ksock_fd, &msg, 0);
195 assert(sz ==
sizeof(req));
200 while (off <
sizeof(*resp)) {
201 sz = read(ksock_fd, (uint8_t *) resp + off,
sizeof(*resp) - off);
203 perror(
"flextcp_kernel_newctx: read failed");
209 if (resp->flexnic_qs_num > FLEXTCP_MAX_FTCPCORES) {
210 fprintf(stderr,
"flextcp_kernel_newctx: stack only supports up to %u " 211 "queues, got %u\n", FLEXTCP_MAX_FTCPCORES, resp->flexnic_qs_num);
215 total_sz =
sizeof(*resp) + resp->flexnic_qs_num *
sizeof(resp->flexnic_qs[0]);
216 while (off < total_sz) {
217 sz = read(ksock_fd, (uint8_t *) resp + off, total_sz - off);
219 perror(
"flextcp_kernel_newctx: read failed");
225 if (resp->status != 0) {
226 fprintf(stderr,
"flextcp_kernel_newctx: request failed\n");
231 ctx->kin_base = (uint8_t *) flexnic_mem + resp->app_out_off;
232 ctx->kin_len = resp->app_out_len /
sizeof(
struct kernel_appout);
235 ctx->kout_base = (uint8_t *) flexnic_mem + resp->app_in_off;
236 ctx->kout_len = resp->app_in_len /
sizeof(
struct kernel_appin);
239 ctx->db_id = resp->flexnic_db_id;
240 ctx->num_queues = resp->flexnic_qs_num;
243 ctx->rxq_len = NIC_RXQ_LEN;
244 ctx->txq_len = NIC_TXQ_LEN;
246 for (i = 0; i < resp->flexnic_qs_num; i++) {
247 ctx->queues[i].rxq_base =
248 (uint8_t *) flexnic_mem + resp->flexnic_qs[i].rxq_off;
249 ctx->queues[i].txq_base =
250 (uint8_t *) flexnic_mem + resp->flexnic_qs[i].txq_off;
252 ctx->queues[i].rxq_head = 0;
253 ctx->queues[i].txq_tail = 0;
254 ctx->queues[i].txq_avail = ctx->txq_len;
255 ctx->queues[i].last_ts = 0;
261 int flextcp_kernel_reqscale(
struct flextcp_context *ctx, uint32_t cores)
263 uint32_t pos = ctx->kin_head;
268 if (kin->type != KERNEL_APPOUT_INVALID) {
269 fprintf(stderr,
"flextcp_kernel_reqscale: no queue space\n");
273 kin->data.req_scale.num_cores = cores;
275 kin->type = KERNEL_APPOUT_REQ_SCALE;
276 flextcp_kernel_kick();
279 if (pos >= ctx->kin_len) {