From patchwork Sun Oct 8 20:12:32 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: 13412786 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 6B594FBF0 for ; Sun, 8 Oct 2023 20:12:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="ne8zeq7i" Received: from mail-oi1-x235.google.com (mail-oi1-x235.google.com [IPv6:2607:f8b0:4864:20::235]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3A2F7B3 for ; Sun, 8 Oct 2023 13:12:49 -0700 (PDT) Received: by mail-oi1-x235.google.com with SMTP id 5614622812f47-3af5fcb5e37so2714543b6e.0 for ; Sun, 08 Oct 2023 13:12:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1696795968; x=1697400768; 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=0ay/TcEg/S/ybayJhZXidfw3Q3AAi4EgcKb1TnJa9+s=; b=ne8zeq7iJ3JxY/MjK9vr51nja9PP9l7vhzuvx8lZPXZLVQn3y2G6XDbCYH0C8Kb1KD qhUoK8wU6x/MTX94fi5qOizPwcbPOh86vpboVCrYJE8K8+DcJsCi1RZDdYOinCZVSfIx 7PzSlI5MW9XzP58rmhTUW1CSybam02kMdpRl8TK/2hfy67OFsdXhRjxQysS6IsP8uGv6 GsWkDnZQm1lQRboF5vDUtuju2eBcDQBlW7JknyBWQtalgAJIrjFzBT084o6jOG5sVDlV G/UJ83Og49/Pjmrb+MeykAhMIR74X+TIlj8+gebFq3u/9uHUxpF4FlTTZAslN74Xwtm4 Ng7Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696795968; x=1697400768; 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=0ay/TcEg/S/ybayJhZXidfw3Q3AAi4EgcKb1TnJa9+s=; b=hayEEssYlkpNMjmQYrITVXgCzLoARRU8rnw1QSn7IGCB9yj/M/XjziQTJCUOJ5NRlx eRnkZae2AciS1mm6mMr3HrAtBpGcPyFnvcMta4RWW8g7cBu9gMlapISB7P3KpJA8rRyO DnWku2ned2UQK7P8DR4fT5gA9OvQ60EuOQNlN3hOVR70gqvUC2YANJgYamwk6z9sXPa+ UdHktq1ses6OWwbXFLwt+LOjHyWr4JPpr1I4eVCFqp3/96LMNwZPl32ekq1JwNFgZMnw qDX0TAOD8jx+ihlYggr+2SrqdRpjpxhr0EoqtmtRiozovchoXbQzjXZX0FSIhJ3hFIh3 5S7w== X-Gm-Message-State: AOJu0YxAR6mYU7C6HGstk4LwGxP6MDN4x7yIKRbUL+pOKZUvM8G8asMG seCXWnhanr2XprOLHnuckWteo5PiKwiZfg== X-Google-Smtp-Source: AGHT+IEEItzD3eOHtFP+UGr9TrCLB8kH92LEi5nAwAhd3xM1/FYzlGtIgbpNNRnvzX3eCG97xFc4cQ== X-Received: by 2002:a05:6808:13d1:b0:3ab:84f0:b490 with SMTP id d17-20020a05680813d100b003ab84f0b490mr17442887oiw.27.1696795968171; Sun, 08 Oct 2023 13:12:48 -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 v18-20020ac87292000000b00419c9215f0asm3075533qto.53.2023.10.08.13.12.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 08 Oct 2023 13:12:47 -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 v2 1/3] net: add skb_segment kunit test Date: Sun, 8 Oct 2023 16:12:32 -0400 Message-ID: <20231008201244.3700784-2-willemdebruijn.kernel@gmail.com> X-Mailer: git-send-email 2.42.0.609.gbb76f46606-goog In-Reply-To: <20231008201244.3700784-1-willemdebruijn.kernel@gmail.com> References: <20231008201244.3700784-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 --- 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..eaa85939ed208 --- /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 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"); +MODULE_DESCRIPTION("KUnit tests for segmentation offload"); From patchwork Sun Oct 8 20:12:33 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: 13412788 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 A75E31A59B for ; Sun, 8 Oct 2023 20:12:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="fl2mfED1" Received: from mail-qk1-x732.google.com (mail-qk1-x732.google.com [IPv6:2607:f8b0:4864:20::732]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 96C58B6 for ; Sun, 8 Oct 2023 13:12:49 -0700 (PDT) Received: by mail-qk1-x732.google.com with SMTP id af79cd13be357-7742da399a2so264989985a.0 for ; Sun, 08 Oct 2023 13:12:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1696795968; x=1697400768; 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=xSWNewQqlaIQyWDI9hrczm+cy6FgsRoLMTzAic6qvbE=; b=fl2mfED1N+xk57Rka4OQi2pPaSoe84Qy0gG8WyzhxIlHfbz0B1gTMOq0niq6PoyA7P eiWC71RwGoBRa+0dIjMNbdJPtI8wRpbi0pP76TIonCvcs/qGofuatoyfbE5STZS7eyVr hGIGGpHXvv58ceSdKBywwAcUVbFaABe4YT1psd20lzXOMdhD2qV0ghdxBxREDYVAgdtF lBBOmLPoMVbiiuqmQI448nJmGpxmEao683FwJQ1x9z6LzirOE1PviiuD9LkS7mldJst6 FZvhC3NPaNPoxX1tvT0O/JGoAy9Hhklvgr4vlbIB4jMG07DD+0I+KB8VYFK/UHhsiCe4 FEww== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696795968; x=1697400768; 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=xSWNewQqlaIQyWDI9hrczm+cy6FgsRoLMTzAic6qvbE=; b=iocVcgVN5w+UJ9JSFjLn4fNr88Y9xv+OMCFid7aKHXyT5KP4wk022SVDH7AqurnYc+ PfIAmKgUp3RZSNv1u8/UKndR4hpU6fMzkMlrU2Z4GXR+5Aay324EZLfc58pdK6vy4w5B 9ugMIGTyE2YcXkMGHuPOWs6tLqzf0SMTRnFQVwATwE4oXECaDHGja5mc+PcdIIkifOYh zCe0QHGMCkkOKOE+hPJm65jr9rCe/4I4Vh1rXnRUdbdfQYH/gkQtbwQp9nZYqr7qyR/W eB8FQGnlpF4UfAAqeewTPDlDylEpIrHYdIonYXgdLLx5bNKXNmLnlcxbBvmFbXQiurrv 6kYw== X-Gm-Message-State: AOJu0YyimSKgKT8W2nRmlL6+2L3KIlbLHumkuxyY0g8j6cu835GVp/+5 zwSR9YaRl+s1NJ/5EUWhZfiAC8xrRb5UQg== X-Google-Smtp-Source: AGHT+IFHy9eUlWfG/7QtSRnZ00C79CtPuMap2tocjK9ndMR2kelO+ZznXK8aeC6TRKxIfRa1PKvnuQ== X-Received: by 2002:a05:622a:647:b0:418:12d4:c096 with SMTP id a7-20020a05622a064700b0041812d4c096mr17986455qtb.2.1696795968664; Sun, 08 Oct 2023 13:12:48 -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 v18-20020ac87292000000b00419c9215f0asm3075533qto.53.2023.10.08.13.12.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 08 Oct 2023 13:12:48 -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 v2 2/3] net: parametrize skb_segment unit test to expand coverage Date: Sun, 8 Oct 2023 16:12:33 -0400 Message-ID: <20231008201244.3700784-3-willemdebruijn.kernel@gmail.com> X-Mailer: git-send-email 2.42.0.609.gbb76f46606-goog In-Reply-To: <20231008201244.3700784-1-willemdebruijn.kernel@gmail.com> References: <20231008201244.3700784-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 eaa85939ed208..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 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 Sun Oct 8 20:12:34 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: 13412787 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 6E5731A59A for ; Sun, 8 Oct 2023 20:12:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="j0zrcUJi" Received: from mail-qt1-x82e.google.com (mail-qt1-x82e.google.com [IPv6:2607:f8b0:4864:20::82e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 0B632BA for ; Sun, 8 Oct 2023 13:12:50 -0700 (PDT) Received: by mail-qt1-x82e.google.com with SMTP id d75a77b69052e-4181462ebf0so26192021cf.3 for ; Sun, 08 Oct 2023 13:12:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1696795969; x=1697400769; 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=17yqKc1kHaOMA6mN8raOlE7hraCjIklZ3SgNF0zPb1c=; b=j0zrcUJiK+qguZJp1HkwDxVytc50EuWIq9D428LlyEOs/kRs621icXA4fj3iJLQKSA L7b2fIW3d8zJMmWot4R7+aMRme2WSnXCGz8lc6+SWPNRE0Ys6bFEpW65XfFqN6/bbFkP 3Q2vMm3ylIBNaBEf1UwTHqvCpmLu7eWVBC2PPTOJl5n/M44hzEIuzkytL3DccNQ6HRR2 Xq13aNbXCGOmEWR21+Aod61zOeY6GzLNXgBhsY1r3Z6NDNC0qfeJLSc+92KoUzWm7vdG A4HclQpkAqMlpdALp7cvZQ2oyr3nonPrItpqBFQ8NhZou8N9CohlTlsu/hm5Oan/qlCo WH0w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1696795969; x=1697400769; 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=17yqKc1kHaOMA6mN8raOlE7hraCjIklZ3SgNF0zPb1c=; b=h7vjfdeG7zvppow+PPdlzg4XV7kY3AwFxS82RW2SQHkZfnTRsTGYP3L88cEI6Vv4eE 1hRvf5J1ubaqk/cCkbxDl+doA44CqgSXo4C7YIBkYIVslRu+1XEyjGIDhzmP0J0mSpYb C++cJX7znvVYz/jS6HAiqFuLn30JemGMjva4soZ3XkLGRcoabm9u81WF5WEXNZ5dOqAr P63iuLO8dFubhmrwZkpfqDYP7aKsT2gmpgV+WUy5qiK7WwphcTJcJ/RYegOyJh6PBkiL lQ7ED8TpecaQ+M42C1gFdRBwDvCb6jF4EnDv6kxoxsmGT54kk3E/H0NUh0viQUcn8Emd 2Kaw== X-Gm-Message-State: AOJu0YyeSn5Ts82ciMfbqy5MzawyZoOmtKijDgfesJ6Ec1o2BpnKJhdK 22fyvj7M5PfafBkd8n4z0IWn5CKxKZkU/A== X-Google-Smtp-Source: AGHT+IFzMwRntua6Sj7EEjeQiR2jzYNjwGuLrAAobzJEJigzgI5Ohz9gCtsRY/P6ZWIvCNAIKWU6Bw== X-Received: by 2002:a05:622a:1cb:b0:418:10d0:96f6 with SMTP id t11-20020a05622a01cb00b0041810d096f6mr18456834qtw.23.1696795969128; Sun, 08 Oct 2023 13:12:49 -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 v18-20020ac87292000000b00419c9215f0asm3075533qto.53.2023.10.08.13.12.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 08 Oct 2023 13:12:48 -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 v2 3/3] net: expand skb_segment unit test with frag_list coverage Date: Sun, 8 Oct 2023 16:12:34 -0400 Message-ID: <20231008201244.3700784-4-willemdebruijn.kernel@gmail.com> X-Mailer: git-send-email 2.42.0.609.gbb76f46606-goog In-Reply-To: <20231008201244.3700784-1-willemdebruijn.kernel@gmail.com> References: <20231008201244.3700784-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 --- 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));