From patchwork Thu Oct 5 13:48:55 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Willem de Bruijn X-Patchwork-Id: 13410037 X-Patchwork-Delegate: kuba@kernel.org Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 18BDD23760 for ; Thu, 5 Oct 2023 13:49:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="fqBjeZKt" Received: from mail-qv1-xf33.google.com (mail-qv1-xf33.google.com [IPv6:2607:f8b0:4864:20::f33]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3813119AC for ; Thu, 5 Oct 2023 06:49:24 -0700 (PDT) Received: by mail-qv1-xf33.google.com with SMTP id 6a1803df08f44-65b051a28b3so5204676d6.2 for ; Thu, 05 Oct 2023 06:49:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1696513763; x=1697118563; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=bsfaXqinfbrv9Ji7zCX0x+UKyaBqsDIyUoNOYyLxpi0=; b=fqBjeZKtLZZs1vKgcp1wU3sJysJRkJ317ih0ITrqREbxikF1W6cgVBfDw938+ANMoW DYCm/SsI11GBP3YOmFWNz3kjGNAiRGEtP/6h80WI6F3wWVs05NqFrzSSZe73IWwmSKvC SvYOXlGprzG5zPryoP01RJYb5nq2CMuvN24BTVySXJpVWjUQVlRUK2hPx6Iw0ipWZJe8 S9K78fU9D1rdMs4xZhghy3mPuVIagQPDZnxACTyPw4w3MJZnT84mBdvFhbY52YJK8eHf UqUyD99QaovqeOIec6dKVRSH4/1/LuSyl51smsGbPCDe1KueBtKoerWNdPBxdfe97RW9 NMDQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696513763; x=1697118563; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=bsfaXqinfbrv9Ji7zCX0x+UKyaBqsDIyUoNOYyLxpi0=; b=sj9ph9dYUECuMA8N4ndAgKZF8gUK1PH7OALTx/cvsjCqMXz9SA5HQZumw9Pgp2LtKk AUYEiBfsJu6arSvo8k7gTAu4fHKh1nFGNb8SgPLy2ElmnhxvkikfDSgyvFbE6W6Zq1KG /i4CLudsP8DavlRzQNUWrIxUJL9czG8QhNcEIy3d1ijtAs7A442S4mQBS9Q8KOUPqBoQ ZFDy2TSzbwQLd6F1ihVgtDQQxTeiS9xXGPxfP8mXh/cGXGma4bcDqQHtZZKSCte17ZEL KQQ3MpH1F3hzgfO4lGGpz4Cdzxs3qUBpCN8CfIRRR7o3fdlrEfIO8diFELMLuIxl+vRD OjjQ== X-Gm-Message-State: AOJu0YwK7HPhGoF/s8suT1KpV6G+lOirF1PdQR5418WFX1WNyzWExbcR J1rGIsIG+kygGce6xl0XTPoGlFJnJ1h8Qw== X-Google-Smtp-Source: AGHT+IE4gzszs5sYTQIIniTl/ZjjyFnLSPueGTiGP8+PQJEj3K5HC9dug3swbrjL8TegiXrnx0WQPA== X-Received: by 2002:a0c:e88b:0:b0:65b:216f:2d65 with SMTP id b11-20020a0ce88b000000b0065b216f2d65mr5146025qvo.5.1696513763194; Thu, 05 Oct 2023 06:49:23 -0700 (PDT) Received: from willemb.c.googlers.com.com (193.132.150.34.bc.googleusercontent.com. [34.150.132.193]) by smtp.gmail.com with ESMTPSA id n20-20020a0cdc94000000b0065b1e6c33dfsm512591qvk.18.2023.10.05.06.49.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 05 Oct 2023 06:49:22 -0700 (PDT) From: Willem de Bruijn To: netdev@vger.kernel.org Cc: davem@davemloft.net, kuba@kernel.org, edumazet@google.com, pabeni@redhat.com, alexander.duyck@gmail.com, fw@strlen.de, Willem de Bruijn Subject: [PATCH net-next 1/3] net: add skb_segment kunit test Date: Thu, 5 Oct 2023 09:48:55 -0400 Message-ID: <20231005134917.2244971-2-willemdebruijn.kernel@gmail.com> X-Mailer: git-send-email 2.42.0.582.g8ccd20d70d-goog In-Reply-To: <20231005134917.2244971-1-willemdebruijn.kernel@gmail.com> References: <20231005134917.2244971-1-willemdebruijn.kernel@gmail.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net X-Patchwork-Delegate: kuba@kernel.org From: Willem de Bruijn Add unit testing for skb segment. This function is exercised by many different code paths, such as GSO_PARTIAL or GSO_BY_FRAGS, linear (with or without head_frag), frags or frag_list skbs, etc. It is infeasible to manually run tests that cover all code paths when making changes. The long and complex function also makes it hard to establish through analysis alone that a patch has no unintended side-effects. Add code coverage through kunit regression testing. Introduce kunit infrastructure for tests under net/core, and add this first test. This first skb_segment test exercises a simple case: a linear skb. Follow-on patches will parametrize the test and add more variants. Tested: Built and ran the test with make ARCH=um mrproper ./tools/testing/kunit/kunit.py run \ --kconfig_add CONFIG_NET=y \ --kconfig_add CONFIG_DEBUG_KERNEL=y \ --kconfig_add CONFIG_DEBUG_INFO=y \ --kconfig_add=CONFIG_DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT=y \ net_core_gso Signed-off-by: Willem de Bruijn --- net/Kconfig | 9 +++++ net/core/Makefile | 1 + net/core/gso_test.c | 86 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 96 insertions(+) create mode 100644 net/core/gso_test.c diff --git a/net/Kconfig b/net/Kconfig index d532ec33f1fed..17676dba10fbe 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -508,4 +508,13 @@ config NETDEV_ADDR_LIST_TEST default KUNIT_ALL_TESTS depends on KUNIT +config NET_TEST + tristate "KUnit tests for networking" if !KUNIT_ALL_TESTS + depends on KUNIT + default KUNIT_ALL_TESTS + help + KUnit tests covering core networking infra, such as sk_buff. + + If unsure, say N. + endif # if NET diff --git a/net/core/Makefile b/net/core/Makefile index 731db2eaa6107..0cb734cbc24b2 100644 --- a/net/core/Makefile +++ b/net/core/Makefile @@ -40,3 +40,4 @@ obj-$(CONFIG_NET_SOCK_MSG) += skmsg.o obj-$(CONFIG_BPF_SYSCALL) += sock_map.o obj-$(CONFIG_BPF_SYSCALL) += bpf_sk_storage.o obj-$(CONFIG_OF) += of_net.o +obj-$(CONFIG_NET_TEST) += gso_test.o diff --git a/net/core/gso_test.c b/net/core/gso_test.c new file mode 100644 index 0000000000000..9a4828b20203a --- /dev/null +++ b/net/core/gso_test.c @@ -0,0 +1,86 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include + +static const char hdr[] = "abcdefgh"; +static const int gso_size = 1000, last_seg_size = 1; + +/* default: create 3 segment gso packet */ +static const int payload_len = (2 * gso_size) + last_seg_size; + +static void __init_skb(struct sk_buff *skb) +{ + skb_reset_mac_header(skb); + memcpy(skb_mac_header(skb), hdr, sizeof(hdr)); + + /* skb_segment expects skb->data at start of payload */ + skb_pull(skb, sizeof(hdr)); + skb_reset_network_header(skb); + skb_reset_transport_header(skb); + + /* proto is arbitrary, as long as not ETH_P_TEB or vlan */ + skb->protocol = htons(ETH_P_ATALK); + skb_shinfo(skb)->gso_size = gso_size; +} + +static void gso_test_func(struct kunit *test) +{ + const int shinfo_size = SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); + struct sk_buff *skb, *segs, *cur; + struct page *page; + + page = alloc_page(GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, page); + skb = build_skb(page_address(page), sizeof(hdr) + payload_len + shinfo_size); + KUNIT_ASSERT_NOT_NULL(test, skb); + __skb_put(skb, sizeof(hdr) + payload_len); + + __init_skb(skb); + + segs = skb_segment(skb, NETIF_F_SG | NETIF_F_HW_CSUM); + if (IS_ERR(segs)) { + KUNIT_FAIL(test, "segs error %lld", PTR_ERR(segs)); + goto free_gso_skb; + } else if (!segs) { + KUNIT_FAIL(test, "no segments"); + goto free_gso_skb; + } + + for (cur = segs; cur; cur = cur->next) { + /* segs have skb->data pointing to the mac header */ + KUNIT_ASSERT_PTR_EQ(test, skb_mac_header(cur), cur->data); + KUNIT_ASSERT_PTR_EQ(test, skb_network_header(cur), cur->data + sizeof(hdr)); + + /* header was copied to all segs */ + KUNIT_ASSERT_EQ(test, memcmp(skb_mac_header(cur), hdr, sizeof(hdr)), 0); + + /* all segs are gso_size, except for last */ + if (cur->next) { + KUNIT_ASSERT_EQ(test, cur->len, sizeof(hdr) + gso_size); + } else { + KUNIT_ASSERT_EQ(test, cur->len, sizeof(hdr) + last_seg_size); + + /* last seg can be found through segs->prev pointer */ + KUNIT_ASSERT_PTR_EQ(test, cur, segs->prev); + } + } + + consume_skb(segs); +free_gso_skb: + consume_skb(skb); +} + +static struct kunit_case gso_test_cases[] = { + KUNIT_CASE(gso_test_func), + {} +}; + +static struct kunit_suite gso_test_suite = { + .name = "net_core_gso", + .test_cases = gso_test_cases, +}; + +kunit_test_suite(gso_test_suite); + +MODULE_LICENSE("GPL"); From patchwork Thu Oct 5 13:48:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Willem de Bruijn X-Patchwork-Id: 13410040 X-Patchwork-Delegate: kuba@kernel.org Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 73F68266BB for ; Thu, 5 Oct 2023 13:49:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Z1GOFM4U" Received: from mail-qv1-xf30.google.com (mail-qv1-xf30.google.com [IPv6:2607:f8b0:4864:20::f30]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9B48819A1 for ; Thu, 5 Oct 2023 06:49:24 -0700 (PDT) Received: by mail-qv1-xf30.google.com with SMTP id 6a1803df08f44-65afd8af8bbso5441976d6.3 for ; Thu, 05 Oct 2023 06:49:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1696513763; x=1697118563; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=PMrD+b8fz9u+6jiIFM4sQLi2ogSziH3Lh07rXPTog2k=; b=Z1GOFM4UDi3ixYNCV0R3QeE6/Cv7ALrF0sJfv+ubXSehVwZ/DXH8+nFPMSw3TnEAy4 L6zb1PiXlBSv9HqZONkY7tHWB3622AB2LVZce5wrbiUxrKEOZiPByRuNPZU7VueNT/Op 7EC66YhE+RIyEeGxliJYeTn/Z+dTGF4Egy1uC9fCtnzX7BVid+WDY+SLXRlEVxc9hM5J 312pFk3bAf8z3b+Qt58Y8NSFfwrT1JTk2+cxtCKrgJRhu3fjXlpx77j76g/jxDGoTKf9 pDVUHcpbv0tiRXEt/EUvIhHiwE47dWvU5Kxndqo7ruWofTUI6sdh/HyGve1Fe9ftJuMx kqsg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696513763; x=1697118563; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=PMrD+b8fz9u+6jiIFM4sQLi2ogSziH3Lh07rXPTog2k=; b=Q8LU7RjXe21dpx0OgeMS421O/PKDYDrcmTPCvGZGBbZ2WMyR8WLvJx4LUSg3m9PLy5 a/2ZB4B5gegiabsIf/3oIFDfXTM3KnW1WPAvyAavHhUl328f+HmQEtgKz46MxtTEdW7H akHQVlek0SoDJbTgT5snJmEM9xokRAIlEYxlhn4Yh64R8CiE4yHpqbryR1n5/LgOFe+d LO9A9Ai18YLVdZR03bXkutmNZtJyu88nA3QxQ1R33nOHNN/mUoQJC1txS4fpw7nsTvh/ GCMWkX6bQszxOmugb6Rp6bK8zLy8ZKgF/EWHiyqFa4MeGUH+jo3oPS5nRA3RXT0uWmak aYUA== X-Gm-Message-State: AOJu0YyPDHy6Kjd7cYS+I87MB2ZZtvqul2VGYwg9drYoJldrdlWngESL aeGcARJ7UlxfVefXNYvOfVEixzVUTJ6EAg== X-Google-Smtp-Source: AGHT+IGPCng27f1Sr4nh0vfIOHiqq1e0QI6J55OERiTDBZMpjk75eBte1UXFGbpp0J/DYRZC7uZ5zA== X-Received: by 2002:a05:6214:5488:b0:64a:9308:3016 with SMTP id lg8-20020a056214548800b0064a93083016mr5448018qvb.56.1696513763640; Thu, 05 Oct 2023 06:49:23 -0700 (PDT) Received: from willemb.c.googlers.com.com (193.132.150.34.bc.googleusercontent.com. [34.150.132.193]) by smtp.gmail.com with ESMTPSA id n20-20020a0cdc94000000b0065b1e6c33dfsm512591qvk.18.2023.10.05.06.49.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 05 Oct 2023 06:49:23 -0700 (PDT) From: Willem de Bruijn To: netdev@vger.kernel.org Cc: davem@davemloft.net, kuba@kernel.org, edumazet@google.com, pabeni@redhat.com, alexander.duyck@gmail.com, fw@strlen.de, Willem de Bruijn Subject: [PATCH net-next 2/3] net: parametrize skb_segment unit test to expand coverage Date: Thu, 5 Oct 2023 09:48:56 -0400 Message-ID: <20231005134917.2244971-3-willemdebruijn.kernel@gmail.com> X-Mailer: git-send-email 2.42.0.582.g8ccd20d70d-goog In-Reply-To: <20231005134917.2244971-1-willemdebruijn.kernel@gmail.com> References: <20231005134917.2244971-1-willemdebruijn.kernel@gmail.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net X-Patchwork-Delegate: kuba@kernel.org From: Willem de Bruijn Expand the test with variants - GSO_TEST_NO_GSO: payload size less than or equal to gso_size - GSO_TEST_FRAGS: payload in both linear and page frags - GSO_TEST_FRAGS_PURE: payload exclusively in page frags - GSO_TEST_GSO_PARTIAL: produce one gso segment of multiple of gso_size, plus optionally one non-gso trailer segment Define a test struct that encodes the input gso skb and output segs. Input in terms of linear and fragment lengths. Output as length of each segment. Signed-off-by: Willem de Bruijn --- net/core/gso_test.c | 129 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 112 insertions(+), 17 deletions(-) diff --git a/net/core/gso_test.c b/net/core/gso_test.c index 9a4828b20203a..41d1daa20831e 100644 --- a/net/core/gso_test.c +++ b/net/core/gso_test.c @@ -4,10 +4,7 @@ #include static const char hdr[] = "abcdefgh"; -static const int gso_size = 1000, last_seg_size = 1; - -/* default: create 3 segment gso packet */ -static const int payload_len = (2 * gso_size) + last_seg_size; +static const int gso_size = 1000; static void __init_skb(struct sk_buff *skb) { @@ -24,21 +21,121 @@ static void __init_skb(struct sk_buff *skb) skb_shinfo(skb)->gso_size = gso_size; } +enum gso_test_nr { + GSO_TEST_LINEAR, + GSO_TEST_NO_GSO, + GSO_TEST_FRAGS, + GSO_TEST_FRAGS_PURE, + GSO_TEST_GSO_PARTIAL, +}; + +struct gso_test_case { + enum gso_test_nr id; + const char *name; + + /* input */ + unsigned int linear_len; + unsigned int nr_frags; + const unsigned int *frags; + + /* output as expected */ + unsigned int nr_segs; + const unsigned int *segs; +}; + +static struct gso_test_case cases[] = { + { + .id = GSO_TEST_NO_GSO, + .name = "no_gso", + .linear_len = gso_size, + .nr_segs = 1, + .segs = (const unsigned int[]) { gso_size }, + }, + { + .id = GSO_TEST_LINEAR, + .name = "linear", + .linear_len = gso_size + gso_size + 1, + .nr_segs = 3, + .segs = (const unsigned int[]) { gso_size, gso_size, 1 }, + }, + { + .id = GSO_TEST_FRAGS, + .name = "frags", + .linear_len = gso_size, + .nr_frags = 2, + .frags = (const unsigned int[]) { gso_size, 1 }, + .nr_segs = 3, + .segs = (const unsigned int[]) { gso_size, gso_size, 1 }, + }, + { + .id = GSO_TEST_FRAGS_PURE, + .name = "frags_pure", + .nr_frags = 3, + .frags = (const unsigned int[]) { gso_size, gso_size, 2 }, + .nr_segs = 3, + .segs = (const unsigned int[]) { gso_size, gso_size, 2 }, + }, + { + .id = GSO_TEST_GSO_PARTIAL, + .name = "gso_partial", + .linear_len = gso_size, + .nr_frags = 2, + .frags = (const unsigned int[]) { gso_size, 3 }, + .nr_segs = 2, + .segs = (const unsigned int[]) { 2 * gso_size, 3 }, + }, +}; + +static void gso_test_case_to_desc(struct gso_test_case *t, char *desc) +{ + sprintf(desc, "%s", t->name); +} + +KUNIT_ARRAY_PARAM(gso_test, cases, gso_test_case_to_desc); + static void gso_test_func(struct kunit *test) { const int shinfo_size = SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); + const struct gso_test_case *tcase; struct sk_buff *skb, *segs, *cur; + netdev_features_t features; struct page *page; + int i; + + tcase = test->param_value; page = alloc_page(GFP_KERNEL); KUNIT_ASSERT_NOT_NULL(test, page); - skb = build_skb(page_address(page), sizeof(hdr) + payload_len + shinfo_size); + skb = build_skb(page_address(page), sizeof(hdr) + tcase->linear_len + shinfo_size); KUNIT_ASSERT_NOT_NULL(test, skb); - __skb_put(skb, sizeof(hdr) + payload_len); + __skb_put(skb, sizeof(hdr) + tcase->linear_len); __init_skb(skb); - segs = skb_segment(skb, NETIF_F_SG | NETIF_F_HW_CSUM); + if (tcase->nr_frags) { + unsigned int pg_off = 0; + + page = alloc_page(GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, page); + page_ref_add(page, tcase->nr_frags - 1); + + for (i = 0; i < tcase->nr_frags; i++) { + skb_fill_page_desc(skb, i, page, pg_off, tcase->frags[i]); + pg_off += tcase->frags[i]; + } + + KUNIT_ASSERT_LE(test, pg_off, PAGE_SIZE); + + skb->data_len = pg_off; + skb->len += skb->data_len; + skb->truesize += skb->data_len; + } + + features = NETIF_F_SG | NETIF_F_HW_CSUM; + if (tcase->id == GSO_TEST_GSO_PARTIAL) + features |= NETIF_F_GSO_PARTIAL; + + segs = skb_segment(skb, features); if (IS_ERR(segs)) { KUNIT_FAIL(test, "segs error %lld", PTR_ERR(segs)); goto free_gso_skb; @@ -47,7 +144,9 @@ static void gso_test_func(struct kunit *test) goto free_gso_skb; } - for (cur = segs; cur; cur = cur->next) { + for (cur = segs, i = 0; cur; cur = cur->next, i++) { + KUNIT_ASSERT_EQ(test, cur->len, sizeof(hdr) + tcase->segs[i]); + /* segs have skb->data pointing to the mac header */ KUNIT_ASSERT_PTR_EQ(test, skb_mac_header(cur), cur->data); KUNIT_ASSERT_PTR_EQ(test, skb_network_header(cur), cur->data + sizeof(hdr)); @@ -55,24 +154,20 @@ static void gso_test_func(struct kunit *test) /* header was copied to all segs */ KUNIT_ASSERT_EQ(test, memcmp(skb_mac_header(cur), hdr, sizeof(hdr)), 0); - /* all segs are gso_size, except for last */ - if (cur->next) { - KUNIT_ASSERT_EQ(test, cur->len, sizeof(hdr) + gso_size); - } else { - KUNIT_ASSERT_EQ(test, cur->len, sizeof(hdr) + last_seg_size); - - /* last seg can be found through segs->prev pointer */ + /* last seg can be found through segs->prev pointer */ + if (!cur->next) KUNIT_ASSERT_PTR_EQ(test, cur, segs->prev); - } } + KUNIT_ASSERT_EQ(test, i, tcase->nr_segs); + consume_skb(segs); free_gso_skb: consume_skb(skb); } static struct kunit_case gso_test_cases[] = { - KUNIT_CASE(gso_test_func), + KUNIT_CASE_PARAM(gso_test_func, gso_test_gen_params), {} }; From patchwork Thu Oct 5 13:48:57 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Willem de Bruijn X-Patchwork-Id: 13410039 X-Patchwork-Delegate: kuba@kernel.org Received: from lindbergh.monkeyblade.net (lindbergh.monkeyblade.net [23.128.96.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4C166266B9 for ; Thu, 5 Oct 2023 13:49:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Vu+cyG48" Received: from mail-qv1-xf30.google.com (mail-qv1-xf30.google.com [IPv6:2607:f8b0:4864:20::f30]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 226DC19BE for ; Thu, 5 Oct 2023 06:49:25 -0700 (PDT) Received: by mail-qv1-xf30.google.com with SMTP id 6a1803df08f44-664bd97692dso5580706d6.0 for ; Thu, 05 Oct 2023 06:49:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1696513764; x=1697118564; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=oymkAwTbxNQflv4ebDC3kcwBFW5bZvGX0rS/wRIi1nw=; b=Vu+cyG48FWW8kSUDKXfMM/eiKC73HgTw14Iih6hCXj4bAQiPx+Xac13kKkecEVUkwc 9SPfPK3ya2nxrOVq01WEMr29PWGxSQh9xdSwELttidsqbj8ic75VZDzp98yo8TOCgYHk 54vnnOSvlSszCQ85H0gUT9gZlqFK73Kz27Q416uBtUXnH5roEoKSbQTCAiNn2O7wQbEP 7eVGNEDLjr1EW1cIgPkL5J5p/WsRATIgKWxp8QqBUBnd0pBy9rZnZCLwBwOw8V8Xib2D vyU4FAs40wyF0BjdJtGdD9bgxtrqPoOR6uMGLq1Ku2Bq3vPK0+cqH9UC1J4Cdrz4f/vk 5RAg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696513764; x=1697118564; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=oymkAwTbxNQflv4ebDC3kcwBFW5bZvGX0rS/wRIi1nw=; b=w8fixLY4K69CQQrs9N/z54DrBkm49GjTTlv9M83ezCEjHRvcxr4mfib4CoLdlSXXoo n/38nplGwBZZRmPPWxmJe3Lvihi95rwB3+ZZOVskIOJEe6zBNC1/5ULrzYScMhcXys2N 7453Tfp8D0w7kuELhsK5xtdLx6FGBQg7ANwcgDOlRpN2YdCLYx/axMBCzMxGh2UKI6T0 6+weqAxeqiLLFT6fWhd7Ykf0eaS01fndXBJUi44e125qKqBGQ/zwiZSOXAy33bXnNRcO 3MMjO3+uwx7QvD8Pt1AY87fxuy2CZEx1fuep+hK2flRU5IlI7A72MyBcQ5Ikf3Oy/iPz Hemw== X-Gm-Message-State: AOJu0YwaA3S2Tmn1qJ262Cg41zTjikUgzPtBiLxLvuUNPKbHt1Teosmm y7J72ka4n74BGv0QX0mpQcYcZ4hcRl4z+w== X-Google-Smtp-Source: AGHT+IG/DHGTjYXtt7EZm5HyWFQfr8UgKZtSiQD6f7I6VXNFqXiAZ1lQkin9wR36sIuiKsOfRYQVUg== X-Received: by 2002:ad4:42b4:0:b0:635:f899:660b with SMTP id e20-20020ad442b4000000b00635f899660bmr5137128qvr.36.1696513764108; Thu, 05 Oct 2023 06:49:24 -0700 (PDT) Received: from willemb.c.googlers.com.com (193.132.150.34.bc.googleusercontent.com. [34.150.132.193]) by smtp.gmail.com with ESMTPSA id n20-20020a0cdc94000000b0065b1e6c33dfsm512591qvk.18.2023.10.05.06.49.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 05 Oct 2023 06:49:23 -0700 (PDT) From: Willem de Bruijn To: netdev@vger.kernel.org Cc: davem@davemloft.net, kuba@kernel.org, edumazet@google.com, pabeni@redhat.com, alexander.duyck@gmail.com, fw@strlen.de, Willem de Bruijn Subject: [PATCH net-next 3/3] net: expand skb_segment unit test with frag_list coverage Date: Thu, 5 Oct 2023 09:48:57 -0400 Message-ID: <20231005134917.2244971-4-willemdebruijn.kernel@gmail.com> X-Mailer: git-send-email 2.42.0.582.g8ccd20d70d-goog In-Reply-To: <20231005134917.2244971-1-willemdebruijn.kernel@gmail.com> References: <20231005134917.2244971-1-willemdebruijn.kernel@gmail.com> Precedence: bulk X-Mailing-List: netdev@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM, RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net X-Patchwork-Delegate: kuba@kernel.org From: Willem de Bruijn Expand the test with these variants that use skb->frag_list: - GSO_TEST_FRAG_LIST: frag_skb length is gso_size - GSO_TEST_FRAG_LIST_PURE: same, data exclusively in frag skbs - GSO_TEST_FRAG_LIST_NON_UNIFORM: frag_skb length may vary - GSO_TEST_GSO_BY_FRAGS: frag_skb length defines gso_size, i.e., segs may have varying sizes. Signed-off-by: Willem de Bruijn --- net/core/gso_test.c | 93 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/net/core/gso_test.c b/net/core/gso_test.c index 41d1daa20831e..dc3ca31d11292 100644 --- a/net/core/gso_test.c +++ b/net/core/gso_test.c @@ -27,6 +27,10 @@ enum gso_test_nr { GSO_TEST_FRAGS, GSO_TEST_FRAGS_PURE, GSO_TEST_GSO_PARTIAL, + GSO_TEST_FRAG_LIST, + GSO_TEST_FRAG_LIST_PURE, + GSO_TEST_FRAG_LIST_NON_UNIFORM, + GSO_TEST_GSO_BY_FRAGS, }; struct gso_test_case { @@ -37,6 +41,8 @@ struct gso_test_case { unsigned int linear_len; unsigned int nr_frags; const unsigned int *frags; + unsigned int nr_frag_skbs; + const unsigned int *frag_skbs; /* output as expected */ unsigned int nr_segs; @@ -84,6 +90,48 @@ static struct gso_test_case cases[] = { .nr_segs = 2, .segs = (const unsigned int[]) { 2 * gso_size, 3 }, }, + { + /* commit 89319d3801d1: frag_list on mss boundaries */ + .id = GSO_TEST_FRAG_LIST, + .name = "frag_list", + .linear_len = gso_size, + .nr_frag_skbs = 2, + .frag_skbs = (const unsigned int[]) { gso_size, gso_size }, + .nr_segs = 3, + .segs = (const unsigned int[]) { gso_size, gso_size, gso_size }, + }, + { + .id = GSO_TEST_FRAG_LIST_PURE, + .name = "frag_list_pure", + .nr_frag_skbs = 2, + .frag_skbs = (const unsigned int[]) { gso_size, gso_size }, + .nr_segs = 2, + .segs = (const unsigned int[]) { gso_size, gso_size }, + }, + { + /* commit 43170c4e0ba7: GRO of frag_list trains */ + .id = GSO_TEST_FRAG_LIST_NON_UNIFORM, + .name = "frag_list_non_uniform", + .linear_len = gso_size, + .nr_frag_skbs = 4, + .frag_skbs = (const unsigned int[]) { gso_size, 1, gso_size, 2 }, + .nr_segs = 4, + .segs = (const unsigned int[]) { gso_size, gso_size, gso_size, 3 }, + }, + { + /* commit 3953c46c3ac7 ("sk_buff: allow segmenting based on frag sizes") and + * commit 90017accff61 ("sctp: Add GSO support") + * + * "there will be a cover skb with protocol headers and + * children ones containing the actual segments" + */ + .id = GSO_TEST_GSO_BY_FRAGS, + .name = "gso_by_frags", + .nr_frag_skbs = 4, + .frag_skbs = (const unsigned int[]) { 100, 200, 300, 400 }, + .nr_segs = 4, + .segs = (const unsigned int[]) { 100, 200, 300, 400 }, + }, }; static void gso_test_case_to_desc(struct gso_test_case *t, char *desc) @@ -131,10 +179,55 @@ static void gso_test_func(struct kunit *test) skb->truesize += skb->data_len; } + if (tcase->frag_skbs) { + unsigned int total_size = 0, total_true_size = 0; + unsigned int alloc_size = 0; + struct sk_buff *frag_skb, *prev = NULL; + + page = alloc_page(GFP_KERNEL); + KUNIT_ASSERT_NOT_NULL(test, page); + page_ref_add(page, tcase->nr_frag_skbs - 1); + + for (i = 0; i < tcase->nr_frag_skbs; i++) { + unsigned int frag_size; + + frag_size = tcase->frag_skbs[i]; + frag_skb = build_skb(page_address(page) + alloc_size, + frag_size + shinfo_size); + KUNIT_ASSERT_NOT_NULL(test, frag_skb); + __skb_put(frag_skb, frag_size); + + if (prev) + prev->next = frag_skb; + else + skb_shinfo(skb)->frag_list = frag_skb; + prev = frag_skb; + + total_size += frag_size; + total_true_size += frag_skb->truesize; + alloc_size += frag_size + shinfo_size; + } + + KUNIT_ASSERT_LE(test, alloc_size, PAGE_SIZE); + + skb->len += total_size; + skb->data_len += total_size; + skb->truesize += total_true_size; + + if (tcase->id == GSO_TEST_GSO_BY_FRAGS) + skb_shinfo(skb)->gso_size = GSO_BY_FRAGS; + } + features = NETIF_F_SG | NETIF_F_HW_CSUM; if (tcase->id == GSO_TEST_GSO_PARTIAL) features |= NETIF_F_GSO_PARTIAL; + /* TODO: this should also work with SG, + * rather than hit BUG_ON(i >= nfrags) + */ + if (tcase->id == GSO_TEST_FRAG_LIST_NON_UNIFORM) + features &= ~NETIF_F_SG; + segs = skb_segment(skb, features); if (IS_ERR(segs)) { KUNIT_FAIL(test, "segs error %lld", PTR_ERR(segs));