From patchwork Thu Jun 30 09:14:22 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dylan Yudaken X-Patchwork-Id: 12901511 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DB263C433EF for ; Thu, 30 Jun 2022 09:21:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233092AbiF3JVZ (ORCPT ); Thu, 30 Jun 2022 05:21:25 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:52638 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234240AbiF3JVR (ORCPT ); Thu, 30 Jun 2022 05:21:17 -0400 Received: from mx0a-00082601.pphosted.com (mx0b-00082601.pphosted.com [67.231.153.30]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C971833EA9 for ; Thu, 30 Jun 2022 02:21:14 -0700 (PDT) Received: from pps.filterd (m0001303.ppops.net [127.0.0.1]) by m0001303.ppops.net (8.17.1.5/8.17.1.5) with ESMTP id 25U0LXUK009461 for ; Thu, 30 Jun 2022 02:21:08 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=fb.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding : content-type; s=facebook; bh=kwN9dS1xhM6SCKWqFGDi17BlRioTEFB/ozRN/PThJXM=; b=ais6d/3EpXv29nvJOzJ07WwXwEFeXltqaMHz+L4YOjq/xuYO4I5AAF5arijeZ5lvxoOr /IP/qaWne3vYfJZYyXH102AfWjET9rtz+7S5LsJPMG8sp37tZ4A6RCwmQb017BuHY85a d+JN2D6ok3tAKcDwgM4oVpQ8RET4AiOC5Tc= Received: from mail.thefacebook.com ([163.114.132.120]) by m0001303.ppops.net (PPS) with ESMTPS id 3h10tfjbvj-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NOT) for ; Thu, 30 Jun 2022 02:21:08 -0700 Received: from snc-exhub201.TheFacebook.com (2620:10d:c085:21d::7) by snc-exhub204.TheFacebook.com (2620:10d:c085:21d::4) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.28; Thu, 30 Jun 2022 02:21:07 -0700 Received: from twshared5640.09.ash9.facebook.com (2620:10d:c085:208::f) by mail.thefacebook.com (2620:10d:c085:21d::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.28; Thu, 30 Jun 2022 02:21:07 -0700 Received: by devbig038.lla2.facebook.com (Postfix, from userid 572232) id D6631259A05C; Thu, 30 Jun 2022 02:14:23 -0700 (PDT) From: Dylan Yudaken To: Jens Axboe , Pavel Begunkov , CC: , Dylan Yudaken Subject: [PATCH v2 liburing 7/7] add accept with overflow test Date: Thu, 30 Jun 2022 02:14:22 -0700 Message-ID: <20220630091422.1463570-8-dylany@fb.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20220630091422.1463570-1-dylany@fb.com> References: <20220630091422.1463570-1-dylany@fb.com> MIME-Version: 1.0 X-FB-Internal: Safe X-Proofpoint-GUID: yetBQQsOwIuPhjvBRHC2ruJN_CngLfce X-Proofpoint-ORIG-GUID: yetBQQsOwIuPhjvBRHC2ruJN_CngLfce X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.205,Aquarius:18.0.883,Hydra:6.0.517,FMLib:17.11.122.1 definitions=2022-06-30_05,2022-06-28_01,2022-06-22_01 Precedence: bulk List-ID: X-Mailing-List: io-uring@vger.kernel.org add test to exercise the overflow codepath for multishot accept. this doesn't actually fail previously, but does at least exerceise the codepath and ensure that some invariants hold wrt flags and IORING_CQE_F_MORE. Signed-off-by: Dylan Yudaken --- test/accept.c | 129 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 101 insertions(+), 28 deletions(-) diff --git a/test/accept.c b/test/accept.c index 77e3ebc..0463173 100644 --- a/test/accept.c +++ b/test/accept.c @@ -24,6 +24,9 @@ #include "liburing.h" #define MAX_FDS 32 +#define NOP_USER_DATA (1LLU << 50) +#define INITIAL_USER_DATA 1000 + static int no_accept; static int no_accept_multi; @@ -39,6 +42,7 @@ struct accept_test_args { bool queue_accept_before_connect; bool multishot; int extra_loops; + bool overflow; }; static void close_fds(int fds[], int nr) @@ -86,6 +90,24 @@ static void queue_recv(struct io_uring *ring, int fd, bool fixed) sqe->flags |= IOSQE_FIXED_FILE; } +static void queue_accept_multishot(struct io_uring *ring, int fd, + int idx, bool fixed) +{ + struct io_uring_sqe *sqe = io_uring_get_sqe(ring); + int ret; + + if (fixed) + io_uring_prep_multishot_accept_direct(sqe, fd, + NULL, NULL, + 0); + else + io_uring_prep_multishot_accept(sqe, fd, NULL, NULL, 0); + + io_uring_sqe_set_data64(sqe, idx); + ret = io_uring_submit(ring); + assert(ret != -1); +} + static void queue_accept_conn(struct io_uring *ring, int fd, struct accept_test_args args) { @@ -93,40 +115,51 @@ static void queue_accept_conn(struct io_uring *ring, int fd, int ret; int fixed_idx = args.fixed ? 0 : -1; int count = 1 + args.extra_loops; - bool multishot = args.multishot; + + if (args.multishot) { + queue_accept_multishot(ring, fd, INITIAL_USER_DATA, args.fixed); + return; + } while (count--) { sqe = io_uring_get_sqe(ring); if (fixed_idx < 0) { - if (!multishot) - io_uring_prep_accept(sqe, fd, NULL, NULL, 0); - else - io_uring_prep_multishot_accept(sqe, fd, NULL, - NULL, 0); + io_uring_prep_accept(sqe, fd, NULL, NULL, 0); } else { - if (!multishot) - io_uring_prep_accept_direct(sqe, fd, NULL, NULL, - 0, fixed_idx); - else - io_uring_prep_multishot_accept_direct(sqe, fd, - NULL, NULL, - 0); + io_uring_prep_accept_direct(sqe, fd, NULL, NULL, + 0, fixed_idx); } - ret = io_uring_submit(ring); assert(ret != -1); } } -static int accept_conn(struct io_uring *ring, int fixed_idx, bool multishot) +static int accept_conn(struct io_uring *ring, int fixed_idx, int *multishot, int fd) { - struct io_uring_cqe *cqe; + struct io_uring_cqe *pcqe; + struct io_uring_cqe cqe; int ret; - ret = io_uring_wait_cqe(ring, &cqe); - assert(!ret); - ret = cqe->res; - io_uring_cqe_seen(ring, cqe); + do { + ret = io_uring_wait_cqe(ring, &pcqe); + assert(!ret); + cqe = *pcqe; + io_uring_cqe_seen(ring, pcqe); + } while (cqe.user_data == NOP_USER_DATA); + + if (*multishot) { + if (!(cqe.flags & IORING_CQE_F_MORE)) { + (*multishot)++; + queue_accept_multishot(ring, fd, *multishot, fixed_idx == 0); + } else { + if (cqe.user_data != *multishot) { + fprintf(stderr, "received multishot after told done!\n"); + return -ECANCELED; + } + } + } + + ret = cqe.res; if (fixed_idx >= 0) { if (ret > 0) { @@ -203,6 +236,32 @@ static int set_client_fd(struct sockaddr_in *addr) return fd; } +static void cause_overflow(struct io_uring *ring) +{ + int i, ret; + + for (i = 0; i < *ring->cq.kring_entries; i++) { + struct io_uring_sqe *sqe = io_uring_get_sqe(ring); + + io_uring_prep_nop(sqe); + io_uring_sqe_set_data64(sqe, NOP_USER_DATA); + ret = io_uring_submit(ring); + assert(ret != -1); + } + +} + +static void clear_overflow(struct io_uring *ring) +{ + struct io_uring_cqe *cqe; + + while (!io_uring_peek_cqe(ring, &cqe)) { + if (cqe->user_data != NOP_USER_DATA) + break; + io_uring_cqe_seen(ring, cqe); + } +} + static int test_loop(struct io_uring *ring, struct accept_test_args args, int recv_s0, @@ -215,15 +274,22 @@ static int test_loop(struct io_uring *ring, bool multishot = args.multishot; uint32_t multishot_mask = 0; int nr_fds = multishot ? MAX_FDS : 1; + int multishot_idx = multishot ? INITIAL_USER_DATA : 0; - for (i = 0; i < nr_fds; i++) + if (args.overflow) + cause_overflow(ring); + + for (i = 0; i < nr_fds; i++) { c_fd[i] = set_client_fd(addr); + if (args.overflow && i == nr_fds / 2) + clear_overflow(ring); + } if (!args.queue_accept_before_connect) queue_accept_conn(ring, recv_s0, args); for (i = 0; i < nr_fds; i++) { - s_fd[i] = accept_conn(ring, fixed ? 0 : -1, multishot); + s_fd[i] = accept_conn(ring, fixed ? 0 : -1, &multishot_idx, recv_s0); if (s_fd[i] == -EINVAL) { if (args.accept_should_error) goto out; @@ -527,14 +593,15 @@ static int test_accept(int count, bool before) return ret; } -static int test_multishot_accept(int count, bool before) +static int test_multishot_accept(int count, bool before, bool overflow) { struct io_uring m_io_uring; int ret; struct accept_test_args args = { .queue_accept_before_connect = before, .multishot = true, - .extra_loops = count - 1 + .extra_loops = count - 1, + .overflow = overflow }; if (no_accept_multi) @@ -779,15 +846,21 @@ int main(int argc, char *argv[]) return ret; } - ret = test_multishot_accept(1, false); + ret = test_multishot_accept(1, true, true); + if (ret) { + fprintf(stderr, "test_multishot_accept(1, false, true) failed\n"); + return ret; + } + + ret = test_multishot_accept(1, false, false); if (ret) { - fprintf(stderr, "test_multishot_accept(1, false) failed\n"); + fprintf(stderr, "test_multishot_accept(1, false, false) failed\n"); return ret; } - ret = test_multishot_accept(1, true); + ret = test_multishot_accept(1, true, false); if (ret) { - fprintf(stderr, "test_multishot_accept(1, true) failed\n"); + fprintf(stderr, "test_multishot_accept(1, true, false) failed\n"); return ret; }