From patchwork Fri May 28 23:52:36 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kumar Kartikeya Dwivedi X-Patchwork-Id: 12287549 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 43781C4708D for ; Fri, 28 May 2021 23:53:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 147F2613EB for ; Fri, 28 May 2021 23:53:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229602AbhE1XzQ (ORCPT ); Fri, 28 May 2021 19:55:16 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45338 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229594AbhE1XzP (ORCPT ); Fri, 28 May 2021 19:55:15 -0400 Received: from mail-pf1-x443.google.com (mail-pf1-x443.google.com [IPv6:2607:f8b0:4864:20::443]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 069A3C061574; Fri, 28 May 2021 16:53:40 -0700 (PDT) Received: by mail-pf1-x443.google.com with SMTP id z26so408654pfj.5; Fri, 28 May 2021 16:53:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=/Agy9x6Mg8As0SqD+0oLSEwC0oEqk9fEZ+8467L6XkQ=; b=HY9k/UkijCOBkH3ui67wovUSEgGGVINUOmjrom8ZbKCTMwsc6ww/XaaexcXLikqtdJ 4AKi3RCpqpkgi8Babb/WClnTqNVZ9Sn3mdtwrsU8PhDYUHYEviwawY5nLIQKbk8bt5/f UemAoEDFNxai8LAJeduJRCb187SWQOTzMOy/NpIN8R9OdN2ZOVbTlhWNsFzLTLGoP1YZ sBfbmBa+FXXMnwqabILcDQQmY77tWh9SVlLmFCjLH9uwuhosTqnOSD2EtZ89GggRFDd+ aCzw0WBOM1GSIVKtri+zDhjwdSnwU/Stc8H42Dt+bREMNydiHwCUTdzYGhvFs8OpsBMo eCaA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=/Agy9x6Mg8As0SqD+0oLSEwC0oEqk9fEZ+8467L6XkQ=; b=f2Xw1EIqc7IO26I26nISd/v45YAeWGhZJXnd9Wx8CLgx+dSk6V2+ooSufHZny9Ghdu oCW/QU61ZBulHnYYD3z0EsBaGt0NojJDaUAdMgL5LRHTo8H6qDDHMpPFnpeSfRjrjejh RnAiJzbJNl8avmc7iONgVdKk2iPXHU5AtUcXhSTdvFvyhZEU6zoY6SgcnL6Juevb0X8J n2ygLJQ6hIAOtSMLiIjr8ofDX5VXBpmg6Tiwy57RSbM18fZ8AId9+TGhscdbz/NFANfs GPmtK5kn76RIxyHLP7sx4R7CFfgVLkAqsTVi1OTIxUlpRrR/8vluRyNURis+mTcOtSa2 r4Fw== X-Gm-Message-State: AOAM533nQ4/9fXaPpMce2s6NF/xFaicmxTy2O2sfCARbWTYL/mqcgG4o wNKhHg46bgOR0/bO6LVkXpkYvxTQ8Yw= X-Google-Smtp-Source: ABdhPJyjX4Hk/LGUFfPGemqT8kCp5nhpWS/6dbFDFf1MEyMalxl9iigVsR60g88pzPWWjMHl1lQAjA== X-Received: by 2002:a62:a101:0:b029:2e8:e878:bdc0 with SMTP id b1-20020a62a1010000b02902e8e878bdc0mr6227257pff.38.1622246019349; Fri, 28 May 2021 16:53:39 -0700 (PDT) Received: from localhost ([2402:3a80:11db:3aa9:ad24:a4a2:844f:6a0a]) by smtp.gmail.com with ESMTPSA id o6sm5304430pfb.126.2021.05.28.16.53.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 28 May 2021 16:53:39 -0700 (PDT) From: Kumar Kartikeya Dwivedi To: bpf@vger.kernel.org Cc: Kumar Kartikeya Dwivedi , Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , "David S. Miller" , Jakub Kicinski , Jesper Dangaard Brouer , =?utf-8?q?Toke_H=C3=B8iland-J?= =?utf-8?q?=C3=B8rgensen?= , netdev@vger.kernel.org Subject: [PATCH RFC bpf-next 01/15] samples: bpf: fix a couple of NULL dereferences Date: Sat, 29 May 2021 05:22:36 +0530 Message-Id: <20210528235250.2635167-2-memxor@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210528235250.2635167-1-memxor@gmail.com> References: <20210528235250.2635167-1-memxor@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net X-Patchwork-State: RFC When giving it just one ifname instead of two, it accesses argv[optind + 1], which is out of bounds (as argc < optind + 1). Signed-off-by: Kumar Kartikeya Dwivedi --- samples/bpf/xdp_redirect_map_user.c | 4 ++-- samples/bpf/xdp_redirect_user.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/samples/bpf/xdp_redirect_map_user.c b/samples/bpf/xdp_redirect_map_user.c index 0e8192688dfc..ad3cdc4c07d3 100644 --- a/samples/bpf/xdp_redirect_map_user.c +++ b/samples/bpf/xdp_redirect_map_user.c @@ -169,8 +169,8 @@ int main(int argc, char **argv) return 1; } - if (optind == argc) { - printf("usage: %s _IN _OUT\n", argv[0]); + if (argc <= optind + 1) { + usage(basename(argv[0])); return 1; } diff --git a/samples/bpf/xdp_redirect_user.c b/samples/bpf/xdp_redirect_user.c index 41d705c3a1f7..4e310660632b 100644 --- a/samples/bpf/xdp_redirect_user.c +++ b/samples/bpf/xdp_redirect_user.c @@ -130,8 +130,8 @@ int main(int argc, char **argv) if (!(xdp_flags & XDP_FLAGS_SKB_MODE)) xdp_flags |= XDP_FLAGS_DRV_MODE; - if (optind == argc) { - printf("usage: %s _IN _OUT\n", argv[0]); + if (argc <= optind + 1) { + usage(basename(argv[0])); return 1; } From patchwork Fri May 28 23:52:37 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Kumar Kartikeya Dwivedi X-Patchwork-Id: 12287551 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id CE7C2C47090 for ; Fri, 28 May 2021 23:53:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9843F613B4 for ; Fri, 28 May 2021 23:53:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229594AbhE1XzT (ORCPT ); Fri, 28 May 2021 19:55:19 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45360 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229647AbhE1XzT (ORCPT ); Fri, 28 May 2021 19:55:19 -0400 Received: from mail-pf1-x441.google.com (mail-pf1-x441.google.com [IPv6:2607:f8b0:4864:20::441]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6C464C061761; Fri, 28 May 2021 16:53:43 -0700 (PDT) Received: by mail-pf1-x441.google.com with SMTP id d78so4410699pfd.10; Fri, 28 May 2021 16:53:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=w4uDJfsiaEde7mtiom3feHmGREEMUxgwXXDZIdtVjj4=; b=SgWXtiljBZS0tybMKTByV6k+FiuKCKaFN/g6flYuc6lSEg43E22dMoSyvJTxjOYZf2 7b4a+8spAqBMcKRBnTKr9yD19H6Vyri6y5qVK7wBM/GVWyzo2MSoJlZ1cSO3ARBTyW/a xurle3Oy/Jd+alkYtYWUDjaHqg2aAO03txmEi/I/+n0D/i+yAh/csULvdMj4MPJ1vwF2 Clr6HcNGhS5L3hYmXRg/PRZizqkkq3HgaS5RXT0PgrTfvlx2egArByoUv7KzdZIG5rTY MPXXtjMSXvSHTD5CvbP0B1DPxRr4/9/iTp+88/TrQ60luEy5ZQoFalrmXHcvkRP90avA kdrA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=w4uDJfsiaEde7mtiom3feHmGREEMUxgwXXDZIdtVjj4=; b=FyynsHUCvAam6XpVnZc6Rc0++5BHqahiaDcgy8XAEhmeE1HzlI6Ou113+yDwBo6feX tEznA3s3hQXi6DBX2jOBKfIQtPrkc1UHrgCLr9pDfrWgCNvQ5TxUEd3T5HycGw2Vi36h AM/5ecPBQobcvVCM1xkY3Qg0HSEGu3UQXV23ctnyJ79tCcSS6nw5NyxdzMgN970n+olr STtX0WPibiUAEy2NIur7hREjKFYRLaI+ZDGRv0B12t63/K2548S/mWiNjCuyD4v7zJCV EoYt6Teuc2fSj5PkT72j6XeIAilVRxCD1tdleNOrIWaS4zuYQNN/GiyXLm7t/UiJp+up cd4w== X-Gm-Message-State: AOAM5338pZru3q6lwoBc/qC1Elhj+yEKQUeFbiq5Dpjp8rlJZlRfbVo/ pnHVicsDMOmGE8WW2WxsZpwa98lhwI4= X-Google-Smtp-Source: ABdhPJywhmRiSIiDvaOFuTlLDzlcgOctv+G28m35JpToTg4hHXaCEusyy+D0MjoaCtHgyzrfGfCA4A== X-Received: by 2002:aa7:8b4f:0:b029:2bd:ea13:c4b4 with SMTP id i15-20020aa78b4f0000b02902bdea13c4b4mr6163994pfd.48.1622246022727; Fri, 28 May 2021 16:53:42 -0700 (PDT) Received: from localhost ([2402:3a80:11db:3aa9:ad24:a4a2:844f:6a0a]) by smtp.gmail.com with ESMTPSA id b9sm5093068pfo.107.2021.05.28.16.53.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 28 May 2021 16:53:42 -0700 (PDT) From: Kumar Kartikeya Dwivedi To: bpf@vger.kernel.org Cc: Kumar Kartikeya Dwivedi , Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , "David S. Miller" , Jakub Kicinski , Jesper Dangaard Brouer , =?utf-8?q?Toke_H=C3=B8iland-J?= =?utf-8?q?=C3=B8rgensen?= , netdev@vger.kernel.org Subject: [PATCH RFC bpf-next 02/15] samples: bpf: fix a couple of warnings Date: Sat, 29 May 2021 05:22:37 +0530 Message-Id: <20210528235250.2635167-3-memxor@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210528235250.2635167-1-memxor@gmail.com> References: <20210528235250.2635167-1-memxor@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net X-Patchwork-State: RFC cookie_uid_helper_example.c: In function ‘main’: cookie_uid_helper_example.c:178:69: warning: ‘ -j ACCEPT’ directive writing 10 bytes into a region of size between 8 and 58 [-Wformat-overflow=] 178 | sprintf(rules, "iptables -A OUTPUT -m bpf --object-pinned %s -j ACCEPT", | ^~~~~~~~~~ /home/kkd/src/linux/samples/bpf/cookie_uid_helper_example.c:178:9: note: ‘sprintf’ output between 53 and 103 bytes into a destination of size 100 178 | sprintf(rules, "iptables -A OUTPUT -m bpf --object-pinned %s -j ACCEPT", | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 179 | file); | ~~~~~ Fix by using snprintf and a sufficiently sized buffer. tracex4_user.c:35:15: warning: ‘write’ reading 12 bytes from a region of size 11 [-Wstringop-overread] 35 | key = write(1, "\e[1;1H\e[2J", 12); /* clear screen */ | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~ Use size as 11. Signed-off-by: Kumar Kartikeya Dwivedi --- samples/bpf/cookie_uid_helper_example.c | 12 +++++++++--- samples/bpf/tracex4_user.c | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/samples/bpf/cookie_uid_helper_example.c b/samples/bpf/cookie_uid_helper_example.c index cc3bce8d3aac..30fdcd664da2 100644 --- a/samples/bpf/cookie_uid_helper_example.c +++ b/samples/bpf/cookie_uid_helper_example.c @@ -1,3 +1,4 @@ + /* This test is a demo of using get_socket_uid and get_socket_cookie * helper function to do per socket based network traffic monitoring. * It requires iptables version higher then 1.6.1. to load pinned eBPF @@ -167,7 +168,7 @@ static void prog_load(void) static void prog_attach_iptables(char *file) { int ret; - char rules[100]; + char rules[256]; if (bpf_obj_pin(prog_fd, file)) error(1, errno, "bpf_obj_pin"); @@ -175,8 +176,13 @@ static void prog_attach_iptables(char *file) printf("file path too long: %s\n", file); exit(1); } - sprintf(rules, "iptables -A OUTPUT -m bpf --object-pinned %s -j ACCEPT", - file); + ret = snprintf(rules, sizeof(rules), + "iptables -A OUTPUT -m bpf --object-pinned %s -j ACCEPT", + file); + if (ret < 0 || ret >= sizeof(rules)) { + printf("error constructing iptables command\n"); + exit(1); + } ret = system(rules); if (ret < 0) { printf("iptables rule update failed: %d/n", WEXITSTATUS(ret)); diff --git a/samples/bpf/tracex4_user.c b/samples/bpf/tracex4_user.c index cea399424bca..566e6440e8c2 100644 --- a/samples/bpf/tracex4_user.c +++ b/samples/bpf/tracex4_user.c @@ -32,7 +32,7 @@ static void print_old_objects(int fd) __u64 key, next_key; struct pair v; - key = write(1, "\e[1;1H\e[2J", 12); /* clear screen */ + key = write(1, "\e[1;1H\e[2J", 11); /* clear screen */ key = -1; while (bpf_map_get_next_key(fd, &key, &next_key) == 0) { From patchwork Fri May 28 23:52:38 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kumar Kartikeya Dwivedi X-Patchwork-Id: 12287553 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B3313C47087 for ; Fri, 28 May 2021 23:53:49 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 940346135F for ; Fri, 28 May 2021 23:53:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229666AbhE1XzX (ORCPT ); Fri, 28 May 2021 19:55:23 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45372 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229647AbhE1XzW (ORCPT ); Fri, 28 May 2021 19:55:22 -0400 Received: from mail-pf1-x444.google.com (mail-pf1-x444.google.com [IPv6:2607:f8b0:4864:20::444]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E200FC061574; Fri, 28 May 2021 16:53:46 -0700 (PDT) Received: by mail-pf1-x444.google.com with SMTP id y202so4413747pfc.6; Fri, 28 May 2021 16:53:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=V86Ql8jRAGbtURMVGsSlMfJC5php4p6tg5O5Rdj4NKQ=; b=pwcPA+yr8DFpkZnV3Jpk/aFTrind6HeRc1oAmrApBtCe1S2fCKHewqnIDFEwke/JUY R4fmxM+OKydOs9FOd3TKvZLS8WzNgdIj8Dw5mxnQF3ufPS2lAAWc4vNxHcEiuVcE/sg/ eSWkd104++t8SpxecSzodBJfuRmxPBRm86DS4Nw9a5A+JUkFBkLM69YGsiZcHJxCDpX1 BDGXDrnvs72h5uMaj6IZS81KoafZEaVpScbIv2fahfeFN0KXs29HAOkP0JILX4bq1ZP4 dJFBdH5bf75FubBJnvRrv0R8lmYilUGNfbPdIT4bgjnbApZBpCtDFfxcCtxNfUZROYo9 NEVA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=V86Ql8jRAGbtURMVGsSlMfJC5php4p6tg5O5Rdj4NKQ=; b=EVRm9q1y0xZQMEd0vyQbSyYCFy8TYluWueR9cFxwYyYJx9cEQT5mM0fS/PTQFsWiv3 a46MLzF9CEXilxrabcP4xdksfAORru1dycfoqMvjCafGkmMQeo7rNVWT+Rj5K4cIsTEu Hf2C7McKijwPN2S5t0KsOayCEkbmLyTCcXtx43pVP2AS+11/MKfGSmyrDDgrvjLemzP1 gVHolSW5M5b1vzUio651A9JRgigakOxeRla/tDfURyqu2e6nxT6qP4yAyFsF8E5p/DGk 5ZG9QMikl0pI9pmh5eK0QXaPvsvcOlC8QmQQlCQ4uSOgIja5EPUmlga8kBN3c+0wfssP G/BA== X-Gm-Message-State: AOAM531mHXInDlRZ4exCG8phY0L2G8e0o8RqPnEGcC4VvyDxokr1VhmQ bmbVRdI2pozaVrydNC4omgCW2D7yCqo= X-Google-Smtp-Source: ABdhPJyb+GcZNHkIqE/azlo0NNh7bNlCdqYJ4o4eufOxMvJ+YSqfQs+FYZKJfvc5HoDEuyyvu05z9Q== X-Received: by 2002:a62:1481:0:b029:2c1:1e90:c54 with SMTP id 123-20020a6214810000b02902c11e900c54mr6168441pfu.55.1622246026196; Fri, 28 May 2021 16:53:46 -0700 (PDT) Received: from localhost ([2402:3a80:11db:3aa9:ad24:a4a2:844f:6a0a]) by smtp.gmail.com with ESMTPSA id x125sm1191860pfx.201.2021.05.28.16.53.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 28 May 2021 16:53:45 -0700 (PDT) From: Kumar Kartikeya Dwivedi To: bpf@vger.kernel.org Cc: Kumar Kartikeya Dwivedi , Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , "David S. Miller" , Jakub Kicinski , Jesper Dangaard Brouer , =?utf-8?q?Toke_H=C3=B8iland-J?= =?utf-8?q?=C3=B8rgensen?= , netdev@vger.kernel.org Subject: [PATCH RFC bpf-next 03/15] samples: bpf: split out common bpf progs to its own file Date: Sat, 29 May 2021 05:22:38 +0530 Message-Id: <20210528235250.2635167-4-memxor@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210528235250.2635167-1-memxor@gmail.com> References: <20210528235250.2635167-1-memxor@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net X-Patchwork-State: RFC This is done to later reuse these in a way that can be shared among multiple samples. We are using xdp_redirect_cpu_kern.c as a base to build further support on top (mostly adding a few other things missing that xdp_monitor does in subsequent patches). Signed-off-by: Kumar Kartikeya Dwivedi --- samples/bpf/xdp_sample_kern.h | 220 ++++++++++++++++++++++++++++++++++ 1 file changed, 220 insertions(+) create mode 100644 samples/bpf/xdp_sample_kern.h diff --git a/samples/bpf/xdp_sample_kern.h b/samples/bpf/xdp_sample_kern.h new file mode 100644 index 000000000000..bb809542ac20 --- /dev/null +++ b/samples/bpf/xdp_sample_kern.h @@ -0,0 +1,220 @@ +// SPDX-License-Identifier: GPL-2.0 +/* GPLv2, Copyright(c) 2017 Jesper Dangaard Brouer, Red Hat, Inc. */ +#pragma once + +#include +#include + +#define MAX_CPUS 64 + +/* Common stats data record to keep userspace more simple */ +struct datarec { + __u64 processed; + __u64 dropped; + __u64 issue; + __u64 xdp_pass; + __u64 xdp_drop; + __u64 xdp_redirect; +}; + +/* Count RX packets, as XDP bpf_prog doesn't get direct TX-success + * feedback. Redirect TX errors can be caught via a tracepoint. + */ +struct { + __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); + __type(key, u32); + __type(value, struct datarec); + __uint(max_entries, 1); +} rx_cnt SEC(".maps"); + +/* Used by trace point */ +struct { + __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); + __type(key, u32); + __type(value, struct datarec); + __uint(max_entries, 2); + /* TODO: have entries for all possible errno's */ +} redirect_err_cnt SEC(".maps"); + +/* Used by trace point */ +struct { + __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); + __type(key, u32); + __type(value, struct datarec); + __uint(max_entries, MAX_CPUS); +} cpumap_enqueue_cnt SEC(".maps"); + +/* Used by trace point */ +struct { + __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); + __type(key, u32); + __type(value, struct datarec); + __uint(max_entries, 1); +} cpumap_kthread_cnt SEC(".maps"); + +/* Used by trace point */ +struct { + __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); + __type(key, u32); + __type(value, struct datarec); + __uint(max_entries, 1); +} exception_cnt SEC(".maps"); + +/*** Trace point code ***/ + +/* Tracepoint format: /sys/kernel/debug/tracing/events/xdp/xdp_redirect/format + * Code in: kernel/include/trace/events/xdp.h + */ +struct xdp_redirect_ctx { + u64 __pad; // First 8 bytes are not accessible by bpf code + int prog_id; // offset:8; size:4; signed:1; + u32 act; // offset:12 size:4; signed:0; + int ifindex; // offset:16 size:4; signed:1; + int err; // offset:20 size:4; signed:1; + int to_ifindex; // offset:24 size:4; signed:1; + u32 map_id; // offset:28 size:4; signed:0; + int map_index; // offset:32 size:4; signed:1; +}; // offset:36 + +enum { + XDP_REDIRECT_SUCCESS = 0, + XDP_REDIRECT_ERROR = 1 +}; + +static __always_inline +int xdp_redirect_collect_stat(struct xdp_redirect_ctx *ctx) +{ + u32 key = XDP_REDIRECT_ERROR; + struct datarec *rec; + int err = ctx->err; + + if (!err) + key = XDP_REDIRECT_SUCCESS; + + rec = bpf_map_lookup_elem(&redirect_err_cnt, &key); + if (!rec) + return 0; + rec->dropped += 1; + + return 0; /* Indicate event was filtered (no further processing)*/ + /* + * Returning 1 here would allow e.g. a perf-record tracepoint + * to see and record these events, but it doesn't work well + * in-practice as stopping perf-record also unload this + * bpf_prog. Plus, there is additional overhead of doing so. + */ +} + +SEC("tracepoint/xdp/xdp_redirect_err") +int trace_xdp_redirect_err(struct xdp_redirect_ctx *ctx) +{ + return xdp_redirect_collect_stat(ctx); +} + +SEC("tracepoint/xdp/xdp_redirect_map_err") +int trace_xdp_redirect_map_err(struct xdp_redirect_ctx *ctx) +{ + return xdp_redirect_collect_stat(ctx); +} + +/* Tracepoint format: /sys/kernel/debug/tracing/events/xdp/xdp_exception/format + * Code in: kernel/include/trace/events/xdp.h + */ +struct xdp_exception_ctx { + u64 __pad; // First 8 bytes are not accessible by bpf code + int prog_id; // offset:8; size:4; signed:1; + u32 act; // offset:12; size:4; signed:0; + int ifindex; // offset:16; size:4; signed:1; +}; + +SEC("tracepoint/xdp/xdp_exception") +int trace_xdp_exception(struct xdp_exception_ctx *ctx) +{ + struct datarec *rec; + u32 key = 0; + + rec = bpf_map_lookup_elem(&exception_cnt, &key); + if (!rec) + return 1; + rec->dropped += 1; + + return 0; +} + +/* Tracepoint: /sys/kernel/debug/tracing/events/xdp/xdp_cpumap_enqueue/format + * Code in: kernel/include/trace/events/xdp.h + */ +struct cpumap_enqueue_ctx { + u64 __pad; // First 8 bytes are not accessible by bpf code + int map_id; // offset:8; size:4; signed:1; + u32 act; // offset:12; size:4; signed:0; + int cpu; // offset:16; size:4; signed:1; + unsigned int drops; // offset:20; size:4; signed:0; + unsigned int processed; // offset:24; size:4; signed:0; + int to_cpu; // offset:28; size:4; signed:1; +}; + +SEC("tracepoint/xdp/xdp_cpumap_enqueue") +int trace_xdp_cpumap_enqueue(struct cpumap_enqueue_ctx *ctx) +{ + u32 to_cpu = ctx->to_cpu; + struct datarec *rec; + + if (to_cpu >= MAX_CPUS) + return 1; + + rec = bpf_map_lookup_elem(&cpumap_enqueue_cnt, &to_cpu); + if (!rec) + return 0; + rec->processed += ctx->processed; + rec->dropped += ctx->drops; + + /* Record bulk events, then userspace can calc average bulk size */ + if (ctx->processed > 0) + rec->issue += 1; + + /* Inception: It's possible to detect overload situations, via + * this tracepoint. This can be used for creating a feedback + * loop to XDP, which can take appropriate actions to mitigate + * this overload situation. + */ + return 0; +} + +/* Tracepoint: /sys/kernel/debug/tracing/events/xdp/xdp_cpumap_kthread/format + * Code in: kernel/include/trace/events/xdp.h + */ +struct cpumap_kthread_ctx { + u64 __pad; // First 8 bytes are not accessible + int map_id; // offset:8; size:4; signed:1; + u32 act; // offset:12; size:4; signed:0; + int cpu; // offset:16; size:4; signed:1; + unsigned int drops; // offset:20; size:4; signed:0; + unsigned int processed; // offset:24; size:4; signed:0; + int sched; // offset:28; size:4; signed:1; + unsigned int xdp_pass; // offset:32; size:4; signed:0; + unsigned int xdp_drop; // offset:36; size:4; signed:0; + unsigned int xdp_redirect; // offset:40; size:4; signed:0; +}; + +SEC("tracepoint/xdp/xdp_cpumap_kthread") +int trace_xdp_cpumap_kthread(struct cpumap_kthread_ctx *ctx) +{ + struct datarec *rec; + u32 key = 0; + + rec = bpf_map_lookup_elem(&cpumap_kthread_cnt, &key); + if (!rec) + return 0; + rec->processed += ctx->processed; + rec->dropped += ctx->drops; + rec->xdp_pass += ctx->xdp_pass; + rec->xdp_drop += ctx->xdp_drop; + rec->xdp_redirect += ctx->xdp_redirect; + + /* Count times kthread yielded CPU via schedule call */ + if (ctx->sched) + rec->issue++; + + return 0; +} From patchwork Fri May 28 23:52:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kumar Kartikeya Dwivedi X-Patchwork-Id: 12287555 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E9C8CC4708C for ; Fri, 28 May 2021 23:53:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C7FAD6135F for ; Fri, 28 May 2021 23:53:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229647AbhE1Xz1 (ORCPT ); Fri, 28 May 2021 19:55:27 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45392 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229683AbhE1Xz0 (ORCPT ); Fri, 28 May 2021 19:55:26 -0400 Received: from mail-pj1-x1042.google.com (mail-pj1-x1042.google.com [IPv6:2607:f8b0:4864:20::1042]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 85A40C061574; Fri, 28 May 2021 16:53:51 -0700 (PDT) Received: by mail-pj1-x1042.google.com with SMTP id q6so3439746pjj.2; Fri, 28 May 2021 16:53:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=RXhVruWbOeNtku5rCwmtjRr9+FG/vhtYR9nyp4K1kC8=; b=K1T/Kri8XuHRsPho3xjuDQH8rijjRfDHlJUxAJf/A/F6JLK9y4SeIiL260kFAlVj4o dFzU1UTqTrRnUv6R7u5prpdb9ec/JOYQOT4ocoBwuzuMsdXpusKwiiQK2WS8BeAa5biM nvnbSvGJI6ptO0/3rhjf23jHVPbs9HQySscq44IPvIJ3vA92j7MfsWnnI5x26G5kd8qY OhcdjPT4eGhIl7rztLcCd+KM05LS2mAGSGaOsCwFQ9jRwAvdQ+dHAPZ3K6sEkPQ4D7E0 0TXWVZ2C91U9CrVmwMDrfDWkXLR0Mdkz284KPIXvHTTroPv65qPOZ7C9P2+OWyBR8y9I YdmA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=RXhVruWbOeNtku5rCwmtjRr9+FG/vhtYR9nyp4K1kC8=; b=LF3gSbv/ky5G0AnqvFt/SprshaH1otSt2Wb4+8UZJLxgsIkZ/e6mk0OyDaov24LRv3 f5qq97AwC8TShhTlYLBylJbZbs0cSQBrbFj1hhSZNtWD0y9aK6bg7QW0a9ZVxmq3eaXZ U1ZVuec3b9mBKR0MtaC537ZA17MgnorgL1foeUske6GEJF9kt4asm3q+BBK+MxFdSUFc BixYeu5IbtwnYlg/IeLzuEk1LB2e5o6ueRIcRa7GcLhPsxGHQNG9LZaRj6i265d5qndN C9LOXU7jPyhCpMcn2YSvlTGXUpmHWzriRzn0IFt9QRMMH2NDnSJj1ZblEs0BD2P5qWf3 sjwg== X-Gm-Message-State: AOAM531CnPsx5t9EHpS6RfEmARfjedrgOsI8laeGFoXSnMocprcOuxqU WOVoU/4HMpbWllLyM45j0INkVUttwsc= X-Google-Smtp-Source: ABdhPJwXnjPmXqj+SvmEpggqbk0WhGlChuhvM+iB9rpWu1WPIuKhb08Bq2x8wzYW4Yf775jbeajj2A== X-Received: by 2002:a17:90a:db51:: with SMTP id u17mr7071539pjx.222.1622246030060; Fri, 28 May 2021 16:53:50 -0700 (PDT) Received: from localhost ([2402:3a80:11db:3aa9:ad24:a4a2:844f:6a0a]) by smtp.gmail.com with ESMTPSA id g72sm5092724pfb.33.2021.05.28.16.53.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 28 May 2021 16:53:49 -0700 (PDT) From: Kumar Kartikeya Dwivedi To: bpf@vger.kernel.org Cc: Kumar Kartikeya Dwivedi , Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , "David S. Miller" , Jakub Kicinski , Jesper Dangaard Brouer , =?utf-8?q?Toke_H=C3=B8iland-J?= =?utf-8?q?=C3=B8rgensen?= , netdev@vger.kernel.org Subject: [PATCH RFC bpf-next 04/15] samples: bpf: refactor generic parts out of xdp_redirect_cpu_user Date: Sat, 29 May 2021 05:22:39 +0530 Message-Id: <20210528235250.2635167-5-memxor@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210528235250.2635167-1-memxor@gmail.com> References: <20210528235250.2635167-1-memxor@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net X-Patchwork-State: RFC This will be used as a common core for multiple samples. Also add a couple of helpers: get_driver_name - Used to print the driver name for ifindex get_mac_addr - Used to get the mac address for ifindex This change also converts xdp_redirect_cpu to use the new xdp_sample helpers. Signed-off-by: Kumar Kartikeya Dwivedi --- samples/bpf/Makefile | 2 +- samples/bpf/xdp_redirect_cpu_kern.c | 213 +--------- samples/bpf/xdp_redirect_cpu_user.c | 560 ++------------------------ samples/bpf/xdp_sample_user.c | 588 ++++++++++++++++++++++++++++ samples/bpf/xdp_sample_user.h | 101 +++++ 5 files changed, 730 insertions(+), 734 deletions(-) create mode 100644 samples/bpf/xdp_sample_user.c create mode 100644 samples/bpf/xdp_sample_user.h diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile index 520434ea966f..c0c02e12e28b 100644 --- a/samples/bpf/Makefile +++ b/samples/bpf/Makefile @@ -101,7 +101,7 @@ per_socket_stats_example-objs := cookie_uid_helper_example.o xdp_redirect-objs := xdp_redirect_user.o xdp_redirect_map-objs := xdp_redirect_map_user.o xdp_redirect_map_multi-objs := xdp_redirect_map_multi_user.o -xdp_redirect_cpu-objs := xdp_redirect_cpu_user.o +xdp_redirect_cpu-objs := xdp_redirect_cpu_user.o xdp_sample_user.o xdp_monitor-objs := xdp_monitor_user.o xdp_rxq_info-objs := xdp_rxq_info_user.o syscall_tp-objs := syscall_tp_user.o diff --git a/samples/bpf/xdp_redirect_cpu_kern.c b/samples/bpf/xdp_redirect_cpu_kern.c index 8255025dea97..06cc37f0289c 100644 --- a/samples/bpf/xdp_redirect_cpu_kern.c +++ b/samples/bpf/xdp_redirect_cpu_kern.c @@ -14,6 +14,7 @@ #include #include #include "hash_func01.h" +#include "xdp_sample_kern.h" #define MAX_CPUS NR_CPUS @@ -25,51 +26,6 @@ struct { __uint(max_entries, MAX_CPUS); } cpu_map SEC(".maps"); -/* Common stats data record to keep userspace more simple */ -struct datarec { - __u64 processed; - __u64 dropped; - __u64 issue; - __u64 xdp_pass; - __u64 xdp_drop; - __u64 xdp_redirect; -}; - -/* Count RX packets, as XDP bpf_prog doesn't get direct TX-success - * feedback. Redirect TX errors can be caught via a tracepoint. - */ -struct { - __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); - __type(key, u32); - __type(value, struct datarec); - __uint(max_entries, 1); -} rx_cnt SEC(".maps"); - -/* Used by trace point */ -struct { - __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); - __type(key, u32); - __type(value, struct datarec); - __uint(max_entries, 2); - /* TODO: have entries for all possible errno's */ -} redirect_err_cnt SEC(".maps"); - -/* Used by trace point */ -struct { - __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); - __type(key, u32); - __type(value, struct datarec); - __uint(max_entries, MAX_CPUS); -} cpumap_enqueue_cnt SEC(".maps"); - -/* Used by trace point */ -struct { - __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); - __type(key, u32); - __type(value, struct datarec); - __uint(max_entries, 1); -} cpumap_kthread_cnt SEC(".maps"); - /* Set of maps controlling available CPU, and for iterating through * selectable redirect CPUs. */ @@ -92,14 +48,6 @@ struct { __uint(max_entries, 1); } cpus_iterator SEC(".maps"); -/* Used by trace point */ -struct { - __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); - __type(key, u32); - __type(value, struct datarec); - __uint(max_entries, 1); -} exception_cnt SEC(".maps"); - /* Helper parse functions */ /* Parse Ethernet layer 2, extract network layer 3 offset and protocol @@ -569,162 +517,3 @@ int xdp_prognum5_lb_hash_ip_pairs(struct xdp_md *ctx) } char _license[] SEC("license") = "GPL"; - -/*** Trace point code ***/ - -/* Tracepoint format: /sys/kernel/debug/tracing/events/xdp/xdp_redirect/format - * Code in: kernel/include/trace/events/xdp.h - */ -struct xdp_redirect_ctx { - u64 __pad; // First 8 bytes are not accessible by bpf code - int prog_id; // offset:8; size:4; signed:1; - u32 act; // offset:12 size:4; signed:0; - int ifindex; // offset:16 size:4; signed:1; - int err; // offset:20 size:4; signed:1; - int to_ifindex; // offset:24 size:4; signed:1; - u32 map_id; // offset:28 size:4; signed:0; - int map_index; // offset:32 size:4; signed:1; -}; // offset:36 - -enum { - XDP_REDIRECT_SUCCESS = 0, - XDP_REDIRECT_ERROR = 1 -}; - -static __always_inline -int xdp_redirect_collect_stat(struct xdp_redirect_ctx *ctx) -{ - u32 key = XDP_REDIRECT_ERROR; - struct datarec *rec; - int err = ctx->err; - - if (!err) - key = XDP_REDIRECT_SUCCESS; - - rec = bpf_map_lookup_elem(&redirect_err_cnt, &key); - if (!rec) - return 0; - rec->dropped += 1; - - return 0; /* Indicate event was filtered (no further processing)*/ - /* - * Returning 1 here would allow e.g. a perf-record tracepoint - * to see and record these events, but it doesn't work well - * in-practice as stopping perf-record also unload this - * bpf_prog. Plus, there is additional overhead of doing so. - */ -} - -SEC("tracepoint/xdp/xdp_redirect_err") -int trace_xdp_redirect_err(struct xdp_redirect_ctx *ctx) -{ - return xdp_redirect_collect_stat(ctx); -} - -SEC("tracepoint/xdp/xdp_redirect_map_err") -int trace_xdp_redirect_map_err(struct xdp_redirect_ctx *ctx) -{ - return xdp_redirect_collect_stat(ctx); -} - -/* Tracepoint format: /sys/kernel/debug/tracing/events/xdp/xdp_exception/format - * Code in: kernel/include/trace/events/xdp.h - */ -struct xdp_exception_ctx { - u64 __pad; // First 8 bytes are not accessible by bpf code - int prog_id; // offset:8; size:4; signed:1; - u32 act; // offset:12; size:4; signed:0; - int ifindex; // offset:16; size:4; signed:1; -}; - -SEC("tracepoint/xdp/xdp_exception") -int trace_xdp_exception(struct xdp_exception_ctx *ctx) -{ - struct datarec *rec; - u32 key = 0; - - rec = bpf_map_lookup_elem(&exception_cnt, &key); - if (!rec) - return 1; - rec->dropped += 1; - - return 0; -} - -/* Tracepoint: /sys/kernel/debug/tracing/events/xdp/xdp_cpumap_enqueue/format - * Code in: kernel/include/trace/events/xdp.h - */ -struct cpumap_enqueue_ctx { - u64 __pad; // First 8 bytes are not accessible by bpf code - int map_id; // offset:8; size:4; signed:1; - u32 act; // offset:12; size:4; signed:0; - int cpu; // offset:16; size:4; signed:1; - unsigned int drops; // offset:20; size:4; signed:0; - unsigned int processed; // offset:24; size:4; signed:0; - int to_cpu; // offset:28; size:4; signed:1; -}; - -SEC("tracepoint/xdp/xdp_cpumap_enqueue") -int trace_xdp_cpumap_enqueue(struct cpumap_enqueue_ctx *ctx) -{ - u32 to_cpu = ctx->to_cpu; - struct datarec *rec; - - if (to_cpu >= MAX_CPUS) - return 1; - - rec = bpf_map_lookup_elem(&cpumap_enqueue_cnt, &to_cpu); - if (!rec) - return 0; - rec->processed += ctx->processed; - rec->dropped += ctx->drops; - - /* Record bulk events, then userspace can calc average bulk size */ - if (ctx->processed > 0) - rec->issue += 1; - - /* Inception: It's possible to detect overload situations, via - * this tracepoint. This can be used for creating a feedback - * loop to XDP, which can take appropriate actions to mitigate - * this overload situation. - */ - return 0; -} - -/* Tracepoint: /sys/kernel/debug/tracing/events/xdp/xdp_cpumap_kthread/format - * Code in: kernel/include/trace/events/xdp.h - */ -struct cpumap_kthread_ctx { - u64 __pad; // First 8 bytes are not accessible - int map_id; // offset:8; size:4; signed:1; - u32 act; // offset:12; size:4; signed:0; - int cpu; // offset:16; size:4; signed:1; - unsigned int drops; // offset:20; size:4; signed:0; - unsigned int processed; // offset:24; size:4; signed:0; - int sched; // offset:28; size:4; signed:1; - unsigned int xdp_pass; // offset:32; size:4; signed:0; - unsigned int xdp_drop; // offset:36; size:4; signed:0; - unsigned int xdp_redirect; // offset:40; size:4; signed:0; -}; - -SEC("tracepoint/xdp/xdp_cpumap_kthread") -int trace_xdp_cpumap_kthread(struct cpumap_kthread_ctx *ctx) -{ - struct datarec *rec; - u32 key = 0; - - rec = bpf_map_lookup_elem(&cpumap_kthread_cnt, &key); - if (!rec) - return 0; - rec->processed += ctx->processed; - rec->dropped += ctx->drops; - rec->xdp_pass += ctx->xdp_pass; - rec->xdp_drop += ctx->xdp_drop; - rec->xdp_redirect += ctx->xdp_redirect; - - /* Count times kthread yielded CPU via schedule call */ - if (ctx->sched) - rec->issue++; - - return 0; -} diff --git a/samples/bpf/xdp_redirect_cpu_user.c b/samples/bpf/xdp_redirect_cpu_user.c index 576411612523..6dbed962a2e2 100644 --- a/samples/bpf/xdp_redirect_cpu_user.c +++ b/samples/bpf/xdp_redirect_cpu_user.c @@ -22,59 +22,21 @@ static const char *__doc__ = #include #include -/* How many xdp_progs are defined in _kern.c */ -#define MAX_PROG 6 - #include #include #include "bpf_util.h" +#include "xdp_sample_user.h" static int ifindex = -1; static char ifname_buf[IF_NAMESIZE]; static char *ifname; static __u32 prog_id; +static int map_fd; +static int avail_fd; +static int count_fd; static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST; -static int n_cpus; - -enum map_type { - CPU_MAP, - RX_CNT, - REDIRECT_ERR_CNT, - CPUMAP_ENQUEUE_CNT, - CPUMAP_KTHREAD_CNT, - CPUS_AVAILABLE, - CPUS_COUNT, - CPUS_ITERATOR, - EXCEPTION_CNT, -}; - -static const char *const map_type_strings[] = { - [CPU_MAP] = "cpu_map", - [RX_CNT] = "rx_cnt", - [REDIRECT_ERR_CNT] = "redirect_err_cnt", - [CPUMAP_ENQUEUE_CNT] = "cpumap_enqueue_cnt", - [CPUMAP_KTHREAD_CNT] = "cpumap_kthread_cnt", - [CPUS_AVAILABLE] = "cpus_available", - [CPUS_COUNT] = "cpus_count", - [CPUS_ITERATOR] = "cpus_iterator", - [EXCEPTION_CNT] = "exception_cnt", -}; - -#define NUM_TP 5 -#define NUM_MAP 9 -struct bpf_link *tp_links[NUM_TP] = {}; -static int map_fds[NUM_MAP]; -static int tp_cnt = 0; - -/* Exit return codes */ -#define EXIT_OK 0 -#define EXIT_FAIL 1 -#define EXIT_FAIL_OPTION 2 -#define EXIT_FAIL_XDP 3 -#define EXIT_FAIL_BPF 4 -#define EXIT_FAIL_MEM 5 static const struct option long_options[] = { {"help", no_argument, NULL, 'h' }, @@ -115,11 +77,8 @@ static void int_exit(int sig) printf("program on interface changed, not removing\n"); } } - /* Detach tracepoints */ - while (tp_cnt) - bpf_link__destroy(tp_links[--tp_cnt]); - exit(EXIT_OK); + sample_exit(EXIT_OK); } static void print_avail_progs(struct bpf_object *obj) @@ -155,423 +114,6 @@ static void usage(char *argv[], struct bpf_object *obj) printf("\n"); } -/* gettime returns the current time of day in nanoseconds. - * Cost: clock_gettime (ns) => 26ns (CLOCK_MONOTONIC) - * clock_gettime (ns) => 9ns (CLOCK_MONOTONIC_COARSE) - */ -#define NANOSEC_PER_SEC 1000000000 /* 10^9 */ -static __u64 gettime(void) -{ - struct timespec t; - int res; - - res = clock_gettime(CLOCK_MONOTONIC, &t); - if (res < 0) { - fprintf(stderr, "Error with gettimeofday! (%i)\n", res); - exit(EXIT_FAIL); - } - return (__u64) t.tv_sec * NANOSEC_PER_SEC + t.tv_nsec; -} - -/* Common stats data record shared with _kern.c */ -struct datarec { - __u64 processed; - __u64 dropped; - __u64 issue; - __u64 xdp_pass; - __u64 xdp_drop; - __u64 xdp_redirect; -}; -struct record { - __u64 timestamp; - struct datarec total; - struct datarec *cpu; -}; -struct stats_record { - struct record rx_cnt; - struct record redir_err; - struct record kthread; - struct record exception; - struct record enq[]; -}; - -static bool map_collect_percpu(int fd, __u32 key, struct record *rec) -{ - /* For percpu maps, userspace gets a value per possible CPU */ - unsigned int nr_cpus = bpf_num_possible_cpus(); - struct datarec values[nr_cpus]; - __u64 sum_xdp_redirect = 0; - __u64 sum_xdp_pass = 0; - __u64 sum_xdp_drop = 0; - __u64 sum_processed = 0; - __u64 sum_dropped = 0; - __u64 sum_issue = 0; - int i; - - if ((bpf_map_lookup_elem(fd, &key, values)) != 0) { - fprintf(stderr, - "ERR: bpf_map_lookup_elem failed key:0x%X\n", key); - return false; - } - /* Get time as close as possible to reading map contents */ - rec->timestamp = gettime(); - - /* Record and sum values from each CPU */ - for (i = 0; i < nr_cpus; i++) { - rec->cpu[i].processed = values[i].processed; - sum_processed += values[i].processed; - rec->cpu[i].dropped = values[i].dropped; - sum_dropped += values[i].dropped; - rec->cpu[i].issue = values[i].issue; - sum_issue += values[i].issue; - rec->cpu[i].xdp_pass = values[i].xdp_pass; - sum_xdp_pass += values[i].xdp_pass; - rec->cpu[i].xdp_drop = values[i].xdp_drop; - sum_xdp_drop += values[i].xdp_drop; - rec->cpu[i].xdp_redirect = values[i].xdp_redirect; - sum_xdp_redirect += values[i].xdp_redirect; - } - rec->total.processed = sum_processed; - rec->total.dropped = sum_dropped; - rec->total.issue = sum_issue; - rec->total.xdp_pass = sum_xdp_pass; - rec->total.xdp_drop = sum_xdp_drop; - rec->total.xdp_redirect = sum_xdp_redirect; - return true; -} - -static struct datarec *alloc_record_per_cpu(void) -{ - unsigned int nr_cpus = bpf_num_possible_cpus(); - struct datarec *array; - - array = calloc(nr_cpus, sizeof(struct datarec)); - if (!array) { - fprintf(stderr, "Mem alloc error (nr_cpus:%u)\n", nr_cpus); - exit(EXIT_FAIL_MEM); - } - return array; -} - -static struct stats_record *alloc_stats_record(void) -{ - struct stats_record *rec; - int i, size; - - size = sizeof(*rec) + n_cpus * sizeof(struct record); - rec = malloc(size); - if (!rec) { - fprintf(stderr, "Mem alloc error\n"); - exit(EXIT_FAIL_MEM); - } - memset(rec, 0, size); - rec->rx_cnt.cpu = alloc_record_per_cpu(); - rec->redir_err.cpu = alloc_record_per_cpu(); - rec->kthread.cpu = alloc_record_per_cpu(); - rec->exception.cpu = alloc_record_per_cpu(); - for (i = 0; i < n_cpus; i++) - rec->enq[i].cpu = alloc_record_per_cpu(); - - return rec; -} - -static void free_stats_record(struct stats_record *r) -{ - int i; - - for (i = 0; i < n_cpus; i++) - free(r->enq[i].cpu); - free(r->exception.cpu); - free(r->kthread.cpu); - free(r->redir_err.cpu); - free(r->rx_cnt.cpu); - free(r); -} - -static double calc_period(struct record *r, struct record *p) -{ - double period_ = 0; - __u64 period = 0; - - period = r->timestamp - p->timestamp; - if (period > 0) - period_ = ((double) period / NANOSEC_PER_SEC); - - return period_; -} - -static __u64 calc_pps(struct datarec *r, struct datarec *p, double period_) -{ - __u64 packets = 0; - __u64 pps = 0; - - if (period_ > 0) { - packets = r->processed - p->processed; - pps = packets / period_; - } - return pps; -} - -static __u64 calc_drop_pps(struct datarec *r, struct datarec *p, double period_) -{ - __u64 packets = 0; - __u64 pps = 0; - - if (period_ > 0) { - packets = r->dropped - p->dropped; - pps = packets / period_; - } - return pps; -} - -static __u64 calc_errs_pps(struct datarec *r, - struct datarec *p, double period_) -{ - __u64 packets = 0; - __u64 pps = 0; - - if (period_ > 0) { - packets = r->issue - p->issue; - pps = packets / period_; - } - return pps; -} - -static void calc_xdp_pps(struct datarec *r, struct datarec *p, - double *xdp_pass, double *xdp_drop, - double *xdp_redirect, double period_) -{ - *xdp_pass = 0, *xdp_drop = 0, *xdp_redirect = 0; - if (period_ > 0) { - *xdp_redirect = (r->xdp_redirect - p->xdp_redirect) / period_; - *xdp_pass = (r->xdp_pass - p->xdp_pass) / period_; - *xdp_drop = (r->xdp_drop - p->xdp_drop) / period_; - } -} - -static void stats_print(struct stats_record *stats_rec, - struct stats_record *stats_prev, - char *prog_name, char *mprog_name, int mprog_fd) -{ - unsigned int nr_cpus = bpf_num_possible_cpus(); - double pps = 0, drop = 0, err = 0; - bool mprog_enabled = false; - struct record *rec, *prev; - int to_cpu; - double t; - int i; - - if (mprog_fd > 0) - mprog_enabled = true; - - /* Header */ - printf("Running XDP/eBPF prog_name:%s\n", prog_name); - printf("%-15s %-7s %-14s %-11s %-9s\n", - "XDP-cpumap", "CPU:to", "pps", "drop-pps", "extra-info"); - - /* XDP rx_cnt */ - { - char *fmt_rx = "%-15s %-7d %'-14.0f %'-11.0f %'-10.0f %s\n"; - char *fm2_rx = "%-15s %-7s %'-14.0f %'-11.0f\n"; - char *errstr = ""; - - rec = &stats_rec->rx_cnt; - prev = &stats_prev->rx_cnt; - t = calc_period(rec, prev); - for (i = 0; i < nr_cpus; i++) { - struct datarec *r = &rec->cpu[i]; - struct datarec *p = &prev->cpu[i]; - - pps = calc_pps(r, p, t); - drop = calc_drop_pps(r, p, t); - err = calc_errs_pps(r, p, t); - if (err > 0) - errstr = "cpu-dest/err"; - if (pps > 0) - printf(fmt_rx, "XDP-RX", - i, pps, drop, err, errstr); - } - pps = calc_pps(&rec->total, &prev->total, t); - drop = calc_drop_pps(&rec->total, &prev->total, t); - err = calc_errs_pps(&rec->total, &prev->total, t); - printf(fm2_rx, "XDP-RX", "total", pps, drop); - } - - /* cpumap enqueue stats */ - for (to_cpu = 0; to_cpu < n_cpus; to_cpu++) { - char *fmt = "%-15s %3d:%-3d %'-14.0f %'-11.0f %'-10.2f %s\n"; - char *fm2 = "%-15s %3s:%-3d %'-14.0f %'-11.0f %'-10.2f %s\n"; - char *errstr = ""; - - rec = &stats_rec->enq[to_cpu]; - prev = &stats_prev->enq[to_cpu]; - t = calc_period(rec, prev); - for (i = 0; i < nr_cpus; i++) { - struct datarec *r = &rec->cpu[i]; - struct datarec *p = &prev->cpu[i]; - - pps = calc_pps(r, p, t); - drop = calc_drop_pps(r, p, t); - err = calc_errs_pps(r, p, t); - if (err > 0) { - errstr = "bulk-average"; - err = pps / err; /* calc average bulk size */ - } - if (pps > 0) - printf(fmt, "cpumap-enqueue", - i, to_cpu, pps, drop, err, errstr); - } - pps = calc_pps(&rec->total, &prev->total, t); - if (pps > 0) { - drop = calc_drop_pps(&rec->total, &prev->total, t); - err = calc_errs_pps(&rec->total, &prev->total, t); - if (err > 0) { - errstr = "bulk-average"; - err = pps / err; /* calc average bulk size */ - } - printf(fm2, "cpumap-enqueue", - "sum", to_cpu, pps, drop, err, errstr); - } - } - - /* cpumap kthread stats */ - { - char *fmt_k = "%-15s %-7d %'-14.0f %'-11.0f %'-10.0f %s\n"; - char *fm2_k = "%-15s %-7s %'-14.0f %'-11.0f %'-10.0f %s\n"; - char *e_str = ""; - - rec = &stats_rec->kthread; - prev = &stats_prev->kthread; - t = calc_period(rec, prev); - for (i = 0; i < nr_cpus; i++) { - struct datarec *r = &rec->cpu[i]; - struct datarec *p = &prev->cpu[i]; - - pps = calc_pps(r, p, t); - drop = calc_drop_pps(r, p, t); - err = calc_errs_pps(r, p, t); - if (err > 0) - e_str = "sched"; - if (pps > 0) - printf(fmt_k, "cpumap_kthread", - i, pps, drop, err, e_str); - } - pps = calc_pps(&rec->total, &prev->total, t); - drop = calc_drop_pps(&rec->total, &prev->total, t); - err = calc_errs_pps(&rec->total, &prev->total, t); - if (err > 0) - e_str = "sched-sum"; - printf(fm2_k, "cpumap_kthread", "total", pps, drop, err, e_str); - } - - /* XDP redirect err tracepoints (very unlikely) */ - { - char *fmt_err = "%-15s %-7d %'-14.0f %'-11.0f\n"; - char *fm2_err = "%-15s %-7s %'-14.0f %'-11.0f\n"; - - rec = &stats_rec->redir_err; - prev = &stats_prev->redir_err; - t = calc_period(rec, prev); - for (i = 0; i < nr_cpus; i++) { - struct datarec *r = &rec->cpu[i]; - struct datarec *p = &prev->cpu[i]; - - pps = calc_pps(r, p, t); - drop = calc_drop_pps(r, p, t); - if (pps > 0) - printf(fmt_err, "redirect_err", i, pps, drop); - } - pps = calc_pps(&rec->total, &prev->total, t); - drop = calc_drop_pps(&rec->total, &prev->total, t); - printf(fm2_err, "redirect_err", "total", pps, drop); - } - - /* XDP general exception tracepoints */ - { - char *fmt_err = "%-15s %-7d %'-14.0f %'-11.0f\n"; - char *fm2_err = "%-15s %-7s %'-14.0f %'-11.0f\n"; - - rec = &stats_rec->exception; - prev = &stats_prev->exception; - t = calc_period(rec, prev); - for (i = 0; i < nr_cpus; i++) { - struct datarec *r = &rec->cpu[i]; - struct datarec *p = &prev->cpu[i]; - - pps = calc_pps(r, p, t); - drop = calc_drop_pps(r, p, t); - if (pps > 0) - printf(fmt_err, "xdp_exception", i, pps, drop); - } - pps = calc_pps(&rec->total, &prev->total, t); - drop = calc_drop_pps(&rec->total, &prev->total, t); - printf(fm2_err, "xdp_exception", "total", pps, drop); - } - - /* CPUMAP attached XDP program that runs on remote/destination CPU */ - if (mprog_enabled) { - char *fmt_k = "%-15s %-7d %'-14.0f %'-11.0f %'-10.0f\n"; - char *fm2_k = "%-15s %-7s %'-14.0f %'-11.0f %'-10.0f\n"; - double xdp_pass, xdp_drop, xdp_redirect; - - printf("\n2nd remote XDP/eBPF prog_name: %s\n", mprog_name); - printf("%-15s %-7s %-14s %-11s %-9s\n", - "XDP-cpumap", "CPU:to", "xdp-pass", "xdp-drop", "xdp-redir"); - - rec = &stats_rec->kthread; - prev = &stats_prev->kthread; - t = calc_period(rec, prev); - for (i = 0; i < nr_cpus; i++) { - struct datarec *r = &rec->cpu[i]; - struct datarec *p = &prev->cpu[i]; - - calc_xdp_pps(r, p, &xdp_pass, &xdp_drop, - &xdp_redirect, t); - if (xdp_pass > 0 || xdp_drop > 0 || xdp_redirect > 0) - printf(fmt_k, "xdp-in-kthread", i, xdp_pass, xdp_drop, - xdp_redirect); - } - calc_xdp_pps(&rec->total, &prev->total, &xdp_pass, &xdp_drop, - &xdp_redirect, t); - printf(fm2_k, "xdp-in-kthread", "total", xdp_pass, xdp_drop, xdp_redirect); - } - - printf("\n"); - fflush(stdout); -} - -static void stats_collect(struct stats_record *rec) -{ - int fd, i; - - fd = map_fds[RX_CNT]; - map_collect_percpu(fd, 0, &rec->rx_cnt); - - fd = map_fds[REDIRECT_ERR_CNT]; - map_collect_percpu(fd, 1, &rec->redir_err); - - fd = map_fds[CPUMAP_ENQUEUE_CNT]; - for (i = 0; i < n_cpus; i++) - map_collect_percpu(fd, i, &rec->enq[i]); - - fd = map_fds[CPUMAP_KTHREAD_CNT]; - map_collect_percpu(fd, 0, &rec->kthread); - - fd = map_fds[EXCEPTION_CNT]; - map_collect_percpu(fd, 0, &rec->exception); -} - - -/* Pointer swap trick */ -static inline void swap(struct stats_record **a, struct stats_record **b) -{ - struct stats_record *tmp; - - tmp = *a; - *a = *b; - *b = tmp; -} - static int create_cpu_entry(__u32 cpu, struct bpf_cpumap_val *value, __u32 avail_idx, bool new) { @@ -579,10 +121,11 @@ static int create_cpu_entry(__u32 cpu, struct bpf_cpumap_val *value, __u32 key = 0; int ret; + /* Update to bpf_skel */ /* Add a CPU entry to cpumap, as this allocate a cpu entry in * the kernel for the cpu. */ - ret = bpf_map_update_elem(map_fds[CPU_MAP], &cpu, value, 0); + ret = bpf_map_update_elem(map_fd, &cpu, value, 0); if (ret) { fprintf(stderr, "Create CPU entry failed (err:%d)\n", ret); exit(EXIT_FAIL_BPF); @@ -591,21 +134,21 @@ static int create_cpu_entry(__u32 cpu, struct bpf_cpumap_val *value, /* Inform bpf_prog's that a new CPU is available to select * from via some control maps. */ - ret = bpf_map_update_elem(map_fds[CPUS_AVAILABLE], &avail_idx, &cpu, 0); + ret = bpf_map_update_elem(avail_fd, &avail_idx, &cpu, 0); if (ret) { fprintf(stderr, "Add to avail CPUs failed\n"); exit(EXIT_FAIL_BPF); } /* When not replacing/updating existing entry, bump the count */ - ret = bpf_map_lookup_elem(map_fds[CPUS_COUNT], &key, &curr_cpus_count); + ret = bpf_map_lookup_elem(count_fd, &key, &curr_cpus_count); if (ret) { fprintf(stderr, "Failed reading curr cpus_count\n"); exit(EXIT_FAIL_BPF); } if (new) { curr_cpus_count++; - ret = bpf_map_update_elem(map_fds[CPUS_COUNT], &key, + ret = bpf_map_update_elem(count_fd, &key, &curr_cpus_count, 0); if (ret) { fprintf(stderr, "Failed write curr cpus_count\n"); @@ -629,7 +172,7 @@ static void mark_cpus_unavailable(void) int ret, i; for (i = 0; i < n_cpus; i++) { - ret = bpf_map_update_elem(map_fds[CPUS_AVAILABLE], &i, + ret = bpf_map_update_elem(avail_fd, &i, &invalid_cpu, 0); if (ret) { fprintf(stderr, "Failed marking CPU unavailable\n"); @@ -653,26 +196,33 @@ static void stress_cpumap(struct bpf_cpumap_val *value) create_cpu_entry(1, value, 0, false); } -static void stats_poll(int interval, bool use_separators, char *prog_name, - char *mprog_name, struct bpf_cpumap_val *value, - bool stress_mode) +static void __stats_poll(int interval, bool use_separators, char *prog_name, + char *mprog_name, struct bpf_cpumap_val *value, + bool stress_mode) { + int mask = SAMPLE_RX_CNT | SAMPLE_REDIRECT_ERR_CNT | + SAMPLE_CPUMAP_ENQUEUE_CNT | SAMPLE_CPUMAP_KTHREAD_CNT | + SAMPLE_EXCEPTION_CNT; struct stats_record *record, *prev; - int mprog_fd; record = alloc_stats_record(); prev = alloc_stats_record(); - stats_collect(record); + sample_stats_collect(mask, record); /* Trick to pretty printf with thousands separators use %' */ if (use_separators) setlocale(LC_NUMERIC, "en_US"); - while (1) { + for (;;) { swap(&prev, &record); - mprog_fd = value->bpf_prog.fd; - stats_collect(record); - stats_print(record, prev, prog_name, mprog_name, mprog_fd); + sample_stats_collect(mask, record); + sample_stats_print(mask, record, prev, prog_name); + /* Depends on SAMPLE_CPUMAP_KTHREAD_CNT */ + sample_stats_print_cpumap_remote(record, prev, + bpf_num_possible_cpus(), + mprog_name); + printf("\n"); + fflush(stdout); sleep(interval); if (stress_mode) stress_cpumap(value); @@ -682,41 +232,6 @@ static void stats_poll(int interval, bool use_separators, char *prog_name, free_stats_record(prev); } -static int init_tracepoints(struct bpf_object *obj) -{ - struct bpf_program *prog; - - bpf_object__for_each_program(prog, obj) { - if (bpf_program__is_tracepoint(prog) != true) - continue; - - tp_links[tp_cnt] = bpf_program__attach(prog); - if (libbpf_get_error(tp_links[tp_cnt])) { - tp_links[tp_cnt] = NULL; - return -EINVAL; - } - tp_cnt++; - } - - return 0; -} - -static int init_map_fds(struct bpf_object *obj) -{ - enum map_type type; - - for (type = 0; type < NUM_MAP; type++) { - map_fds[type] = - bpf_object__find_map_fd_by_name(obj, - map_type_strings[type]); - - if (map_fds[type] < 0) - return -ENOENT; - } - - return 0; -} - static int load_cpumap_prog(char *file_name, char *prog_name, char *redir_interface, char *redir_map) { @@ -790,8 +305,6 @@ int main(int argc, char **argv) int *cpu, i; __u32 qsize; - n_cpus = get_nprocs_conf(); - /* Notice: choosing he queue size is very important with the * ixgbe driver, because it's driver page recycling trick is * dependend on pages being returned quickly. The number of @@ -812,15 +325,20 @@ int main(int argc, char **argv) return err; } - if (init_tracepoints(obj) < 0) { - fprintf(stderr, "ERR: bpf_program__attach failed\n"); + if (sample_init(obj) < 0) { + fprintf(stderr, "ERR: Failed to initialize sample\n"); return err; } - if (init_map_fds(obj) < 0) { - fprintf(stderr, "bpf_object__find_map_fd_by_name failed\n"); - return err; + map_fd = bpf_object__find_map_fd_by_name(obj, "cpu_map"); + avail_fd = bpf_object__find_map_fd_by_name(obj, "cpus_available"); + count_fd = bpf_object__find_map_fd_by_name(obj, "cpus_count"); + + if (map_fd < 0 || avail_fd < 0 || count_fd < 0) { + fprintf(stderr, "failed to find map\n"); + return EXIT_FAIL; } + mark_cpus_unavailable(); cpu = malloc(n_cpus * sizeof(int)); @@ -967,8 +485,8 @@ int main(int argc, char **argv) } prog_id = info.id; - stats_poll(interval, use_separators, prog_name, mprog_name, - &value, stress_mode); + __stats_poll(interval, use_separators, prog_name, mprog_name, + &value, stress_mode); err = EXIT_OK; out: diff --git a/samples/bpf/xdp_sample_user.c b/samples/bpf/xdp_sample_user.c new file mode 100644 index 000000000000..be60fbddd8c7 --- /dev/null +++ b/samples/bpf/xdp_sample_user.c @@ -0,0 +1,588 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* Copyright(c) 2017 Jesper Dangaard Brouer, Red Hat, Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef SIOCETHTOOL +#define SIOCETHTOOL 0x8946 +#endif + +#include +#include + +#include +#include + +#include "bpf_util.h" +#include "xdp_sample_user.h" + +struct bpf_link *tp_links[NUM_TP] = {}; +int map_fds[NUM_MAP], tp_cnt, n_cpus; + +#define NANOSEC_PER_SEC 1000000000 /* 10^9 */ +static __u64 gettime(void) +{ + struct timespec t; + int res; + + res = clock_gettime(CLOCK_MONOTONIC, &t); + if (res < 0) { + fprintf(stderr, "Error with gettimeofday! (%i)\n", res); + exit(EXIT_FAIL); + } + return (__u64) t.tv_sec * NANOSEC_PER_SEC + t.tv_nsec; +} + +static bool map_collect_percpu(int fd, __u32 key, struct record *rec) +{ + /* For percpu maps, userspace gets a value per possible CPU */ + unsigned int nr_cpus = bpf_num_possible_cpus(); + struct datarec values[nr_cpus]; + __u64 sum_xdp_redirect = 0; + __u64 sum_xdp_pass = 0; + __u64 sum_xdp_drop = 0; + __u64 sum_processed = 0; + __u64 sum_dropped = 0; + __u64 sum_issue = 0; + int i; + + if ((bpf_map_lookup_elem(fd, &key, values)) != 0) { + fprintf(stderr, + "ERR: bpf_map_lookup_elem failed key:0x%X\n", key); + return false; + } + /* Get time as close as possible to reading map contents */ + rec->timestamp = gettime(); + + /* Record and sum values from each CPU */ + for (i = 0; i < nr_cpus; i++) { + rec->cpu[i].processed = values[i].processed; + sum_processed += values[i].processed; + rec->cpu[i].dropped = values[i].dropped; + sum_dropped += values[i].dropped; + rec->cpu[i].issue = values[i].issue; + sum_issue += values[i].issue; + rec->cpu[i].xdp_pass = values[i].xdp_pass; + sum_xdp_pass += values[i].xdp_pass; + rec->cpu[i].xdp_drop = values[i].xdp_drop; + sum_xdp_drop += values[i].xdp_drop; + rec->cpu[i].xdp_redirect = values[i].xdp_redirect; + sum_xdp_redirect += values[i].xdp_redirect; + } + rec->total.processed = sum_processed; + rec->total.dropped = sum_dropped; + rec->total.issue = sum_issue; + rec->total.xdp_pass = sum_xdp_pass; + rec->total.xdp_drop = sum_xdp_drop; + rec->total.xdp_redirect = sum_xdp_redirect; + return true; +} + +static struct datarec *alloc_record_per_cpu(void) +{ + unsigned int nr_cpus = bpf_num_possible_cpus(); + struct datarec *array; + + array = calloc(nr_cpus, sizeof(struct datarec)); + if (!array) { + fprintf(stderr, "Mem alloc error (nr_cpus:%u)\n", nr_cpus); + exit(EXIT_FAIL_MEM); + } + return array; +} + +struct stats_record *alloc_stats_record(void) +{ + struct stats_record *rec; + int i, size; + + size = sizeof(*rec) + n_cpus * sizeof(struct record); + rec = malloc(size); + if (!rec) { + fprintf(stderr, "Mem alloc error\n"); + exit(EXIT_FAIL_MEM); + } + memset(rec, 0, size); + rec->rx_cnt.cpu = alloc_record_per_cpu(); + rec->redir_err.cpu = alloc_record_per_cpu(); + rec->kthread.cpu = alloc_record_per_cpu(); + rec->exception.cpu = alloc_record_per_cpu(); + for (i = 0; i < n_cpus; i++) + rec->enq[i].cpu = alloc_record_per_cpu(); + + return rec; +} + +void free_stats_record(struct stats_record *r) +{ + int i; + + for (i = 0; i < n_cpus; i++) + free(r->enq[i].cpu); + free(r->exception.cpu); + free(r->kthread.cpu); + free(r->redir_err.cpu); + free(r->rx_cnt.cpu); + free(r); +} + +static double calc_period(struct record *r, struct record *p) +{ + double period_ = 0; + __u64 period = 0; + + period = r->timestamp - p->timestamp; + if (period > 0) + period_ = ((double) period / NANOSEC_PER_SEC); + + return period_; +} + +static __u64 calc_pps(struct datarec *r, struct datarec *p, double period_) +{ + __u64 packets = 0; + __u64 pps = 0; + + if (period_ > 0) { + packets = r->processed - p->processed; + pps = packets / period_; + } + return pps; +} + +static __u64 calc_drop_pps(struct datarec *r, struct datarec *p, double period_) +{ + __u64 packets = 0; + __u64 pps = 0; + + if (period_ > 0) { + packets = r->dropped - p->dropped; + pps = packets / period_; + } + return pps; +} + +static __u64 calc_errs_pps(struct datarec *r, + struct datarec *p, double period_) +{ + __u64 packets = 0; + __u64 pps = 0; + + if (period_ > 0) { + packets = r->issue - p->issue; + pps = packets / period_; + } + return pps; +} + +static void calc_xdp_pps(struct datarec *r, struct datarec *p, + double *xdp_pass, double *xdp_drop, + double *xdp_redirect, double period_) +{ + *xdp_pass = 0, *xdp_drop = 0, *xdp_redirect = 0; + if (period_ > 0) { + *xdp_redirect = (r->xdp_redirect - p->xdp_redirect) / period_; + *xdp_pass = (r->xdp_pass - p->xdp_pass) / period_; + *xdp_drop = (r->xdp_drop - p->xdp_drop) / period_; + } +} + +static void stats_print_rx_cnt(struct stats_record *stats_rec, + struct stats_record *stats_prev, + unsigned int nr_cpus) +{ + char *fmt_rx = "%-15s %-7d %'-14.0f %'-11.0f %'-10.0f %s\n"; + char *fm2_rx = "%-15s %-7s %'-14.0f %'-11.0f\n"; + struct record *rec, *prev; + double t, pps, drop, err; + char *errstr = ""; + int i; + + rec = &stats_rec->rx_cnt; + prev = &stats_prev->rx_cnt; + t = calc_period(rec, prev); + for (i = 0; i < nr_cpus; i++) { + struct datarec *r = &rec->cpu[i]; + struct datarec *p = &prev->cpu[i]; + + pps = calc_pps(r, p, t); + drop = calc_drop_pps(r, p, t); + err = calc_errs_pps(r, p, t); + if (err > 0) + errstr = "cpu-dest/err"; + if (pps > 0) + printf(fmt_rx, "XDP-RX", i, pps, drop, err, errstr); + } + pps = calc_pps(&rec->total, &prev->total, t); + drop = calc_drop_pps(&rec->total, &prev->total, t); + err = calc_errs_pps(&rec->total, &prev->total, t); + printf(fm2_rx, "XDP-RX", "total", pps, drop); +} + +static void stats_print_cpumap_enqueue(struct stats_record *stats_rec, + struct stats_record *stats_prev, + unsigned int nr_cpus) +{ + struct record *rec, *prev; + double t, pps, drop, err; + int i, to_cpu; + + /* cpumap enqueue stats */ + for (to_cpu = 0; to_cpu < n_cpus; to_cpu++) { + char *fmt = "%-15s %3d:%-3d %'-14.0f %'-11.0f %'-10.2f %s\n"; + char *fm2 = "%-15s %3s:%-3d %'-14.0f %'-11.0f %'-10.2f %s\n"; + char *errstr = ""; + + rec = &stats_rec->enq[to_cpu]; + prev = &stats_prev->enq[to_cpu]; + t = calc_period(rec, prev); + for (i = 0; i < nr_cpus; i++) { + struct datarec *r = &rec->cpu[i]; + struct datarec *p = &prev->cpu[i]; + + pps = calc_pps(r, p, t); + drop = calc_drop_pps(r, p, t); + err = calc_errs_pps(r, p, t); + if (err > 0) { + errstr = "bulk-average"; + err = pps / err; /* calc average bulk size */ + } + if (pps > 0) + printf(fmt, "cpumap-enqueue", + i, to_cpu, pps, drop, err, errstr); + } + pps = calc_pps(&rec->total, &prev->total, t); + if (pps > 0) { + drop = calc_drop_pps(&rec->total, &prev->total, t); + err = calc_errs_pps(&rec->total, &prev->total, t); + if (err > 0) { + errstr = "bulk-average"; + err = pps / err; /* calc average bulk size */ + } + printf(fm2, "cpumap-enqueue", + "sum", to_cpu, pps, drop, err, errstr); + } + } +} + +static void stats_print_cpumap_kthread(struct stats_record *stats_rec, + struct stats_record *stats_prev, + unsigned int nr_cpus) +{ + char *fmt_k = "%-15s %-7d %'-14.0f %'-11.0f %'-10.0f %s\n"; + char *fm2_k = "%-15s %-7s %'-14.0f %'-11.0f %'-10.0f %s\n"; + struct record *rec, *prev; + double t, pps, drop, err; + char *e_str = ""; + int i; + + rec = &stats_rec->kthread; + prev = &stats_prev->kthread; + t = calc_period(rec, prev); + for (i = 0; i < nr_cpus; i++) { + struct datarec *r = &rec->cpu[i]; + struct datarec *p = &prev->cpu[i]; + + pps = calc_pps(r, p, t); + drop = calc_drop_pps(r, p, t); + err = calc_errs_pps(r, p, t); + if (err > 0) + e_str = "sched"; + if (pps > 0) + printf(fmt_k, "cpumap_kthread", i, pps, drop, err, + e_str); + } + pps = calc_pps(&rec->total, &prev->total, t); + drop = calc_drop_pps(&rec->total, &prev->total, t); + err = calc_errs_pps(&rec->total, &prev->total, t); + if (err > 0) + e_str = "sched-sum"; + printf(fm2_k, "cpumap_kthread", "total", pps, drop, err, e_str); +} + +static void stats_print_redirect_err_cnt(struct stats_record *stats_rec, + struct stats_record *stats_prev, + unsigned int nr_cpus) +{ + char *fmt_err = "%-15s %-7d %'-14.0f %'-11.0f\n"; + char *fm2_err = "%-15s %-7s %'-14.0f %'-11.0f\n"; + struct record *rec, *prev; + double t, pps, drop; + int i; + + rec = &stats_rec->redir_err; + prev = &stats_prev->redir_err; + t = calc_period(rec, prev); + for (i = 0; i < nr_cpus; i++) { + struct datarec *r = &rec->cpu[i]; + struct datarec *p = &prev->cpu[i]; + + pps = calc_pps(r, p, t); + drop = calc_drop_pps(r, p, t); + if (pps > 0) + printf(fmt_err, "redirect_err", i, pps, drop); + } + pps = calc_pps(&rec->total, &prev->total, t); + drop = calc_drop_pps(&rec->total, &prev->total, t); + printf(fm2_err, "redirect_err", "total", pps, drop); +} + +static void stats_print_exception_cnt(struct stats_record *stats_rec, + struct stats_record *stats_prev, + unsigned int nr_cpus) +{ + char *fmt_err = "%-15s %-7d %'-14.0f %'-11.0f\n"; + char *fm2_err = "%-15s %-7s %'-14.0f %'-11.0f\n"; + struct record *rec, *prev; + double t, pps, drop; + int i; + + rec = &stats_rec->exception; + prev = &stats_prev->exception; + t = calc_period(rec, prev); + for (i = 0; i < nr_cpus; i++) { + struct datarec *r = &rec->cpu[i]; + struct datarec *p = &prev->cpu[i]; + + pps = calc_pps(r, p, t); + drop = calc_drop_pps(r, p, t); + if (pps > 0) + printf(fmt_err, "xdp_exception", i, pps, drop); + } + pps = calc_pps(&rec->total, &prev->total, t); + drop = calc_drop_pps(&rec->total, &prev->total, t); + printf(fm2_err, "xdp_exception", "total", pps, drop); +} + +void sample_stats_print_cpumap_remote(struct stats_record *stats_rec, + struct stats_record *stats_prev, + unsigned int nr_cpus, char *mprog_name) +{ + char *fmt_k = "%-15s %-7d %'-14.0f %'-11.0f %'-10.0f\n"; + char *fm2_k = "%-15s %-7s %'-14.0f %'-11.0f %'-10.0f\n"; + double xdp_pass, xdp_drop, xdp_redirect; + struct record *rec, *prev; + double t; + int i; + + printf("\n2nd remote XDP/eBPF prog_name: %s\n", mprog_name ?: "(none)"); + printf("%-15s %-7s %-14s %-11s %-9s\n", "XDP-cpumap", "CPU:to", + "xdp-pass", "xdp-drop", "xdp-redir"); + + rec = &stats_rec->kthread; + prev = &stats_prev->kthread; + t = calc_period(rec, prev); + for (i = 0; i < nr_cpus; i++) { + struct datarec *r = &rec->cpu[i]; + struct datarec *p = &prev->cpu[i]; + + calc_xdp_pps(r, p, &xdp_pass, &xdp_drop, &xdp_redirect, t); + if (xdp_pass > 0 || xdp_drop > 0 || xdp_redirect > 0) + printf(fmt_k, "xdp-in-kthread", i, xdp_pass, xdp_drop, + xdp_redirect); + } + calc_xdp_pps(&rec->total, &prev->total, &xdp_pass, &xdp_drop, + &xdp_redirect, t); + printf(fm2_k, "xdp-in-kthread", "total", xdp_pass, xdp_drop, + xdp_redirect); +} + +static int init_tracepoints(struct bpf_object *obj) +{ + struct bpf_program *prog; + + bpf_object__for_each_program(prog, obj) { + if (bpf_program__is_tracepoint(prog) != true) + continue; + + tp_links[tp_cnt] = bpf_program__attach(prog); + if (libbpf_get_error(tp_links[tp_cnt])) { + tp_links[tp_cnt] = NULL; + return -EINVAL; + } + tp_cnt++; + } + + return 0; +} + +static int init_map_fds(struct bpf_object *obj) +{ + enum map_type type; + + for (type = 0; type < NUM_MAP; type++) { + map_fds[type] = + bpf_object__find_map_fd_by_name(obj, + map_type_strings[type]); + + if (map_fds[type] < 0) + return -ENOENT; + } + + return 0; +} + +int sample_init(struct bpf_object *obj) +{ + n_cpus = get_nprocs_conf(); + return init_tracepoints(obj) ? : init_map_fds(obj); +} + +void sample_exit(int status) +{ + while (tp_cnt) + bpf_link__destroy(tp_links[--tp_cnt]); + + exit(status); +} + +void sample_stats_collect(int mask, struct stats_record *rec) +{ + int i; + + if (mask & SAMPLE_RX_CNT) + map_collect_percpu(map_fds[RX_CNT], 0, &rec->rx_cnt); + + if (mask & SAMPLE_REDIRECT_ERR_CNT) + map_collect_percpu(map_fds[REDIRECT_ERR_CNT], 1, &rec->redir_err); + + if (mask & SAMPLE_CPUMAP_ENQUEUE_CNT) + for (i = 0; i < n_cpus; i++) + map_collect_percpu(map_fds[CPUMAP_ENQUEUE_CNT], i, &rec->enq[i]); + + if (mask & SAMPLE_CPUMAP_KTHREAD_CNT) + map_collect_percpu(map_fds[CPUMAP_KTHREAD_CNT], 0, &rec->kthread); + + if (mask & SAMPLE_EXCEPTION_CNT) + map_collect_percpu(map_fds[EXCEPTION_CNT], 0, &rec->exception); +} + +void sample_stats_print(int mask, struct stats_record *cur, + struct stats_record *prev, char *prog_name) +{ + int nr_cpus = bpf_num_possible_cpus(); + + printf("Running XDP/eBPF prog_name:%s\n", prog_name ?: "(none)"); + printf("%-15s %-7s %-14s %-11s %-9s\n", + "XDP-event", "CPU:to", "pps", "drop-pps", "extra-info"); + + if (mask & SAMPLE_RX_CNT) + stats_print_rx_cnt(cur, prev, nr_cpus); + + if (mask & SAMPLE_REDIRECT_ERR_CNT) + stats_print_redirect_err_cnt(cur, prev, nr_cpus); + + if (mask & SAMPLE_CPUMAP_ENQUEUE_CNT) + stats_print_cpumap_enqueue(cur, prev, nr_cpus); + + if (mask & SAMPLE_CPUMAP_KTHREAD_CNT) + stats_print_cpumap_kthread(cur, prev, nr_cpus); + + if (mask & SAMPLE_EXCEPTION_CNT) + stats_print_exception_cnt(cur, prev, nr_cpus); +} + +void sample_stats_poll(int interval, int mask, char *prog_name, int use_separators) +{ + struct stats_record *record, *prev; + + record = alloc_stats_record(); + prev = alloc_stats_record(); + sample_stats_collect(mask, record); + + /* Trick to pretty printf with thousands separators use %' */ + if (use_separators) + setlocale(LC_NUMERIC, "en_US"); + + for (;;) { + swap(&prev, &record); + sample_stats_collect(mask, record); + sample_stats_print(mask, record, prev, NULL); + printf("\n"); + fflush(stdout); + sleep(interval); + } + + free_stats_record(record); + free_stats_record(prev); +} + +const char *get_driver_name(int ifindex) +{ + struct ethtool_drvinfo drv = {}; + char ifname[IF_NAMESIZE]; + static char drvname[32]; + struct ifreq ifr = {}; + int fd, r; + + fd = socket(AF_INET, SOCK_DGRAM, 0); + if (fd < 0) + return NULL; + + if (!if_indextoname(ifindex, ifname)) + goto end; + + drv.cmd = ETHTOOL_GDRVINFO; + strncpy(ifr.ifr_name, ifname, IF_NAMESIZE); + ifr.ifr_data = (void *)&drv; + + r = ioctl(fd, SIOCETHTOOL, &ifr); + if (r) + goto end; + + strncpy(drvname, drv.driver, sizeof(drvname)); + + close(fd); + return drvname; + +end: + close(fd); + return NULL; +} + +int get_mac_addr(int ifindex, void *mac_addr) +{ + char ifname[IF_NAMESIZE]; + struct ifreq ifr = {}; + int fd, r; + + fd = socket(AF_INET, SOCK_DGRAM, 0); + if (fd < 0) + return -errno; + + if (!if_indextoname(ifindex, ifname)) { + r = -errno; + goto end; + } + + strncpy(ifr.ifr_name, ifname, IF_NAMESIZE); + + r = ioctl(fd, SIOCGIFHWADDR, &ifr); + if (r) { + r = -errno; + goto end; + } + + memcpy(mac_addr, ifr.ifr_hwaddr.sa_data, 6 * sizeof(char)); + +end: + close(fd); + return r; +} diff --git a/samples/bpf/xdp_sample_user.h b/samples/bpf/xdp_sample_user.h new file mode 100644 index 000000000000..3427baf70fc0 --- /dev/null +++ b/samples/bpf/xdp_sample_user.h @@ -0,0 +1,101 @@ +// SPDX-License-Identifier: GPL-2.0-only +#pragma once + +#include + +enum map_type { + RX_CNT, + REDIRECT_ERR_CNT, + CPUMAP_ENQUEUE_CNT, + CPUMAP_KTHREAD_CNT, + EXCEPTION_CNT, + NUM_MAP, +}; + +enum tp_type { + TP_REDIRECT_ERR_CNT, + TP_REDIRECT_MAP_ERR_CNT, + TP_CPUMAP_ENQUEUE_CNT, + TP_CPUMAP_KTHREAD_CNT, + TP_EXCEPTION_CNT, + NUM_TP, +}; + +enum stats_mask { + SAMPLE_RX_CNT = 1U << 1, + SAMPLE_REDIRECT_ERR_CNT = 1U << 2, + SAMPLE_CPUMAP_ENQUEUE_CNT = 1U << 3, + SAMPLE_CPUMAP_KTHREAD_CNT = 1U << 4, + SAMPLE_EXCEPTION_CNT = 1U << 5, +}; + +static const char *const map_type_strings[] = { + [RX_CNT] = "rx_cnt", + [REDIRECT_ERR_CNT] = "redirect_err_cnt", + [CPUMAP_ENQUEUE_CNT] = "cpumap_enqueue_cnt", + [CPUMAP_KTHREAD_CNT] = "cpumap_kthread_cnt", + [EXCEPTION_CNT] = "exception_cnt", +}; + +extern struct bpf_link *tp_links[NUM_TP]; +extern int map_fds[NUM_MAP]; +extern int n_cpus; +extern int tp_cnt; + +/* Exit return codes */ +#define EXIT_OK 0 +#define EXIT_FAIL 1 +#define EXIT_FAIL_OPTION 2 +#define EXIT_FAIL_XDP 3 +#define EXIT_FAIL_BPF 4 +#define EXIT_FAIL_MEM 5 + +/* Common stats data record shared with _kern.c */ +struct datarec { + __u64 processed; + __u64 dropped; + __u64 issue; + __u64 xdp_pass; + __u64 xdp_drop; + __u64 xdp_redirect; +}; + +struct record { + __u64 timestamp; + struct datarec total; + struct datarec *cpu; +}; + +struct stats_record { + struct record rx_cnt; + struct record redir_err; + struct record kthread; + struct record exception; + struct record enq[]; +}; + +int sample_init(struct bpf_object *obj); +void sample_exit(int status); +struct stats_record *alloc_stats_record(void); +void free_stats_record(struct stats_record *rec); +void sample_stats_print(int mask, struct stats_record *cur, + struct stats_record *prev, char *prog_name); +void sample_stats_collect(int mask, struct stats_record *rec); +void sample_stats_poll(int interval, int mask, char *prog_name, + int use_separators); +void sample_stats_print_cpumap_remote(struct stats_record *stats_rec, + struct stats_record *stats_prev, + unsigned int nr_cpus, char *mprog_name); + +const char *get_driver_name(int ifindex); +int get_mac_addr(int ifindex, void *mac_addr); + +/* Pointer swap trick */ +static inline void swap(struct stats_record **a, struct stats_record **b) +{ + struct stats_record *tmp; + + tmp = *a; + *a = *b; + *b = tmp; +} From patchwork Fri May 28 23:52:40 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kumar Kartikeya Dwivedi X-Patchwork-Id: 12287557 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.9 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNWANTED_LANGUAGE_BODY, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5D72EC4708D for ; Fri, 28 May 2021 23:53:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 41A95608FC for ; Fri, 28 May 2021 23:53:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229719AbhE1Xzd (ORCPT ); Fri, 28 May 2021 19:55:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45400 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229693AbhE1Xza (ORCPT ); Fri, 28 May 2021 19:55:30 -0400 Received: from mail-pg1-x542.google.com (mail-pg1-x542.google.com [IPv6:2607:f8b0:4864:20::542]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5BBF0C061574; Fri, 28 May 2021 16:53:54 -0700 (PDT) Received: by mail-pg1-x542.google.com with SMTP id j12so3699035pgh.7; Fri, 28 May 2021 16:53:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=eo+mNprptPl7srpNm0OMmFfBSNsoaoCtntagOadHIHQ=; b=Z0PPNl2UeIx7fncayz/zJQk3p5eqzRoCGOzlwi4NTJWgsUjcU6ftgwVA7eBNsVnGpZ icMjeveAq/k1ZNaZRod0N+EkGwnWA/UrD3zF0r5incCQfj1rNnbwXKz4/tObSutVOmw+ M+vrgdOJ+jx/KSQBa8+kb+TeqQQ8ErTHedifVVhcgbGD9lLD8NBcE1zD7cr6Hu/WCgff A/ZLUz9a0/0jkJqVdkFo/FA+IIhn57w0YfqtiBjq2uGwDllODmOmGLOgY4iACI6eHRhi lMJsZz6Mw6Eq5AqClgNt1uANaV5ZtBVoOyd8O+tFDEv7P9IDOdHqe0EfYXvjnze6WUwz NHRA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=eo+mNprptPl7srpNm0OMmFfBSNsoaoCtntagOadHIHQ=; b=cYkN5ds5LlFFVG5YGAQywZugN0mtgLl2UhUYoO085HpZBzMFxJqtyOwveG5XNmi2/D ptPkPAs2H+RZ/Swd07vzVPstRU0dc9EisCsTVNXzue4MnDJcEWuSSH9Mmp/aCGU2OgGn Aps0sCb29C5saeIwVYWk7sAMzxOmvDwFD9vc9cvNp8CTKEBbSmJSzraCayEPC5yWWwBw oqgGpEmNI4G72nHVh4E/4L7TmUz56JQRDm+PhuaXvGzIqHktsybRSEylG4x8M7jy42Mu E0qKFC+cVAYCiLSal7gjWRtLz08jllnmt7k3y1MWvODLUINIf+S9JozaaYeEq+Q6AfjF S1aw== X-Gm-Message-State: AOAM5313FKSfpiiUVrwlXnGf1whAqWAQgjgR/Bje2zN2DfX/Gr8LdQ+5 YDkEyzZslEqhzm+zg3bi9tTi+5vTmkA= X-Google-Smtp-Source: ABdhPJwpPa3Tnjfr7PH9HrVwL8HXIOO/5T5vKRALoN+LCGhxb/BPekgB2t7Xf+yg/QByhOlA7d/3pA== X-Received: by 2002:a63:e709:: with SMTP id b9mr11398198pgi.153.1622246033625; Fri, 28 May 2021 16:53:53 -0700 (PDT) Received: from localhost ([2402:3a80:11db:3aa9:ad24:a4a2:844f:6a0a]) by smtp.gmail.com with ESMTPSA id f9sm4890398pfc.42.2021.05.28.16.53.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 28 May 2021 16:53:53 -0700 (PDT) From: Kumar Kartikeya Dwivedi To: bpf@vger.kernel.org Cc: Kumar Kartikeya Dwivedi , Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , "David S. Miller" , Jakub Kicinski , Jesper Dangaard Brouer , =?utf-8?q?Toke_H=C3=B8iland-J?= =?utf-8?q?=C3=B8rgensen?= , netdev@vger.kernel.org Subject: [PATCH RFC bpf-next 05/15] samples: bpf: convert xdp_redirect_map to use xdp_samples Date: Sat, 29 May 2021 05:22:40 +0530 Message-Id: <20210528235250.2635167-6-memxor@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210528235250.2635167-1-memxor@gmail.com> References: <20210528235250.2635167-1-memxor@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net X-Patchwork-State: RFC This uses the xdp_sample_* reorg we did in the past commits to report more statistics than just the per second packet count. Signed-off-by: Kumar Kartikeya Dwivedi --- samples/bpf/Makefile | 2 +- samples/bpf/xdp_redirect_map_kern.c | 23 +++---- samples/bpf/xdp_redirect_map_user.c | 96 +++++++++++------------------ 3 files changed, 44 insertions(+), 77 deletions(-) diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile index c0c02e12e28b..ea7100c8b760 100644 --- a/samples/bpf/Makefile +++ b/samples/bpf/Makefile @@ -99,8 +99,8 @@ xdp_tx_iptunnel-objs := xdp_tx_iptunnel_user.o test_map_in_map-objs := test_map_in_map_user.o per_socket_stats_example-objs := cookie_uid_helper_example.o xdp_redirect-objs := xdp_redirect_user.o -xdp_redirect_map-objs := xdp_redirect_map_user.o xdp_redirect_map_multi-objs := xdp_redirect_map_multi_user.o +xdp_redirect_map-objs := xdp_redirect_map_user.o xdp_sample_user.o xdp_redirect_cpu-objs := xdp_redirect_cpu_user.o xdp_sample_user.o xdp_monitor-objs := xdp_monitor_user.o xdp_rxq_info-objs := xdp_rxq_info_user.o diff --git a/samples/bpf/xdp_redirect_map_kern.c b/samples/bpf/xdp_redirect_map_kern.c index a92b8e567bdd..cf8b8f6d15da 100644 --- a/samples/bpf/xdp_redirect_map_kern.c +++ b/samples/bpf/xdp_redirect_map_kern.c @@ -19,6 +19,8 @@ #include #include +#include "xdp_sample_kern.h" + /* The 2nd xdp prog on egress does not support skb mode, so we define two * maps, tx_port_general and tx_port_native. */ @@ -36,16 +38,6 @@ struct { __uint(max_entries, 100); } tx_port_native SEC(".maps"); -/* Count RX packets, as XDP bpf_prog doesn't get direct TX-success - * feedback. Redirect TX errors can be caught via a tracepoint. - */ -struct { - __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); - __type(key, u32); - __type(value, long); - __uint(max_entries, 1); -} rxcnt SEC(".maps"); - /* map to store egress interface mac address */ struct { __uint(type, BPF_MAP_TYPE_ARRAY); @@ -75,7 +67,7 @@ static __always_inline int xdp_redirect_map(struct xdp_md *ctx, void *redirect_m void *data_end = (void *)(long)ctx->data_end; void *data = (void *)(long)ctx->data; struct ethhdr *eth = data; - int rc = XDP_DROP; + struct datarec *rec; long *value; u32 key = 0; u64 nh_off; @@ -83,15 +75,16 @@ static __always_inline int xdp_redirect_map(struct xdp_md *ctx, void *redirect_m nh_off = sizeof(*eth); if (data + nh_off > data_end) - return rc; + return XDP_DROP; /* constant virtual port */ vport = 0; /* count packet in global counter */ - value = bpf_map_lookup_elem(&rxcnt, &key); - if (value) - *value += 1; + rec = bpf_map_lookup_elem(&rx_cnt, &key); + if (!rec) + return XDP_ABORTED; + rec->processed++; swap_src_dst_mac(data); diff --git a/samples/bpf/xdp_redirect_map_user.c b/samples/bpf/xdp_redirect_map_user.c index ad3cdc4c07d3..42893385ba96 100644 --- a/samples/bpf/xdp_redirect_map_user.c +++ b/samples/bpf/xdp_redirect_map_user.c @@ -13,15 +13,11 @@ #include #include #include -#include -#include -#include -#include -#include #include "bpf_util.h" #include #include +#include "xdp_sample_user.h" static int ifindex_in; static int ifindex_out; @@ -31,7 +27,6 @@ static __u32 prog_id; static __u32 dummy_prog_id; static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST; -static int rxcnt_map_fd; static void int_exit(int sig) { @@ -62,56 +57,8 @@ static void int_exit(int sig) else printf("program on iface OUT changed, not removing\n"); } - exit(0); -} -static void poll_stats(int interval, int ifindex) -{ - unsigned int nr_cpus = bpf_num_possible_cpus(); - __u64 values[nr_cpus], prev[nr_cpus]; - - memset(prev, 0, sizeof(prev)); - - while (1) { - __u64 sum = 0; - __u32 key = 0; - int i; - - sleep(interval); - assert(bpf_map_lookup_elem(rxcnt_map_fd, &key, values) == 0); - for (i = 0; i < nr_cpus; i++) - sum += (values[i] - prev[i]); - if (sum) - printf("ifindex %i: %10llu pkt/s\n", - ifindex, sum / interval); - memcpy(prev, values, sizeof(values)); - } -} - -static int get_mac_addr(unsigned int ifindex_out, void *mac_addr) -{ - char ifname[IF_NAMESIZE]; - struct ifreq ifr; - int fd, ret = -1; - - fd = socket(AF_INET, SOCK_DGRAM, 0); - if (fd < 0) - return ret; - - if (!if_indextoname(ifindex_out, ifname)) - goto err_out; - - strcpy(ifr.ifr_name, ifname); - - if (ioctl(fd, SIOCGIFHWADDR, &ifr) != 0) - goto err_out; - - memcpy(mac_addr, ifr.ifr_hwaddr.sa_data, 6 * sizeof(char)); - ret = 0; - -err_out: - close(fd); - return ret; + sample_exit(EXIT_OK); } static void usage(const char *prog) @@ -128,6 +75,8 @@ static void usage(const char *prog) int main(int argc, char **argv) { + int mask = SAMPLE_RX_CNT | SAMPLE_REDIRECT_ERR_CNT | + SAMPLE_EXCEPTION_CNT; struct bpf_prog_load_attr prog_load_attr = { .prog_type = BPF_PROG_TYPE_UNSPEC, }; @@ -136,8 +85,11 @@ int main(int argc, char **argv) int tx_port_map_fd, tx_mac_map_fd; struct bpf_devmap_val devmap_val; struct bpf_prog_info info = {}; + char str[2 * IF_NAMESIZE + 1]; __u32 info_len = sizeof(info); + char ifname_out[IF_NAMESIZE]; const char *optstr = "FSNX"; + char ifname_in[IF_NAMESIZE]; struct bpf_object *obj; int ret, opt, key = 0; char filename[256]; @@ -182,14 +134,17 @@ int main(int argc, char **argv) if (!ifindex_out) ifindex_out = strtoul(argv[optind + 1], NULL, 0); - printf("input: %d output: %d\n", ifindex_in, ifindex_out); - snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]); prog_load_attr.file = filename; if (bpf_prog_load_xattr(&prog_load_attr, &obj, &prog_fd)) return 1; + if (sample_init(obj) < 0) { + fprintf(stderr, "Failed to initialize sample\n"); + return 1; + } + if (xdp_flags & XDP_FLAGS_SKB_MODE) { prog = bpf_object__find_program_by_name(obj, "xdp_redirect_map_general"); tx_port_map_fd = bpf_object__find_map_fd_by_name(obj, "tx_port_general"); @@ -210,8 +165,7 @@ int main(int argc, char **argv) } tx_mac_map_fd = bpf_object__find_map_fd_by_name(obj, "tx_mac"); - rxcnt_map_fd = bpf_object__find_map_fd_by_name(obj, "rxcnt"); - if (tx_mac_map_fd < 0 || rxcnt_map_fd < 0) { + if (tx_mac_map_fd < 0) { printf("bpf_object__find_map_fd_by_name failed\n"); return 1; } @@ -281,8 +235,28 @@ int main(int argc, char **argv) goto out; } - poll_stats(2, ifindex_out); + if (!if_indextoname(ifindex_in, ifname_in)) { + perror("if_nametoindex"); + goto out; + } + + if (!if_indextoname(ifindex_out, ifname_out)) { + perror("if_nametoindex"); + goto out; + } + + strncpy(str, get_driver_name(ifindex_in) ?: "(err)", sizeof(str)); + + printf("Redirecting from %s (ifindex %d; driver %s) to %s (ifindex %d; driver %s)\n", + ifname_in, ifindex_in, str, ifname_out, ifindex_out, + get_driver_name(ifindex_out) ?: "(err)"); + + snprintf(str, sizeof(str), "%s->%s", ifname_in, ifname_out); + + sample_stats_poll(1, mask, str, true); -out: return 0; + +out: + return 1; } From patchwork Fri May 28 23:52:41 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kumar Kartikeya Dwivedi X-Patchwork-Id: 12287559 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5073AC4708D for ; Fri, 28 May 2021 23:54:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 32FF2608FC for ; Fri, 28 May 2021 23:54:03 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229708AbhE1Xzg (ORCPT ); Fri, 28 May 2021 19:55:36 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45430 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229736AbhE1Xze (ORCPT ); Fri, 28 May 2021 19:55:34 -0400 Received: from mail-pg1-x542.google.com (mail-pg1-x542.google.com [IPv6:2607:f8b0:4864:20::542]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DDC22C061574; Fri, 28 May 2021 16:53:57 -0700 (PDT) Received: by mail-pg1-x542.google.com with SMTP id q15so3684096pgg.12; Fri, 28 May 2021 16:53:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=px1IWmk2mPYAMtxfJLLuZNJj0lwhMZ8hOJ0HTI06GFw=; b=XoYCREa6tqH4IoQdawMymXihkMP5gS1LNWyq1WDeOl2DHJqClNxbv9MTxfedc1QBvc c5MznTaJ7ezUQ98IPL0dP5dsDMFIDz2XzAZYOzGUrpEGmrGyGsqvSACTiqwki7AeYZAw BjmtKaiAdR+CJgXp/xhSD1Guxx5ykYzc92+4wEj9XXDX0dr8QuYlR5Fr5GnZtU+zuO6U qhHLgTfrH+NIS7Bj/W3DjP3MwtkXVHtCtmMHCn+mAC0gUyBq2IrqeSeTgyQf8i7KRAqa NQKJ1kP6rCBYIJhw8zYA7vrCV8MheiyEeAT0jllnoWIxGgpgl+uQmnm1zmxchdyJxqeJ Ir6A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=px1IWmk2mPYAMtxfJLLuZNJj0lwhMZ8hOJ0HTI06GFw=; b=smqNqF0fKo0iKWNrruufXK2nxforccejWvq3Vi7CGhIzT+0noeQTvRAjoKS1zMWM7F 2UNcyNferON1+PxTjcVi8uToG39HB4bEl8dKcWNWTLOXjFcF2ARBoktpUBrW31Wcyjfv ahSUKRmK+6NnYEkI6IX+iMSWAsI9iIMVNBwLSTQJj8++SioTqhvQ9tWldYpa9wnW8joy htvdTotFE8kSqISiLXDvkDV0i/yyId8XSDc7q30IQe+Q2SfI8yayyAF7VhTFR//TaTc1 cx8H5yZrp+2izf1GLxQGkoq7ozhRkFBXtTi+1uGS9238g8NYuJoIR8+qKwDaQ1khkFtD afTA== X-Gm-Message-State: AOAM533Wjt391u5reqyuObxym/2MxWgXDQEeOxCA2KgCmbemdkvd2hEX X42B1t8I/0QmUsqE2XQ+JeQrVeO92dg= X-Google-Smtp-Source: ABdhPJx6Vnj0Om+IoWmPvbqiXQ6tNORMEASxygIOFdEs02Wrr7domJZ2XZKDcyD8N4bGDrtdSuCr1g== X-Received: by 2002:a63:8c55:: with SMTP id q21mr11257178pgn.96.1622246037087; Fri, 28 May 2021 16:53:57 -0700 (PDT) Received: from localhost ([2402:3a80:11db:3aa9:ad24:a4a2:844f:6a0a]) by smtp.gmail.com with ESMTPSA id i8sm5067698pgt.58.2021.05.28.16.53.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 28 May 2021 16:53:56 -0700 (PDT) From: Kumar Kartikeya Dwivedi To: bpf@vger.kernel.org Cc: Kumar Kartikeya Dwivedi , Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , "David S. Miller" , Jakub Kicinski , Jesper Dangaard Brouer , =?utf-8?q?Toke_H=C3=B8iland-J?= =?utf-8?q?=C3=B8rgensen?= , netdev@vger.kernel.org Subject: [PATCH RFC bpf-next 06/15] samples: bpf: prepare devmap_xmit support in xdp_sample Date: Sat, 29 May 2021 05:22:41 +0530 Message-Id: <20210528235250.2635167-7-memxor@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210528235250.2635167-1-memxor@gmail.com> References: <20210528235250.2635167-1-memxor@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net X-Patchwork-State: RFC This will be used to convert xdp_monitor to xdp_sample reorg in the next patch. Signed-off-by: Kumar Kartikeya Dwivedi --- samples/bpf/xdp_redirect_map_user.c | 3 +- samples/bpf/xdp_sample_kern.h | 51 +++++++++++++++++++++- samples/bpf/xdp_sample_user.c | 68 +++++++++++++++++++++++++++++ samples/bpf/xdp_sample_user.h | 10 ++++- 4 files changed, 129 insertions(+), 3 deletions(-) diff --git a/samples/bpf/xdp_redirect_map_user.c b/samples/bpf/xdp_redirect_map_user.c index 42893385ba96..b2c7adad99ec 100644 --- a/samples/bpf/xdp_redirect_map_user.c +++ b/samples/bpf/xdp_redirect_map_user.c @@ -76,7 +76,7 @@ static void usage(const char *prog) int main(int argc, char **argv) { int mask = SAMPLE_RX_CNT | SAMPLE_REDIRECT_ERR_CNT | - SAMPLE_EXCEPTION_CNT; + SAMPLE_EXCEPTION_CNT | SAMPLE_DEVMAP_XMIT_CNT; struct bpf_prog_load_attr prog_load_attr = { .prog_type = BPF_PROG_TYPE_UNSPEC, }; @@ -148,6 +148,7 @@ int main(int argc, char **argv) if (xdp_flags & XDP_FLAGS_SKB_MODE) { prog = bpf_object__find_program_by_name(obj, "xdp_redirect_map_general"); tx_port_map_fd = bpf_object__find_map_fd_by_name(obj, "tx_port_general"); + mask &= ~SAMPLE_DEVMAP_XMIT_CNT; } else { prog = bpf_object__find_program_by_name(obj, "xdp_redirect_map_native"); tx_port_map_fd = bpf_object__find_map_fd_by_name(obj, "tx_port_native"); diff --git a/samples/bpf/xdp_sample_kern.h b/samples/bpf/xdp_sample_kern.h index bb809542ac20..3b85d71434d3 100644 --- a/samples/bpf/xdp_sample_kern.h +++ b/samples/bpf/xdp_sample_kern.h @@ -12,7 +12,10 @@ struct datarec { __u64 processed; __u64 dropped; __u64 issue; - __u64 xdp_pass; + union { + __u64 xdp_pass; + __u64 info; + }; __u64 xdp_drop; __u64 xdp_redirect; }; @@ -60,6 +63,13 @@ struct { __uint(max_entries, 1); } exception_cnt SEC(".maps"); +struct { + __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); + __type(key, u32); + __type(value, struct datarec); + __uint(max_entries, 1); +} devmap_xmit_cnt SEC(".maps"); + /*** Trace point code ***/ /* Tracepoint format: /sys/kernel/debug/tracing/events/xdp/xdp_redirect/format @@ -218,3 +228,42 @@ int trace_xdp_cpumap_kthread(struct cpumap_kthread_ctx *ctx) return 0; } + +/* Tracepoint: /sys/kernel/debug/tracing/events/xdp/xdp_devmap_xmit/format + * Code in: kernel/include/trace/events/xdp.h + */ +struct devmap_xmit_ctx { + u64 __pad; // First 8 bytes are not accessible by bpf code + int from_ifindex; // offset:8; size:4; signed:1; + u32 act; // offset:12; size:4; signed:0; + int to_ifindex; // offset:16; size:4; signed:1; + int drops; // offset:20; size:4; signed:1; + int sent; // offset:24; size:4; signed:1; + int err; // offset:28; size:4; signed:1; +}; + +SEC("tracepoint/xdp/xdp_devmap_xmit") +int trace_xdp_devmap_xmit(struct devmap_xmit_ctx *ctx) +{ + struct datarec *rec; + u32 key = 0; + + rec = bpf_map_lookup_elem(&devmap_xmit_cnt, &key); + if (!rec) + return 0; + rec->processed += ctx->sent; + rec->dropped += ctx->drops; + + /* Record bulk events, then userspace can calc average bulk size */ + rec->info += 1; + + /* Record error cases, where no frame were sent */ + if (ctx->err) + rec->issue++; + + /* Catch API error of drv ndo_xdp_xmit sent more than count */ + if (ctx->drops < 0) + rec->issue++; + + return 1; +} diff --git a/samples/bpf/xdp_sample_user.c b/samples/bpf/xdp_sample_user.c index be60fbddd8c7..56cd79ba303a 100644 --- a/samples/bpf/xdp_sample_user.c +++ b/samples/bpf/xdp_sample_user.c @@ -124,6 +124,7 @@ struct stats_record *alloc_stats_record(void) rec->redir_err.cpu = alloc_record_per_cpu(); rec->kthread.cpu = alloc_record_per_cpu(); rec->exception.cpu = alloc_record_per_cpu(); + rec->devmap_xmit.cpu = alloc_record_per_cpu(); for (i = 0; i < n_cpus; i++) rec->enq[i].cpu = alloc_record_per_cpu(); @@ -136,6 +137,7 @@ void free_stats_record(struct stats_record *r) for (i = 0; i < n_cpus; i++) free(r->enq[i].cpu); + free(r->devmap_xmit.cpu); free(r->exception.cpu); free(r->kthread.cpu); free(r->redir_err.cpu); @@ -192,6 +194,19 @@ static __u64 calc_errs_pps(struct datarec *r, return pps; } +static __u64 calc_info_pps(struct datarec *r, + struct datarec *p, double period_) +{ + __u64 packets = 0; + __u64 pps = 0; + + if (period_ > 0) { + packets = r->info - p->info; + pps = packets / period_; + } + return pps; +} + static void calc_xdp_pps(struct datarec *r, struct datarec *p, double *xdp_pass, double *xdp_drop, double *xdp_redirect, double period_) @@ -404,6 +419,53 @@ void sample_stats_print_cpumap_remote(struct stats_record *stats_rec, xdp_redirect); } +static void stats_print_devmap_xmit(struct stats_record *stats_rec, + struct stats_record *stats_prev, + unsigned int nr_cpus) +{ + char *fmt1 = "%-15s %-7d %'-14.0f %'-11.0f %'-10.0f %s %s\n"; + char *fmt2 = "%-15s %-7s %'-14.0f %'-11.0f %'-10.0f %s %s\n"; + double pps, drop, info, err; + struct record *rec, *prev; + char *err_str = ""; + char *i_str = ""; + double t; + int i; + + rec = &stats_rec->devmap_xmit; + prev = &stats_prev->devmap_xmit; + t = calc_period(rec, prev); + for (i = 0; i < nr_cpus; i++) { + struct datarec *r = &rec->cpu[i]; + struct datarec *p = &prev->cpu[i]; + + pps = calc_pps(r, p, t); + drop = calc_drop_pps(r, p, t); + info = calc_info_pps(r, p, t); + err = calc_errs_pps(r, p, t); + if (info > 0) { + i_str = "bulk-average"; + info = (pps + drop) / info; /* calc avg bulk */ + } + if (err > 0) + err_str = "drv-err"; + if (pps > 0 || drop > 0) + printf(fmt1, "devmap-xmit", i, pps, drop, info, i_str, + err_str); + } + pps = calc_pps(&rec->total, &prev->total, t); + drop = calc_drop_pps(&rec->total, &prev->total, t); + info = calc_info_pps(&rec->total, &prev->total, t); + err = calc_errs_pps(&rec->total, &prev->total, t); + if (info > 0) { + i_str = "bulk-average"; + info = (pps + drop) / info; /* calc avg bulk */ + } + if (err > 0) + err_str = "drv-err"; + printf(fmt2, "devmap-xmit", "total", pps, drop, info, i_str, err_str); +} + static int init_tracepoints(struct bpf_object *obj) { struct bpf_program *prog; @@ -472,6 +534,9 @@ void sample_stats_collect(int mask, struct stats_record *rec) if (mask & SAMPLE_EXCEPTION_CNT) map_collect_percpu(map_fds[EXCEPTION_CNT], 0, &rec->exception); + + if (mask & SAMPLE_DEVMAP_XMIT_CNT) + map_collect_percpu(map_fds[DEVMAP_XMIT_CNT], 0, &rec->devmap_xmit); } void sample_stats_print(int mask, struct stats_record *cur, @@ -497,6 +562,9 @@ void sample_stats_print(int mask, struct stats_record *cur, if (mask & SAMPLE_EXCEPTION_CNT) stats_print_exception_cnt(cur, prev, nr_cpus); + + if (mask & SAMPLE_DEVMAP_XMIT_CNT) + stats_print_devmap_xmit(cur, prev, nr_cpus); } void sample_stats_poll(int interval, int mask, char *prog_name, int use_separators) diff --git a/samples/bpf/xdp_sample_user.h b/samples/bpf/xdp_sample_user.h index 3427baf70fc0..75a4ea4b55ad 100644 --- a/samples/bpf/xdp_sample_user.h +++ b/samples/bpf/xdp_sample_user.h @@ -9,6 +9,7 @@ enum map_type { CPUMAP_ENQUEUE_CNT, CPUMAP_KTHREAD_CNT, EXCEPTION_CNT, + DEVMAP_XMIT_CNT, NUM_MAP, }; @@ -18,6 +19,7 @@ enum tp_type { TP_CPUMAP_ENQUEUE_CNT, TP_CPUMAP_KTHREAD_CNT, TP_EXCEPTION_CNT, + TP_DEVMAP_XMIT_CNT, NUM_TP, }; @@ -27,6 +29,7 @@ enum stats_mask { SAMPLE_CPUMAP_ENQUEUE_CNT = 1U << 3, SAMPLE_CPUMAP_KTHREAD_CNT = 1U << 4, SAMPLE_EXCEPTION_CNT = 1U << 5, + SAMPLE_DEVMAP_XMIT_CNT = 1U << 6, }; static const char *const map_type_strings[] = { @@ -35,6 +38,7 @@ static const char *const map_type_strings[] = { [CPUMAP_ENQUEUE_CNT] = "cpumap_enqueue_cnt", [CPUMAP_KTHREAD_CNT] = "cpumap_kthread_cnt", [EXCEPTION_CNT] = "exception_cnt", + [DEVMAP_XMIT_CNT] = "devmap_xmit_cnt", }; extern struct bpf_link *tp_links[NUM_TP]; @@ -55,7 +59,10 @@ struct datarec { __u64 processed; __u64 dropped; __u64 issue; - __u64 xdp_pass; + union { + __u64 xdp_pass; + __u64 info; + }; __u64 xdp_drop; __u64 xdp_redirect; }; @@ -71,6 +78,7 @@ struct stats_record { struct record redir_err; struct record kthread; struct record exception; + struct record devmap_xmit; struct record enq[]; }; From patchwork Fri May 28 23:52:42 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kumar Kartikeya Dwivedi X-Patchwork-Id: 12287561 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 18E88C4708E for ; Fri, 28 May 2021 23:54:05 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id F113C6135F for ; Fri, 28 May 2021 23:54:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229721AbhE1Xzi (ORCPT ); Fri, 28 May 2021 19:55:38 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45450 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229700AbhE1Xzg (ORCPT ); Fri, 28 May 2021 19:55:36 -0400 Received: from mail-pf1-x441.google.com (mail-pf1-x441.google.com [IPv6:2607:f8b0:4864:20::441]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 45F58C061574; Fri, 28 May 2021 16:54:01 -0700 (PDT) Received: by mail-pf1-x441.google.com with SMTP id y15so456234pfl.4; Fri, 28 May 2021 16:54:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=ffTMzd8u6S5X9o61xEi2TOtbJBb+RT7uqEVsFVrSITM=; b=EVHmeksSerOZ3RDks7djP07ktmrDnrXvXrhWdZ3vgF+XtJ1A1xG1OR1HI1KhpCam7n vXM7T7b0/RVaUnvz15V5k8GUgPsnhNk5DUxxHmLn7hDscc/ewiQ5pYjfEFuiEhFyPXNP ZY650eV525HfB38d1zQxO1Ny+vNEjuE18WhVuQsawNNxiYYc4yXEXrMotTSyw/I4WJIi f04CozEDE7M3L9P0aDBzKhnBlO42appEFmCOf8u2bg740KB2+ONRjycJCZqbLDeoy52Z RLeJUaecckcy9WwAjuYsE27BrdLoKDz4vyS/Bw3BREcvyw7JH+KupU287pDIjIISS3nI CV/A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ffTMzd8u6S5X9o61xEi2TOtbJBb+RT7uqEVsFVrSITM=; b=kPu4wlFNFXfF8HpG5hZa4l1qqSLcTBWokeqwxRefnvElXRa3Liqeoy8jTd3N6gVccA CeIhR1Nw6yNFKYZ9EVbNhnny99dQWzUevNGOY6EcS8DbRF66ZUQiQuENzaJ4SY6Jy8uM XPdz6CHsg8ela34EQXiovIavT6Rn1kzE+onb7VR+vpDtOhP1xejm2NJUYJdgwkSmz/pS 1wHP8OFqwFtkFCkUQZP3xz3NJL5YaWuEdcD7SM9ozMRkMKL3RbaFkEiHk1Ec4oyomIOU fKPN2EL4mo47Gh814iYuynbu6NVv9de6+LRhMOmEy00hrgu8OaBXjPwKVZehUf4wBsWN 9biA== X-Gm-Message-State: AOAM533lX9pbSRiOk80uY8nJ22q22heLkXpVhDQTsFYeM/NG5y0mAcw4 /PPcPa99wYFHAN0Q73tuxm1yQap3BnU= X-Google-Smtp-Source: ABdhPJyC40qqjmaMQPPBdA8WE1U87cC79s2+H5K+ZSG1FlNxZrepSPfM0754nqHWRCIhR244If3f+g== X-Received: by 2002:a63:561d:: with SMTP id k29mr11402563pgb.335.1622246040605; Fri, 28 May 2021 16:54:00 -0700 (PDT) Received: from localhost ([2402:3a80:11db:3aa9:ad24:a4a2:844f:6a0a]) by smtp.gmail.com with ESMTPSA id o134sm5261417pfd.58.2021.05.28.16.53.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 28 May 2021 16:54:00 -0700 (PDT) From: Kumar Kartikeya Dwivedi To: bpf@vger.kernel.org Cc: Kumar Kartikeya Dwivedi , Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , "David S. Miller" , Jakub Kicinski , Jesper Dangaard Brouer , =?utf-8?q?Toke_H=C3=B8iland-J?= =?utf-8?q?=C3=B8rgensen?= , netdev@vger.kernel.org Subject: [PATCH RFC bpf-next 07/15] samples: bpf: add extended reporting for xdp redirect error Date: Sat, 29 May 2021 05:22:42 +0530 Message-Id: <20210528235250.2635167-8-memxor@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210528235250.2635167-1-memxor@gmail.com> References: <20210528235250.2635167-1-memxor@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net X-Patchwork-State: RFC This again is needed for xdp_monitor support. We also record the most common errnos, but don't report for now. A future commit that modifies output format will arrange for printing it properly. Signed-off-by: Kumar Kartikeya Dwivedi --- samples/bpf/xdp_sample_kern.h | 53 +++++++++++++++++++++++++++--- samples/bpf/xdp_sample_user.c | 62 +++++++++++++++++++++++++++-------- samples/bpf/xdp_sample_user.h | 13 +++++++- 3 files changed, 108 insertions(+), 20 deletions(-) diff --git a/samples/bpf/xdp_sample_kern.h b/samples/bpf/xdp_sample_kern.h index 3b85d71434d3..4131b9cb1ec4 100644 --- a/samples/bpf/xdp_sample_kern.h +++ b/samples/bpf/xdp_sample_kern.h @@ -7,6 +7,11 @@ #define MAX_CPUS 64 +#define EINVAL 22 +#define ENETDOWN 100 +#define EMSGSIZE 90 +#define EOPNOTSUPP 95 + /* Common stats data record to keep userspace more simple */ struct datarec { __u64 processed; @@ -35,8 +40,11 @@ struct { __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); __type(key, u32); __type(value, struct datarec); - __uint(max_entries, 2); - /* TODO: have entries for all possible errno's */ + __uint(max_entries, 2 + + 1 /* EINVAL */ + + 1 /* ENETDOWN */ + + 1 /* EMSGSIZE */ + + 1 /* EOPNOTSUPP */); } redirect_err_cnt SEC(".maps"); /* Used by trace point */ @@ -91,6 +99,25 @@ enum { XDP_REDIRECT_ERROR = 1 }; +static __always_inline +__u32 xdp_get_err_key(int err) +{ + switch (err) { + case 0: + return 0; + case -EINVAL: + return 2; + case -ENETDOWN: + return 3; + case -EMSGSIZE: + return 4; + case -EOPNOTSUPP: + return 5; + default: + return 1; + } +} + static __always_inline int xdp_redirect_collect_stat(struct xdp_redirect_ctx *ctx) { @@ -98,13 +125,15 @@ int xdp_redirect_collect_stat(struct xdp_redirect_ctx *ctx) struct datarec *rec; int err = ctx->err; - if (!err) - key = XDP_REDIRECT_SUCCESS; + key = xdp_get_err_key(err); rec = bpf_map_lookup_elem(&redirect_err_cnt, &key); if (!rec) return 0; - rec->dropped += 1; + if (key) + rec->dropped++; + else + rec->processed++; return 0; /* Indicate event was filtered (no further processing)*/ /* @@ -127,6 +156,20 @@ int trace_xdp_redirect_map_err(struct xdp_redirect_ctx *ctx) return xdp_redirect_collect_stat(ctx); } +/* Likely unloaded when prog starts */ +SEC("tracepoint/xdp/xdp_redirect") +int trace_xdp_redirect(struct xdp_redirect_ctx *ctx) +{ + return xdp_redirect_collect_stat(ctx); +} + +/* Likely unloaded when prog starts */ +SEC("tracepoint/xdp/xdp_redirect_map") +int trace_xdp_redirect_map(struct xdp_redirect_ctx *ctx) +{ + return xdp_redirect_collect_stat(ctx); +} + /* Tracepoint format: /sys/kernel/debug/tracing/events/xdp/xdp_exception/format * Code in: kernel/include/trace/events/xdp.h */ diff --git a/samples/bpf/xdp_sample_user.c b/samples/bpf/xdp_sample_user.c index 56cd79ba303a..29410d551574 100644 --- a/samples/bpf/xdp_sample_user.c +++ b/samples/bpf/xdp_sample_user.c @@ -121,7 +121,8 @@ struct stats_record *alloc_stats_record(void) } memset(rec, 0, size); rec->rx_cnt.cpu = alloc_record_per_cpu(); - rec->redir_err.cpu = alloc_record_per_cpu(); + rec->redir_err[0].cpu = alloc_record_per_cpu(); + rec->redir_err[1].cpu = alloc_record_per_cpu(); rec->kthread.cpu = alloc_record_per_cpu(); rec->exception.cpu = alloc_record_per_cpu(); rec->devmap_xmit.cpu = alloc_record_per_cpu(); @@ -140,7 +141,8 @@ void free_stats_record(struct stats_record *r) free(r->devmap_xmit.cpu); free(r->exception.cpu); free(r->kthread.cpu); - free(r->redir_err.cpu); + free(r->redir_err[1].cpu); + free(r->redir_err[0].cpu); free(r->rx_cnt.cpu); free(r); } @@ -332,31 +334,54 @@ static void stats_print_cpumap_kthread(struct stats_record *stats_rec, printf(fm2_k, "cpumap_kthread", "total", pps, drop, err, e_str); } +static void stats_print_redirect_cnt(struct stats_record *stats_rec, + struct stats_record *stats_prev, + unsigned int nr_cpus) +{ + char *fmt1 = "%-15s %-7d %'-14.0f %'-11.0f %s\n"; + char *fmt2 = "%-15s %-7s %'-14.0f %'-11.0f %s\n"; + struct record *rec, *prev; + double t, pps; + int i; + + rec = &stats_rec->redir_err[0]; + prev = &stats_prev->redir_err[0]; + t = calc_period(rec, prev); + for (i = 0; i < nr_cpus; i++) { + struct datarec *r = &rec->cpu[i]; + struct datarec *p = &prev->cpu[i]; + + pps = calc_pps(r, p, t); + if (pps > 0) + printf(fmt1, "redirect", i, pps, 0.0, "Success"); + } + pps = calc_pps(&rec->total, &prev->total, t); + printf(fmt2, "redirect", "total", pps, 0.0, "Success"); +} + static void stats_print_redirect_err_cnt(struct stats_record *stats_rec, struct stats_record *stats_prev, unsigned int nr_cpus) { - char *fmt_err = "%-15s %-7d %'-14.0f %'-11.0f\n"; - char *fm2_err = "%-15s %-7s %'-14.0f %'-11.0f\n"; + char *fmt1 = "%-15s %-7d %'-14.0f %'-11.0f %s\n"; + char *fmt2 = "%-15s %-7s %'-14.0f %'-11.0f %s\n"; struct record *rec, *prev; - double t, pps, drop; + double t, drop; int i; - rec = &stats_rec->redir_err; - prev = &stats_prev->redir_err; + rec = &stats_rec->redir_err[1]; + prev = &stats_prev->redir_err[1]; t = calc_period(rec, prev); for (i = 0; i < nr_cpus; i++) { struct datarec *r = &rec->cpu[i]; struct datarec *p = &prev->cpu[i]; - pps = calc_pps(r, p, t); drop = calc_drop_pps(r, p, t); - if (pps > 0) - printf(fmt_err, "redirect_err", i, pps, drop); + if (drop > 0) + printf(fmt1, "redirect", i, 0.0, drop, "Error"); } - pps = calc_pps(&rec->total, &prev->total, t); drop = calc_drop_pps(&rec->total, &prev->total, t); - printf(fm2_err, "redirect_err", "total", pps, drop); + printf(fmt2, "redirect", "total", 0.0, drop, "Error"); } static void stats_print_exception_cnt(struct stats_record *stats_rec, @@ -522,8 +547,14 @@ void sample_stats_collect(int mask, struct stats_record *rec) if (mask & SAMPLE_RX_CNT) map_collect_percpu(map_fds[RX_CNT], 0, &rec->rx_cnt); - if (mask & SAMPLE_REDIRECT_ERR_CNT) - map_collect_percpu(map_fds[REDIRECT_ERR_CNT], 1, &rec->redir_err); + /* Success case */ + if (mask & SAMPLE_REDIRECT_CNT) + map_collect_percpu(map_fds[REDIRECT_ERR_CNT], 0, &rec->redir_err[0]); + + if (mask & SAMPLE_REDIRECT_ERR_CNT) { + for (i = 1; i < XDP_REDIRECT_ERR_MAX; i++) + map_collect_percpu(map_fds[REDIRECT_ERR_CNT], i, &rec->redir_err[i]); + } if (mask & SAMPLE_CPUMAP_ENQUEUE_CNT) for (i = 0; i < n_cpus; i++) @@ -551,6 +582,9 @@ void sample_stats_print(int mask, struct stats_record *cur, if (mask & SAMPLE_RX_CNT) stats_print_rx_cnt(cur, prev, nr_cpus); + if (mask & SAMPLE_REDIRECT_CNT) + stats_print_redirect_cnt(cur, prev, nr_cpus); + if (mask & SAMPLE_REDIRECT_ERR_CNT) stats_print_redirect_err_cnt(cur, prev, nr_cpus); diff --git a/samples/bpf/xdp_sample_user.h b/samples/bpf/xdp_sample_user.h index 75a4ea4b55ad..a3a3c746e73e 100644 --- a/samples/bpf/xdp_sample_user.h +++ b/samples/bpf/xdp_sample_user.h @@ -14,6 +14,8 @@ enum map_type { }; enum tp_type { + TP_REDIRECT_CNT, + TP_REDIRECT_MAP_CNT, TP_REDIRECT_ERR_CNT, TP_REDIRECT_MAP_ERR_CNT, TP_CPUMAP_ENQUEUE_CNT, @@ -30,6 +32,7 @@ enum stats_mask { SAMPLE_CPUMAP_KTHREAD_CNT = 1U << 4, SAMPLE_EXCEPTION_CNT = 1U << 5, SAMPLE_DEVMAP_XMIT_CNT = 1U << 6, + SAMPLE_REDIRECT_CNT = 1U << 7, }; static const char *const map_type_strings[] = { @@ -54,6 +57,14 @@ extern int tp_cnt; #define EXIT_FAIL_BPF 4 #define EXIT_FAIL_MEM 5 +#define XDP_REDIRECT_ERR_MAX 6 + +static const char *xdp_redirect_err_names[XDP_REDIRECT_ERR_MAX] = { + /* Key=1 keeps unknown errors */ + "Success", "Unknown", "EINVAL", "ENETDOWN", "EMSGSIZE", + "EOPNOTSUPP", +}; + /* Common stats data record shared with _kern.c */ struct datarec { __u64 processed; @@ -75,7 +86,7 @@ struct record { struct stats_record { struct record rx_cnt; - struct record redir_err; + struct record redir_err[XDP_REDIRECT_ERR_MAX]; struct record kthread; struct record exception; struct record devmap_xmit; From patchwork Fri May 28 23:52:43 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kumar Kartikeya Dwivedi X-Patchwork-Id: 12287563 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B16D9C47087 for ; Fri, 28 May 2021 23:54:08 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 93DA7608FC for ; Fri, 28 May 2021 23:54:08 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229737AbhE1Xzn (ORCPT ); Fri, 28 May 2021 19:55:43 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45472 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229700AbhE1Xzk (ORCPT ); Fri, 28 May 2021 19:55:40 -0400 Received: from mail-pj1-x1044.google.com (mail-pj1-x1044.google.com [IPv6:2607:f8b0:4864:20::1044]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BB81BC061574; Fri, 28 May 2021 16:54:04 -0700 (PDT) Received: by mail-pj1-x1044.google.com with SMTP id ot16so3427772pjb.3; Fri, 28 May 2021 16:54:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=NLJmgoALRRKu0OLvtlrqv7GEJkir/uMI8l7e7jcjPug=; b=ZTn7EZOKM+0tHAMnyXB6+9B4CueKKpMGnP0Su4xGDTuGtMCxlxsAMyTH3889prI+o8 i0Ms8RTRf2QsSXTYuV/Gww0YxiGH5K871idDZKv+AeegAVvD8bFG2tfyoWQKjDpmyWDj peTg4eJx1tcc77+dT4jy8cYGdTZDc0r3UaZXtfJ+4HV+MObZ3oH7kwjdre8E9XPlCNI3 a1f9u6/tb3whbIn15g3eXF8e38vTjt5PIGoE0HDxAXwtUu7gyUkdcFTSy2069Oxex8r5 pQ5jQnU+ClgHJVBheMDmvMVX/z6rAzKhgHdIDWGh18lQ8z+zJWn12MXd31KwtjPHURxe Ourg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=NLJmgoALRRKu0OLvtlrqv7GEJkir/uMI8l7e7jcjPug=; b=tx73X5UCwSMx77M92uQnfCPBWWcKYLOKQdHD47DWO3kkPza4KnMgTtbNuBVHNnDFcd 8B0rZR6JmV15Qeks714OUEf1LxX/RgM76ONlmBF17UCIaWHuZTe84sNtwABneQeyVN87 x+xl2AookhpqI2+ISWd7UsC8eQ410WYZQLKSQ7yXCJ4s8rBGiF++j0o8OERn6fv4I2Vp EVTG+BqU33s+yuCkhaS/R/b0BvBu0l3l95Rvphx7Tx2N0Jm4mFcp/pTi1bvQYRhaLnq/ odNz0T62cjDn9b3gdCjm7GUEHHB9P4xY1ftksun8bShM1Ctv2lYVpCOEPJt/9+eC+Oi/ S4Kw== X-Gm-Message-State: AOAM5325lR6Il/8wri9G9oSAsQjdi3wgT/KWtQxgnP3unNVF00hHgWU8 6wX0DgFxp/Y5K5lcPuquyUjXDcvHv7U= X-Google-Smtp-Source: ABdhPJxMI6OpZQNe78gAQyppO29vkSMQnmCU5KZ5vvF88xlXMmaZsJTwQUVRoWR6RcZ1HCgyimIDlw== X-Received: by 2002:a17:90a:5649:: with SMTP id d9mr6998959pji.163.1622246044037; Fri, 28 May 2021 16:54:04 -0700 (PDT) Received: from localhost ([2402:3a80:11db:3aa9:ad24:a4a2:844f:6a0a]) by smtp.gmail.com with ESMTPSA id n23sm5297911pff.93.2021.05.28.16.54.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 28 May 2021 16:54:03 -0700 (PDT) From: Kumar Kartikeya Dwivedi To: bpf@vger.kernel.org Cc: Kumar Kartikeya Dwivedi , Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , "David S. Miller" , Jakub Kicinski , Jesper Dangaard Brouer , =?utf-8?q?Toke_H=C3=B8iland-J?= =?utf-8?q?=C3=B8rgensen?= , netdev@vger.kernel.org Subject: [PATCH RFC bpf-next 08/15] samples: bpf: add per exception reporting for xdp_exception Date: Sat, 29 May 2021 05:22:43 +0530 Message-Id: <20210528235250.2635167-9-memxor@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210528235250.2635167-1-memxor@gmail.com> References: <20210528235250.2635167-1-memxor@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net X-Patchwork-State: RFC This is taken from xdp_monitor, in preparation for the conversion in a subsequent patch. Signed-off-by: Kumar Kartikeya Dwivedi --- samples/bpf/xdp_sample_kern.h | 8 ++++-- samples/bpf/xdp_sample_user.c | 47 ++++++++++++++++++++--------------- samples/bpf/xdp_sample_user.h | 24 ++++++++++++++++-- 3 files changed, 55 insertions(+), 24 deletions(-) diff --git a/samples/bpf/xdp_sample_kern.h b/samples/bpf/xdp_sample_kern.h index 4131b9cb1ec4..ec36e7b4a3ba 100644 --- a/samples/bpf/xdp_sample_kern.h +++ b/samples/bpf/xdp_sample_kern.h @@ -63,12 +63,13 @@ struct { __uint(max_entries, 1); } cpumap_kthread_cnt SEC(".maps"); +#define XDP_UNKNOWN (XDP_REDIRECT + 1) /* Used by trace point */ struct { __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); __type(key, u32); __type(value, struct datarec); - __uint(max_entries, 1); + __uint(max_entries, XDP_UNKNOWN + 1); } exception_cnt SEC(".maps"); struct { @@ -184,7 +185,10 @@ SEC("tracepoint/xdp/xdp_exception") int trace_xdp_exception(struct xdp_exception_ctx *ctx) { struct datarec *rec; - u32 key = 0; + u32 key = ctx->act; + + if (key > XDP_REDIRECT) + key = XDP_UNKNOWN; rec = bpf_map_lookup_elem(&exception_cnt, &key); if (!rec) diff --git a/samples/bpf/xdp_sample_user.c b/samples/bpf/xdp_sample_user.c index 29410d551574..446668edf8d8 100644 --- a/samples/bpf/xdp_sample_user.c +++ b/samples/bpf/xdp_sample_user.c @@ -124,7 +124,8 @@ struct stats_record *alloc_stats_record(void) rec->redir_err[0].cpu = alloc_record_per_cpu(); rec->redir_err[1].cpu = alloc_record_per_cpu(); rec->kthread.cpu = alloc_record_per_cpu(); - rec->exception.cpu = alloc_record_per_cpu(); + for (i = 0; i < XDP_ACTION_MAX; i++) + rec->exception[i].cpu = alloc_record_per_cpu(); rec->devmap_xmit.cpu = alloc_record_per_cpu(); for (i = 0; i < n_cpus; i++) rec->enq[i].cpu = alloc_record_per_cpu(); @@ -139,7 +140,8 @@ void free_stats_record(struct stats_record *r) for (i = 0; i < n_cpus; i++) free(r->enq[i].cpu); free(r->devmap_xmit.cpu); - free(r->exception.cpu); + for (i = 0; i < XDP_ACTION_MAX; i++) + free(r->exception[i].cpu); free(r->kthread.cpu); free(r->redir_err[1].cpu); free(r->redir_err[0].cpu); @@ -388,27 +390,31 @@ static void stats_print_exception_cnt(struct stats_record *stats_rec, struct stats_record *stats_prev, unsigned int nr_cpus) { - char *fmt_err = "%-15s %-7d %'-14.0f %'-11.0f\n"; - char *fm2_err = "%-15s %-7s %'-14.0f %'-11.0f\n"; + char *fmt1 = "%-15s %-7d %'-12.0f %'-12.0f %s\n"; + char *fmt2 = "%-15s %-7s %'-12.0f %'-12.0f %s\n"; struct record *rec, *prev; - double t, pps, drop; - int i; + double t, drop; + int rec_i, i; - rec = &stats_rec->exception; - prev = &stats_prev->exception; - t = calc_period(rec, prev); - for (i = 0; i < nr_cpus; i++) { - struct datarec *r = &rec->cpu[i]; - struct datarec *p = &prev->cpu[i]; + for (rec_i = 0; rec_i < XDP_ACTION_MAX; rec_i++) { + rec = &stats_rec->exception[rec_i]; + prev = &stats_prev->exception[rec_i]; + t = calc_period(rec, prev); - pps = calc_pps(r, p, t); - drop = calc_drop_pps(r, p, t); - if (pps > 0) - printf(fmt_err, "xdp_exception", i, pps, drop); + for (i = 0; i < nr_cpus; i++) { + struct datarec *r = &rec->cpu[i]; + struct datarec *p = &prev->cpu[i]; + + drop = calc_drop_pps(r, p, t); + if (drop > 0) + printf(fmt1, "xdp_exception", i, + 0.0, drop, action2str(rec_i)); + } + drop = calc_drop_pps(&rec->total, &prev->total, t); + if (drop > 0) + printf(fmt2, "xdp_exception", "total", + 0.0, drop, action2str(rec_i)); } - pps = calc_pps(&rec->total, &prev->total, t); - drop = calc_drop_pps(&rec->total, &prev->total, t); - printf(fm2_err, "xdp_exception", "total", pps, drop); } void sample_stats_print_cpumap_remote(struct stats_record *stats_rec, @@ -564,7 +570,8 @@ void sample_stats_collect(int mask, struct stats_record *rec) map_collect_percpu(map_fds[CPUMAP_KTHREAD_CNT], 0, &rec->kthread); if (mask & SAMPLE_EXCEPTION_CNT) - map_collect_percpu(map_fds[EXCEPTION_CNT], 0, &rec->exception); + for (i = 0; i < XDP_ACTION_MAX; i++) + map_collect_percpu(map_fds[EXCEPTION_CNT], i, &rec->exception[i]); if (mask & SAMPLE_DEVMAP_XMIT_CNT) map_collect_percpu(map_fds[DEVMAP_XMIT_CNT], 0, &rec->devmap_xmit); diff --git a/samples/bpf/xdp_sample_user.h b/samples/bpf/xdp_sample_user.h index a3a3c746e73e..bc0362575d4b 100644 --- a/samples/bpf/xdp_sample_user.h +++ b/samples/bpf/xdp_sample_user.h @@ -59,12 +59,32 @@ extern int tp_cnt; #define XDP_REDIRECT_ERR_MAX 6 -static const char *xdp_redirect_err_names[XDP_REDIRECT_ERR_MAX] = { +__attribute__((unused)) static const char *xdp_redirect_err_names[XDP_REDIRECT_ERR_MAX] = { /* Key=1 keeps unknown errors */ "Success", "Unknown", "EINVAL", "ENETDOWN", "EMSGSIZE", "EOPNOTSUPP", }; +/* enum xdp_action */ +#define XDP_UNKNOWN (XDP_REDIRECT + 1) +#define XDP_ACTION_MAX (XDP_UNKNOWN + 1) + +static const char *xdp_action_names[XDP_ACTION_MAX] = { + [XDP_ABORTED] = "XDP_ABORTED", + [XDP_DROP] = "XDP_DROP", + [XDP_PASS] = "XDP_PASS", + [XDP_TX] = "XDP_TX", + [XDP_REDIRECT] = "XDP_REDIRECT", + [XDP_UNKNOWN] = "XDP_UNKNOWN", +}; + +__attribute__((unused)) static inline const char *action2str(int action) +{ + if (action < XDP_ACTION_MAX) + return xdp_action_names[action]; + return NULL; +} + /* Common stats data record shared with _kern.c */ struct datarec { __u64 processed; @@ -88,7 +108,7 @@ struct stats_record { struct record rx_cnt; struct record redir_err[XDP_REDIRECT_ERR_MAX]; struct record kthread; - struct record exception; + struct record exception[XDP_ACTION_MAX]; struct record devmap_xmit; struct record enq[]; }; From patchwork Fri May 28 23:52:44 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kumar Kartikeya Dwivedi X-Patchwork-Id: 12287565 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B3B99C4708C for ; Fri, 28 May 2021 23:54:12 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 94DB3608FC for ; Fri, 28 May 2021 23:54:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229706AbhE1Xzr (ORCPT ); Fri, 28 May 2021 19:55:47 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45476 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229724AbhE1Xzp (ORCPT ); Fri, 28 May 2021 19:55:45 -0400 Received: from mail-pl1-x644.google.com (mail-pl1-x644.google.com [IPv6:2607:f8b0:4864:20::644]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D2708C061574; Fri, 28 May 2021 16:54:08 -0700 (PDT) Received: by mail-pl1-x644.google.com with SMTP id v13so2338625ple.9; Fri, 28 May 2021 16:54:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=iRj+jj4JHScG7zHlnmdQCZKLe5g9HZ0AbhyTur65Bto=; b=UievWkFLn4zDg6FyifgEzywdbvF2y0ls4pbeATErK5cVWZ8yISu5OBKrz76R5wWHyq odFMfRy82naslinfeMcVVAaxjyUyFCuQS+/qZuIX2gPMnbAsY1LIuUSACnAAWl6/pH4K HMg66aqFtOzvZI4nN8KVfpvJbV+17+UoM6l+BhWj/ECyeGiwuLo96H0ya+VRYWPuvyH5 AuqRw/fXpVALqp7vOm9P7L0XZizzxLl2iOu490fE7PlS6CcXMc9PdMC/l/PK1WREPA5T JpK1Lnz3I2/MGuCy4qJKUpwJ3Vr8YSmOZgx3duKR5jUCNxKfmBEPmPN+jnKtXjxBVgCc MJZA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=iRj+jj4JHScG7zHlnmdQCZKLe5g9HZ0AbhyTur65Bto=; b=Z+8k+3/V/PaNa8nsGTP1FOUnJS2M6e8NWqRW1SiP5S6jz5V1ZLKeXbmnwt+DGBbAUe 7v4BQ+Bj+a4nHzMqWkLXvqBgX/SFRL6zbu35j/P3joQk1jSDrrotU8Sv1A+e7NXnST4e MqxbqsopLAMFf63QMNXQt5fOaG5A9qCVxJGMmuxvE1yqricg+7Ov1mWl5KIkU99cGL/1 LBzhfOBz14G07Hj+blBMZ3Dmd9Q8Ohc8+kIxF4QQkTp8DQztaxigrZNKpPGaWdLf4NTb hNSDVZasRK1bam9dYwLZ41ySnGkwzTXYq4yywJRdFFa5aiwxYzG83dhwauQ6CBjeWPWA HESQ== X-Gm-Message-State: AOAM533ftrEoYGDb3rCOPCIHkwrO5OwmiHqpQlEvEwSyX42N+cZUORG2 +JDEwR4lixnb/Bgzq/tvW32k3Lfkl8k= X-Google-Smtp-Source: ABdhPJyZ1ubF5RXYhRzVpUqIw15mzUbFe4lMSuyH9zP5A1qj4s40FDAJtgLBikpYxpaFWxzmkTnGsg== X-Received: by 2002:a17:90a:288:: with SMTP id w8mr7074092pja.111.1622246047857; Fri, 28 May 2021 16:54:07 -0700 (PDT) Received: from localhost ([2402:3a80:11db:3aa9:ad24:a4a2:844f:6a0a]) by smtp.gmail.com with ESMTPSA id 6sm5321155pjm.21.2021.05.28.16.54.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 28 May 2021 16:54:07 -0700 (PDT) From: Kumar Kartikeya Dwivedi To: bpf@vger.kernel.org Cc: Kumar Kartikeya Dwivedi , Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , "David S. Miller" , Jakub Kicinski , Jesper Dangaard Brouer , =?utf-8?q?Toke_H=C3=B8iland-J?= =?utf-8?q?=C3=B8rgensen?= , netdev@vger.kernel.org Subject: [PATCH RFC bpf-next 09/15] samples: bpf: convert xdp_monitor to use xdp_samples Date: Sat, 29 May 2021 05:22:44 +0530 Message-Id: <20210528235250.2635167-10-memxor@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210528235250.2635167-1-memxor@gmail.com> References: <20210528235250.2635167-1-memxor@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net X-Patchwork-State: RFC This reuses the samples support added so far. Signed-off-by: Kumar Kartikeya Dwivedi --- samples/bpf/Makefile | 2 +- samples/bpf/xdp_monitor_kern.c | 253 +------------ samples/bpf/xdp_monitor_user.c | 625 +-------------------------------- samples/bpf/xdp_sample_kern.h | 6 +- 4 files changed, 23 insertions(+), 863 deletions(-) diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile index ea7100c8b760..8750233dcf07 100644 --- a/samples/bpf/Makefile +++ b/samples/bpf/Makefile @@ -102,7 +102,7 @@ xdp_redirect-objs := xdp_redirect_user.o xdp_redirect_map_multi-objs := xdp_redirect_map_multi_user.o xdp_redirect_map-objs := xdp_redirect_map_user.o xdp_sample_user.o xdp_redirect_cpu-objs := xdp_redirect_cpu_user.o xdp_sample_user.o -xdp_monitor-objs := xdp_monitor_user.o +xdp_monitor-objs := xdp_monitor_user.o xdp_sample_user.o xdp_rxq_info-objs := xdp_rxq_info_user.o syscall_tp-objs := syscall_tp_user.o cpustat-objs := cpustat_user.o diff --git a/samples/bpf/xdp_monitor_kern.c b/samples/bpf/xdp_monitor_kern.c index 5c955b812c47..46c4fe4d7878 100644 --- a/samples/bpf/xdp_monitor_kern.c +++ b/samples/bpf/xdp_monitor_kern.c @@ -3,255 +3,6 @@ * * XDP monitor tool, based on tracepoints */ -#include -#include +#include "xdp_sample_kern.h" -struct { - __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); - __type(key, u32); - __type(value, u64); - __uint(max_entries, 2); - /* TODO: have entries for all possible errno's */ -} redirect_err_cnt SEC(".maps"); - -#define XDP_UNKNOWN XDP_REDIRECT + 1 -struct { - __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); - __type(key, u32); - __type(value, u64); - __uint(max_entries, XDP_UNKNOWN + 1); -} exception_cnt SEC(".maps"); - -/* Tracepoint format: /sys/kernel/debug/tracing/events/xdp/xdp_redirect/format - * Code in: kernel/include/trace/events/xdp.h - */ -struct xdp_redirect_ctx { - u64 __pad; // First 8 bytes are not accessible by bpf code - int prog_id; // offset:8; size:4; signed:1; - u32 act; // offset:12 size:4; signed:0; - int ifindex; // offset:16 size:4; signed:1; - int err; // offset:20 size:4; signed:1; - int to_ifindex; // offset:24 size:4; signed:1; - u32 map_id; // offset:28 size:4; signed:0; - int map_index; // offset:32 size:4; signed:1; -}; // offset:36 - -enum { - XDP_REDIRECT_SUCCESS = 0, - XDP_REDIRECT_ERROR = 1 -}; - -static __always_inline -int xdp_redirect_collect_stat(struct xdp_redirect_ctx *ctx) -{ - u32 key = XDP_REDIRECT_ERROR; - int err = ctx->err; - u64 *cnt; - - if (!err) - key = XDP_REDIRECT_SUCCESS; - - cnt = bpf_map_lookup_elem(&redirect_err_cnt, &key); - if (!cnt) - return 1; - *cnt += 1; - - return 0; /* Indicate event was filtered (no further processing)*/ - /* - * Returning 1 here would allow e.g. a perf-record tracepoint - * to see and record these events, but it doesn't work well - * in-practice as stopping perf-record also unload this - * bpf_prog. Plus, there is additional overhead of doing so. - */ -} - -SEC("tracepoint/xdp/xdp_redirect_err") -int trace_xdp_redirect_err(struct xdp_redirect_ctx *ctx) -{ - return xdp_redirect_collect_stat(ctx); -} - - -SEC("tracepoint/xdp/xdp_redirect_map_err") -int trace_xdp_redirect_map_err(struct xdp_redirect_ctx *ctx) -{ - return xdp_redirect_collect_stat(ctx); -} - -/* Likely unloaded when prog starts */ -SEC("tracepoint/xdp/xdp_redirect") -int trace_xdp_redirect(struct xdp_redirect_ctx *ctx) -{ - return xdp_redirect_collect_stat(ctx); -} - -/* Likely unloaded when prog starts */ -SEC("tracepoint/xdp/xdp_redirect_map") -int trace_xdp_redirect_map(struct xdp_redirect_ctx *ctx) -{ - return xdp_redirect_collect_stat(ctx); -} - -/* Tracepoint format: /sys/kernel/debug/tracing/events/xdp/xdp_exception/format - * Code in: kernel/include/trace/events/xdp.h - */ -struct xdp_exception_ctx { - u64 __pad; // First 8 bytes are not accessible by bpf code - int prog_id; // offset:8; size:4; signed:1; - u32 act; // offset:12; size:4; signed:0; - int ifindex; // offset:16; size:4; signed:1; -}; - -SEC("tracepoint/xdp/xdp_exception") -int trace_xdp_exception(struct xdp_exception_ctx *ctx) -{ - u64 *cnt; - u32 key; - - key = ctx->act; - if (key > XDP_REDIRECT) - key = XDP_UNKNOWN; - - cnt = bpf_map_lookup_elem(&exception_cnt, &key); - if (!cnt) - return 1; - *cnt += 1; - - return 0; -} - -/* Common stats data record shared with _user.c */ -struct datarec { - u64 processed; - u64 dropped; - u64 info; - u64 err; -}; -#define MAX_CPUS 64 - -struct { - __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); - __type(key, u32); - __type(value, struct datarec); - __uint(max_entries, MAX_CPUS); -} cpumap_enqueue_cnt SEC(".maps"); - -struct { - __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); - __type(key, u32); - __type(value, struct datarec); - __uint(max_entries, 1); -} cpumap_kthread_cnt SEC(".maps"); - -/* Tracepoint: /sys/kernel/debug/tracing/events/xdp/xdp_cpumap_enqueue/format - * Code in: kernel/include/trace/events/xdp.h - */ -struct cpumap_enqueue_ctx { - u64 __pad; // First 8 bytes are not accessible by bpf code - int map_id; // offset:8; size:4; signed:1; - u32 act; // offset:12; size:4; signed:0; - int cpu; // offset:16; size:4; signed:1; - unsigned int drops; // offset:20; size:4; signed:0; - unsigned int processed; // offset:24; size:4; signed:0; - int to_cpu; // offset:28; size:4; signed:1; -}; - -SEC("tracepoint/xdp/xdp_cpumap_enqueue") -int trace_xdp_cpumap_enqueue(struct cpumap_enqueue_ctx *ctx) -{ - u32 to_cpu = ctx->to_cpu; - struct datarec *rec; - - if (to_cpu >= MAX_CPUS) - return 1; - - rec = bpf_map_lookup_elem(&cpumap_enqueue_cnt, &to_cpu); - if (!rec) - return 0; - rec->processed += ctx->processed; - rec->dropped += ctx->drops; - - /* Record bulk events, then userspace can calc average bulk size */ - if (ctx->processed > 0) - rec->info += 1; - - return 0; -} - -/* Tracepoint: /sys/kernel/debug/tracing/events/xdp/xdp_cpumap_kthread/format - * Code in: kernel/include/trace/events/xdp.h - */ -struct cpumap_kthread_ctx { - u64 __pad; // First 8 bytes are not accessible by bpf code - int map_id; // offset:8; size:4; signed:1; - u32 act; // offset:12; size:4; signed:0; - int cpu; // offset:16; size:4; signed:1; - unsigned int drops; // offset:20; size:4; signed:0; - unsigned int processed; // offset:24; size:4; signed:0; - int sched; // offset:28; size:4; signed:1; -}; - -SEC("tracepoint/xdp/xdp_cpumap_kthread") -int trace_xdp_cpumap_kthread(struct cpumap_kthread_ctx *ctx) -{ - struct datarec *rec; - u32 key = 0; - - rec = bpf_map_lookup_elem(&cpumap_kthread_cnt, &key); - if (!rec) - return 0; - rec->processed += ctx->processed; - rec->dropped += ctx->drops; - - /* Count times kthread yielded CPU via schedule call */ - if (ctx->sched) - rec->info++; - - return 0; -} - -struct { - __uint(type, BPF_MAP_TYPE_PERCPU_ARRAY); - __type(key, u32); - __type(value, struct datarec); - __uint(max_entries, 1); -} devmap_xmit_cnt SEC(".maps"); - -/* Tracepoint: /sys/kernel/debug/tracing/events/xdp/xdp_devmap_xmit/format - * Code in: kernel/include/trace/events/xdp.h - */ -struct devmap_xmit_ctx { - u64 __pad; // First 8 bytes are not accessible by bpf code - int from_ifindex; // offset:8; size:4; signed:1; - u32 act; // offset:12; size:4; signed:0; - int to_ifindex; // offset:16; size:4; signed:1; - int drops; // offset:20; size:4; signed:1; - int sent; // offset:24; size:4; signed:1; - int err; // offset:28; size:4; signed:1; -}; - -SEC("tracepoint/xdp/xdp_devmap_xmit") -int trace_xdp_devmap_xmit(struct devmap_xmit_ctx *ctx) -{ - struct datarec *rec; - u32 key = 0; - - rec = bpf_map_lookup_elem(&devmap_xmit_cnt, &key); - if (!rec) - return 0; - rec->processed += ctx->sent; - rec->dropped += ctx->drops; - - /* Record bulk events, then userspace can calc average bulk size */ - rec->info += 1; - - /* Record error cases, where no frame were sent */ - if (ctx->err) - rec->err++; - - /* Catch API error of drv ndo_xdp_xmit sent more than count */ - if (ctx->drops < 0) - rec->err++; - - return 1; -} +char _license[] SEC("license") = "GPL"; diff --git a/samples/bpf/xdp_monitor_user.c b/samples/bpf/xdp_monitor_user.c index 49ebc49aefc3..babb9fcc1a17 100644 --- a/samples/bpf/xdp_monitor_user.c +++ b/samples/bpf/xdp_monitor_user.c @@ -30,32 +30,9 @@ static const char *__doc_err_only__= #include #include #include "bpf_util.h" +#include "xdp_sample_user.h" -enum map_type { - REDIRECT_ERR_CNT, - EXCEPTION_CNT, - CPUMAP_ENQUEUE_CNT, - CPUMAP_KTHREAD_CNT, - DEVMAP_XMIT_CNT, -}; - -static const char *const map_type_strings[] = { - [REDIRECT_ERR_CNT] = "redirect_err_cnt", - [EXCEPTION_CNT] = "exception_cnt", - [CPUMAP_ENQUEUE_CNT] = "cpumap_enqueue_cnt", - [CPUMAP_KTHREAD_CNT] = "cpumap_kthread_cnt", - [DEVMAP_XMIT_CNT] = "devmap_xmit_cnt", -}; - -#define NUM_MAP 5 -#define NUM_TP 8 - -static int tp_cnt; -static int map_cnt; -static int verbose = 1; static bool debug = false; -struct bpf_map *map_data[NUM_MAP] = {}; -struct bpf_link *tp_links[NUM_TP] = {}; struct bpf_object *obj; static const struct option long_options[] = { @@ -68,12 +45,8 @@ static const struct option long_options[] = { static void int_exit(int sig) { - /* Detach tracepoints */ - while (tp_cnt) - bpf_link__destroy(tp_links[--tp_cnt]); - bpf_object__close(obj); - exit(0); + sample_exit(EXIT_OK); } /* C standard specifies two constants, EXIT_SUCCESS(0) and EXIT_FAILURE(1) */ @@ -100,557 +73,6 @@ static void usage(char *argv[]) printf("\n"); } -#define NANOSEC_PER_SEC 1000000000 /* 10^9 */ -static __u64 gettime(void) -{ - struct timespec t; - int res; - - res = clock_gettime(CLOCK_MONOTONIC, &t); - if (res < 0) { - fprintf(stderr, "Error with gettimeofday! (%i)\n", res); - exit(EXIT_FAILURE); - } - return (__u64) t.tv_sec * NANOSEC_PER_SEC + t.tv_nsec; -} - -enum { - REDIR_SUCCESS = 0, - REDIR_ERROR = 1, -}; -#define REDIR_RES_MAX 2 -static const char *redir_names[REDIR_RES_MAX] = { - [REDIR_SUCCESS] = "Success", - [REDIR_ERROR] = "Error", -}; -static const char *err2str(int err) -{ - if (err < REDIR_RES_MAX) - return redir_names[err]; - return NULL; -} -/* enum xdp_action */ -#define XDP_UNKNOWN XDP_REDIRECT + 1 -#define XDP_ACTION_MAX (XDP_UNKNOWN + 1) -static const char *xdp_action_names[XDP_ACTION_MAX] = { - [XDP_ABORTED] = "XDP_ABORTED", - [XDP_DROP] = "XDP_DROP", - [XDP_PASS] = "XDP_PASS", - [XDP_TX] = "XDP_TX", - [XDP_REDIRECT] = "XDP_REDIRECT", - [XDP_UNKNOWN] = "XDP_UNKNOWN", -}; -static const char *action2str(int action) -{ - if (action < XDP_ACTION_MAX) - return xdp_action_names[action]; - return NULL; -} - -/* Common stats data record shared with _kern.c */ -struct datarec { - __u64 processed; - __u64 dropped; - __u64 info; - __u64 err; -}; -#define MAX_CPUS 64 - -/* Userspace structs for collection of stats from maps */ -struct record { - __u64 timestamp; - struct datarec total; - struct datarec *cpu; -}; -struct u64rec { - __u64 processed; -}; -struct record_u64 { - /* record for _kern side __u64 values */ - __u64 timestamp; - struct u64rec total; - struct u64rec *cpu; -}; - -struct stats_record { - struct record_u64 xdp_redirect[REDIR_RES_MAX]; - struct record_u64 xdp_exception[XDP_ACTION_MAX]; - struct record xdp_cpumap_kthread; - struct record xdp_cpumap_enqueue[MAX_CPUS]; - struct record xdp_devmap_xmit; -}; - -static bool map_collect_record(int fd, __u32 key, struct record *rec) -{ - /* For percpu maps, userspace gets a value per possible CPU */ - unsigned int nr_cpus = bpf_num_possible_cpus(); - struct datarec values[nr_cpus]; - __u64 sum_processed = 0; - __u64 sum_dropped = 0; - __u64 sum_info = 0; - __u64 sum_err = 0; - int i; - - if ((bpf_map_lookup_elem(fd, &key, values)) != 0) { - fprintf(stderr, - "ERR: bpf_map_lookup_elem failed key:0x%X\n", key); - return false; - } - /* Get time as close as possible to reading map contents */ - rec->timestamp = gettime(); - - /* Record and sum values from each CPU */ - for (i = 0; i < nr_cpus; i++) { - rec->cpu[i].processed = values[i].processed; - sum_processed += values[i].processed; - rec->cpu[i].dropped = values[i].dropped; - sum_dropped += values[i].dropped; - rec->cpu[i].info = values[i].info; - sum_info += values[i].info; - rec->cpu[i].err = values[i].err; - sum_err += values[i].err; - } - rec->total.processed = sum_processed; - rec->total.dropped = sum_dropped; - rec->total.info = sum_info; - rec->total.err = sum_err; - return true; -} - -static bool map_collect_record_u64(int fd, __u32 key, struct record_u64 *rec) -{ - /* For percpu maps, userspace gets a value per possible CPU */ - unsigned int nr_cpus = bpf_num_possible_cpus(); - struct u64rec values[nr_cpus]; - __u64 sum_total = 0; - int i; - - if ((bpf_map_lookup_elem(fd, &key, values)) != 0) { - fprintf(stderr, - "ERR: bpf_map_lookup_elem failed key:0x%X\n", key); - return false; - } - /* Get time as close as possible to reading map contents */ - rec->timestamp = gettime(); - - /* Record and sum values from each CPU */ - for (i = 0; i < nr_cpus; i++) { - rec->cpu[i].processed = values[i].processed; - sum_total += values[i].processed; - } - rec->total.processed = sum_total; - return true; -} - -static double calc_period(struct record *r, struct record *p) -{ - double period_ = 0; - __u64 period = 0; - - period = r->timestamp - p->timestamp; - if (period > 0) - period_ = ((double) period / NANOSEC_PER_SEC); - - return period_; -} - -static double calc_period_u64(struct record_u64 *r, struct record_u64 *p) -{ - double period_ = 0; - __u64 period = 0; - - period = r->timestamp - p->timestamp; - if (period > 0) - period_ = ((double) period / NANOSEC_PER_SEC); - - return period_; -} - -static double calc_pps(struct datarec *r, struct datarec *p, double period) -{ - __u64 packets = 0; - double pps = 0; - - if (period > 0) { - packets = r->processed - p->processed; - pps = packets / period; - } - return pps; -} - -static double calc_pps_u64(struct u64rec *r, struct u64rec *p, double period) -{ - __u64 packets = 0; - double pps = 0; - - if (period > 0) { - packets = r->processed - p->processed; - pps = packets / period; - } - return pps; -} - -static double calc_drop(struct datarec *r, struct datarec *p, double period) -{ - __u64 packets = 0; - double pps = 0; - - if (period > 0) { - packets = r->dropped - p->dropped; - pps = packets / period; - } - return pps; -} - -static double calc_info(struct datarec *r, struct datarec *p, double period) -{ - __u64 packets = 0; - double pps = 0; - - if (period > 0) { - packets = r->info - p->info; - pps = packets / period; - } - return pps; -} - -static double calc_err(struct datarec *r, struct datarec *p, double period) -{ - __u64 packets = 0; - double pps = 0; - - if (period > 0) { - packets = r->err - p->err; - pps = packets / period; - } - return pps; -} - -static void stats_print(struct stats_record *stats_rec, - struct stats_record *stats_prev, - bool err_only) -{ - unsigned int nr_cpus = bpf_num_possible_cpus(); - int rec_i = 0, i, to_cpu; - double t = 0, pps = 0; - - /* Header */ - printf("%-15s %-7s %-12s %-12s %-9s\n", - "XDP-event", "CPU:to", "pps", "drop-pps", "extra-info"); - - /* tracepoint: xdp:xdp_redirect_* */ - if (err_only) - rec_i = REDIR_ERROR; - - for (; rec_i < REDIR_RES_MAX; rec_i++) { - struct record_u64 *rec, *prev; - char *fmt1 = "%-15s %-7d %'-12.0f %'-12.0f %s\n"; - char *fmt2 = "%-15s %-7s %'-12.0f %'-12.0f %s\n"; - - rec = &stats_rec->xdp_redirect[rec_i]; - prev = &stats_prev->xdp_redirect[rec_i]; - t = calc_period_u64(rec, prev); - - for (i = 0; i < nr_cpus; i++) { - struct u64rec *r = &rec->cpu[i]; - struct u64rec *p = &prev->cpu[i]; - - pps = calc_pps_u64(r, p, t); - if (pps > 0) - printf(fmt1, "XDP_REDIRECT", i, - rec_i ? 0.0: pps, rec_i ? pps : 0.0, - err2str(rec_i)); - } - pps = calc_pps_u64(&rec->total, &prev->total, t); - printf(fmt2, "XDP_REDIRECT", "total", - rec_i ? 0.0: pps, rec_i ? pps : 0.0, err2str(rec_i)); - } - - /* tracepoint: xdp:xdp_exception */ - for (rec_i = 0; rec_i < XDP_ACTION_MAX; rec_i++) { - struct record_u64 *rec, *prev; - char *fmt1 = "%-15s %-7d %'-12.0f %'-12.0f %s\n"; - char *fmt2 = "%-15s %-7s %'-12.0f %'-12.0f %s\n"; - - rec = &stats_rec->xdp_exception[rec_i]; - prev = &stats_prev->xdp_exception[rec_i]; - t = calc_period_u64(rec, prev); - - for (i = 0; i < nr_cpus; i++) { - struct u64rec *r = &rec->cpu[i]; - struct u64rec *p = &prev->cpu[i]; - - pps = calc_pps_u64(r, p, t); - if (pps > 0) - printf(fmt1, "Exception", i, - 0.0, pps, action2str(rec_i)); - } - pps = calc_pps_u64(&rec->total, &prev->total, t); - if (pps > 0) - printf(fmt2, "Exception", "total", - 0.0, pps, action2str(rec_i)); - } - - /* cpumap enqueue stats */ - for (to_cpu = 0; to_cpu < MAX_CPUS; to_cpu++) { - char *fmt1 = "%-15s %3d:%-3d %'-12.0f %'-12.0f %'-10.2f %s\n"; - char *fmt2 = "%-15s %3s:%-3d %'-12.0f %'-12.0f %'-10.2f %s\n"; - struct record *rec, *prev; - char *info_str = ""; - double drop, info; - - rec = &stats_rec->xdp_cpumap_enqueue[to_cpu]; - prev = &stats_prev->xdp_cpumap_enqueue[to_cpu]; - t = calc_period(rec, prev); - for (i = 0; i < nr_cpus; i++) { - struct datarec *r = &rec->cpu[i]; - struct datarec *p = &prev->cpu[i]; - - pps = calc_pps(r, p, t); - drop = calc_drop(r, p, t); - info = calc_info(r, p, t); - if (info > 0) { - info_str = "bulk-average"; - info = pps / info; /* calc average bulk size */ - } - if (pps > 0) - printf(fmt1, "cpumap-enqueue", - i, to_cpu, pps, drop, info, info_str); - } - pps = calc_pps(&rec->total, &prev->total, t); - if (pps > 0) { - drop = calc_drop(&rec->total, &prev->total, t); - info = calc_info(&rec->total, &prev->total, t); - if (info > 0) { - info_str = "bulk-average"; - info = pps / info; /* calc average bulk size */ - } - printf(fmt2, "cpumap-enqueue", - "sum", to_cpu, pps, drop, info, info_str); - } - } - - /* cpumap kthread stats */ - { - char *fmt1 = "%-15s %-7d %'-12.0f %'-12.0f %'-10.0f %s\n"; - char *fmt2 = "%-15s %-7s %'-12.0f %'-12.0f %'-10.0f %s\n"; - struct record *rec, *prev; - double drop, info; - char *i_str = ""; - - rec = &stats_rec->xdp_cpumap_kthread; - prev = &stats_prev->xdp_cpumap_kthread; - t = calc_period(rec, prev); - for (i = 0; i < nr_cpus; i++) { - struct datarec *r = &rec->cpu[i]; - struct datarec *p = &prev->cpu[i]; - - pps = calc_pps(r, p, t); - drop = calc_drop(r, p, t); - info = calc_info(r, p, t); - if (info > 0) - i_str = "sched"; - if (pps > 0 || drop > 0) - printf(fmt1, "cpumap-kthread", - i, pps, drop, info, i_str); - } - pps = calc_pps(&rec->total, &prev->total, t); - drop = calc_drop(&rec->total, &prev->total, t); - info = calc_info(&rec->total, &prev->total, t); - if (info > 0) - i_str = "sched-sum"; - printf(fmt2, "cpumap-kthread", "total", pps, drop, info, i_str); - } - - /* devmap ndo_xdp_xmit stats */ - { - char *fmt1 = "%-15s %-7d %'-12.0f %'-12.0f %'-10.2f %s %s\n"; - char *fmt2 = "%-15s %-7s %'-12.0f %'-12.0f %'-10.2f %s %s\n"; - struct record *rec, *prev; - double drop, info, err; - char *i_str = ""; - char *err_str = ""; - - rec = &stats_rec->xdp_devmap_xmit; - prev = &stats_prev->xdp_devmap_xmit; - t = calc_period(rec, prev); - for (i = 0; i < nr_cpus; i++) { - struct datarec *r = &rec->cpu[i]; - struct datarec *p = &prev->cpu[i]; - - pps = calc_pps(r, p, t); - drop = calc_drop(r, p, t); - info = calc_info(r, p, t); - err = calc_err(r, p, t); - if (info > 0) { - i_str = "bulk-average"; - info = (pps+drop) / info; /* calc avg bulk */ - } - if (err > 0) - err_str = "drv-err"; - if (pps > 0 || drop > 0) - printf(fmt1, "devmap-xmit", - i, pps, drop, info, i_str, err_str); - } - pps = calc_pps(&rec->total, &prev->total, t); - drop = calc_drop(&rec->total, &prev->total, t); - info = calc_info(&rec->total, &prev->total, t); - err = calc_err(&rec->total, &prev->total, t); - if (info > 0) { - i_str = "bulk-average"; - info = (pps+drop) / info; /* calc avg bulk */ - } - if (err > 0) - err_str = "drv-err"; - printf(fmt2, "devmap-xmit", "total", pps, drop, - info, i_str, err_str); - } - - printf("\n"); -} - -static bool stats_collect(struct stats_record *rec) -{ - int fd; - int i; - - /* TODO: Detect if someone unloaded the perf event_fd's, as - * this can happen by someone running perf-record -e - */ - - fd = bpf_map__fd(map_data[REDIRECT_ERR_CNT]); - for (i = 0; i < REDIR_RES_MAX; i++) - map_collect_record_u64(fd, i, &rec->xdp_redirect[i]); - - fd = bpf_map__fd(map_data[EXCEPTION_CNT]); - for (i = 0; i < XDP_ACTION_MAX; i++) { - map_collect_record_u64(fd, i, &rec->xdp_exception[i]); - } - - fd = bpf_map__fd(map_data[CPUMAP_ENQUEUE_CNT]); - for (i = 0; i < MAX_CPUS; i++) - map_collect_record(fd, i, &rec->xdp_cpumap_enqueue[i]); - - fd = bpf_map__fd(map_data[CPUMAP_KTHREAD_CNT]); - map_collect_record(fd, 0, &rec->xdp_cpumap_kthread); - - fd = bpf_map__fd(map_data[DEVMAP_XMIT_CNT]); - map_collect_record(fd, 0, &rec->xdp_devmap_xmit); - - return true; -} - -static void *alloc_rec_per_cpu(int record_size) -{ - unsigned int nr_cpus = bpf_num_possible_cpus(); - void *array; - - array = calloc(nr_cpus, record_size); - if (!array) { - fprintf(stderr, "Mem alloc error (nr_cpus:%u)\n", nr_cpus); - exit(EXIT_FAIL_MEM); - } - return array; -} - -static struct stats_record *alloc_stats_record(void) -{ - struct stats_record *rec; - int rec_sz; - int i; - - /* Alloc main stats_record structure */ - rec = calloc(1, sizeof(*rec)); - if (!rec) { - fprintf(stderr, "Mem alloc error\n"); - exit(EXIT_FAIL_MEM); - } - - /* Alloc stats stored per CPU for each record */ - rec_sz = sizeof(struct u64rec); - for (i = 0; i < REDIR_RES_MAX; i++) - rec->xdp_redirect[i].cpu = alloc_rec_per_cpu(rec_sz); - - for (i = 0; i < XDP_ACTION_MAX; i++) - rec->xdp_exception[i].cpu = alloc_rec_per_cpu(rec_sz); - - rec_sz = sizeof(struct datarec); - rec->xdp_cpumap_kthread.cpu = alloc_rec_per_cpu(rec_sz); - rec->xdp_devmap_xmit.cpu = alloc_rec_per_cpu(rec_sz); - - for (i = 0; i < MAX_CPUS; i++) - rec->xdp_cpumap_enqueue[i].cpu = alloc_rec_per_cpu(rec_sz); - - return rec; -} - -static void free_stats_record(struct stats_record *r) -{ - int i; - - for (i = 0; i < REDIR_RES_MAX; i++) - free(r->xdp_redirect[i].cpu); - - for (i = 0; i < XDP_ACTION_MAX; i++) - free(r->xdp_exception[i].cpu); - - free(r->xdp_cpumap_kthread.cpu); - free(r->xdp_devmap_xmit.cpu); - - for (i = 0; i < MAX_CPUS; i++) - free(r->xdp_cpumap_enqueue[i].cpu); - - free(r); -} - -/* Pointer swap trick */ -static inline void swap(struct stats_record **a, struct stats_record **b) -{ - struct stats_record *tmp; - - tmp = *a; - *a = *b; - *b = tmp; -} - -static void stats_poll(int interval, bool err_only) -{ - struct stats_record *rec, *prev; - - rec = alloc_stats_record(); - prev = alloc_stats_record(); - stats_collect(rec); - - if (err_only) - printf("\n%s\n", __doc_err_only__); - - /* Trick to pretty printf with thousands separators use %' */ - setlocale(LC_NUMERIC, "en_US"); - - /* Header */ - if (verbose) - printf("\n%s", __doc__); - - /* TODO Need more advanced stats on error types */ - if (verbose) { - printf(" - Stats map0: %s\n", bpf_map__name(map_data[0])); - printf(" - Stats map1: %s\n", bpf_map__name(map_data[1])); - printf("\n"); - } - fflush(stdout); - - while (1) { - swap(&prev, &rec); - stats_collect(rec); - stats_print(rec, prev, err_only); - fflush(stdout); - sleep(interval); - } - - free_stats_record(rec); - free_stats_record(prev); -} - static void print_bpf_prog_info(void) { struct bpf_program *prog; @@ -666,7 +88,7 @@ static void print_bpf_prog_info(void) i = 0; /* Maps info */ - printf("Loaded BPF prog have %d map(s)\n", map_cnt); + printf("Loaded BPF prog have %d map(s)\n", NUM_MAP); bpf_object__for_each_map(map, obj) { const char *name = bpf_map__name(map); int fd = bpf_map__fd(map); @@ -687,10 +109,11 @@ static void print_bpf_prog_info(void) int main(int argc, char **argv) { - struct bpf_program *prog; + int mask = SAMPLE_REDIRECT_ERR_CNT | SAMPLE_CPUMAP_ENQUEUE_CNT | + SAMPLE_CPUMAP_KTHREAD_CNT | SAMPLE_EXCEPTION_CNT | + SAMPLE_DEVMAP_XMIT_CNT; int longindex = 0, opt; int ret = EXIT_FAILURE; - enum map_type type; char filename[256]; /* Default settings: */ @@ -736,25 +159,9 @@ int main(int argc, char **argv) goto cleanup; } - for (type = 0; type < NUM_MAP; type++) { - map_data[type] = - bpf_object__find_map_by_name(obj, map_type_strings[type]); - - if (libbpf_get_error(map_data[type])) { - printf("ERROR: finding a map in obj file failed\n"); - goto cleanup; - } - map_cnt++; - } - - bpf_object__for_each_program(prog, obj) { - tp_links[tp_cnt] = bpf_program__attach(prog); - if (libbpf_get_error(tp_links[tp_cnt])) { - printf("ERROR: bpf_program__attach failed\n"); - tp_links[tp_cnt] = NULL; - goto cleanup; - } - tp_cnt++; + if (sample_init(obj) < 0) { + fprintf(stderr, "Failed to initialize sample\n"); + goto cleanup; } if (debug) { @@ -763,6 +170,8 @@ int main(int argc, char **argv) /* Unload/stop tracepoint event by closing bpf_link's */ if (errors_only) { + printf("%s", __doc_err_only__); + /* The bpf_link[i] depend on the order of * the functions was defined in _kern.c */ @@ -771,17 +180,13 @@ int main(int argc, char **argv) bpf_link__destroy(tp_links[3]); /* tracepoint/xdp/xdp_redirect_map */ tp_links[3] = NULL; + } else { + mask |= SAMPLE_REDIRECT_CNT; } - stats_poll(interval, errors_only); - - ret = EXIT_SUCCESS; + sample_stats_poll(interval, mask, "xdp_monitor", true); cleanup: - /* Detach tracepoints */ - while (tp_cnt) - bpf_link__destroy(tp_links[--tp_cnt]); - bpf_object__close(obj); - return ret; + sample_exit(EXIT_OK); } diff --git a/samples/bpf/xdp_sample_kern.h b/samples/bpf/xdp_sample_kern.h index ec36e7b4a3ba..dd7f7ea63166 100644 --- a/samples/bpf/xdp_sample_kern.h +++ b/samples/bpf/xdp_sample_kern.h @@ -5,7 +5,11 @@ #include #include -#define MAX_CPUS 64 +#ifndef NR_CPUS +#define NR_CPUS 64 +#endif + +#define MAX_CPUS NR_CPUS #define EINVAL 22 #define ENETDOWN 100 From patchwork Fri May 28 23:52:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kumar Kartikeya Dwivedi X-Patchwork-Id: 12287567 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-12.9 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,UNWANTED_LANGUAGE_BODY, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 20441C47087 for ; Fri, 28 May 2021 23:54:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E8C7D6135F for ; Fri, 28 May 2021 23:54:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229693AbhE1Xzw (ORCPT ); Fri, 28 May 2021 19:55:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45518 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229729AbhE1Xzs (ORCPT ); Fri, 28 May 2021 19:55:48 -0400 Received: from mail-pg1-x542.google.com (mail-pg1-x542.google.com [IPv6:2607:f8b0:4864:20::542]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9721CC061761; Fri, 28 May 2021 16:54:12 -0700 (PDT) Received: by mail-pg1-x542.google.com with SMTP id t193so3711672pgb.4; Fri, 28 May 2021 16:54:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=8amNBLbzUuPKwP3i6AuNQrdaqZbY4zH/YLcQB8X1ykQ=; b=C9dn9RdFf+3hSOeDO49rtb5SDmsS3lCq51FNwh6YDBusMB0WslSzq0ZSKkJFPLONJG U8g8Ckc70qEJj4onNosZUOUtYXorZGN1iD4Fw3bCP175RPEnqr4dKG8MPAgmHBHjcpoh q+hdbQrndUl/Oro+Cw/qrdzC/EkiW0Y14UHD5nepGuBG39sRLWP2dIsluJ6WnButkq18 /NkoCDWwFJrhq1D9MblUQq7f2vgXDOetL+RiAvraib1y/qW9OZqL/IZusZhYniNxeFdY dEfiqg2G4qrtXKKzaDbWOn1bprJd0+h/I+TEB/7SDUs6CljD7olZw/NKO+0sfnGeoEt8 /Csw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=8amNBLbzUuPKwP3i6AuNQrdaqZbY4zH/YLcQB8X1ykQ=; b=KHYGDEbEXyF4pBGc01rS4YkP+OyyMDw9I6PjKJyexiqa0J/athiNItnU1aulbcYLPJ wmv7NkYybkl7g4+PS4ivgwyE1LKi7vYSEexYa7iRZHeAqjWl6BqQej6aRFcAhrpLVFuI eI+c9b1hpK6gMi34cv4tSW53zYaTtLMDwEklcgP1kSTOfKhJs4JAsK/m16ix4VZj8IyH EmJ32nV4SbL5alfd3XKEs9DGexE7WcWdxGo9o9rfbXLAXoG0Y4x3zxz0kRw8j0eJiRZj 4+0FjW+BVwMqd/I8zvCLls8DJLfONSLGALMrAYoCxCnjp2CKJYuR3vk9UqnyiqN3bqmr +JBQ== X-Gm-Message-State: AOAM530KmyEqUw0vLY/997gv+ukOMH1ocl7JJeUKkhZOIVLjgrkmdOMu 6q1mZzgtYTnSFVEYz//O3QTxfpXkNBc= X-Google-Smtp-Source: ABdhPJx7jUyUVHPl71g2uL+QGWbyemvCfztS7p9WZjq0cpst4ChYka/+ZWbcY0TRhF9ybGm8hhNINA== X-Received: by 2002:a65:584d:: with SMTP id s13mr11542511pgr.97.1622246051443; Fri, 28 May 2021 16:54:11 -0700 (PDT) Received: from localhost ([2402:3a80:11db:3aa9:ad24:a4a2:844f:6a0a]) by smtp.gmail.com with ESMTPSA id c17sm5343412pgm.3.2021.05.28.16.54.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 28 May 2021 16:54:11 -0700 (PDT) From: Kumar Kartikeya Dwivedi To: bpf@vger.kernel.org Cc: Kumar Kartikeya Dwivedi , Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , "David S. Miller" , Jakub Kicinski , Jesper Dangaard Brouer , =?utf-8?q?Toke_H=C3=B8iland-J?= =?utf-8?q?=C3=B8rgensen?= , netdev@vger.kernel.org Subject: [PATCH RFC bpf-next 10/15] samples: bpf: implement terse output mode and make it default Date: Sat, 29 May 2021 05:22:45 +0530 Message-Id: <20210528235250.2635167-11-memxor@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210528235250.2635167-1-memxor@gmail.com> References: <20210528235250.2635167-1-memxor@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net X-Patchwork-State: RFC Also allow an easy way to go back to the verbose output using Ctrl+\ (SIGQUIT). One change we make to exception printing is that we skip the per CPU per action exception count printing (not collection), as it isn't too useful in general. Signed-off-by: Kumar Kartikeya Dwivedi --- samples/bpf/Makefile | 2 +- samples/bpf/xdp_monitor_user.c | 2 +- samples/bpf/xdp_redirect_cpu_user.c | 6 +- samples/bpf/xdp_sample_user.c | 522 +++++++++++++++++++--------- samples/bpf/xdp_sample_user.h | 36 ++ 5 files changed, 402 insertions(+), 166 deletions(-) diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile index 8750233dcf07..d1977fe56dce 100644 --- a/samples/bpf/Makefile +++ b/samples/bpf/Makefile @@ -194,7 +194,7 @@ BPF_EXTRA_CFLAGS += -I$(srctree)/arch/mips/include/asm/mach-generic endif endif -TPROGS_CFLAGS += -Wall -O2 +TPROGS_CFLAGS += -Wall -O2 -lm TPROGS_CFLAGS += -Wmissing-prototypes TPROGS_CFLAGS += -Wstrict-prototypes diff --git a/samples/bpf/xdp_monitor_user.c b/samples/bpf/xdp_monitor_user.c index babb9fcc1a17..73d6d35f0c65 100644 --- a/samples/bpf/xdp_monitor_user.c +++ b/samples/bpf/xdp_monitor_user.c @@ -184,7 +184,7 @@ int main(int argc, char **argv) mask |= SAMPLE_REDIRECT_CNT; } - sample_stats_poll(interval, mask, "xdp_monitor", true); + sample_stats_poll(interval, mask, NULL, true); cleanup: bpf_object__close(obj); diff --git a/samples/bpf/xdp_redirect_cpu_user.c b/samples/bpf/xdp_redirect_cpu_user.c index 6dbed962a2e2..3983ed71d879 100644 --- a/samples/bpf/xdp_redirect_cpu_user.c +++ b/samples/bpf/xdp_redirect_cpu_user.c @@ -216,16 +216,18 @@ static void __stats_poll(int interval, bool use_separators, char *prog_name, for (;;) { swap(&prev, &record); sample_stats_collect(mask, record); - sample_stats_print(mask, record, prev, prog_name); + sample_stats_print(mask, record, prev, NULL); /* Depends on SAMPLE_CPUMAP_KTHREAD_CNT */ sample_stats_print_cpumap_remote(record, prev, bpf_num_possible_cpus(), mprog_name); - printf("\n"); + if (sample_log_level & LL_DEFAULT) + printf("\n"); fflush(stdout); sleep(interval); if (stress_mode) stress_cpumap(value); + sample_reset_mode(); } free_stats_record(record); diff --git a/samples/bpf/xdp_sample_user.c b/samples/bpf/xdp_sample_user.c index 446668edf8d8..d0b26023f1db 100644 --- a/samples/bpf/xdp_sample_user.c +++ b/samples/bpf/xdp_sample_user.c @@ -9,7 +9,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -35,6 +37,39 @@ struct bpf_link *tp_links[NUM_TP] = {}; int map_fds[NUM_MAP], tp_cnt, n_cpus; +static int sample_sig_fd; +enum log_level sample_log_level = LL_SIMPLE; +static bool err_exp; + +#define __sample_print(fmt, cond, printer, ...) \ + ({ \ + if (cond) \ + printer(fmt, ##__VA_ARGS__); \ + }) + +#define print_always(fmt, ...) __sample_print(fmt, 1, printf, ##__VA_ARGS__) +#define print_default(fmt, ...) \ + __sample_print(fmt, sample_log_level & LL_DEFAULT, printf, ##__VA_ARGS__) +#define __print_err(err, fmt, printer, ...) \ + ({ \ + __sample_print(fmt, err > 0 || sample_log_level & LL_DEFAULT, \ + printer, ##__VA_ARGS__); \ + err_exp = err_exp ? true : err > 0; \ + }) +#define print_err(err, fmt, ...) __print_err(err, fmt, printf, ##__VA_ARGS__) + +#define __COLUMN(x) "%'10" x " %-13s" +#define FMT_COLUMNf __COLUMN(".0f") +#define FMT_COLUMNd __COLUMN("d") +#define FMT_COLUMNl __COLUMN("llu") +#define RX(rx) rx, "rx/s" +#define PPS(pps) pps, "pkt/s" +#define DROP(drop) drop, "drop/s" +#define ERR(err) err, "error/s" +#define HITS(hits) hits, "hit/s" +#define XMIT(xmit) xmit, "xmit/s" +#define PASS(pass) pass, "pass/s" +#define REDIR(redir) redir, "redir/s" #define NANOSEC_PER_SEC 1000000000 /* 10^9 */ static __u64 gettime(void) @@ -121,8 +156,8 @@ struct stats_record *alloc_stats_record(void) } memset(rec, 0, size); rec->rx_cnt.cpu = alloc_record_per_cpu(); - rec->redir_err[0].cpu = alloc_record_per_cpu(); - rec->redir_err[1].cpu = alloc_record_per_cpu(); + for (i = 0; i < XDP_REDIRECT_ERR_MAX; i++) + rec->redir_err[i].cpu = alloc_record_per_cpu(); rec->kthread.cpu = alloc_record_per_cpu(); for (i = 0; i < XDP_ACTION_MAX; i++) rec->exception[i].cpu = alloc_record_per_cpu(); @@ -143,8 +178,8 @@ void free_stats_record(struct stats_record *r) for (i = 0; i < XDP_ACTION_MAX; i++) free(r->exception[i].cpu); free(r->kthread.cpu); - free(r->redir_err[1].cpu); - free(r->redir_err[0].cpu); + for (i = 0; i < XDP_REDIRECT_ERR_MAX; i++) + free(r->redir_err[i].cpu); free(r->rx_cnt.cpu); free(r); } @@ -161,6 +196,13 @@ static double calc_period(struct record *r, struct record *p) return period_; } +static double sample_round(double val) +{ + if (val - floor(val) < 0.5) + return floor(val); + return ceil(val); +} + static __u64 calc_pps(struct datarec *r, struct datarec *p, double period_) { __u64 packets = 0; @@ -168,7 +210,7 @@ static __u64 calc_pps(struct datarec *r, struct datarec *p, double period_) if (period_ > 0) { packets = r->processed - p->processed; - pps = packets / period_; + pps = sample_round(packets / period_); } return pps; } @@ -180,7 +222,7 @@ static __u64 calc_drop_pps(struct datarec *r, struct datarec *p, double period_) if (period_ > 0) { packets = r->dropped - p->dropped; - pps = packets / period_; + pps = sample_round(packets / period_); } return pps; } @@ -193,7 +235,7 @@ static __u64 calc_errs_pps(struct datarec *r, if (period_ > 0) { packets = r->issue - p->issue; - pps = packets / period_; + pps = sample_round(packets / period_); } return pps; } @@ -206,7 +248,7 @@ static __u64 calc_info_pps(struct datarec *r, if (period_ > 0) { packets = r->info - p->info; - pps = packets / period_; + pps = sample_round(packets / period_); } return pps; } @@ -223,41 +265,52 @@ static void calc_xdp_pps(struct datarec *r, struct datarec *p, } } -static void stats_print_rx_cnt(struct stats_record *stats_rec, - struct stats_record *stats_prev, - unsigned int nr_cpus) +static void stats_get_rx_cnt(struct stats_record *stats_rec, + struct stats_record *stats_prev, + unsigned int nr_cpus, struct sample_output *out) { - char *fmt_rx = "%-15s %-7d %'-14.0f %'-11.0f %'-10.0f %s\n"; - char *fm2_rx = "%-15s %-7s %'-14.0f %'-11.0f\n"; struct record *rec, *prev; double t, pps, drop, err; - char *errstr = ""; int i; rec = &stats_rec->rx_cnt; prev = &stats_prev->rx_cnt; t = calc_period(rec, prev); + for (i = 0; i < nr_cpus; i++) { struct datarec *r = &rec->cpu[i]; struct datarec *p = &prev->cpu[i]; + char str[256]; pps = calc_pps(r, p, t); + if (!pps) + continue; + + snprintf(str, sizeof(str), "cpu:%d", i); + drop = calc_drop_pps(r, p, t); err = calc_errs_pps(r, p, t); - if (err > 0) - errstr = "cpu-dest/err"; - if (pps > 0) - printf(fmt_rx, "XDP-RX", i, pps, drop, err, errstr); + print_default(" %-12s " FMT_COLUMNf FMT_COLUMNf FMT_COLUMNf "\n", + str, PPS(pps), DROP(drop), ERR(err)); + } + + if (out) { + pps = calc_pps(&rec->total, &prev->total, t); + drop = calc_drop_pps(&rec->total, &prev->total, t); + err = calc_errs_pps(&rec->total, &prev->total, t); + + out->rx_cnt.pps = pps; + out->rx_cnt.drop = drop; + out->rx_cnt.err = err; + out->totals.rx += pps; + out->totals.drop += drop; + out->totals.err += err; } - pps = calc_pps(&rec->total, &prev->total, t); - drop = calc_drop_pps(&rec->total, &prev->total, t); - err = calc_errs_pps(&rec->total, &prev->total, t); - printf(fm2_rx, "XDP-RX", "total", pps, drop); } -static void stats_print_cpumap_enqueue(struct stats_record *stats_rec, - struct stats_record *stats_prev, - unsigned int nr_cpus) +static void stats_get_cpumap_enqueue(struct stats_record *stats_rec, + struct stats_record *stats_prev, + unsigned int nr_cpus) { struct record *rec, *prev; double t, pps, drop, err; @@ -265,83 +318,88 @@ static void stats_print_cpumap_enqueue(struct stats_record *stats_rec, /* cpumap enqueue stats */ for (to_cpu = 0; to_cpu < n_cpus; to_cpu++) { - char *fmt = "%-15s %3d:%-3d %'-14.0f %'-11.0f %'-10.2f %s\n"; - char *fm2 = "%-15s %3s:%-3d %'-14.0f %'-11.0f %'-10.2f %s\n"; - char *errstr = ""; - rec = &stats_rec->enq[to_cpu]; prev = &stats_prev->enq[to_cpu]; t = calc_period(rec, prev); + + pps = calc_pps(&rec->total, &prev->total, t); + drop = calc_drop_pps(&rec->total, &prev->total, t); + err = calc_errs_pps(&rec->total, &prev->total, t); + + if (pps > 0) { + char str[256]; + + snprintf(str, sizeof(str), "enqueue to cpu %d", to_cpu); + + if (err > 0) + err = pps / err; /* calc average bulk size */ + print_default(" %-20s " FMT_COLUMNf FMT_COLUMNf __COLUMN(".2f") "\n", + str, PPS(pps), DROP(drop), err, "bulk_avg"); + } + for (i = 0; i < nr_cpus; i++) { struct datarec *r = &rec->cpu[i]; struct datarec *p = &prev->cpu[i]; + char str[256]; pps = calc_pps(r, p, t); + if (!pps) + continue; + + snprintf(str, sizeof(str), "cpu:%d->%d", i, to_cpu); + drop = calc_drop_pps(r, p, t); err = calc_errs_pps(r, p, t); - if (err > 0) { - errstr = "bulk-average"; - err = pps / err; /* calc average bulk size */ - } - if (pps > 0) - printf(fmt, "cpumap-enqueue", - i, to_cpu, pps, drop, err, errstr); - } - pps = calc_pps(&rec->total, &prev->total, t); - if (pps > 0) { - drop = calc_drop_pps(&rec->total, &prev->total, t); - err = calc_errs_pps(&rec->total, &prev->total, t); - if (err > 0) { - errstr = "bulk-average"; + if (err > 0) err = pps / err; /* calc average bulk size */ - } - printf(fm2, "cpumap-enqueue", - "sum", to_cpu, pps, drop, err, errstr); + print_default(" %-12s " FMT_COLUMNf FMT_COLUMNf + __COLUMN(".2f") "\n", str, PPS(pps), DROP(drop), + err, "bulk_avg"); } } } -static void stats_print_cpumap_kthread(struct stats_record *stats_rec, - struct stats_record *stats_prev, - unsigned int nr_cpus) +static void stats_get_cpumap_kthread(struct stats_record *stats_rec, + struct stats_record *stats_prev, + unsigned int nr_cpus) { - char *fmt_k = "%-15s %-7d %'-14.0f %'-11.0f %'-10.0f %s\n"; - char *fm2_k = "%-15s %-7s %'-14.0f %'-11.0f %'-10.0f %s\n"; struct record *rec, *prev; double t, pps, drop, err; - char *e_str = ""; int i; rec = &stats_rec->kthread; prev = &stats_prev->kthread; t = calc_period(rec, prev); + + pps = calc_pps(&rec->total, &prev->total, t); + drop = calc_drop_pps(&rec->total, &prev->total, t); + err = calc_errs_pps(&rec->total, &prev->total, t); + + print_default(" %-20s " FMT_COLUMNf FMT_COLUMNf FMT_COLUMNf "\n", "kthread total", + PPS(pps), DROP(drop), err, "sched"); + for (i = 0; i < nr_cpus; i++) { struct datarec *r = &rec->cpu[i]; struct datarec *p = &prev->cpu[i]; + char str[256]; pps = calc_pps(r, p, t); + if (!pps) + continue; + + snprintf(str, sizeof(str), "cpu:%d", i); + drop = calc_drop_pps(r, p, t); err = calc_errs_pps(r, p, t); - if (err > 0) - e_str = "sched"; - if (pps > 0) - printf(fmt_k, "cpumap_kthread", i, pps, drop, err, - e_str); + print_default(" %-12s " FMT_COLUMNf FMT_COLUMNf FMT_COLUMNf "\n", + str, PPS(pps), DROP(drop), err, "sched"); } - pps = calc_pps(&rec->total, &prev->total, t); - drop = calc_drop_pps(&rec->total, &prev->total, t); - err = calc_errs_pps(&rec->total, &prev->total, t); - if (err > 0) - e_str = "sched-sum"; - printf(fm2_k, "cpumap_kthread", "total", pps, drop, err, e_str); } -static void stats_print_redirect_cnt(struct stats_record *stats_rec, - struct stats_record *stats_prev, - unsigned int nr_cpus) +static void stats_get_redirect_cnt(struct stats_record *stats_rec, + struct stats_record *stats_prev, + unsigned int nr_cpus, struct sample_output *out) { - char *fmt1 = "%-15s %-7d %'-14.0f %'-11.0f %s\n"; - char *fmt2 = "%-15s %-7s %'-14.0f %'-11.0f %s\n"; struct record *rec, *prev; double t, pps; int i; @@ -352,68 +410,106 @@ static void stats_print_redirect_cnt(struct stats_record *stats_rec, for (i = 0; i < nr_cpus; i++) { struct datarec *r = &rec->cpu[i]; struct datarec *p = &prev->cpu[i]; + char str[256]; pps = calc_pps(r, p, t); - if (pps > 0) - printf(fmt1, "redirect", i, pps, 0.0, "Success"); - } - pps = calc_pps(&rec->total, &prev->total, t); - printf(fmt2, "redirect", "total", pps, 0.0, "Success"); -} + if (!pps) + continue; -static void stats_print_redirect_err_cnt(struct stats_record *stats_rec, - struct stats_record *stats_prev, - unsigned int nr_cpus) -{ - char *fmt1 = "%-15s %-7d %'-14.0f %'-11.0f %s\n"; - char *fmt2 = "%-15s %-7s %'-14.0f %'-11.0f %s\n"; - struct record *rec, *prev; - double t, drop; - int i; + snprintf(str, sizeof(str), "cpu:%d", i); - rec = &stats_rec->redir_err[1]; - prev = &stats_prev->redir_err[1]; - t = calc_period(rec, prev); - for (i = 0; i < nr_cpus; i++) { - struct datarec *r = &rec->cpu[i]; - struct datarec *p = &prev->cpu[i]; + print_default(" %-11s " FMT_COLUMNf "\n", str, REDIR(pps)); + } - drop = calc_drop_pps(r, p, t); - if (drop > 0) - printf(fmt1, "redirect", i, 0.0, drop, "Error"); + if (out) { + pps = calc_pps(&rec->total, &prev->total, t); + out->redir_cnt.suc = pps; + out->totals.redir += pps; } - drop = calc_drop_pps(&rec->total, &prev->total, t); - printf(fmt2, "redirect", "total", 0.0, drop, "Error"); + } -static void stats_print_exception_cnt(struct stats_record *stats_rec, - struct stats_record *stats_prev, - unsigned int nr_cpus) +static void stats_get_redirect_err_cnt(struct stats_record *stats_rec, + struct stats_record *stats_prev, + unsigned int nr_cpus, struct sample_output *out) { - char *fmt1 = "%-15s %-7d %'-12.0f %'-12.0f %s\n"; - char *fmt2 = "%-15s %-7s %'-12.0f %'-12.0f %s\n"; struct record *rec, *prev; - double t, drop; + double t, drop, sum = 0; int rec_i, i; - for (rec_i = 0; rec_i < XDP_ACTION_MAX; rec_i++) { - rec = &stats_rec->exception[rec_i]; - prev = &stats_prev->exception[rec_i]; + for (rec_i = 1; rec_i < XDP_REDIRECT_ERR_MAX; rec_i++) { + char str[256]; + int l = 0; + + rec = &stats_rec->redir_err[rec_i]; + prev = &stats_prev->redir_err[rec_i]; t = calc_period(rec, prev); + drop = calc_drop_pps(&rec->total, &prev->total, t); + if (drop > 0 && !out) { + l = snprintf(str, sizeof(str), + sample_log_level & LL_DEFAULT ? + "%s total" : + "%s", + xdp_redirect_err_names[rec_i]); + l = l >= sizeof(str) ? sizeof(str) - 1 : l; + print_err(drop, " %-18s " FMT_COLUMNf "\n", str, + ERR(drop)); + } + for (i = 0; i < nr_cpus; i++) { struct datarec *r = &rec->cpu[i]; struct datarec *p = &prev->cpu[i]; + double drop; + int sp, ll; drop = calc_drop_pps(r, p, t); - if (drop > 0) - printf(fmt1, "xdp_exception", i, - 0.0, drop, action2str(rec_i)); + if (!drop) + continue; + + ll = snprintf(str, sizeof(str), "cpu:%d", i); + ll = ll >= sizeof(str) ? sizeof(str) - 1 : ll; + + sp = l - ll > 0 ? l - ll : 0; + ll = 19 - sp > 0 ? 19 - sp : 0; + + /* Align dynamically under error string */ + print_default(" %*c%-*s" FMT_COLUMNf "\n", sp, ' ', ll, str, ERR(drop)); } + + sum += drop; + } + + if (out) { + out->redir_cnt.err = sum; + out->totals.err += sum; + } +} + +static void stats_get_exception_cnt(struct stats_record *stats_rec, + struct stats_record *stats_prev, + unsigned int nr_cpus, struct sample_output *out) +{ + double t, drop, sum = 0; + struct record *rec, *prev; + int rec_i; + + + for (rec_i = 0; rec_i < XDP_ACTION_MAX; rec_i++) { + rec = &stats_rec->exception[rec_i]; + prev = &stats_prev->exception[rec_i]; + t = calc_period(rec, prev); + drop = calc_drop_pps(&rec->total, &prev->total, t); - if (drop > 0) - printf(fmt2, "xdp_exception", "total", - 0.0, drop, action2str(rec_i)); + /* Fold out errors after heading */ + if (drop > 0 && !out) + print_always(" %-18s " FMT_COLUMNf "\n", action2str(rec_i), ERR(drop)); + sum += drop; + } + + if (out) { + out->except_cnt.hits = sum; + out->totals.err += sum; } } @@ -421,16 +517,12 @@ void sample_stats_print_cpumap_remote(struct stats_record *stats_rec, struct stats_record *stats_prev, unsigned int nr_cpus, char *mprog_name) { - char *fmt_k = "%-15s %-7d %'-14.0f %'-11.0f %'-10.0f\n"; - char *fm2_k = "%-15s %-7s %'-14.0f %'-11.0f %'-10.0f\n"; double xdp_pass, xdp_drop, xdp_redirect; struct record *rec, *prev; double t; int i; - printf("\n2nd remote XDP/eBPF prog_name: %s\n", mprog_name ?: "(none)"); - printf("%-15s %-7s %-14s %-11s %-9s\n", "XDP-cpumap", "CPU:to", - "xdp-pass", "xdp-drop", "xdp-redir"); + print_default("\n2nd remote XDP/eBPF prog_name: %s\n", mprog_name ?: "(none)"); rec = &stats_rec->kthread; prev = &stats_prev->kthread; @@ -438,28 +530,28 @@ void sample_stats_print_cpumap_remote(struct stats_record *stats_rec, for (i = 0; i < nr_cpus; i++) { struct datarec *r = &rec->cpu[i]; struct datarec *p = &prev->cpu[i]; + char str[256]; calc_xdp_pps(r, p, &xdp_pass, &xdp_drop, &xdp_redirect, t); - if (xdp_pass > 0 || xdp_drop > 0 || xdp_redirect > 0) - printf(fmt_k, "xdp-in-kthread", i, xdp_pass, xdp_drop, - xdp_redirect); + if (!xdp_pass || !xdp_drop || !xdp_redirect) + continue; + + snprintf(str, sizeof(str), "cpu:%d", i); + print_default(" %-5s " FMT_COLUMNf FMT_COLUMNf FMT_COLUMNf "\n", + str, PASS(xdp_pass), DROP(xdp_drop), REDIR(xdp_redirect)); } calc_xdp_pps(&rec->total, &prev->total, &xdp_pass, &xdp_drop, &xdp_redirect, t); - printf(fm2_k, "xdp-in-kthread", "total", xdp_pass, xdp_drop, - xdp_redirect); + print_default(" %-20s " FMT_COLUMNf FMT_COLUMNf FMT_COLUMNf "\n", + "xdp_in_kthread total", PASS(xdp_pass), DROP(xdp_drop), REDIR(xdp_redirect)); } -static void stats_print_devmap_xmit(struct stats_record *stats_rec, - struct stats_record *stats_prev, - unsigned int nr_cpus) +static void stats_get_devmap_xmit(struct stats_record *stats_rec, + struct stats_record *stats_prev, + unsigned int nr_cpus, struct sample_output *out) { - char *fmt1 = "%-15s %-7d %'-14.0f %'-11.0f %'-10.0f %s %s\n"; - char *fmt2 = "%-15s %-7s %'-14.0f %'-11.0f %'-10.0f %s %s\n"; double pps, drop, info, err; struct record *rec, *prev; - char *err_str = ""; - char *i_str = ""; double t; int i; @@ -469,32 +561,114 @@ static void stats_print_devmap_xmit(struct stats_record *stats_rec, for (i = 0; i < nr_cpus; i++) { struct datarec *r = &rec->cpu[i]; struct datarec *p = &prev->cpu[i]; + char str[256]; pps = calc_pps(r, p, t); drop = calc_drop_pps(r, p, t); + + if (!pps) + continue; + + snprintf(str, sizeof(str), "cpu:%d", i); + info = calc_info_pps(r, p, t); err = calc_errs_pps(r, p, t); - if (info > 0) { - i_str = "bulk-average"; + if (info > 0) info = (pps + drop) / info; /* calc avg bulk */ - } - if (err > 0) - err_str = "drv-err"; - if (pps > 0 || drop > 0) - printf(fmt1, "devmap-xmit", i, pps, drop, info, i_str, - err_str); + print_default(" %-9s" FMT_COLUMNf FMT_COLUMNf + FMT_COLUMNf __COLUMN(".2f") "\n", + str, XMIT(pps), DROP(drop), err, "drv_err/s", + info, "bulk_avg"); } - pps = calc_pps(&rec->total, &prev->total, t); - drop = calc_drop_pps(&rec->total, &prev->total, t); - info = calc_info_pps(&rec->total, &prev->total, t); - err = calc_errs_pps(&rec->total, &prev->total, t); - if (info > 0) { - i_str = "bulk-average"; - info = (pps + drop) / info; /* calc avg bulk */ + if (out) { + pps = calc_pps(&rec->total, &prev->total, t); + drop = calc_drop_pps(&rec->total, &prev->total, t); + info = calc_info_pps(&rec->total, &prev->total, t); + if (info > 0) + info = (pps + drop) / info; /* calc avg bulk */ + err = calc_errs_pps(&rec->total, &prev->total, t); + + out->xmit_cnt.pps = pps; + out->xmit_cnt.drop = drop; + out->xmit_cnt.bavg = info; + out->xmit_cnt.err = err; + out->totals.xmit += pps; + out->totals.err += err; + } +} + +static void stats_print(const char *prefix, int mask, struct stats_record *r, + struct stats_record *p, struct sample_output *out) +{ + int nr_cpus = bpf_num_possible_cpus(); + const char *str; + + print_always("%-23s", prefix ?: "Summary"); + if (mask & SAMPLE_RX_CNT) + print_always(FMT_COLUMNl, RX(out->totals.rx)); + if (mask & SAMPLE_REDIRECT_CNT) + print_always(FMT_COLUMNl, REDIR(out->totals.redir)); + printf(FMT_COLUMNl, ERR(out->totals.err + out->totals.drop)); + if (mask & SAMPLE_DEVMAP_XMIT_CNT) + printf(FMT_COLUMNl, XMIT(out->totals.xmit)); + printf("\n"); + + if (mask & SAMPLE_RX_CNT) { + str = (sample_log_level & LL_DEFAULT) && out->rx_cnt.pps ? + "receive total" : "receive"; + print_err( + (out->rx_cnt.err || out->rx_cnt.drop), + " %-20s " FMT_COLUMNl FMT_COLUMNl FMT_COLUMNl "\n", + str, PPS(out->rx_cnt.pps), DROP(out->rx_cnt.drop), + ERR(out->rx_cnt.err)); + + stats_get_rx_cnt(r, p, nr_cpus, NULL); + } + + if (mask & SAMPLE_CPUMAP_ENQUEUE_CNT) + stats_get_cpumap_enqueue(r, p, nr_cpus); + if (mask & SAMPLE_CPUMAP_KTHREAD_CNT) + stats_get_cpumap_kthread(r, p, nr_cpus); + + if (mask & SAMPLE_REDIRECT_CNT) { + str = out->redir_cnt.suc ? "redirect total" : "redirect"; + print_default(" %-20s " FMT_COLUMNl "\n", str, REDIR(out->redir_cnt.suc)); + + stats_get_redirect_cnt(r, p, nr_cpus, NULL); + } + + if (mask & SAMPLE_REDIRECT_ERR_CNT) { + str = (sample_log_level & LL_DEFAULT) && out->redir_cnt.err ? + "redirect_err total" : "redirect_err"; + print_err(out->redir_cnt.err, " %-20s " FMT_COLUMNl "\n", str, + ERR(out->redir_cnt.err)); + + stats_get_redirect_err_cnt(r, p, nr_cpus, NULL); + } + + if (mask & SAMPLE_EXCEPTION_CNT) { + str = out->except_cnt.hits ? "xdp_exception total" : "xdp_exception"; + print_err(out->except_cnt.hits, " %-20s " FMT_COLUMNl "\n", + str, HITS(out->except_cnt.hits)); + + stats_get_exception_cnt(r, p, nr_cpus, NULL); + } + + if (mask & SAMPLE_DEVMAP_XMIT_CNT) { + str = (sample_log_level & LL_DEFAULT) && out->xmit_cnt.pps ? + "devmap_xmit total" : "devmap_xmit"; + print_err(out->xmit_cnt.err, + " %-20s " FMT_COLUMNl FMT_COLUMNl FMT_COLUMNl __COLUMN(".2f") "\n", + str, XMIT(out->xmit_cnt.pps), DROP(out->xmit_cnt.drop), + out->xmit_cnt.err, "drv_err/s", out->xmit_cnt.bavg, "bulk_avg"); + + stats_get_devmap_xmit(r, p, nr_cpus, NULL); + } + + if (sample_log_level & LL_DEFAULT || ((sample_log_level & LL_SIMPLE) && err_exp)) { + err_exp = false; + printf("\n"); } - if (err > 0) - err_str = "drv-err"; - printf(fmt2, "devmap-xmit", "total", pps, drop, info, i_str, err_str); } static int init_tracepoints(struct bpf_object *obj) @@ -534,15 +708,47 @@ static int init_map_fds(struct bpf_object *obj) int sample_init(struct bpf_object *obj) { + sigset_t st; + n_cpus = get_nprocs_conf(); + + sigemptyset(&st); + sigaddset(&st, SIGQUIT); + + if (sigprocmask(SIG_BLOCK, &st, NULL) < 0) + return -errno; + + sample_sig_fd = signalfd(-1, &st, SFD_CLOEXEC|SFD_NONBLOCK); + if (sample_sig_fd < 0) + return -errno; + return init_tracepoints(obj) ? : init_map_fds(obj); } +void sample_reset_mode(void) +{ + struct signalfd_siginfo si; + int r; + + r = read(sample_sig_fd, &si, sizeof(si)); + if (r < 0) { + if (errno == EAGAIN) + return; + return; + } + + if (si.ssi_signo == SIGQUIT) { + sample_log_level ^= LL_DEBUG - 1; + printf("\n"); + } +} + void sample_exit(int status) { while (tp_cnt) bpf_link__destroy(tp_links[--tp_cnt]); + close(sample_sig_fd); exit(status); } @@ -580,32 +786,24 @@ void sample_stats_collect(int mask, struct stats_record *rec) void sample_stats_print(int mask, struct stats_record *cur, struct stats_record *prev, char *prog_name) { - int nr_cpus = bpf_num_possible_cpus(); - - printf("Running XDP/eBPF prog_name:%s\n", prog_name ?: "(none)"); - printf("%-15s %-7s %-14s %-11s %-9s\n", - "XDP-event", "CPU:to", "pps", "drop-pps", "extra-info"); + struct sample_output out = {}; if (mask & SAMPLE_RX_CNT) - stats_print_rx_cnt(cur, prev, nr_cpus); + stats_get_rx_cnt(cur, prev, 0, &out); if (mask & SAMPLE_REDIRECT_CNT) - stats_print_redirect_cnt(cur, prev, nr_cpus); + stats_get_redirect_cnt(cur, prev, 0, &out); if (mask & SAMPLE_REDIRECT_ERR_CNT) - stats_print_redirect_err_cnt(cur, prev, nr_cpus); - - if (mask & SAMPLE_CPUMAP_ENQUEUE_CNT) - stats_print_cpumap_enqueue(cur, prev, nr_cpus); - - if (mask & SAMPLE_CPUMAP_KTHREAD_CNT) - stats_print_cpumap_kthread(cur, prev, nr_cpus); + stats_get_redirect_err_cnt(cur, prev, 0, &out); if (mask & SAMPLE_EXCEPTION_CNT) - stats_print_exception_cnt(cur, prev, nr_cpus); + stats_get_exception_cnt(cur, prev, 0, &out); if (mask & SAMPLE_DEVMAP_XMIT_CNT) - stats_print_devmap_xmit(cur, prev, nr_cpus); + stats_get_devmap_xmit(cur, prev, 0, &out); + + stats_print(prog_name, mask, cur, prev, &out); } void sample_stats_poll(int interval, int mask, char *prog_name, int use_separators) @@ -623,10 +821,10 @@ void sample_stats_poll(int interval, int mask, char *prog_name, int use_separato for (;;) { swap(&prev, &record); sample_stats_collect(mask, record); - sample_stats_print(mask, record, prev, NULL); - printf("\n"); + sample_stats_print(mask, record, prev, prog_name); fflush(stdout); sleep(interval); + sample_reset_mode(); } free_stats_record(record); diff --git a/samples/bpf/xdp_sample_user.h b/samples/bpf/xdp_sample_user.h index bc0362575d4b..6ca934b346ef 100644 --- a/samples/bpf/xdp_sample_user.h +++ b/samples/bpf/xdp_sample_user.h @@ -44,10 +44,17 @@ static const char *const map_type_strings[] = { [DEVMAP_XMIT_CNT] = "devmap_xmit_cnt", }; +enum log_level { + LL_DEFAULT = 1U << 0, + LL_SIMPLE = 1U << 1, + LL_DEBUG = 1U << 2, +}; + extern struct bpf_link *tp_links[NUM_TP]; extern int map_fds[NUM_MAP]; extern int n_cpus; extern int tp_cnt; +extern enum log_level sample_log_level; /* Exit return codes */ #define EXIT_OK 0 @@ -113,6 +120,34 @@ struct stats_record { struct record enq[]; }; +struct sample_output { + struct { + __u64 rx; + __u64 redir; + __u64 drop; + __u64 err; + __u64 xmit; + } totals; + struct { + __u64 pps; + __u64 drop; + __u64 err; + } rx_cnt; + struct { + __u64 suc; + __u64 err; + } redir_cnt; + struct { + __u64 hits; + } except_cnt; + struct { + __u64 pps; + __u64 drop; + __u64 err; + double bavg; + } xmit_cnt; +}; + int sample_init(struct bpf_object *obj); void sample_exit(int status); struct stats_record *alloc_stats_record(void); @@ -125,6 +160,7 @@ void sample_stats_poll(int interval, int mask, char *prog_name, void sample_stats_print_cpumap_remote(struct stats_record *stats_rec, struct stats_record *stats_prev, unsigned int nr_cpus, char *mprog_name); +void sample_reset_mode(void); const char *get_driver_name(int ifindex); int get_mac_addr(int ifindex, void *mac_addr); From patchwork Fri May 28 23:52:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kumar Kartikeya Dwivedi X-Patchwork-Id: 12287569 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9C2DCC4708C for ; Fri, 28 May 2021 23:54:19 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 80505613B4 for ; Fri, 28 May 2021 23:54:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229729AbhE1Xzx (ORCPT ); Fri, 28 May 2021 19:55:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45530 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229744AbhE1Xzw (ORCPT ); Fri, 28 May 2021 19:55:52 -0400 Received: from mail-pg1-x541.google.com (mail-pg1-x541.google.com [IPv6:2607:f8b0:4864:20::541]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id BBD21C061574; Fri, 28 May 2021 16:54:15 -0700 (PDT) Received: by mail-pg1-x541.google.com with SMTP id j12so3699436pgh.7; Fri, 28 May 2021 16:54:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=HOsaKyuguNk7X64KL0+mdKcQaE9q+46io+EdBwhI/HE=; b=bPylqBLWgQa8zPT+3Zvf4SfE73L9k3zd2769uiQpzz7BIBvZr2oL6MaqXTWUhrh72S +hjIom7pR2KC0BnSo7CrGGOKKN2r0vSkSBRBFBap7jVh3e8RtGKcodmOuA8okd3dN3Uq wjG2oRVNUcTZGigpsG+DKRg7vP1ZWeIzS1H2mEqD862yHgUZgxdX5A5Ml2SeXuzm1T7W 0LxhfTWX0wMSsPvkEJx9KioJ06njDiQRRhLOAGliMDI4Ak9zx64Yp+DUAEWMDHSJShsw 0gPE2ZgnNKgSc/4AjBvcizqmfS+CQ7PlDhJmQt0kz9cSrktoGzGz/XZAfZp1BWw4LQwh Y+/w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=HOsaKyuguNk7X64KL0+mdKcQaE9q+46io+EdBwhI/HE=; b=dZ6V3JVLc6phTk4aS3Uccec0Tg7kR8zN+uGov4TACRUrjQNeZgCe4yQnOC/fGCnaM9 HTBMSMfaAKqcU12wE09nQIK0GK/hvMkrWM0sGuMaHhEJbbRkeuZE3Li4havXd5LycnSS euN6Xdl5sBPu0WCeOWDrbPhmNnNCVGyUyE7CzdVi3r7psLmzOBkwlBOaAwdoXBVF7UlV Omqa5zNp2HR7zbl6rvqjdP6tdyeMQU6KSQsrJezn65ZaxYA2wyaH0UTD+/sFnUO3MQGW /Tz4kFEGDlZz9dmEacAVi41CskdzCnrUeXqm/sEgerVdi/tHNIvyZrwkLVeQ2KilSEDQ ffJw== X-Gm-Message-State: AOAM530nme0HixRGEvvMMDqsoUOnt2xIZ9GZw1XW/AO10UGkxNmpa/30 hS57CbHj84ms9+FpVI7xXIqf0VmVFWA= X-Google-Smtp-Source: ABdhPJwYf/eKOjmugknMYst3VHTlQU0LjqYyBRW4jUNFwsFyRrCpWn8sCuQlvtYksh2RcchgoqyV5Q== X-Received: by 2002:aa7:9a8e:0:b029:2e7:e3fd:4fa4 with SMTP id w14-20020aa79a8e0000b02902e7e3fd4fa4mr6358497pfi.63.1622246054931; Fri, 28 May 2021 16:54:14 -0700 (PDT) Received: from localhost ([2402:3a80:11db:3aa9:ad24:a4a2:844f:6a0a]) by smtp.gmail.com with ESMTPSA id y66sm4986604pgb.14.2021.05.28.16.54.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 28 May 2021 16:54:14 -0700 (PDT) From: Kumar Kartikeya Dwivedi To: bpf@vger.kernel.org Cc: Kumar Kartikeya Dwivedi , Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , "David S. Miller" , Jakub Kicinski , Jesper Dangaard Brouer , =?utf-8?q?Toke_H=C3=B8iland-J?= =?utf-8?q?=C3=B8rgensen?= , netdev@vger.kernel.org Subject: [PATCH RFC bpf-next 11/15] samples: bpf: print summary of session on exit Date: Sat, 29 May 2021 05:22:46 +0530 Message-Id: <20210528235250.2635167-12-memxor@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210528235250.2635167-1-memxor@gmail.com> References: <20210528235250.2635167-1-memxor@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net X-Patchwork-State: RFC This collects total statistics and prints the totals and averages for main attributes when exiting. These are collected on each polling interval. Signed-off-by: Kumar Kartikeya Dwivedi --- samples/bpf/xdp_redirect_cpu_user.c | 2 +- samples/bpf/xdp_redirect_map_user.c | 2 +- samples/bpf/xdp_sample_user.c | 141 +++++++++++++++++++++++++--- samples/bpf/xdp_sample_user.h | 22 +++-- 4 files changed, 145 insertions(+), 22 deletions(-) diff --git a/samples/bpf/xdp_redirect_cpu_user.c b/samples/bpf/xdp_redirect_cpu_user.c index 3983ed71d879..4c9f32229508 100644 --- a/samples/bpf/xdp_redirect_cpu_user.c +++ b/samples/bpf/xdp_redirect_cpu_user.c @@ -216,7 +216,7 @@ static void __stats_poll(int interval, bool use_separators, char *prog_name, for (;;) { swap(&prev, &record); sample_stats_collect(mask, record); - sample_stats_print(mask, record, prev, NULL); + sample_stats_print(mask, record, prev, NULL, interval); /* Depends on SAMPLE_CPUMAP_KTHREAD_CNT */ sample_stats_print_cpumap_remote(record, prev, bpf_num_possible_cpus(), diff --git a/samples/bpf/xdp_redirect_map_user.c b/samples/bpf/xdp_redirect_map_user.c index b2c7adad99ec..ed53dd2cd93a 100644 --- a/samples/bpf/xdp_redirect_map_user.c +++ b/samples/bpf/xdp_redirect_map_user.c @@ -75,7 +75,7 @@ static void usage(const char *prog) int main(int argc, char **argv) { - int mask = SAMPLE_RX_CNT | SAMPLE_REDIRECT_ERR_CNT | + int mask = SAMPLE_RX_CNT | SAMPLE_REDIRECT_ERR_MAP_CNT | SAMPLE_EXCEPTION_CNT | SAMPLE_DEVMAP_XMIT_CNT; struct bpf_prog_load_attr prog_load_attr = { .prog_type = BPF_PROG_TYPE_UNSPEC, diff --git a/samples/bpf/xdp_sample_user.c b/samples/bpf/xdp_sample_user.c index d0b26023f1db..909257ffe54c 100644 --- a/samples/bpf/xdp_sample_user.c +++ b/samples/bpf/xdp_sample_user.c @@ -26,8 +26,10 @@ #define SIOCETHTOOL 0x8946 #endif +#include #include #include +#include #include #include @@ -39,6 +41,7 @@ struct bpf_link *tp_links[NUM_TP] = {}; int map_fds[NUM_MAP], tp_cnt, n_cpus; static int sample_sig_fd; enum log_level sample_log_level = LL_SIMPLE; +static struct sample_output sum_out; static bool err_exp; #define __sample_print(fmt, cond, printer, ...) \ @@ -58,6 +61,9 @@ static bool err_exp; }) #define print_err(err, fmt, ...) __print_err(err, fmt, printf, ##__VA_ARGS__) +#define print_link_err(err, str, width, type) \ + __print_err(err, str, print_link, width, type) + #define __COLUMN(x) "%'10" x " %-13s" #define FMT_COLUMNf __COLUMN(".0f") #define FMT_COLUMNd __COLUMN("d") @@ -71,6 +77,66 @@ static bool err_exp; #define PASS(pass) pass, "pass/s" #define REDIR(redir) redir, "redir/s" +static const char *elixir_search[NUM_TP] = { + [TP_REDIRECT_CNT] = "_trace_xdp_redirect", + [TP_REDIRECT_MAP_CNT] = "_trace_xdp_redirect_map", + [TP_REDIRECT_ERR_CNT] = "_trace_xdp_redirect_err", + [TP_REDIRECT_MAP_ERR_CNT] = "_trace_xdp_redirect_map_err", + [TP_CPUMAP_ENQUEUE_CNT] = "trace_xdp_cpumap_enqueue", + [TP_CPUMAP_KTHREAD_CNT] = "trace_xdp_cpumap_kthread", + [TP_EXCEPTION_CNT] = "trace_xdp_exception", + [TP_DEVMAP_XMIT_CNT] = "trace_xdp_devmap_xmit", +}; + +static const char *make_url(enum tp_type i) +{ + const char *key = elixir_search[i]; + static struct utsname uts = {}; + static char url[128]; + static bool uts_init; + int maj, min; + char c[2]; + + if (!uts_init) { + if (uname(&uts) < 0) + return NULL; + uts_init = true; + } + + if (!key || sscanf(uts.release, "%d.%d%1s", &maj, &min, c) != 3) + return NULL; + + snprintf(url, sizeof(url), "https://elixir.bootlin.com/linux/v%d.%d/C/ident/%s", + maj, min, key); + + return url; +} + +static void print_link(const char *str, int width, enum tp_type i) +{ + static int t = -1; + const char *s; + int fd, l; + + if (t < 0) { + fd = open("/proc/self/fd/1", O_RDONLY); + if (fd < 0) + return; + t = isatty(fd); + close(fd); + } + + s = make_url(i); + if (!s || !t) { + printf(" %-*s", width, str); + return; + } + + l = strlen(str); + width = width - l > 0 ? width - l : 0; + printf(" \x1B]8;;%s\a%s\x1B]8;;\a%*c", s, str, width, ' '); +} + #define NANOSEC_PER_SEC 1000000000 /* 10^9 */ static __u64 gettime(void) { @@ -333,8 +399,11 @@ static void stats_get_cpumap_enqueue(struct stats_record *stats_rec, if (err > 0) err = pps / err; /* calc average bulk size */ - print_default(" %-20s " FMT_COLUMNf FMT_COLUMNf __COLUMN(".2f") "\n", - str, PPS(pps), DROP(drop), err, "bulk_avg"); + + print_link_err(drop, str, 20, TP_CPUMAP_ENQUEUE_CNT); + print_err(drop, + " " FMT_COLUMNf FMT_COLUMNf __COLUMN(".2f") "\n", + PPS(pps), DROP(drop), err, "bulk_avg"); } for (i = 0; i < nr_cpus; i++) { @@ -375,8 +444,9 @@ static void stats_get_cpumap_kthread(struct stats_record *stats_rec, drop = calc_drop_pps(&rec->total, &prev->total, t); err = calc_errs_pps(&rec->total, &prev->total, t); - print_default(" %-20s " FMT_COLUMNf FMT_COLUMNf FMT_COLUMNf "\n", "kthread total", - PPS(pps), DROP(drop), err, "sched"); + print_link_err(drop, pps ? "kthread total" : "kthread", 20, TP_CPUMAP_KTHREAD_CNT); + print_err(drop, " " FMT_COLUMNf FMT_COLUMNf FMT_COLUMNf "\n", + PPS(pps), DROP(drop), err, "sched"); for (i = 0; i < nr_cpus; i++) { struct datarec *r = &rec->cpu[i]; @@ -632,7 +702,9 @@ static void stats_print(const char *prefix, int mask, struct stats_record *r, if (mask & SAMPLE_REDIRECT_CNT) { str = out->redir_cnt.suc ? "redirect total" : "redirect"; - print_default(" %-20s " FMT_COLUMNl "\n", str, REDIR(out->redir_cnt.suc)); + print_link_err(0, str, 20, mask & _SAMPLE_REDIRECT_MAP ? + TP_REDIRECT_MAP_CNT : TP_REDIRECT_CNT); + print_default(" " FMT_COLUMNl "\n", REDIR(out->redir_cnt.suc)); stats_get_redirect_cnt(r, p, nr_cpus, NULL); } @@ -640,6 +712,8 @@ static void stats_print(const char *prefix, int mask, struct stats_record *r, if (mask & SAMPLE_REDIRECT_ERR_CNT) { str = (sample_log_level & LL_DEFAULT) && out->redir_cnt.err ? "redirect_err total" : "redirect_err"; + print_link_err(out->redir_cnt.err, str, 20, mask & _SAMPLE_REDIRECT_MAP ? + TP_REDIRECT_MAP_ERR_CNT : TP_REDIRECT_ERR_CNT); print_err(out->redir_cnt.err, " %-20s " FMT_COLUMNl "\n", str, ERR(out->redir_cnt.err)); @@ -648,8 +722,9 @@ static void stats_print(const char *prefix, int mask, struct stats_record *r, if (mask & SAMPLE_EXCEPTION_CNT) { str = out->except_cnt.hits ? "xdp_exception total" : "xdp_exception"; - print_err(out->except_cnt.hits, " %-20s " FMT_COLUMNl "\n", - str, HITS(out->except_cnt.hits)); + + print_link_err(out->except_cnt.hits, str, 20, TP_EXCEPTION_CNT); + print_err(out->except_cnt.hits, " " FMT_COLUMNl "\n", HITS(out->except_cnt.hits)); stats_get_exception_cnt(r, p, nr_cpus, NULL); } @@ -657,9 +732,11 @@ static void stats_print(const char *prefix, int mask, struct stats_record *r, if (mask & SAMPLE_DEVMAP_XMIT_CNT) { str = (sample_log_level & LL_DEFAULT) && out->xmit_cnt.pps ? "devmap_xmit total" : "devmap_xmit"; + + print_link_err(out->xmit_cnt.err, str, 20, TP_DEVMAP_XMIT_CNT); print_err(out->xmit_cnt.err, - " %-20s " FMT_COLUMNl FMT_COLUMNl FMT_COLUMNl __COLUMN(".2f") "\n", - str, XMIT(out->xmit_cnt.pps), DROP(out->xmit_cnt.drop), + " " FMT_COLUMNl FMT_COLUMNl FMT_COLUMNl __COLUMN(".2f") "\n", + XMIT(out->xmit_cnt.pps), DROP(out->xmit_cnt.drop), out->xmit_cnt.err, "drv_err/s", out->xmit_cnt.bavg, "bulk_avg"); stats_get_devmap_xmit(r, p, nr_cpus, NULL); @@ -747,7 +824,7 @@ void sample_exit(int status) { while (tp_cnt) bpf_link__destroy(tp_links[--tp_cnt]); - + sample_summary_print(); close(sample_sig_fd); exit(status); } @@ -783,8 +860,46 @@ void sample_stats_collect(int mask, struct stats_record *rec) map_collect_percpu(map_fds[DEVMAP_XMIT_CNT], 0, &rec->devmap_xmit); } +void sample_summary_update(struct sample_output *out, int interval) +{ + sum_out.totals.rx += out->totals.rx; + sum_out.totals.redir += out->totals.redir; + sum_out.totals.drop += out->totals.drop; + sum_out.totals.err += out->totals.err; + sum_out.totals.xmit += out->totals.xmit; + sum_out.rx_cnt.pps += interval; +} + +void sample_summary_print(void) +{ + double period = sum_out.rx_cnt.pps; + + print_always("\nTotals\n"); + if (sum_out.totals.rx) { + double pkts = sum_out.totals.rx; + + print_always(" Packets received : %'-10llu\n", sum_out.totals.rx); + print_always(" Average packets/s : %'-10.0f\n", sample_round(pkts/period)); + } + if (sum_out.totals.redir) { + double pkts = sum_out.totals.redir; + + print_always(" Packets redirected : %'-10llu\n", sum_out.totals.redir); + print_always(" Average redir/s : %'-10.0f\n", sample_round(pkts/period)); + } + print_always(" Packets dropped : %'-10llu\n", sum_out.totals.drop); + print_always(" Errors recorded : %'-10llu\n", sum_out.totals.err); + if (sum_out.totals.xmit) { + double pkts = sum_out.totals.xmit; + + print_always(" Packets transmitted : %'-10llu\n", sum_out.totals.xmit); + print_always(" Average transmit/s : %'-10.0f\n", sample_round(pkts/period)); + } +} + void sample_stats_print(int mask, struct stats_record *cur, - struct stats_record *prev, char *prog_name) + struct stats_record *prev, char *prog_name, + int interval) { struct sample_output out = {}; @@ -803,6 +918,8 @@ void sample_stats_print(int mask, struct stats_record *cur, if (mask & SAMPLE_DEVMAP_XMIT_CNT) stats_get_devmap_xmit(cur, prev, 0, &out); + sample_summary_update(&out, interval); + stats_print(prog_name, mask, cur, prev, &out); } @@ -821,7 +938,7 @@ void sample_stats_poll(int interval, int mask, char *prog_name, int use_separato for (;;) { swap(&prev, &record); sample_stats_collect(mask, record); - sample_stats_print(mask, record, prev, prog_name); + sample_stats_print(mask, record, prev, prog_name, interval); fflush(stdout); sleep(interval); sample_reset_mode(); diff --git a/samples/bpf/xdp_sample_user.h b/samples/bpf/xdp_sample_user.h index 6ca934b346ef..abe4ec25c310 100644 --- a/samples/bpf/xdp_sample_user.h +++ b/samples/bpf/xdp_sample_user.h @@ -26,13 +26,16 @@ enum tp_type { }; enum stats_mask { - SAMPLE_RX_CNT = 1U << 1, - SAMPLE_REDIRECT_ERR_CNT = 1U << 2, - SAMPLE_CPUMAP_ENQUEUE_CNT = 1U << 3, - SAMPLE_CPUMAP_KTHREAD_CNT = 1U << 4, - SAMPLE_EXCEPTION_CNT = 1U << 5, - SAMPLE_DEVMAP_XMIT_CNT = 1U << 6, - SAMPLE_REDIRECT_CNT = 1U << 7, + _SAMPLE_REDIRECT_MAP = 1U << 0, + SAMPLE_RX_CNT = 1U << 1, + SAMPLE_REDIRECT_ERR_CNT = 1U << 2, + SAMPLE_CPUMAP_ENQUEUE_CNT = 1U << 3, + SAMPLE_CPUMAP_KTHREAD_CNT = 1U << 4, + SAMPLE_EXCEPTION_CNT = 1U << 5, + SAMPLE_DEVMAP_XMIT_CNT = 1U << 6, + SAMPLE_REDIRECT_CNT = 1U << 7, + SAMPLE_REDIRECT_MAP_CNT = SAMPLE_REDIRECT_CNT | _SAMPLE_REDIRECT_MAP, + SAMPLE_REDIRECT_ERR_MAP_CNT = SAMPLE_REDIRECT_ERR_CNT | _SAMPLE_REDIRECT_MAP, }; static const char *const map_type_strings[] = { @@ -153,8 +156,11 @@ void sample_exit(int status); struct stats_record *alloc_stats_record(void); void free_stats_record(struct stats_record *rec); void sample_stats_print(int mask, struct stats_record *cur, - struct stats_record *prev, char *prog_name); + struct stats_record *prev, char *prog_name, + int interval); void sample_stats_collect(int mask, struct stats_record *rec); +void sample_summary_update(struct sample_output *out, int interval); +void sample_summary_print(void); void sample_stats_poll(int interval, int mask, char *prog_name, int use_separators); void sample_stats_print_cpumap_remote(struct stats_record *stats_rec, From patchwork Fri May 28 23:52:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kumar Kartikeya Dwivedi X-Patchwork-Id: 12287571 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B6CEDC4708F for ; Fri, 28 May 2021 23:54:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9DB00613EB for ; Fri, 28 May 2021 23:54:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229768AbhE1Xzz (ORCPT ); Fri, 28 May 2021 19:55:55 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45548 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229763AbhE1Xzy (ORCPT ); Fri, 28 May 2021 19:55:54 -0400 Received: from mail-pf1-x443.google.com (mail-pf1-x443.google.com [IPv6:2607:f8b0:4864:20::443]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F0E94C061574; Fri, 28 May 2021 16:54:18 -0700 (PDT) Received: by mail-pf1-x443.google.com with SMTP id z26so409488pfj.5; Fri, 28 May 2021 16:54:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=N3RXRHLbKO0cZgpX4qTKu5VVb4lJzIqHv/hIzI5RO6o=; b=F0WYBCRl3MNTqym0+/AJL1FthpOcCxRCrLCfrmMlvDmVgptPbyzONJIgQrGif+90nI QUTBw+zDiHYuvRNEwyxOYJt6uOTu9O1Zb60TcKz19RDJG19WGoHDcOLZJnpQcx6X07Yc 9AD8Z1KM+R3LZKkmEKAn4k2h9gXYrCiAtQWdkpoQYTBWGFNhUDjVrx3Vkz/uqYh0Ngip 4aJoTRfLviJSEGm7JpPseWfO0arvGsJyWgqtL9IYb9ZbjiTU05gPBkWNpLX6al4JEVrN g/yp6gH3iN6RkxVvHsbXNbkTm5VQvrWWQvSPN8MZ/kIj6SL9jaIypQ9/PNGrW5+pOa9s b0qw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=N3RXRHLbKO0cZgpX4qTKu5VVb4lJzIqHv/hIzI5RO6o=; b=JE8p+I+wFWQfmRij5a12rfJtUcdosz68HcBHT3NwsN6tvZvwC3pUD6jaopBIWOninb /zH/AjVBMbOv6PtXAwhzstNz/W0aygIua7nSqbUMNGG9v8numz7g9/2+yGfMMj4fts1c 0Y8C6U//v5Fs2l4YCk8IQm9JrjShBvNkp4CpEDsAr9sq6x22bm34M/+j4Ziv+pYKqF/u r7GVe0fZdiyPgjuAG5Cb/UC9M4uzqb6UnB9nhimTUUsEqeQu2VopWGDOjC+3DwTx8lCr UkGLvbR42q2THE50NY1lvRkVg2S90ZVk3yYMg8Ngw/Ja3RWOO8Kq6rvlrW+0MPe614ye Uosw== X-Gm-Message-State: AOAM530bRBCeV3XXV9E3DMF3aSL8rEuOcL0Ccqsf/HMqBA5rc8i1F/4a Y+XNOaGjOpP+epSA+EOuEn5579YtIdg= X-Google-Smtp-Source: ABdhPJyy/0drfdLol6vZ63ZQAW4Llj4q7VBGh3cpiTm1mPzc69cflY3lE4yhLQR1aSmdiJC/X8DiVw== X-Received: by 2002:a63:5252:: with SMTP id s18mr11491055pgl.229.1622246058374; Fri, 28 May 2021 16:54:18 -0700 (PDT) Received: from localhost ([2402:3a80:11db:3aa9:ad24:a4a2:844f:6a0a]) by smtp.gmail.com with ESMTPSA id 30sm5092267pgo.7.2021.05.28.16.54.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 28 May 2021 16:54:18 -0700 (PDT) From: Kumar Kartikeya Dwivedi To: bpf@vger.kernel.org Cc: Kumar Kartikeya Dwivedi , Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , "David S. Miller" , Jakub Kicinski , Jesper Dangaard Brouer , =?utf-8?q?Toke_H=C3=B8iland-J?= =?utf-8?q?=C3=B8rgensen?= , netdev@vger.kernel.org Subject: [PATCH RFC bpf-next 12/15] samples: bpf: subtract time spent in collection from polling interval Date: Sat, 29 May 2021 05:22:47 +0530 Message-Id: <20210528235250.2635167-13-memxor@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210528235250.2635167-1-memxor@gmail.com> References: <20210528235250.2635167-1-memxor@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net X-Patchwork-State: RFC This improves sleeping precision and reduces the possibility of reporting incorrect statistics to the user. Signed-off-by: Kumar Kartikeya Dwivedi --- samples/bpf/xdp_redirect_cpu_user.c | 7 ++++++- samples/bpf/xdp_sample_user.c | 27 ++++++++++++++++++++++++++- samples/bpf/xdp_sample_user.h | 2 ++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/samples/bpf/xdp_redirect_cpu_user.c b/samples/bpf/xdp_redirect_cpu_user.c index 4c9f32229508..103ac5c24163 100644 --- a/samples/bpf/xdp_redirect_cpu_user.c +++ b/samples/bpf/xdp_redirect_cpu_user.c @@ -214,6 +214,9 @@ static void __stats_poll(int interval, bool use_separators, char *prog_name, setlocale(LC_NUMERIC, "en_US"); for (;;) { + struct timespec ots, nts; + + clock_gettime(CLOCK_MONOTONIC, &ots); swap(&prev, &record); sample_stats_collect(mask, record); sample_stats_print(mask, record, prev, NULL, interval); @@ -224,7 +227,9 @@ static void __stats_poll(int interval, bool use_separators, char *prog_name, if (sample_log_level & LL_DEFAULT) printf("\n"); fflush(stdout); - sleep(interval); + clock_gettime(CLOCK_MONOTONIC, &nts); + sample_calc_timediff(&nts, &ots, interval); + nanosleep(&nts, NULL); if (stress_mode) stress_cpumap(value); sample_reset_mode(); diff --git a/samples/bpf/xdp_sample_user.c b/samples/bpf/xdp_sample_user.c index 909257ffe54c..96d36c708ee3 100644 --- a/samples/bpf/xdp_sample_user.c +++ b/samples/bpf/xdp_sample_user.c @@ -923,6 +923,26 @@ void sample_stats_print(int mask, struct stats_record *cur, stats_print(prog_name, mask, cur, prev, &out); } +static void calc_timediff(struct timespec *cur, const struct timespec *prev) +{ + if (cur->tv_nsec - prev->tv_nsec < 0) { + cur->tv_sec = cur->tv_sec - prev->tv_sec - 1; + cur->tv_nsec = cur->tv_nsec - prev->tv_nsec + NANOSEC_PER_SEC; + } else { + cur->tv_sec -= prev->tv_sec; + cur->tv_nsec -= prev->tv_nsec; + } +} + +void sample_calc_timediff(struct timespec *cur, const struct timespec *prev, int interval) +{ + struct timespec ts = { .tv_sec = interval }; + + calc_timediff(cur, prev); + calc_timediff(&ts, cur); + *cur = ts; +} + void sample_stats_poll(int interval, int mask, char *prog_name, int use_separators) { struct stats_record *record, *prev; @@ -936,11 +956,16 @@ void sample_stats_poll(int interval, int mask, char *prog_name, int use_separato setlocale(LC_NUMERIC, "en_US"); for (;;) { + struct timespec ots, nts; + + clock_gettime(CLOCK_MONOTONIC, &ots); swap(&prev, &record); sample_stats_collect(mask, record); sample_stats_print(mask, record, prev, prog_name, interval); fflush(stdout); - sleep(interval); + clock_gettime(CLOCK_MONOTONIC, &nts); + sample_calc_timediff(&nts, &ots, interval); + nanosleep(&nts, NULL); sample_reset_mode(); } diff --git a/samples/bpf/xdp_sample_user.h b/samples/bpf/xdp_sample_user.h index abe4ec25c310..588bd2f15352 100644 --- a/samples/bpf/xdp_sample_user.h +++ b/samples/bpf/xdp_sample_user.h @@ -161,6 +161,8 @@ void sample_stats_print(int mask, struct stats_record *cur, void sample_stats_collect(int mask, struct stats_record *rec); void sample_summary_update(struct sample_output *out, int interval); void sample_summary_print(void); +void sample_calc_timediff(struct timespec *cur, const struct timespec *prev, + int interval); void sample_stats_poll(int interval, int mask, char *prog_name, int use_separators); void sample_stats_print_cpumap_remote(struct stats_record *stats_rec, From patchwork Fri May 28 23:52:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kumar Kartikeya Dwivedi X-Patchwork-Id: 12287573 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id DB9C9C4708C for ; Fri, 28 May 2021 23:54:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id BE08B6135F for ; Fri, 28 May 2021 23:54:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229794AbhE1X4C (ORCPT ); Fri, 28 May 2021 19:56:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45570 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229744AbhE1Xz6 (ORCPT ); Fri, 28 May 2021 19:55:58 -0400 Received: from mail-pg1-x541.google.com (mail-pg1-x541.google.com [IPv6:2607:f8b0:4864:20::541]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8F200C061574; Fri, 28 May 2021 16:54:22 -0700 (PDT) Received: by mail-pg1-x541.google.com with SMTP id m190so3722592pga.2; Fri, 28 May 2021 16:54:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Lh4cjVXDCTKkenmqi16kX1wwtaby01C381mbKiAGCaw=; b=AHURk11A7mBZ2uA3w3VSsysAccDU/6Jpr5PJVMxIA3nWDGqBM5jVYKbRIar95YGtk+ cOa2x/cGzhIN+klgKIH0T+/wNx1D1WHYfMyulpDa8OSwNISClh08gBUM4Equf5R81G2K PwWMHLADlLaU1Xj0myk4j1GWRHtj5PH5+fg2KbzNMwt4WEGrme9Fp29QEU5KHLWiwmXA JbPKxgQ8zlNjk0QHBitosCrpiJsiImMUmiRjd5LfefHgn2INJ7Wz1+/DUPULANRtmXNv O9knbWAlvX1zw+bfLs70R16yItxXcK7H9ZH+PUV9cwzvFapsKOkFgX52rrNLJR3I9Rjh rnRw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Lh4cjVXDCTKkenmqi16kX1wwtaby01C381mbKiAGCaw=; b=nyMDAfnvq0M5dROhgz2tuZ/RxN9CqDA8M3/4/6HI8Sh30plAur35XJCY7y6rR8dpkq Sg1y+Tx0emdvvnFLO9TplBg1XnIgGpR1j4mHM5kpcyFhD6d+Hh235wScviWSEIsCDt8k UkjEyjXFjYi89jKgcMDTt8HiYTMOKrsJqrt7AAuIZLECUWXtNBlTLYJOKFsMZWaH1C7f 2STDALL9eLivER6FNvo0i5/FfTRAjgFUR14jcBgybm+cmCKZxXTREUXcnGHpckDuzy+l teTg9nVKqGzQN4Kmqfhfg6rqhAKFgz3D/xn+xV+NzHsR3759drrnlSHm1f3Usc0Qweva q22A== X-Gm-Message-State: AOAM530fX+iUg686LqxXr9s1ZENo+LRyIEhVcRg0HlAJ8ZdE0VSCwmxU jtQwmthSlrS5Po9lRxXC00DQKK/34PE= X-Google-Smtp-Source: ABdhPJxb1UpMs4d1IKn5D8X3U6f3p76MOn7UEzZVxvZsBY0TjmzzZUuRz16mxPQnYDqX1ZipQ834pA== X-Received: by 2002:a63:fc11:: with SMTP id j17mr11207453pgi.355.1622246061765; Fri, 28 May 2021 16:54:21 -0700 (PDT) Received: from localhost ([2402:3a80:11db:3aa9:ad24:a4a2:844f:6a0a]) by smtp.gmail.com with ESMTPSA id o6sm5305091pfb.126.2021.05.28.16.54.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 28 May 2021 16:54:21 -0700 (PDT) From: Kumar Kartikeya Dwivedi To: bpf@vger.kernel.org Cc: Kumar Kartikeya Dwivedi , Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , "David S. Miller" , Jakub Kicinski , Jesper Dangaard Brouer , =?utf-8?q?Toke_H=C3=B8iland-J?= =?utf-8?q?=C3=B8rgensen?= , netdev@vger.kernel.org Subject: [PATCH RFC bpf-next 13/15] samples: bpf: add new options for xdp samples Date: Sat, 29 May 2021 05:22:48 +0530 Message-Id: <20210528235250.2635167-14-memxor@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210528235250.2635167-1-memxor@gmail.com> References: <20210528235250.2635167-1-memxor@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net X-Patchwork-State: RFC These are -i for polling interval and -v for verbose output by default. Some of these tools already supported -s, but we now use that to enable performance impacting success case reporting tracepoint. This is disabled by default, but can be enabled explicitly by user. Use separators (-z) is also dropped. Signed-off-by: Kumar Kartikeya Dwivedi --- samples/bpf/xdp_monitor_user.c | 16 ++++--- samples/bpf/xdp_redirect_cpu_user.c | 41 ++++++++++++----- samples/bpf/xdp_redirect_map_user.c | 71 +++++++++++++++++++++++------ 3 files changed, 96 insertions(+), 32 deletions(-) diff --git a/samples/bpf/xdp_monitor_user.c b/samples/bpf/xdp_monitor_user.c index 73d6d35f0c65..b37d8f7379ec 100644 --- a/samples/bpf/xdp_monitor_user.c +++ b/samples/bpf/xdp_monitor_user.c @@ -38,9 +38,10 @@ struct bpf_object *obj; static const struct option long_options[] = { {"help", no_argument, NULL, 'h' }, {"debug", no_argument, NULL, 'D' }, - {"stats", no_argument, NULL, 'S' }, - {"sec", required_argument, NULL, 's' }, - {0, 0, NULL, 0 } + {"stats", no_argument, NULL, 's' }, + {"interval", required_argument, NULL, 'i' }, + {"verbose", no_argument, NULL, 'v' }, + {} }; static void int_exit(int sig) @@ -121,18 +122,21 @@ int main(int argc, char **argv) int interval = 2; /* Parse commands line args */ - while ((opt = getopt_long(argc, argv, "hDSs:", + while ((opt = getopt_long(argc, argv, "hDi:vs", long_options, &longindex)) != -1) { switch (opt) { case 'D': debug = true; break; - case 'S': + case 's': errors_only = false; break; - case 's': + case 'i': interval = atoi(optarg); break; + case 'v': + sample_log_level ^= LL_DEBUG - 1; + break; case 'h': default: usage(argv); diff --git a/samples/bpf/xdp_redirect_cpu_user.c b/samples/bpf/xdp_redirect_cpu_user.c index 103ac5c24163..d56b89254cd1 100644 --- a/samples/bpf/xdp_redirect_cpu_user.c +++ b/samples/bpf/xdp_redirect_cpu_user.c @@ -42,19 +42,20 @@ static const struct option long_options[] = { {"help", no_argument, NULL, 'h' }, {"dev", required_argument, NULL, 'd' }, {"skb-mode", no_argument, NULL, 'S' }, - {"sec", required_argument, NULL, 's' }, {"progname", required_argument, NULL, 'p' }, {"qsize", required_argument, NULL, 'q' }, {"cpu", required_argument, NULL, 'c' }, {"stress-mode", no_argument, NULL, 'x' }, - {"no-separators", no_argument, NULL, 'z' }, {"force", no_argument, NULL, 'F' }, {"mprog-disable", no_argument, NULL, 'n' }, {"mprog-name", required_argument, NULL, 'e' }, {"mprog-filename", required_argument, NULL, 'f' }, {"redirect-device", required_argument, NULL, 'r' }, {"redirect-map", required_argument, NULL, 'm' }, - {0, 0, NULL, 0 } + {"interval", required_argument, NULL, 'i' }, + {"verbose", no_argument, NULL, 'v' }, + {"stats", no_argument, NULL, 's' }, + {} }; static void int_exit(int sig) @@ -196,7 +197,7 @@ static void stress_cpumap(struct bpf_cpumap_val *value) create_cpu_entry(1, value, 0, false); } -static void __stats_poll(int interval, bool use_separators, char *prog_name, +static void __stats_poll(int interval, bool redir_suc, char *prog_name, char *mprog_name, struct bpf_cpumap_val *value, bool stress_mode) { @@ -210,8 +211,10 @@ static void __stats_poll(int interval, bool use_separators, char *prog_name, sample_stats_collect(mask, record); /* Trick to pretty printf with thousands separators use %' */ - if (use_separators) - setlocale(LC_NUMERIC, "en_US"); + setlocale(LC_NUMERIC, "en_US"); + + if (redir_suc) + mask |= SAMPLE_REDIRECT_CNT; for (;;) { struct timespec ots, nts; @@ -298,12 +301,12 @@ int main(int argc, char **argv) struct bpf_prog_info info = {}; __u32 info_len = sizeof(info); struct bpf_cpumap_val value; - bool use_separators = true; bool stress_mode = false; struct bpf_program *prog; struct bpf_object *obj; int err = EXIT_FAIL; char filename[256]; + bool redir = false; int added_cpus = 0; int longindex = 0; int interval = 2; @@ -356,7 +359,7 @@ int main(int argc, char **argv) memset(cpu, 0, n_cpus * sizeof(int)); /* Parse commands line args */ - while ((opt = getopt_long(argc, argv, "hSd:s:p:q:c:xzFf:e:r:m:", + while ((opt = getopt_long(argc, argv, "hSd:sp:q:c:xi:vFf:e:r:m:", long_options, &longindex)) != -1) { switch (opt) { case 'd': @@ -375,6 +378,9 @@ int main(int argc, char **argv) } break; case 's': + redir = true; + break; + case 'i': interval = atoi(optarg); break; case 'S': @@ -383,9 +389,6 @@ int main(int argc, char **argv) case 'x': stress_mode = true; break; - case 'z': - use_separators = false; - break; case 'p': /* Selecting eBPF prog to load */ prog_name = optarg; @@ -422,6 +425,9 @@ int main(int argc, char **argv) case 'F': xdp_flags &= ~XDP_FLAGS_UPDATE_IF_NOEXIST; break; + case 'v': + sample_log_level ^= LL_DEBUG - 1; + break; case 'h': error: default: @@ -492,7 +498,18 @@ int main(int argc, char **argv) } prog_id = info.id; - __stats_poll(interval, use_separators, prog_name, mprog_name, + if (!redir) { + /* The bpf_link[i] depend on the order of + * the functions was defined in _kern.c + */ + bpf_link__destroy(tp_links[2]); /* tracepoint/xdp/xdp_redirect */ + tp_links[2] = NULL; + + bpf_link__destroy(tp_links[3]); /* tracepoint/xdp/xdp_redirect_map */ + tp_links[3] = NULL; + } + + __stats_poll(interval, redir, prog_name, mprog_name, &value, stress_mode); err = EXIT_OK; diff --git a/samples/bpf/xdp_redirect_map_user.c b/samples/bpf/xdp_redirect_map_user.c index ed53dd2cd93a..eb4013fa58cb 100644 --- a/samples/bpf/xdp_redirect_map_user.c +++ b/samples/bpf/xdp_redirect_map_user.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "bpf_util.h" #include @@ -28,6 +29,18 @@ static __u32 dummy_prog_id; static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST; +static const struct option long_options[] = { + {"help", no_argument, NULL, 'h' }, + {"skb-mode", no_argument, NULL, 'S' }, + {"native-mode", no_argument, NULL, 'N' }, + {"force", no_argument, NULL, 'F' }, + {"load-egress", no_argument, NULL, 'X' }, + {"stats", no_argument, NULL, 's' }, + {"interval", required_argument, NULL, 'i' }, + {"verbose", no_argument, NULL, 'v' }, + {} +}; + static void int_exit(int sig) { __u32 curr_prog_id = 0; @@ -61,16 +74,25 @@ static void int_exit(int sig) sample_exit(EXIT_OK); } -static void usage(const char *prog) +static void usage(char *argv[]) { - fprintf(stderr, - "usage: %s [OPTS] _IN _OUT\n\n" - "OPTS:\n" - " -S use skb-mode\n" - " -N enforce native mode\n" - " -F force loading prog\n" - " -X load xdp program on egress\n", - prog); + int i; + + printf("\n"); + printf(" Usage: %s (options-see-below)\n", + argv[0]); + printf(" Listing options:\n"); + for (i = 0; long_options[i].name != 0; i++) { + printf(" --%-15s", long_options[i].name); + if (long_options[i].flag != NULL) + printf(" flag (internal value:%d)", + *long_options[i].flag); + else + printf("short-option: -%c", + long_options[i].val); + printf("\n"); + } + printf("\n"); } int main(int argc, char **argv) @@ -88,13 +110,14 @@ int main(int argc, char **argv) char str[2 * IF_NAMESIZE + 1]; __u32 info_len = sizeof(info); char ifname_out[IF_NAMESIZE]; - const char *optstr = "FSNX"; char ifname_in[IF_NAMESIZE]; struct bpf_object *obj; int ret, opt, key = 0; char filename[256]; + int interval = 2; - while ((opt = getopt(argc, argv, optstr)) != -1) { + while ((opt = getopt_long(argc, argv, "FSNXi:vs", + long_options, NULL)) != -1) { switch (opt) { case 'S': xdp_flags |= XDP_FLAGS_SKB_MODE; @@ -108,8 +131,17 @@ int main(int argc, char **argv) case 'X': xdp_devmap_attached = true; break; + case 'i': + interval = atoi(optarg); + break; + case 'v': + sample_log_level ^= LL_DEBUG - 1; + break; + case 's': + mask |= SAMPLE_REDIRECT_MAP_CNT; + break; default: - usage(basename(argv[0])); + usage(argv); return 1; } } @@ -122,7 +154,7 @@ int main(int argc, char **argv) } if (argc <= optind + 1) { - usage(basename(argv[0])); + usage(argv); return 1; } @@ -252,9 +284,20 @@ int main(int argc, char **argv) ifname_in, ifindex_in, str, ifname_out, ifindex_out, get_driver_name(ifindex_out) ?: "(err)"); + if ((mask & SAMPLE_REDIRECT_CNT) == 0) { + /* The bpf_link[i] depend on the order of + * the functions was defined in _kern.c + */ + bpf_link__destroy(tp_links[2]); /* tracepoint/xdp/xdp_redirect */ + tp_links[2] = NULL; + + bpf_link__destroy(tp_links[3]); /* tracepoint/xdp/xdp_redirect_map */ + tp_links[3] = NULL; + } + snprintf(str, sizeof(str), "%s->%s", ifname_in, ifname_out); - sample_stats_poll(1, mask, str, true); + sample_stats_poll(interval, mask, str, true); return 0; From patchwork Fri May 28 23:52:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kumar Kartikeya Dwivedi X-Patchwork-Id: 12287575 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 956E7C4708C for ; Fri, 28 May 2021 23:54:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7A132608FC for ; Fri, 28 May 2021 23:54:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229804AbhE1X4J (ORCPT ); Fri, 28 May 2021 19:56:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45612 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229775AbhE1X4F (ORCPT ); Fri, 28 May 2021 19:56:05 -0400 Received: from mail-pg1-x544.google.com (mail-pg1-x544.google.com [IPv6:2607:f8b0:4864:20::544]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D4C7FC0613ED; Fri, 28 May 2021 16:54:25 -0700 (PDT) Received: by mail-pg1-x544.google.com with SMTP id v14so3705755pgi.6; Fri, 28 May 2021 16:54:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=0QZLbqkCIH0r+P47KlUh/Z70XeLVxWHCUDIgLe1Pyr8=; b=cReB7qvr21/+jI88eUmp1kJUJEg+p1stl+YvjIFuDHvPK3/SeCXOJS9kxNrXh/6PBn xbmcMG1kwVHTeE6IGm2eAxcN6e1jUTBz5UXqpkY3d3y8s6SEcVJDCGxuGUaes4mIRxoz W9AHgTMSXmmVD4wZhwJ0Tpws2HgU9QS0agmOA/yfOG/mlI1gtxzMn6P1j97p5oCj+bhk I8+jFHI62tkdRvhazYXuYl/0D74ifRy4PRvbUOhWQjtYS9WGYBl3WpwhOvJ4Gvygf7UD D+ybCObWZ/ZbWbfQrgbU6t/8KwzQs3n9X9sOvz5bEHWn6K6lNxovarYZyfV0BtGdNStW BZaw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=0QZLbqkCIH0r+P47KlUh/Z70XeLVxWHCUDIgLe1Pyr8=; b=FaJAaDXiAWW4CWY5IkTlgxL5iBNHBem4TZFkeX6fpHCJEHlxUeiXYea2RqYG78JXGM zMS8KT2U7EQTbKxX6GzmLB8gn19QgG04fVk8hfYbWlzV7AMjK1LvIVDS11Kkhn8BaAEb Sap/Zg5PRd8tWKWv5dk+yE32k40sJr2cUTGIgAAMg3EN1nvVNvE8pWT8xFYxvRwTXLDV I9Jw4ULXU0XK9HgK+CsfDbr9g5B7o78U4zwPzDYn3evF+/b7dazIqbmo187gXefSLSGd BcDuRZimJoEME+jazWJvZ9+JHyw26D4cqkz0si9PP/4k65FUnOKgclhrasTOxg+zXLK+ YXIw== X-Gm-Message-State: AOAM53220WPOYx6ixObvk6jPlBYg6yl8s2oFEMxhjPNtpaXv2+K60jWk yYxw6VZGBH3Lhkx3J7Rif0PQl2mBBms= X-Google-Smtp-Source: ABdhPJxMwGLKEYq27r5EBvsW31BOlHVK+fEDzonZGYEILp9YQZSFHc8rKQ3ZXi0L1oMu1n4l+ZwJOA== X-Received: by 2002:a63:fd44:: with SMTP id m4mr11712379pgj.396.1622246065161; Fri, 28 May 2021 16:54:25 -0700 (PDT) Received: from localhost ([2402:3a80:11db:3aa9:ad24:a4a2:844f:6a0a]) by smtp.gmail.com with ESMTPSA id 141sm402521pgf.20.2021.05.28.16.54.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 28 May 2021 16:54:24 -0700 (PDT) From: Kumar Kartikeya Dwivedi To: bpf@vger.kernel.org Cc: Kumar Kartikeya Dwivedi , Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , "David S. Miller" , Jakub Kicinski , Jesper Dangaard Brouer , =?utf-8?q?Toke_H=C3=B8iland-J?= =?utf-8?q?=C3=B8rgensen?= , netdev@vger.kernel.org Subject: [PATCH RFC bpf-next 14/15] samples: bpf: add documentation Date: Sat, 29 May 2021 05:22:49 +0530 Message-Id: <20210528235250.2635167-15-memxor@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210528235250.2635167-1-memxor@gmail.com> References: <20210528235250.2635167-1-memxor@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net X-Patchwork-State: RFC This prints some help text meant to explain the output. Signed-off-by: Kumar Kartikeya Dwivedi --- samples/bpf/xdp_monitor_user.c | 10 ++++-- samples/bpf/xdp_redirect_cpu_user.c | 8 +++-- samples/bpf/xdp_redirect_map_user.c | 6 ++-- samples/bpf/xdp_sample_user.c | 52 +++++++++++++++++++++++++++++ samples/bpf/xdp_sample_user.h | 1 + 5 files changed, 69 insertions(+), 8 deletions(-) diff --git a/samples/bpf/xdp_monitor_user.c b/samples/bpf/xdp_monitor_user.c index b37d8f7379ec..71d59e714bae 100644 --- a/samples/bpf/xdp_monitor_user.c +++ b/samples/bpf/xdp_monitor_user.c @@ -35,6 +35,10 @@ static const char *__doc_err_only__= static bool debug = false; struct bpf_object *obj; +static int mask = SAMPLE_REDIRECT_ERR_CNT | SAMPLE_CPUMAP_ENQUEUE_CNT | + SAMPLE_CPUMAP_KTHREAD_CNT | SAMPLE_EXCEPTION_CNT | + SAMPLE_DEVMAP_XMIT_CNT; + static const struct option long_options[] = { {"help", no_argument, NULL, 'h' }, {"debug", no_argument, NULL, 'D' }, @@ -56,6 +60,9 @@ static void int_exit(int sig) static void usage(char *argv[]) { int i; + + sample_print_help(mask); + printf("\nDOCUMENTATION:\n%s\n", __doc__); printf("\n"); printf(" Usage: %s (options-see-below)\n", @@ -110,9 +117,6 @@ static void print_bpf_prog_info(void) int main(int argc, char **argv) { - int mask = SAMPLE_REDIRECT_ERR_CNT | SAMPLE_CPUMAP_ENQUEUE_CNT | - SAMPLE_CPUMAP_KTHREAD_CNT | SAMPLE_EXCEPTION_CNT | - SAMPLE_DEVMAP_XMIT_CNT; int longindex = 0, opt; int ret = EXIT_FAILURE; char filename[256]; diff --git a/samples/bpf/xdp_redirect_cpu_user.c b/samples/bpf/xdp_redirect_cpu_user.c index d56b89254cd1..9233b8a2bf2d 100644 --- a/samples/bpf/xdp_redirect_cpu_user.c +++ b/samples/bpf/xdp_redirect_cpu_user.c @@ -37,6 +37,9 @@ static int avail_fd; static int count_fd; static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST; +static int mask = SAMPLE_RX_CNT | SAMPLE_REDIRECT_ERR_CNT | + SAMPLE_CPUMAP_ENQUEUE_CNT | SAMPLE_CPUMAP_KTHREAD_CNT | + SAMPLE_EXCEPTION_CNT; static const struct option long_options[] = { {"help", no_argument, NULL, 'h' }, @@ -96,6 +99,8 @@ static void usage(char *argv[], struct bpf_object *obj) { int i; + sample_print_help(mask); + printf("\nDOCUMENTATION:\n%s\n", __doc__); printf("\n"); printf(" Usage: %s (options-see-below)\n", argv[0]); @@ -201,9 +206,6 @@ static void __stats_poll(int interval, bool redir_suc, char *prog_name, char *mprog_name, struct bpf_cpumap_val *value, bool stress_mode) { - int mask = SAMPLE_RX_CNT | SAMPLE_REDIRECT_ERR_CNT | - SAMPLE_CPUMAP_ENQUEUE_CNT | SAMPLE_CPUMAP_KTHREAD_CNT | - SAMPLE_EXCEPTION_CNT; struct stats_record *record, *prev; record = alloc_stats_record(); diff --git a/samples/bpf/xdp_redirect_map_user.c b/samples/bpf/xdp_redirect_map_user.c index eb4013fa58cb..f4bdefa83709 100644 --- a/samples/bpf/xdp_redirect_map_user.c +++ b/samples/bpf/xdp_redirect_map_user.c @@ -28,6 +28,8 @@ static __u32 prog_id; static __u32 dummy_prog_id; static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST; +static int mask = SAMPLE_RX_CNT | SAMPLE_REDIRECT_ERR_MAP_CNT | + SAMPLE_EXCEPTION_CNT | SAMPLE_DEVMAP_XMIT_CNT; static const struct option long_options[] = { {"help", no_argument, NULL, 'h' }, @@ -78,6 +80,8 @@ static void usage(char *argv[]) { int i; + sample_print_help(mask); + printf("\n"); printf(" Usage: %s (options-see-below)\n", argv[0]); @@ -97,8 +101,6 @@ static void usage(char *argv[]) int main(int argc, char **argv) { - int mask = SAMPLE_RX_CNT | SAMPLE_REDIRECT_ERR_MAP_CNT | - SAMPLE_EXCEPTION_CNT | SAMPLE_DEVMAP_XMIT_CNT; struct bpf_prog_load_attr prog_load_attr = { .prog_type = BPF_PROG_TYPE_UNSPEC, }; diff --git a/samples/bpf/xdp_sample_user.c b/samples/bpf/xdp_sample_user.c index 96d36c708ee3..aa02d9bbea6c 100644 --- a/samples/bpf/xdp_sample_user.c +++ b/samples/bpf/xdp_sample_user.c @@ -77,6 +77,58 @@ static bool err_exp; #define PASS(pass) pass, "pass/s" #define REDIR(redir) redir, "redir/s" +void sample_print_help(int mask) +{ + printf("Output format description\n\n" + "By default, redirect success statistics are disabled, use -s to enable.\n" + "The terse output mode is default, verbose mode can be activated using -v\n" + "Use SIGQUIT (Ctrl + \\) to switch the mode dynamically at runtime\n\n" + "Terse mode displays at most the following fields:\n" + " rx/s Number of packets received per second\n" + " redir/s Number of packets successfully redirected per second\n" + " error/s Aggregated count of errors per second (including dropped packets)\n" + " xmit/s Number of packets transmitted on the output device per second\n\n" + "Output description for verbose mode:\n" + " FIELD DESCRIPTION\n"); + if (mask & SAMPLE_RX_CNT) { + printf(" receive\tDisplays the number of packets received & errors encountered\n" + " \t\tWhenever an error or packet drop occurs, details of per CPU error\n" + " \t\tand drop statistics will be expanded inline in terse mode.\n" + " \t\t\tpkt/s - Packets received per second\n" + " \t\t\tdrop/s - Packets dropped per second\n" + " \t\t\terror/s - Errors encountered per second\n\n"); + } + if (mask & (SAMPLE_REDIRECT_CNT|SAMPLE_REDIRECT_ERR_CNT)) { + printf(" redirect\tDisplays the number of packets successfully redirected\n" + " \t\tErrors encountered are expanded under redirect_err field\n" + " \t\tNote that passing -s to enable it has a per packet overhead\n" + " \t\t\tredir/s - Packets redirected successfully per second\n\n" + " redirect_err\tDisplays the number of packets that failed redirection\n" + " \t\tThe errno is expanded under this field with per CPU count\n" + " \t\tThe recognized errors are EOPNOTSUPP, EINVAL, ENETDOWN and EMSGSIZE\n" + " \t\t\terror/s - Packets that failed redirection per second\n\n"); + } + + if (mask & SAMPLE_EXCEPTION_CNT) { + printf(" xdp_exception\tDisplays xdp_exception tracepoint events\n" + " \t\tThis can occur due to internal driver errors, unrecognized\n" + " \t\tXDP actions and due to explicit user trigger by use of XDP_ABORTED\n" + " \t\tEach action is expanded below this field with its count\n" + " \t\t\thit/s - Number of times the tracepoint was hit per second\n\n"); + } + + if (mask & SAMPLE_DEVMAP_XMIT_CNT) { + printf(" devmap_xmit\tDisplays devmap_xmit tracepoint events\n" + " \t\tThis tracepoint is invoked for successful transmissions on output\n" + " \t\tdevice but these statistics are not available for generic XDP mode,\n" + " \t\thence they will be omitted from the output when using SKB mode\n" + " \t\t\txmit/s - Number of packets that were transmitted per second\n" + " \t\t\tdrop/s - Number of packets that failed transmissions per second\n" + " \t\t\tdrv_err/s - Number of internal driver errors per second\n" + " \t\t\tbulk_avg - Average number of packets processed for each event\n\n"); + } +} + static const char *elixir_search[NUM_TP] = { [TP_REDIRECT_CNT] = "_trace_xdp_redirect", [TP_REDIRECT_MAP_CNT] = "_trace_xdp_redirect_map", diff --git a/samples/bpf/xdp_sample_user.h b/samples/bpf/xdp_sample_user.h index 588bd2f15352..41be57d7b663 100644 --- a/samples/bpf/xdp_sample_user.h +++ b/samples/bpf/xdp_sample_user.h @@ -169,6 +169,7 @@ void sample_stats_print_cpumap_remote(struct stats_record *stats_rec, struct stats_record *stats_prev, unsigned int nr_cpus, char *mprog_name); void sample_reset_mode(void); +void sample_print_help(int mask); const char *get_driver_name(int ifindex); int get_mac_addr(int ifindex, void *mac_addr); From patchwork Fri May 28 23:52:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kumar Kartikeya Dwivedi X-Patchwork-Id: 12287577 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id AB4F7C4708D for ; Fri, 28 May 2021 23:54:36 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7D254613B4 for ; Fri, 28 May 2021 23:54:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229780AbhE1X4K (ORCPT ); Fri, 28 May 2021 19:56:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:45614 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229783AbhE1X4G (ORCPT ); Fri, 28 May 2021 19:56:06 -0400 Received: from mail-pj1-x1042.google.com (mail-pj1-x1042.google.com [IPv6:2607:f8b0:4864:20::1042]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5E5B9C06138A; Fri, 28 May 2021 16:54:29 -0700 (PDT) Received: by mail-pj1-x1042.google.com with SMTP id lx17-20020a17090b4b11b029015f3b32b8dbso5477487pjb.0; Fri, 28 May 2021 16:54:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=mQVWnl5kD4VZJGsvupF6sFLlOwXDd/uH9jRxPkLWhRE=; b=DCKCEUaXO3M7SuyK3CFkRo4p0+FRQ8EOSfNdca7pm87L4NPtZaF3AjrdIXTmAhD7aR cqQFfxT5QlETKevwgEcueirhu5sjGFhGV7PXHqP5ITCoEYYr3oUoqmmKKjtc3iwnJvMc 6IndgMeFw3+0VQhr0xqajANXhONBbIYqPumRRgwRy5wHJ/nEJINn2a5tUM5QaGB0AZvt k8tXjEJuEF/qXrq6YmwPjyrxwddu0jCur2UTo3KZ1IhDGuEEpxOOUQgoiD2dFxPxVxPN K+QCSJJyngS31TFALN2jBeb6+B5bT4MIrIMQ6zAVqf5HshlTZT4ps7xx2GfyP1aAfFKf 6zig== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=mQVWnl5kD4VZJGsvupF6sFLlOwXDd/uH9jRxPkLWhRE=; b=VX/K18Qh1PV0HUKnysnqpMkwQ2xjXuX6LtG6OWUPFMr8qgKL5nwuhB+/aZT6bXgk0c 4J3AsZs4sv//GIzwWsLz9aTZzkM+mr03HYemCF9pmCRnTKJDyTsFWG19VdYeLeVZiwiJ 0FyuwLoKJgcWR2nLKi1Lp8JmTwr/3vmcjeQDgYjfZ3wVTioeT3Q/z+2ViFpgiwAFkIT4 f9hLWu8y4xpiwtuUQlaZrOskAJpPIz++lptHYfFoYvXxRslMT36YmbG2+br3sZExn/9P AX+1XZW8fmWsHAP7ND4UKsh4qIYHDVESNPxMcoJCU/DrzZKiNju5yeUja3lHgsrzmzLj dFrg== X-Gm-Message-State: AOAM532qFLeEmLoUTtnSFgATb4SYwbPq5Y8iviMVI/bQihlLWAUwjIv/ LSPFZUPLVKa0fMixbBkjrNCQcgzbAuY= X-Google-Smtp-Source: ABdhPJz4Pa7mqTfr3xzapFUEmmX1JtoVd4K49xhXmYURDfEzACYU80QgQhSwpzYwqjfpHj9a2khXHQ== X-Received: by 2002:a17:903:228a:b029:f7:9f7e:aa2c with SMTP id b10-20020a170903228ab02900f79f7eaa2cmr10167345plh.71.1622246068663; Fri, 28 May 2021 16:54:28 -0700 (PDT) Received: from localhost ([2402:3a80:11db:3aa9:ad24:a4a2:844f:6a0a]) by smtp.gmail.com with ESMTPSA id f186sm5382410pfb.36.2021.05.28.16.54.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 28 May 2021 16:54:28 -0700 (PDT) From: Kumar Kartikeya Dwivedi To: bpf@vger.kernel.org Cc: Kumar Kartikeya Dwivedi , Alexei Starovoitov , Daniel Borkmann , Andrii Nakryiko , Martin KaFai Lau , Song Liu , Yonghong Song , John Fastabend , KP Singh , "David S. Miller" , Jakub Kicinski , Jesper Dangaard Brouer , =?utf-8?q?Toke_H=C3=B8iland-J?= =?utf-8?q?=C3=B8rgensen?= , netdev@vger.kernel.org Subject: [PATCH RFC bpf-next 15/15] samples: bpf: convert xdp_samples to use raw_tracepoints Date: Sat, 29 May 2021 05:22:50 +0530 Message-Id: <20210528235250.2635167-16-memxor@gmail.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20210528235250.2635167-1-memxor@gmail.com> References: <20210528235250.2635167-1-memxor@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: bpf@vger.kernel.org X-Patchwork-Delegate: bpf@iogearbox.net X-Patchwork-State: RFC These are faster, and hence speeds up cases where user passes --stats to enable success case redirect accounting. We can extend this to all other tracepoints as well, so make that part of this change. Signed-off-by: Kumar Kartikeya Dwivedi --- samples/bpf/xdp_sample_kern.h | 145 +++++++++++----------------------- samples/bpf/xdp_sample_user.c | 2 +- 2 files changed, 45 insertions(+), 102 deletions(-) diff --git a/samples/bpf/xdp_sample_kern.h b/samples/bpf/xdp_sample_kern.h index dd7f7ea63166..08fbc55df3fd 100644 --- a/samples/bpf/xdp_sample_kern.h +++ b/samples/bpf/xdp_sample_kern.h @@ -3,6 +3,9 @@ #pragma once #include +#include +#include +#include #include #ifndef NR_CPUS @@ -85,20 +88,6 @@ struct { /*** Trace point code ***/ -/* Tracepoint format: /sys/kernel/debug/tracing/events/xdp/xdp_redirect/format - * Code in: kernel/include/trace/events/xdp.h - */ -struct xdp_redirect_ctx { - u64 __pad; // First 8 bytes are not accessible by bpf code - int prog_id; // offset:8; size:4; signed:1; - u32 act; // offset:12 size:4; signed:0; - int ifindex; // offset:16 size:4; signed:1; - int err; // offset:20 size:4; signed:1; - int to_ifindex; // offset:24 size:4; signed:1; - u32 map_id; // offset:28 size:4; signed:0; - int map_index; // offset:32 size:4; signed:1; -}; // offset:36 - enum { XDP_REDIRECT_SUCCESS = 0, XDP_REDIRECT_ERROR = 1 @@ -124,11 +113,11 @@ __u32 xdp_get_err_key(int err) } static __always_inline -int xdp_redirect_collect_stat(struct xdp_redirect_ctx *ctx) +int xdp_redirect_collect_stat(struct bpf_raw_tracepoint_args *ctx) { u32 key = XDP_REDIRECT_ERROR; + int err = ctx->args[3]; struct datarec *rec; - int err = ctx->err; key = xdp_get_err_key(err); @@ -149,47 +138,35 @@ int xdp_redirect_collect_stat(struct xdp_redirect_ctx *ctx) */ } -SEC("tracepoint/xdp/xdp_redirect_err") -int trace_xdp_redirect_err(struct xdp_redirect_ctx *ctx) +SEC("raw_tracepoint/xdp_redirect_err") +int trace_xdp_redirect_err(struct bpf_raw_tracepoint_args *ctx) { return xdp_redirect_collect_stat(ctx); } -SEC("tracepoint/xdp/xdp_redirect_map_err") -int trace_xdp_redirect_map_err(struct xdp_redirect_ctx *ctx) +SEC("raw_tracepoint/xdp_redirect_map_err") +int trace_xdp_redirect_map_err(struct bpf_raw_tracepoint_args *ctx) { return xdp_redirect_collect_stat(ctx); } -/* Likely unloaded when prog starts */ -SEC("tracepoint/xdp/xdp_redirect") -int trace_xdp_redirect(struct xdp_redirect_ctx *ctx) +SEC("raw_tracepoint/xdp_redirect") +int trace_xdp_redirect(struct bpf_raw_tracepoint_args *ctx) { return xdp_redirect_collect_stat(ctx); } -/* Likely unloaded when prog starts */ -SEC("tracepoint/xdp/xdp_redirect_map") -int trace_xdp_redirect_map(struct xdp_redirect_ctx *ctx) +SEC("raw_tracepoint/xdp_redirect_map") +int trace_xdp_redirect_map(struct bpf_raw_tracepoint_args *ctx) { return xdp_redirect_collect_stat(ctx); } -/* Tracepoint format: /sys/kernel/debug/tracing/events/xdp/xdp_exception/format - * Code in: kernel/include/trace/events/xdp.h - */ -struct xdp_exception_ctx { - u64 __pad; // First 8 bytes are not accessible by bpf code - int prog_id; // offset:8; size:4; signed:1; - u32 act; // offset:12; size:4; signed:0; - int ifindex; // offset:16; size:4; signed:1; -}; - -SEC("tracepoint/xdp/xdp_exception") -int trace_xdp_exception(struct xdp_exception_ctx *ctx) +SEC("raw_tracepoint/xdp_exception") +int trace_xdp_exception(struct bpf_raw_tracepoint_args *ctx) { + u32 key = ctx->args[2]; struct datarec *rec; - u32 key = ctx->act; if (key > XDP_REDIRECT) key = XDP_UNKNOWN; @@ -202,23 +179,10 @@ int trace_xdp_exception(struct xdp_exception_ctx *ctx) return 0; } -/* Tracepoint: /sys/kernel/debug/tracing/events/xdp/xdp_cpumap_enqueue/format - * Code in: kernel/include/trace/events/xdp.h - */ -struct cpumap_enqueue_ctx { - u64 __pad; // First 8 bytes are not accessible by bpf code - int map_id; // offset:8; size:4; signed:1; - u32 act; // offset:12; size:4; signed:0; - int cpu; // offset:16; size:4; signed:1; - unsigned int drops; // offset:20; size:4; signed:0; - unsigned int processed; // offset:24; size:4; signed:0; - int to_cpu; // offset:28; size:4; signed:1; -}; - -SEC("tracepoint/xdp/xdp_cpumap_enqueue") -int trace_xdp_cpumap_enqueue(struct cpumap_enqueue_ctx *ctx) +SEC("raw_tracepoint/xdp_cpumap_enqueue") +int trace_xdp_cpumap_enqueue(struct bpf_raw_tracepoint_args *ctx) { - u32 to_cpu = ctx->to_cpu; + u32 to_cpu = ctx->args[3]; struct datarec *rec; if (to_cpu >= MAX_CPUS) @@ -227,11 +191,11 @@ int trace_xdp_cpumap_enqueue(struct cpumap_enqueue_ctx *ctx) rec = bpf_map_lookup_elem(&cpumap_enqueue_cnt, &to_cpu); if (!rec) return 0; - rec->processed += ctx->processed; - rec->dropped += ctx->drops; + rec->processed += ctx->args[1]; + rec->dropped += ctx->args[2]; /* Record bulk events, then userspace can calc average bulk size */ - if (ctx->processed > 0) + if (ctx->args[1] > 0) rec->issue += 1; /* Inception: It's possible to detect overload situations, via @@ -242,78 +206,57 @@ int trace_xdp_cpumap_enqueue(struct cpumap_enqueue_ctx *ctx) return 0; } -/* Tracepoint: /sys/kernel/debug/tracing/events/xdp/xdp_cpumap_kthread/format - * Code in: kernel/include/trace/events/xdp.h - */ -struct cpumap_kthread_ctx { - u64 __pad; // First 8 bytes are not accessible - int map_id; // offset:8; size:4; signed:1; - u32 act; // offset:12; size:4; signed:0; - int cpu; // offset:16; size:4; signed:1; - unsigned int drops; // offset:20; size:4; signed:0; - unsigned int processed; // offset:24; size:4; signed:0; - int sched; // offset:28; size:4; signed:1; - unsigned int xdp_pass; // offset:32; size:4; signed:0; - unsigned int xdp_drop; // offset:36; size:4; signed:0; - unsigned int xdp_redirect; // offset:40; size:4; signed:0; -}; - -SEC("tracepoint/xdp/xdp_cpumap_kthread") -int trace_xdp_cpumap_kthread(struct cpumap_kthread_ctx *ctx) +SEC("raw_tracepoint/xdp_cpumap_kthread") +int trace_xdp_cpumap_kthread(struct bpf_raw_tracepoint_args *ctx) { + struct xdp_cpumap_stats *stats; struct datarec *rec; u32 key = 0; + stats = (struct xdp_cpumap_stats *) ctx->args[4]; + if (!stats) + return 0; + rec = bpf_map_lookup_elem(&cpumap_kthread_cnt, &key); if (!rec) return 0; - rec->processed += ctx->processed; - rec->dropped += ctx->drops; - rec->xdp_pass += ctx->xdp_pass; - rec->xdp_drop += ctx->xdp_drop; - rec->xdp_redirect += ctx->xdp_redirect; + rec->processed += ctx->args[1]; + rec->dropped += ctx->args[2]; + + rec->xdp_pass += BPF_CORE_READ(stats, pass); + rec->xdp_drop += BPF_CORE_READ(stats, drop); + rec->xdp_redirect += BPF_CORE_READ(stats, redirect); /* Count times kthread yielded CPU via schedule call */ - if (ctx->sched) + if (ctx->args[3]) rec->issue++; return 0; } -/* Tracepoint: /sys/kernel/debug/tracing/events/xdp/xdp_devmap_xmit/format - * Code in: kernel/include/trace/events/xdp.h - */ -struct devmap_xmit_ctx { - u64 __pad; // First 8 bytes are not accessible by bpf code - int from_ifindex; // offset:8; size:4; signed:1; - u32 act; // offset:12; size:4; signed:0; - int to_ifindex; // offset:16; size:4; signed:1; - int drops; // offset:20; size:4; signed:1; - int sent; // offset:24; size:4; signed:1; - int err; // offset:28; size:4; signed:1; -}; - -SEC("tracepoint/xdp/xdp_devmap_xmit") -int trace_xdp_devmap_xmit(struct devmap_xmit_ctx *ctx) +SEC("raw_tracepoint/xdp_devmap_xmit") +int trace_xdp_devmap_xmit(struct bpf_raw_tracepoint_args *ctx) { struct datarec *rec; u32 key = 0; + int drops; rec = bpf_map_lookup_elem(&devmap_xmit_cnt, &key); if (!rec) return 0; - rec->processed += ctx->sent; - rec->dropped += ctx->drops; + rec->processed += ctx->args[2]; + rec->dropped += ctx->args[3]; /* Record bulk events, then userspace can calc average bulk size */ rec->info += 1; /* Record error cases, where no frame were sent */ - if (ctx->err) + if (ctx->args[4]) rec->issue++; + drops = ctx->args[3]; /* Catch API error of drv ndo_xdp_xmit sent more than count */ - if (ctx->drops < 0) + if (drops < 0) rec->issue++; return 1; diff --git a/samples/bpf/xdp_sample_user.c b/samples/bpf/xdp_sample_user.c index aa02d9bbea6c..539c0c78fcb0 100644 --- a/samples/bpf/xdp_sample_user.c +++ b/samples/bpf/xdp_sample_user.c @@ -805,7 +805,7 @@ static int init_tracepoints(struct bpf_object *obj) struct bpf_program *prog; bpf_object__for_each_program(prog, obj) { - if (bpf_program__is_tracepoint(prog) != true) + if (!bpf_program__is_raw_tracepoint(prog)) continue; tp_links[tp_cnt] = bpf_program__attach(prog);