int dpdk_packet_io(void) { int ret; struct vr_dpdk_lcore *lcore = vr_dpdk.lcores[rte_lcore_id()]; wait_for_connection: RTE_LOG(DEBUG, VROUTER, "%s[%lx]: waiting for packet transport\n", __func__, pthread_self()); while (!vr_dpdk.packet_transport) { /* handle an IPC command */ if (unlikely(vr_dpdk_lcore_cmd_handle(lcore))) return -1; usleep(VR_DPDK_SLEEP_SERVICE_US); } RTE_LOG(DEBUG, VROUTER, "%s[%lx]: FD %d\n", __func__, pthread_self(), ((struct vr_usocket *)vr_dpdk.packet_transport)->usock_fd); ret = vr_usocket_io(vr_dpdk.packet_transport); if (ret < 0) { vr_dpdk.packet_transport = NULL; /* handle an IPC command */ if (unlikely(vr_dpdk_lcore_cmd_handle(lcore))) return -1; usleep(VR_DPDK_SLEEP_SERVICE_US); goto wait_for_connection; } return ret; }
/* * start io on socket */ int vr_usocket_io(void *transport) { int ret, i, processed; int timeout; struct pollfd *pfd; struct vr_usocket *usockp = (struct vr_usocket *)transport; unsigned lcore_id = rte_lcore_id(); struct vr_dpdk_lcore *lcore = vr_dpdk.lcores[lcore_id]; if (!usockp) return -1; RTE_LOG(DEBUG, USOCK, "%s[%lx]: FD %d\n", __func__, pthread_self(), usockp->usock_fd); if ((ret = usock_init_poll(usockp))) goto return_from_io; pfd = &usockp->usock_pfds[0]; pfd->fd = usockp->usock_fd; pfd->events = POLLIN; usockp->usock_io_in_progress = 1; timeout = usockp->usock_poll_block ? INFINITE_TIMEOUT : 0; while (1) { if (usockp->usock_should_close) { usock_close(usockp); return -1; } /* * Handle an IPC commands for IO_LCORE_ID up * and just check the stop flag for the rest. */ if (lcore_id >= VR_DPDK_IO_LCORE_ID) { if (unlikely(vr_dpdk_lcore_cmd_handle(lcore))) break; } else { if (unlikely(vr_dpdk_is_stop_flag_set())) break; } rcu_thread_offline(); ret = poll(usockp->usock_pfds, usockp->usock_max_cfds, timeout); if (ret < 0) { usock_set_error(usockp, ret); /* all other errors are fatal */ if (errno != EINTR) goto return_from_io; } rcu_thread_online(); processed = 0; pfd = usockp->usock_pfds; for (i = 0; (i < usockp->usock_max_cfds) && (processed < ret); i++, pfd++) { if ((pfd->fd >= 0)) { if (pfd->revents & POLLIN) { if (i == 0) { ret = vr_usocket_read(usockp); if (ret < 0) return ret; } else { vr_usocket_read(usockp->usock_children[i]); } } if (pfd->revents & POLLOUT) { usock_write(usockp->usock_children[i]); } if (pfd->revents & POLLHUP) { if (i) { usock_close(usockp->usock_children[i]); } else { break; } } if (pfd->revents) processed++; } } if (!timeout) return 0; } return_from_io: usockp->usock_io_in_progress = 0; usock_deinit_poll(usockp); return ret; }