Received: by 2002:a05:6a10:d5a5:0:0:0:0 with SMTP id gn37csp4076841pxb; Mon, 4 Oct 2021 16:57:09 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxnQ0F7x8Vpc8ieoIkXVJl4u5F9JPezjru08uzbh4N+r8GPx1kneVf0cnzt6x5HTbRb8h0X X-Received: by 2002:a62:7d0f:0:b0:43e:11e2:d490 with SMTP id y15-20020a627d0f000000b0043e11e2d490mr27066739pfc.56.1633391829026; Mon, 04 Oct 2021 16:57:09 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1633391829; cv=none; d=google.com; s=arc-20160816; b=ULgiQFpO2m4tlivRGc2HhYgyImfllWlcwjIQl6/5i1o/Q3CO1OUOgwX4NkyuRSUn0a aZKIkSrfZS6StC3OqkK29yc1hn8iwQrkhmvO9rHMTBnGaHJKa5lzoAPX5cBxmZKzNJOx 1x+PpVYDe05xnoMBRZw45shHEY5vNuRKN4ekFv/HoGi+ztzbZmBzijsiE9+zClzIgBHj 5uqzAgm516ReMfvlE1FyglmG7R1GfgnBHNrlZwvxvMPU3bCvRx5dylu9TdCkSA2FyXYu Y0+AUTKiJyz6BR6Jpk5pKHjPLsCJRt0bSGzArD+OETGZMy8OV8BPZ/JFn8HNgGiUniq7 1q6g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:subject:cc:to:from:date :dkim-signature; bh=ndrs43lm/x74UZhJxmfjZoIIexcVCLBfgtdEDtn74mo=; b=a8Gzi0H1wmkF6SafadmWuBdbEEDSx0tTYz6zaBpRMJ8qzJSGC0OOHFxkirK7gbGefp c4pnYJfGsWTGeQVb2CoCuHPdEi70ApLpoGlB0i/F23hKoihGURe2/q1ZrNZGZ5i73fxp q9Zid4hF+1i/2uGOfNr4SGAWDFeWDip1mNirDfCwdbtJdwlo7rjaeQaDRkp8qsDtxjfG aZvaO36cVXQnBCQKI3vzpOiyuXQo0ZIIR4YGIxHyq0wKLlQiB9I6WXxeXlsujg8saTvH 4CzuRxWxqr+FcKSkZde/79pImfh53eDWFG1kZqa5AIo0sfOklEmPA6y8esyytGGOUbz1 P0kg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b="pI2/QjWW"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id cp18si18842026plb.448.2021.10.04.16.56.56; Mon, 04 Oct 2021 16:57:09 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b="pI2/QjWW"; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233933AbhJDXqF (ORCPT + 99 others); Mon, 4 Oct 2021 19:46:05 -0400 Received: from mail.kernel.org ([198.145.29.99]:36154 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229703AbhJDXqF (ORCPT ); Mon, 4 Oct 2021 19:46:05 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id E7F3F61381; Mon, 4 Oct 2021 23:44:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1633391055; bh=eXQTxp06FhapF/t+dZjCHKv+wufhogFdqMBNGl5+xd4=; h=Date:From:To:Cc:Subject:In-Reply-To:References:From; b=pI2/QjWWUUNLdS9SbBBbh/vEB+DOUuqx2idvkn6QJNrMg7RFyrCqW84mY4g5gBe/o TDMBXWyyWG7NinXQxd0FNp/ovLSPL38nKRQwLRtFQ+dRLuyTvu+yHuqZ1456hhe6uG oNH6czZNRQXfYJN5P6ssFKuw+Np+WvNSQ/j9G0ZUutH97qsEaTtm8b7ggkZctuNabe WsskH+BygFXCzC0vLamRofpcPJ5BqRG1XxA+GQgSvfAFBZ/wPk5N2TwClUT9YjrvVI GPOXxUlY00bsxJbypwjfPv6wM7MVuHJHLo1QEBRSCzCR1XwKzFXz5xPoW+91xQUnPJ VzK97iZYQusLw== Date: Mon, 4 Oct 2021 16:44:13 -0700 From: Jakub Kicinski To: Leon Romanovsky Cc: "David S . Miller" , Leon Romanovsky , Ido Schimmel , Ingo Molnar , Jiri Pirko , linux-kernel@vger.kernel.org, linux-rdma@vger.kernel.org, mlxsw@nvidia.com, Moshe Shemesh , netdev@vger.kernel.org, Saeed Mahameed , Salil Mehta , Shay Drory , Steven Rostedt , Tariq Toukan , Yisen Zhuang Subject: Re: [PATCH net-next v2 3/5] devlink: Allow set specific ops callbacks dynamically Message-ID: <20211004164413.60e9ce80@kicinski-fedora-pc1c0hjn.dhcp.thefacebook.com> In-Reply-To: <92971648bcad41d095d12f5296246fc44ab8f5c7.1633284302.git.leonro@nvidia.com> References: <92971648bcad41d095d12f5296246fc44ab8f5c7.1633284302.git.leonro@nvidia.com> MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Sun, 3 Oct 2021 21:12:04 +0300 Leon Romanovsky wrote: > From: Leon Romanovsky > > Introduce new devlink call to set specific ops callback during > device initialization phase after devlink_alloc() is already > called. > > This allows us to set specific ops based on device property which > is not known at the beginning of driver initialization. > > For the sake of simplicity, this API lacks any type of locking and > needs to be called before devlink_register() to make sure that no > parallel access to the ops is possible at this stage. The fact that it's not registered does not mean that the callbacks won't be invoked. Look at uses of devlink_compat_flash_update(). > diff --git a/net/core/devlink.c b/net/core/devlink.c > index 4e484afeadea..25c2aa2b35cd 100644 > --- a/net/core/devlink.c > +++ b/net/core/devlink.c > @@ -53,7 +53,7 @@ struct devlink { > struct list_head trap_list; > struct list_head trap_group_list; > struct list_head trap_policer_list; > - const struct devlink_ops *ops; > + struct devlink_ops ops; Security people like ops to live in read-only memory. You're making them r/w for every devlink instance now. > struct xarray snapshot_ids; > struct devlink_dev_stats stats; > struct device *dev; > +/** > + * devlink_set_ops - Set devlink ops dynamically > + * > + * @devlink: devlink > + * @ops: devlink ops to set > + * > + * This interface allows us to set ops based on device property > + * which is known after devlink_alloc() was already called. > + * > + * This call sets fields that are not initialized yet and ignores > + * already set fields. > + * > + * It should be called before devlink_register(), so doesn't have any > + * protection from concurent access. > + */ > +void devlink_set_ops(struct devlink *devlink, const struct devlink_ops *ops) > +{ > + struct devlink_ops *dev_ops = &devlink->ops; > + > + WARN_ON(!devlink_reload_actions_valid(ops)); > + ASSERT_DEVLINK_NOT_REGISTERED(devlink); > + > +#define SET_DEVICE_OP(ptr, op, name) \ > + do { \ > + if ((op)->name) \ > + if (!((ptr)->name)) \ > + (ptr)->name = (op)->name; \ > + } while (0) > + > + /* Keep sorte alphabetically for readability */ > + SET_DEVICE_OP(dev_ops, ops, eswitch_encap_mode_get); > + SET_DEVICE_OP(dev_ops, ops, eswitch_encap_mode_set); > + SET_DEVICE_OP(dev_ops, ops, eswitch_inline_mode_get); > + SET_DEVICE_OP(dev_ops, ops, eswitch_inline_mode_set); > + SET_DEVICE_OP(dev_ops, ops, eswitch_mode_get); > + SET_DEVICE_OP(dev_ops, ops, eswitch_mode_set); > + SET_DEVICE_OP(dev_ops, ops, flash_update); > + SET_DEVICE_OP(dev_ops, ops, info_get); > + SET_DEVICE_OP(dev_ops, ops, port_del); > + SET_DEVICE_OP(dev_ops, ops, port_fn_state_get); > + SET_DEVICE_OP(dev_ops, ops, port_fn_state_set); > + SET_DEVICE_OP(dev_ops, ops, port_function_hw_addr_get); > + SET_DEVICE_OP(dev_ops, ops, port_function_hw_addr_set); > + SET_DEVICE_OP(dev_ops, ops, port_new); > + SET_DEVICE_OP(dev_ops, ops, port_split); > + SET_DEVICE_OP(dev_ops, ops, port_type_set); > + SET_DEVICE_OP(dev_ops, ops, port_unsplit); > + SET_DEVICE_OP(dev_ops, ops, rate_leaf_parent_set); > + SET_DEVICE_OP(dev_ops, ops, rate_leaf_tx_max_set); > + SET_DEVICE_OP(dev_ops, ops, rate_leaf_tx_share_set); > + SET_DEVICE_OP(dev_ops, ops, rate_node_del); > + SET_DEVICE_OP(dev_ops, ops, rate_node_new); > + SET_DEVICE_OP(dev_ops, ops, rate_node_parent_set); > + SET_DEVICE_OP(dev_ops, ops, rate_node_tx_max_set); > + SET_DEVICE_OP(dev_ops, ops, rate_node_tx_share_set); > + SET_DEVICE_OP(dev_ops, ops, reload_actions); > + SET_DEVICE_OP(dev_ops, ops, reload_down); > + SET_DEVICE_OP(dev_ops, ops, reload_limits); > + SET_DEVICE_OP(dev_ops, ops, reload_up); > + SET_DEVICE_OP(dev_ops, ops, sb_occ_max_clear); > + SET_DEVICE_OP(dev_ops, ops, sb_occ_port_pool_get); > + SET_DEVICE_OP(dev_ops, ops, sb_occ_snapshot); > + SET_DEVICE_OP(dev_ops, ops, sb_occ_tc_port_bind_get); > + SET_DEVICE_OP(dev_ops, ops, sb_pool_get); > + SET_DEVICE_OP(dev_ops, ops, sb_pool_set); > + SET_DEVICE_OP(dev_ops, ops, sb_port_pool_get); > + SET_DEVICE_OP(dev_ops, ops, sb_port_pool_set); > + SET_DEVICE_OP(dev_ops, ops, sb_tc_pool_bind_get); > + SET_DEVICE_OP(dev_ops, ops, sb_tc_pool_bind_set); > + SET_DEVICE_OP(dev_ops, ops, supported_flash_update_params); > + SET_DEVICE_OP(dev_ops, ops, trap_action_set); > + SET_DEVICE_OP(dev_ops, ops, trap_drop_counter_get); > + SET_DEVICE_OP(dev_ops, ops, trap_fini); > + SET_DEVICE_OP(dev_ops, ops, trap_group_action_set); > + SET_DEVICE_OP(dev_ops, ops, trap_group_init); > + SET_DEVICE_OP(dev_ops, ops, trap_group_set); > + SET_DEVICE_OP(dev_ops, ops, trap_init); > + SET_DEVICE_OP(dev_ops, ops, trap_policer_counter_get); > + SET_DEVICE_OP(dev_ops, ops, trap_policer_fini); > + SET_DEVICE_OP(dev_ops, ops, trap_policer_init); > + SET_DEVICE_OP(dev_ops, ops, trap_policer_set); > + > +#undef SET_DEVICE_OP > +} > +EXPORT_SYMBOL_GPL(devlink_set_ops); I still don't like this. IMO using feature bits to dynamically mask-off capabilities has much better properties. We already have static caps in devlink_ops (first 3 members), we should build on top of that.