From patchwork Wed Jan 23 06:45:28 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Kicinski X-Patchwork-Id: 1029701 X-Patchwork-Delegate: bpf@iogearbox.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=netronome.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=netronome-com.20150623.gappssmtp.com header.i=@netronome-com.20150623.gappssmtp.com header.b="SGH8LH85"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 43kwmC5Js0z9s9G for ; Wed, 23 Jan 2019 17:46:03 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726910AbfAWGqC (ORCPT ); Wed, 23 Jan 2019 01:46:02 -0500 Received: from mail-qk1-f195.google.com ([209.85.222.195]:42514 "EHLO mail-qk1-f195.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726886AbfAWGqB (ORCPT ); Wed, 23 Jan 2019 01:46:01 -0500 Received: by mail-qk1-f195.google.com with SMTP id 68so570525qke.9 for ; Tue, 22 Jan 2019 22:46:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=netronome-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=NOp6sT6CHytWb1J/7ArxZ4Iyc1CHTEcJJ8Nb2Z8A0lo=; b=SGH8LH85xNL0LwKl6zCGsvG2R+cnfSb8KnEjLXkuMDb5bVYCwp+xQZFxgEqCHJP31W 3f3Z7HnLjiJB2P2+2mz/+wonK7Tua0wmuBSRuOGOuEIn75zXfS/25Olwf1EFB8VyqA6y rpywwUoGURAHfigwr2YyymuqLHUcfaovK114UvVmXn/UXpbrr99PtECgMOtj96gm1oBK NYx/sQdhYAqSe68TRz285meM6CKTmlSlk0J5/mfXnoUHyN8M3AYqM6hEHgXlvwmtHw1F ZqYemHQeAk/q5NX3VL+UCRtSP9AmoP+lHnyUOGYqUP8s4mu3VB1tTb/gTXJ4s90BJVj1 MIPg== 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=NOp6sT6CHytWb1J/7ArxZ4Iyc1CHTEcJJ8Nb2Z8A0lo=; b=dg5gBYRKRfcj2UCGAyTpTIxXBGA3BSxLtA7Dj5UnZ3MV+lT7jq7dzo8xGgkYuwRnye fbXtcnTElhgfNRTEX1BI0BFU5tIXGQ6w+bZeeVBw9IPSG5dQ/QapmgnBx2/0sbQPZ5D/ JGKNVPPi47oYUcDEh80i+Fji12r8ah+JxQIq4p6O+qXBXSFlmeZUYJ0P8NN9tgYorqGU Pzj1GShC5yA7/c/X76vHfMkxF1+91uk42cA1oqNVqgUGm8SZ2vEMU5sl2l+GsSdg7a4R 8ObdVX6pDKjikvJT2MsL8k/qkmxMDMqWE/kP80y8VrG9N/GUGx9orvdvcx5hHmkVUFLN 1kYw== X-Gm-Message-State: AJcUukcwpQpoH9+caP1Qgy+sId5yt3ibkJ7R9ThkyTHDqfNhfuyIQyG2 EzazoMBt5ObCJkfpKfePqz0j/g== X-Google-Smtp-Source: ALg8bN62Mbadz1/1/k8+QD2CDsxyVpY9I77McwV4nR/e/deLCkrVDjpfA2VSDQfcsVhL66+voeNXXA== X-Received: by 2002:ae9:dfc7:: with SMTP id t190mr784698qkf.43.1548225959633; Tue, 22 Jan 2019 22:45:59 -0800 (PST) Received: from jkicinski-Precision-T1700.netronome.com ([66.60.152.14]) by smtp.gmail.com with ESMTPSA id k6sm80589046qtk.41.2019.01.22.22.45.58 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 22 Jan 2019 22:45:59 -0800 (PST) From: Jakub Kicinski To: alexei.starovoitov@gmail.com, daniel@iogearbox.net Cc: yhs@fb.com, netdev@vger.kernel.org, oss-drivers@netronome.com, kafai@fb.com, Jakub Kicinski Subject: [PATCH bpf-next v5 11/12] nfp: bpf: support optimizing dead branches Date: Tue, 22 Jan 2019 22:45:28 -0800 Message-Id: <20190123064529.13518-12-jakub.kicinski@netronome.com> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20190123064529.13518-1-jakub.kicinski@netronome.com> References: <20190123064529.13518-1-jakub.kicinski@netronome.com> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org Verifier will now optimize out branches to dead code, implement the replace_insn callback to take advantage of that optimization. Signed-off-by: Jakub Kicinski Reviewed-by: Quentin Monnet --- drivers/net/ethernet/netronome/nfp/bpf/main.h | 14 ++++++++ .../net/ethernet/netronome/nfp/bpf/offload.c | 1 + .../net/ethernet/netronome/nfp/bpf/verifier.c | 34 +++++++++++++++++++ 3 files changed, 49 insertions(+) diff --git a/drivers/net/ethernet/netronome/nfp/bpf/main.h b/drivers/net/ethernet/netronome/nfp/bpf/main.h index 07879eee3d46..a33aa7df1979 100644 --- a/drivers/net/ethernet/netronome/nfp/bpf/main.h +++ b/drivers/net/ethernet/netronome/nfp/bpf/main.h @@ -412,6 +412,17 @@ static inline bool is_mbpf_div(const struct nfp_insn_meta *meta) return is_mbpf_alu(meta) && mbpf_op(meta) == BPF_DIV; } +static inline bool is_mbpf_cond_jump(const struct nfp_insn_meta *meta) +{ + u8 op; + + if (BPF_CLASS(meta->insn.code) != BPF_JMP) + return false; + + op = BPF_OP(meta->insn.code); + return op != BPF_JA && op != BPF_EXIT && op != BPF_CALL; +} + static inline bool is_mbpf_helper_call(const struct nfp_insn_meta *meta) { struct bpf_insn insn = meta->insn; @@ -520,6 +531,9 @@ int nfp_verify_insn(struct bpf_verifier_env *env, int insn_idx, int prev_insn_idx); int nfp_bpf_finalize(struct bpf_verifier_env *env); +int nfp_bpf_opt_replace_insn(struct bpf_verifier_env *env, u32 off, + struct bpf_insn *insn); + extern const struct bpf_prog_offload_ops nfp_bpf_dev_ops; struct netdev_bpf; diff --git a/drivers/net/ethernet/netronome/nfp/bpf/offload.c b/drivers/net/ethernet/netronome/nfp/bpf/offload.c index c10aab392cf6..877c1b8f95e2 100644 --- a/drivers/net/ethernet/netronome/nfp/bpf/offload.c +++ b/drivers/net/ethernet/netronome/nfp/bpf/offload.c @@ -592,6 +592,7 @@ int nfp_net_bpf_offload(struct nfp_net *nn, struct bpf_prog *prog, const struct bpf_prog_offload_ops nfp_bpf_dev_ops = { .insn_hook = nfp_verify_insn, .finalize = nfp_bpf_finalize, + .replace_insn = nfp_bpf_opt_replace_insn, .prepare = nfp_bpf_verifier_prep, .translate = nfp_bpf_translate, .destroy = nfp_bpf_destroy, diff --git a/drivers/net/ethernet/netronome/nfp/bpf/verifier.c b/drivers/net/ethernet/netronome/nfp/bpf/verifier.c index 2712ab17d57c..32468e1b1b73 100644 --- a/drivers/net/ethernet/netronome/nfp/bpf/verifier.c +++ b/drivers/net/ethernet/netronome/nfp/bpf/verifier.c @@ -786,3 +786,37 @@ int nfp_bpf_finalize(struct bpf_verifier_env *env) return 0; } + +int nfp_bpf_opt_replace_insn(struct bpf_verifier_env *env, u32 off, + struct bpf_insn *insn) +{ + struct nfp_prog *nfp_prog = env->prog->aux->offload->dev_priv; + struct bpf_insn_aux_data *aux_data = env->insn_aux_data; + struct nfp_insn_meta *meta = nfp_prog->verifier_meta; + + meta = nfp_bpf_goto_meta(nfp_prog, meta, aux_data[off].orig_idx); + nfp_prog->verifier_meta = meta; + + /* conditional jump to jump conversion */ + if (is_mbpf_cond_jump(meta) && + insn->code == (BPF_JMP | BPF_JA | BPF_K)) { + unsigned int tgt_off; + + tgt_off = off + insn->off + 1; + + if (!insn->off) { + meta->jmp_dst = list_next_entry(meta, l); + meta->jump_neg_op = false; + } else if (meta->jmp_dst->n != aux_data[tgt_off].orig_idx) { + pr_vlog(env, "branch hard wire at %d changes target %d -> %d\n", + off, meta->jmp_dst->n, + aux_data[tgt_off].orig_idx); + return -EINVAL; + } + return 0; + } + + pr_vlog(env, "unsupported instruction replacement %hhx -> %hhx\n", + meta->insn.code, insn->code); + return -EINVAL; +}