From patchwork Mon Oct 9 14:41:51 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: 13413846 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 BB35C18C3F for ; Mon, 9 Oct 2023 14:42:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Iu+cG290" Received: from mail-qv1-xf32.google.com (mail-qv1-xf32.google.com [IPv6:2607:f8b0:4864:20::f32]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D4387B0 for ; Mon, 9 Oct 2023 07:42:10 -0700 (PDT) Received: by mail-qv1-xf32.google.com with SMTP id 6a1803df08f44-65b0dad1f98so30700006d6.0 for ; Mon, 09 Oct 2023 07:42:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1696862530; x=1697467330; 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=zlET0UUPyGUD8kVASjY6uHbtDOXx+5mqoroI6Ddp8oI=; b=Iu+cG290HglW5G/9PrVmgSMMEtTEJoT64Z66i4G5t0q3FxLStSoJe/9l3wHJD1p0Ic ixuXxHzZ5my/zNNpia44ReVMXZo1N1ih8Es+1KoSQGAFUQHaZdB5t1XOJjZa+JJHsjsq fEZGD/GquJ2DZR1zZBT5BjysOe3E6VgVfE2nnvlhU1ePSgOw5IByGbSo4jaud6XHBTlR /LbbZeGEEtX7zfWt73oko5a1XU+mK83qyy6lK+Lylvqdp0MW9K+VYMkTbEZFwhcbEeut AwPNoEmZANGy3TD5EWsIjlsxE9XrgeNLNR60mev0gjuuISyJvFDTCMOnyiPOCatoQLQW VmGQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696862530; x=1697467330; 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=zlET0UUPyGUD8kVASjY6uHbtDOXx+5mqoroI6Ddp8oI=; b=X43s/o+SsPN7PhPZurs+cGeNr+OapsYdBRrp1WLae6uLytHHCX0ECf9eIb2NMZAN/I RYvdowPVIZRMUYqZrgMoA85s8FnFxvxitF3+nkGPrShin1J6q476Ra1kvqQoS1Nmi2TO GI/sNQ9HCkSAXx9ujnObN7r94uh5coAHeG64R/K82QCN5gHrJu7eGHniyb8vCegjc7/t tEzcWHOjl71FvA6sshmZSuWFtuA7Sxqeiw7QYp5tDGuCsryy/4Uwcc1MPoSrSW5Mhj+D mqDw6CKJtvCM/uTOz6ZrNSkH0l9ipbAAAud/a+1EMgugp6wVG7Bq9kaKIqFNJC5fmia2 6kPA== X-Gm-Message-State: AOJu0Yzftgj1QcMsK0dj7s2KEH0Yj7C53L8XmkkY05FgU1407ex++gWb gPmWOHcvgb9W0KrMTsrtm1SkMe0xCNTURw== X-Google-Smtp-Source: AGHT+IGtzqd9hkC5guRUd7UE2D5wH6HQ3exXmJPnukLdReTbBzBZN8h6Bd7uJdhhU/Ws9xFgzdzFcw== X-Received: by 2002:a05:6214:33ca:b0:656:2fa3:ecdd with SMTP id mw10-20020a05621433ca00b006562fa3ecddmr15854074qvb.57.1696862529811; Mon, 09 Oct 2023 07:42:09 -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 i1-20020a0cf381000000b0064f43efc844sm3873592qvk.32.2023.10.09.07.42.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 Oct 2023 07:42:09 -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 v3 1/3] net: add skb_segment kunit test Date: Mon, 9 Oct 2023 10:41:51 -0400 Message-ID: <20231009144205.269931-2-willemdebruijn.kernel@gmail.com> X-Mailer: git-send-email 2.42.0.609.gbb76f46606-goog In-Reply-To: <20231009144205.269931-1-willemdebruijn.kernel@gmail.com> References: <20231009144205.269931-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 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 Reviewed-by: Florian Westphal --- v2->v3 - make payload_len non-const. somehow the const of gso_size gets lost in the expression. - add Florian's Reviewed-by based on v1. v1->v2 - add MODULE_DESCRIPTION --- net/Kconfig | 9 +++++ net/core/Makefile | 1 + net/core/gso_test.c | 87 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 97 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..454874c11b90f --- /dev/null +++ b/net/core/gso_test.c @@ -0,0 +1,87 @@ +// 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 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"); +MODULE_DESCRIPTION("KUnit tests for segmentation offload"); From patchwork Mon Oct 9 14:41:52 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: 13413845 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 473DEC8CB for ; Mon, 9 Oct 2023 14:42:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="DnMpe4Mf" Received: from mail-yb1-xb31.google.com (mail-yb1-xb31.google.com [IPv6:2607:f8b0:4864:20::b31]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 32A03C6 for ; Mon, 9 Oct 2023 07:42:11 -0700 (PDT) Received: by mail-yb1-xb31.google.com with SMTP id 3f1490d57ef6-d9a398f411fso359882276.3 for ; Mon, 09 Oct 2023 07:42:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1696862530; x=1697467330; 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=wekXm/Qhr1M0gvk/LTJJvAOXL/suHG184YeXYTB6nBw=; b=DnMpe4Mfh2eWVNk1EuVoOe23ZsrzwMosgzGx3BVC+CU9GeBSIaShMDLwBCIw6lD2jY YBb8f0c2ZvjAQ5OCAMooggI9f3agNcRD2NcJwKvQlyL/FLdKtdIa09EsNWSmMjQ9ljX0 OAwdjWIJlpYXfZVhCcLFxj2JWEqU6IGqFhJOZXbrzhUF65ktlpnwdozI0p3h3sGQ6kAC aoeoVDonacSgTarBA6kHVLr4d2autsNdPi+LzEsg2rckYmcDqgvcVfSDzuJ7JftxTzw1 S77GydMpwWGPquReUHcI5DCNP+lGG7dg33UyMsIofA7HpYTDoKeqwp07MaOjqaFk5sJ9 IS0g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696862530; x=1697467330; 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=wekXm/Qhr1M0gvk/LTJJvAOXL/suHG184YeXYTB6nBw=; b=RxNKzKrqDE43ZtvsBD8d/AuMwfp5LIY6TnrfZnAJVbuDLEGE7nVIysnjVX+2iUUsDf nXK5sPRDkgBntbPY6yfGmxnV21oPgoAO/TZAzxabJKWTQ2HsiUIrtENRl7CWz/Zw6DDS NHusiBc/ncFZPRrST8+ppxalYyqtzMmB3cmopWnD/FCuTjcVDse7u9q5N1JhLd1hixJl 7nDlIXLbra4bRwy0qHlHI4WG0mXQVeSu7iEtDErBtykQhENqq5fPao8zzlF+5NdffYYW WTS9GjWzA5j2OX1Ya04XMfZMrqybMAMiWgTfKpTsMe+ngXIZ2YS1NSlOAsAWHWr19enR popg== X-Gm-Message-State: AOJu0YxytAHvaW7gYfVZDPtD0EK/hzxTUp8P5PRt0vwU35jb4LPEO/61 e1ivP0VSxBNmP4h6huq2QW3LLU7HGfWpiw== X-Google-Smtp-Source: AGHT+IHBPrUe/kCyYgRCCMKmYKf3QEtsEi3ElcGldorlPS9aRisznOhEwxRAL9O3Eow5I41XW2f1zQ== X-Received: by 2002:a25:fc15:0:b0:d7f:7ce1:994f with SMTP id v21-20020a25fc15000000b00d7f7ce1994fmr14916778ybd.10.1696862530269; Mon, 09 Oct 2023 07:42:10 -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 i1-20020a0cf381000000b0064f43efc844sm3873592qvk.32.2023.10.09.07.42.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 Oct 2023 07:42:10 -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 v3 2/3] net: parametrize skb_segment unit test to expand coverage Date: Mon, 9 Oct 2023 10:41:52 -0400 Message-ID: <20231009144205.269931-3-willemdebruijn.kernel@gmail.com> X-Mailer: git-send-email 2.42.0.609.gbb76f46606-goog In-Reply-To: <20231009144205.269931-1-willemdebruijn.kernel@gmail.com> References: <20231009144205.269931-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 Reviewed-by: Florian Westphal --- v2->v3 - add Florian's Reviewed-by based on v1. --- 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 454874c11b90f..c4e0b0832dbac 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 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 Mon Oct 9 14:41:53 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: 13413847 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 4F1E919BD3 for ; Mon, 9 Oct 2023 14:42:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="QXHwO76b" Received: from mail-qk1-x72b.google.com (mail-qk1-x72b.google.com [IPv6:2607:f8b0:4864:20::72b]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 978EEB4 for ; Mon, 9 Oct 2023 07:42:11 -0700 (PDT) Received: by mail-qk1-x72b.google.com with SMTP id af79cd13be357-775810b032aso314374185a.1 for ; Mon, 09 Oct 2023 07:42:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1696862531; x=1697467331; 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=A2CneznQ/yZkm1+ntbZ8O9t3a7G8zboj4AqLfjJjUSw=; b=QXHwO76b+6LPUUYvEmtvFktUqiKRN+0nCn1RuYLWqnl0TAsCdlZR/Kh2TOJJQ7j/kW 8JJQzTMzRA6Acv0sprJBi9+Kqd0w/4/SazYKXKYs62cpqLGe3TFzkivIBS2vO2OGuEBC 1YvHVEOWTTwP0phQvIkw9qpHGeKhTHJ+vyHitWccQZwGeymi1TYUZDeSZPZ7zpMEXlaU ffASE2zIeMCb7UfEtptqSSg+Fk1gxa3RHDUTfwwd2rm/uD4ykJUcmYY7pIHi8Bo2UNPh /mvvdwGWSSbjdtZCRQnxwcM04ztkTACbttJLAu65luozHXLtsUgGFkNPgfoDLqjvmLOa o/ww== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696862531; x=1697467331; 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=A2CneznQ/yZkm1+ntbZ8O9t3a7G8zboj4AqLfjJjUSw=; b=phNjYQuZHWo9/2aDxd+USBDuNirLabwJ+/7nKw+ykAiflZLCriGP36WfAwXo6vc05H LnAaHxBtDv1A+5sqnDYyEdKT6jZLICPSAXE/E++/dUGp6WWN64hPUSJehS7MiZnXCldl bnwMbxEXM2nUke4DGOfslz+rsx8EkeivoGRkyxab0AnGU6jwvE43PQxWtnptzWjvzsQV jiOO93kBUqM4wfu/bA07Xs/sNYAK/lF1hDzprS3272TK4aLHQO2Mc0C3zDhPdCCio8oK jp3jhazIF2VA2LQ59lJ/RzPlfBzNPIYFDAyCyxPmy5yyY2gpMBh+z0VFhzmlVmvT4NJw Fc8w== X-Gm-Message-State: AOJu0YwUZ7Ra1bnCOLM5Im5qy/Lym9MJYI1e6xu3ZERPBW467MK+lZcO kI55SQuVANXh+8GPW5CkKpLVeRchUW/ASQ== X-Google-Smtp-Source: AGHT+IHMv/9KK7CaKX2T5IlEL4/xTIZ9Uw18aSt772hRMhGepLp9MlpNJs6TkDlguJanoI3d5Ds8mw== X-Received: by 2002:a0c:e48f:0:b0:656:5535:ef27 with SMTP id n15-20020a0ce48f000000b006565535ef27mr17197601qvl.48.1696862530715; Mon, 09 Oct 2023 07:42:10 -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 i1-20020a0cf381000000b0064f43efc844sm3873592qvk.32.2023.10.09.07.42.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 09 Oct 2023 07:42:10 -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 v3 3/3] net: expand skb_segment unit test with frag_list coverage Date: Mon, 9 Oct 2023 10:41:53 -0400 Message-ID: <20231009144205.269931-4-willemdebruijn.kernel@gmail.com> X-Mailer: git-send-email 2.42.0.609.gbb76f46606-goog In-Reply-To: <20231009144205.269931-1-willemdebruijn.kernel@gmail.com> References: <20231009144205.269931-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_NONE,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 Reviewed-by: Florian Westphal --- v2->v3 - add Florian's Reviewed-by based on v1. v1->v2 - maintain reverse christmas tree --- net/core/gso_test.c | 92 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/net/core/gso_test.c b/net/core/gso_test.c index c4e0b0832dbac..c1a6cffb6f961 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,54 @@ 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, 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));