From mboxrd@z Thu Jan 1 00:00:00 1970 From: Jakub Kicinski Subject: [PATCH bpf-next 4/8] bpf: offload: free prog->aux->offload when device disappears Date: Tue, 19 Dec 2017 20:10:02 -0800 Message-ID: <20171220041006.25629-5-jakub.kicinski@netronome.com> References: <20171220041006.25629-1-jakub.kicinski@netronome.com> Cc: ktkhai@virtuozzo.com, oss-drivers@netronome.com, Jakub Kicinski To: netdev@vger.kernel.org, alexei.starovoitov@gmail.com, daniel@iogearbox.net Return-path: Received: from mail-pl0-f66.google.com ([209.85.160.66]:38401 "EHLO mail-pl0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754208AbdLTELa (ORCPT ); Tue, 19 Dec 2017 23:11:30 -0500 Received: by mail-pl0-f66.google.com with SMTP id s10so8309280plj.5 for ; Tue, 19 Dec 2017 20:11:29 -0800 (PST) In-Reply-To: <20171220041006.25629-1-jakub.kicinski@netronome.com> Sender: netdev-owner@vger.kernel.org List-ID: All bpf offload operations should now be under bpf_devs_lock, it's safe to free and clear the entire offload structure, not only the netdev pointer. __bpf_prog_offload_destroy() will no longer be called multiple times. Suggested-by: Alexei Starovoitov Signed-off-by: Jakub Kicinski Reviewed-by: Quentin Monnet Acked-by: Alexei Starovoitov --- kernel/bpf/offload.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/kernel/bpf/offload.c b/kernel/bpf/offload.c index cda2d8350fe1..9988dc4038e6 100644 --- a/kernel/bpf/offload.c +++ b/kernel/bpf/offload.c @@ -68,12 +68,14 @@ int bpf_prog_offload_init(struct bpf_prog *prog, union bpf_attr *attr) static int __bpf_offload_ndo(struct bpf_prog *prog, enum bpf_netdev_command cmd, struct netdev_bpf *data) { - struct net_device *netdev = prog->aux->offload->netdev; + struct bpf_dev_offload *offload = prog->aux->offload; + struct net_device *netdev; ASSERT_RTNL(); - if (!netdev) + if (!offload) return -ENODEV; + netdev = offload->netdev; if (!netdev->netdev_ops->ndo_bpf) return -EOPNOTSUPP; @@ -109,7 +111,7 @@ int bpf_prog_offload_verify_insn(struct bpf_verifier_env *env, down_read(&bpf_devs_lock); offload = env->prog->aux->offload; - if (offload->netdev) + if (offload) ret = offload->dev_ops->insn_hook(env, insn_idx, prev_insn_idx); up_read(&bpf_devs_lock); @@ -121,31 +123,24 @@ static void __bpf_prog_offload_destroy(struct bpf_prog *prog) struct bpf_dev_offload *offload = prog->aux->offload; struct netdev_bpf data = {}; - /* Caution - if netdev is destroyed before the program, this function - * will be called twice. - */ - data.offload.prog = prog; if (offload->dev_state) WARN_ON(__bpf_offload_ndo(prog, BPF_OFFLOAD_DESTROY, &data)); - offload->dev_state = false; list_del_init(&offload->offloads); - offload->netdev = NULL; + kfree(offload); + prog->aux->offload = NULL; } void bpf_prog_offload_destroy(struct bpf_prog *prog) { - struct bpf_dev_offload *offload = prog->aux->offload; - rtnl_lock(); down_write(&bpf_devs_lock); - __bpf_prog_offload_destroy(prog); + if (prog->aux->offload) + __bpf_prog_offload_destroy(prog); up_write(&bpf_devs_lock); rtnl_unlock(); - - kfree(offload); } static int bpf_prog_offload_translate(struct bpf_prog *prog) -- 2.15.1