From mboxrd@z Thu Jan 1 00:00:00 1970 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=-6.8 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH, MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED 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 4EEEEC47256 for ; Tue, 5 May 2020 19:25:42 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2D6482075E for ; Tue, 5 May 2020 19:25:42 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=broadcom.com header.i=@broadcom.com header.b="SJdtgGTW" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728773AbgEETZl (ORCPT ); Tue, 5 May 2020 15:25:41 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41284 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727785AbgEETZl (ORCPT ); Tue, 5 May 2020 15:25:41 -0400 Received: from mail-oi1-x243.google.com (mail-oi1-x243.google.com [IPv6:2607:f8b0:4864:20::243]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C6E85C061A10 for ; Tue, 5 May 2020 12:25:40 -0700 (PDT) Received: by mail-oi1-x243.google.com with SMTP id k133so2852712oih.12 for ; Tue, 05 May 2020 12:25:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=broadcom.com; s=google; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=RKLj+Bvazx+0GBaDeiW8XR54CzGKY4AHaP4cILqovw8=; b=SJdtgGTW5rf7rigkvrS0mGJrpwJvn5sAzRAkkSYrU2yWA/lI6TmCZF0sq1SvNFwlg1 kREVUdbiAPDNjSfxcJ7oIXu434wnGVlmGdtL6WbnnD9hbqTKUgJpUSsrG2XH0oFtkDpS blRYXGrjL79B5wOO2fnZ53Ph/JTysPZXNngkk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=RKLj+Bvazx+0GBaDeiW8XR54CzGKY4AHaP4cILqovw8=; b=SP9iu/gNxacJUYlhtgQicjHmbwyx2amok7FH3ZgD4Ch1OCEhVpQPs0x3GDLhup+Bkw UpSwPs/EUsCXnntcHwj76SeyfaW1TFbjwIuMSVjnn91mtHWm4FhK+hILHHKcrJ5L4BHW e9VuRzMrGBe2e68BmEodJWMdCeA96ClPAReuI/pfiBorxIMcLzaXXPTSWbYOflcMZeRW aiS7noQDLRpoAlYL1AdLDluVK/u/TT4JdPSVl86uYjYpLI8IVVQStBM3PTHLNOmax6yN kJuqpSlLjI0OuVCSasHVqX4Gzx/QhlT8RVqKLia43K+QWi/0rMN9rnGMJQ789XN5AVoz 421g== X-Gm-Message-State: AGi0PuazG49SxivEqIEjHWw8GjqdcfcYU4GsW/lPAy/QjHV9I4WJW0IB wLrv9qsYeGiixoIdOKgX7GTg/um/yByqC9aY6aMTzkpz X-Google-Smtp-Source: APiQypJj1DkGUZt7VIZXosUiRMoBR0Hk5xmD/ibsZ1474R2bICyoP6W/sR5eJX+NBmdVffk3jmYWOAdQstorpI7Bi6g= X-Received: by 2002:aca:403:: with SMTP id 3mr227565oie.166.1588706739870; Tue, 05 May 2020 12:25:39 -0700 (PDT) MIME-Version: 1.0 References: <20200505140231.16600-1-brgl@bgdev.pl> <20200505140231.16600-6-brgl@bgdev.pl> In-Reply-To: <20200505140231.16600-6-brgl@bgdev.pl> From: Edwin Peer Date: Tue, 5 May 2020 12:25:03 -0700 Message-ID: Subject: Re: [PATCH 05/11] net: core: provide devm_register_netdev() To: Bartosz Golaszewski Cc: Rob Herring , "David S . Miller" , Matthias Brugger , Felix Fietkau , John Crispin , Sean Wang , Mark Lee , Jakub Kicinski , Arnd Bergmann , Fabien Parent , devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, netdev@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org, Bartosz Golaszewski Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Tue, May 5, 2020 at 7:05 AM Bartosz Golaszewski wrote: > > From: Bartosz Golaszewski > > Provide devm_register_netdev() - a device resource managed variant > of register_netdev(). This new helper will only work for net_device > structs that have a parent device assigned and are devres managed too. > > Signed-off-by: Bartosz Golaszewski > --- > include/linux/netdevice.h | 4 ++++ > net/core/dev.c | 48 +++++++++++++++++++++++++++++++++++++++ > net/ethernet/eth.c | 1 + > 3 files changed, 53 insertions(+) > > diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h > index 130a668049ab..433bd5ca2efc 100644 > --- a/include/linux/netdevice.h > +++ b/include/linux/netdevice.h > @@ -1515,6 +1515,8 @@ struct net_device_ops { > * @IFF_FAILOVER_SLAVE: device is lower dev of a failover master device > * @IFF_L3MDEV_RX_HANDLER: only invoke the rx handler of L3 master device > * @IFF_LIVE_RENAME_OK: rename is allowed while device is up and running > + * @IFF_IS_DEVRES: this structure was allocated dynamically and is managed by > + * devres > */ > enum netdev_priv_flags { > IFF_802_1Q_VLAN = 1<<0, > @@ -1548,6 +1550,7 @@ enum netdev_priv_flags { > IFF_FAILOVER_SLAVE = 1<<28, > IFF_L3MDEV_RX_HANDLER = 1<<29, > IFF_LIVE_RENAME_OK = 1<<30, > + IFF_IS_DEVRES = 1<<31, > }; > > #define IFF_802_1Q_VLAN IFF_802_1Q_VLAN > @@ -4206,6 +4209,7 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name, > count) > > int register_netdev(struct net_device *dev); > +int devm_register_netdev(struct net_device *ndev); > void unregister_netdev(struct net_device *dev); > > /* General hardware address lists handling functions */ > diff --git a/net/core/dev.c b/net/core/dev.c > index 522288177bbd..99db537c9468 100644 > --- a/net/core/dev.c > +++ b/net/core/dev.c > @@ -9519,6 +9519,54 @@ int register_netdev(struct net_device *dev) > } > EXPORT_SYMBOL(register_netdev); > > +struct netdevice_devres { > + struct net_device *ndev; > +}; > + > +static void devm_netdev_release(struct device *dev, void *this) > +{ > + struct netdevice_devres *res = this; > + > + unregister_netdev(res->ndev); > +} > + > +/** > + * devm_register_netdev - resource managed variant of register_netdev() > + * @ndev: device to register > + * > + * This is a devres variant of register_netdev() for which the unregister > + * function will be call automatically when the parent device of ndev > + * is detached. > + */ > +int devm_register_netdev(struct net_device *ndev) > +{ > + struct netdevice_devres *dr; > + int ret; > + > + /* struct net_device itself must be devres managed. */ > + BUG_ON(!(ndev->priv_flags & IFF_IS_DEVRES)); > + /* struct net_device must have a parent device - it will be the device > + * managing this resource. > + */ Catching static programming errors seems like an expensive use of the last runtime flag in the enum. It would be weird to devres manage the unregister and not also choose to manage the underlying memory in the same fashion, so it wouldn't be an obvious mistake to make. If it must be enforced, one could also iterate over the registered release functions and check for the presence of devm_free_netdev without burning the flag. > + BUG_ON(!ndev->dev.parent); > + > + dr = devres_alloc(devm_netdev_release, sizeof(*dr), GFP_KERNEL); > + if (!dr) > + return -ENOMEM; > + > + ret = register_netdev(ndev); > + if (ret) { > + devres_free(dr); > + return ret; > + } > + > + dr->ndev = ndev; > + devres_add(ndev->dev.parent, dr); > + > + return 0; > +} > +EXPORT_SYMBOL(devm_register_netdev); > + > int netdev_refcnt_read(const struct net_device *dev) > { > int i, refcnt = 0; > diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c > index c8b903302ff2..ce9b5e576f20 100644 > --- a/net/ethernet/eth.c > +++ b/net/ethernet/eth.c > @@ -423,6 +423,7 @@ struct net_device *devm_alloc_etherdev_mqs(struct device *dev, int sizeof_priv, > > *dr = netdev; > devres_add(dev, dr); > + netdev->priv_flags |= IFF_IS_DEVRES; > > return netdev; > } > -- > 2.25.0 > Regards, Edwin Peer