From: Daniel Salzman Date: Thu, 12 Mar 2020 08:52:44 +0000 (+0100) Subject: xdp: rework knot_xsk_sendmmsg() X-Git-Tag: embedded_lmdb~35^2~35 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bba21d5a2158497facbc5076dec59a6a20ebf101;p=thirdparty%2Fknot-dns.git xdp: rework knot_xsk_sendmmsg() --- diff --git a/src/libknot/xdp/af_xdp.c b/src/libknot/xdp/af_xdp.c index 5275796657..583238ac51 100644 --- a/src/libknot/xdp/af_xdp.c +++ b/src/libknot/xdp/af_xdp.c @@ -255,23 +255,6 @@ static void udp_checksum_finish(size_t *result) } } -static int pkt_send(struct knot_xsk_socket *xsk, uint64_t addr, uint32_t len) -{ - uint32_t tx_idx; - int ret = xsk_ring_prod__reserve(&xsk->tx, 1, &tx_idx); - if (unlikely(ret != 1)) { - return KNOT_NET_ESEND; - } - - *xsk_ring_prod__tx_desc(&xsk->tx, tx_idx) = (struct xdp_desc){ - .addr = addr, - .len = len, - }; - xsk_ring_prod__submit(&xsk->tx, 1); - xsk->kernel_needs_wakeup = true; - return KNOT_EOK; -} - static uint8_t *msg_uframe_p(struct knot_xsk_socket *socket, const knot_xsk_msg_t *msg, /* these are just for debugging */ bool ipv6, bool send) @@ -285,18 +268,17 @@ static uint8_t *msg_uframe_p(struct knot_xsk_socket *socket, const knot_xsk_msg_ const uint8_t *umem_mem_end = umem_mem_start + FRAME_SIZE * UMEM_FRAME_COUNT; if (uframe_p < umem_mem_start || uframe_p >= umem_mem_end) { // not allocated msg->payload correctly + assert(0); return NULL; } return uframe_p; } -static int xsk_sendmsg_ipv4(struct knot_xsk_socket *socket, const knot_xsk_msg_t *msg) +static void xsk_sendmsg_ipv4(struct knot_xsk_socket *socket, const knot_xsk_msg_t *msg, + uint32_t index) { uint8_t *uframe_p = msg_uframe_p(socket, msg, false, true); - if (uframe_p == NULL) { - return KNOT_EINVAL; - } struct umem_frame *uframe = (struct umem_frame *)uframe_p; struct udpv4 *h = &uframe->udpv4; @@ -334,15 +316,16 @@ static int xsk_sendmsg_ipv4(struct knot_xsk_socket *socket, const knot_xsk_msg_t uint32_t eth_len = FRAME_PAYLOAD_OFFSET4 + msg->payload.iov_len; - return pkt_send(socket, h->bytes - socket->umem->frames->bytes, eth_len); + *xsk_ring_prod__tx_desc(&socket->tx, index) = (struct xdp_desc){ + .addr = h->bytes - socket->umem->frames->bytes, + .len = eth_len, + }; } -static int xsk_sendmsg_ipv6(struct knot_xsk_socket *socket, const knot_xsk_msg_t *msg) +static void xsk_sendmsg_ipv6(struct knot_xsk_socket *socket, const knot_xsk_msg_t *msg, + uint32_t index) { uint8_t *uframe_p = msg_uframe_p(socket, msg, true, true); - if (uframe_p == NULL) { - return KNOT_EINVAL; - } struct umem_frame *uframe = (struct umem_frame *)uframe_p; struct udpv6 *h = &uframe->udpv6; @@ -388,34 +371,54 @@ static int xsk_sendmsg_ipv6(struct knot_xsk_socket *socket, const knot_xsk_msg_t uint32_t eth_len = FRAME_PAYLOAD_OFFSET6 + msg->payload.iov_len; - return pkt_send(socket, h->bytes - socket->umem->frames->bytes, eth_len); + *xsk_ring_prod__tx_desc(&socket->tx, index) = (struct xdp_desc){ + .addr = h->bytes - socket->umem->frames->bytes, + .len = eth_len, + }; } -_public_ -int knot_xsk_sendmsg(struct knot_xsk_socket *socket, const knot_xsk_msg_t *msg) +static void xsk_sendmsg_error(struct knot_xsk_socket *socket, const knot_xsk_msg_t *msg, + uint32_t index) { - switch (msg->ip_from.ss_family) { - case AF_INET: - return xsk_sendmsg_ipv4(socket, msg); - case AF_INET6: - return xsk_sendmsg_ipv6(socket, msg); - default: - return KNOT_EINVAL; - } + *xsk_ring_prod__tx_desc(&socket->tx, index) = (struct xdp_desc){ + .addr = msg, + .len = 0, + }; } _public_ int knot_xsk_sendmmsg(struct knot_xsk_socket *socket, const knot_xsk_msg_t msgs[], uint32_t count, uint32_t *sent) { - int ret = KNOT_EOK; - *sent = 0; - for (int i = 0; i < count && ret == KNOT_EOK; i++) { - if (msgs[i].payload.iov_len > 0) { - ret = knot_xsk_sendmsg(socket, &msgs[i]); - *sent += (ret == KNOT_EOK ? 1 : 0); + if (socket == NULL || msgs == NULL || sent == NULL) { + return KNOT_EINVAL; + } + + uint32_t idx = 0; + const uint32_t reserved = xsk_ring_prod__reserve(&socket->tx, count, &idx); + + for (uint32_t i = 0; i < reserved; ++i) { + const knot_xsk_msg_t *msg = &msgs[i]; + + switch (msg->ip_from.ss_family) { + case AF_INET: + xsk_sendmsg_ipv4(socket, msg, idx); + break; + case AF_INET6: + xsk_sendmsg_ipv6(socket, msg, idx); + break; + default: + xsk_sendmsg_error(socket, msg, idx); + break; } + + idx++; } - return ret; + + xsk_ring_prod__submit(&socket->tx, reserved); + socket->kernel_needs_wakeup = true; + *sent = reserved; + + return KNOT_EOK; } _public_ diff --git a/src/libknot/xdp/af_xdp.h b/src/libknot/xdp/af_xdp.h index df5bfee541..1743595493 100644 --- a/src/libknot/xdp/af_xdp.h +++ b/src/libknot/xdp/af_xdp.h @@ -91,19 +91,6 @@ void knot_xsk_prepare_alloc(struct knot_xsk_socket *socket); int knot_xsk_alloc_packet(struct knot_xsk_socket *socket, bool ipv6, knot_xsk_msg_t *out, const knot_xsk_msg_t *in_reply_to); -/*! - * \brief Send single packet thru XDP. - * - * \param socket XDP socket. - * \param msg Packet to be sent. - * - * \note The packet must have been allocated by knot_xsk_alloc_frame()! - * \note Do not free the packet payload afterwards. - * - * \return KNOT_E* - */ -int knot_xsk_sendmsg(struct knot_xsk_socket *socket, const knot_xsk_msg_t *msg); - /*! * \brief Send multiple packets thru XDP. *