* [PATCH v2 1/5] Documentation: devres: add a missing section for networking helpers
2020-05-23 13:27 [PATCH v2 0/5] net: provide a devres variant of register_netdev() Bartosz Golaszewski
@ 2020-05-23 13:27 ` Bartosz Golaszewski
2020-05-23 13:27 ` [PATCH v2 2/5] net: move devres helpers into a separate source file Bartosz Golaszewski
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Bartosz Golaszewski @ 2020-05-23 13:27 UTC (permalink / raw)
To: Jonathan Corbet, David S . Miller, Matthias Brugger,
John Crispin, Sean Wang, Mark Lee, Jakub Kicinski, Arnd Bergmann,
Fabien Parent, Heiner Kallweit, Edwin Peer
Cc: devicetree, Stephane Le Provost, netdev, linux-kernel,
Bartosz Golaszewski, linux-mediatek, Andrew Perepech, Pedro Tsai,
linux-arm-kernel
From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Add a new section for networking devres helpers to devres.rst and list
the two existing devm functions.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
Documentation/driver-api/driver-model/devres.rst | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Documentation/driver-api/driver-model/devres.rst b/Documentation/driver-api/driver-model/devres.rst
index 46c13780994c..50df28d20fa7 100644
--- a/Documentation/driver-api/driver-model/devres.rst
+++ b/Documentation/driver-api/driver-model/devres.rst
@@ -372,6 +372,10 @@ MUX
devm_mux_chip_register()
devm_mux_control_get()
+NET
+ devm_alloc_etherdev()
+ devm_alloc_etherdev_mqs()
+
PER-CPU MEM
devm_alloc_percpu()
devm_free_percpu()
--
2.25.0
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v2 2/5] net: move devres helpers into a separate source file
2020-05-23 13:27 [PATCH v2 0/5] net: provide a devres variant of register_netdev() Bartosz Golaszewski
2020-05-23 13:27 ` [PATCH v2 1/5] Documentation: devres: add a missing section for networking helpers Bartosz Golaszewski
@ 2020-05-23 13:27 ` Bartosz Golaszewski
2020-05-23 13:27 ` [PATCH v2 3/5] net: devres: define a separate devres structure for devm_alloc_etherdev() Bartosz Golaszewski
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Bartosz Golaszewski @ 2020-05-23 13:27 UTC (permalink / raw)
To: Jonathan Corbet, David S . Miller, Matthias Brugger,
John Crispin, Sean Wang, Mark Lee, Jakub Kicinski, Arnd Bergmann,
Fabien Parent, Heiner Kallweit, Edwin Peer
Cc: devicetree, Stephane Le Provost, netdev, linux-kernel,
Bartosz Golaszewski, linux-mediatek, Andrew Perepech, Pedro Tsai,
linux-arm-kernel
From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
There's currently only a single devres helper in net/ - devm variant
of alloc_etherdev. Let's move it to net/devres.c with the intention of
assing a second one: devm_register_netdev(). This new routine will need
to know the address of the release function of devm_alloc_etherdev() so
that it can verify (using devres_find()) that the struct net_device
that's being passed to it is also resource managed.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
net/Makefile | 2 +-
net/devres.c | 36 ++++++++++++++++++++++++++++++++++++
net/ethernet/eth.c | 28 ----------------------------
3 files changed, 37 insertions(+), 29 deletions(-)
create mode 100644 net/devres.c
diff --git a/net/Makefile b/net/Makefile
index 07ea48160874..5744bf1997fd 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -6,7 +6,7 @@
# Rewritten to use lists instead of if-statements.
#
-obj-$(CONFIG_NET) := socket.o core/
+obj-$(CONFIG_NET) := devres.o socket.o core/
tmp-$(CONFIG_COMPAT) := compat.o
obj-$(CONFIG_NET) += $(tmp-y)
diff --git a/net/devres.c b/net/devres.c
new file mode 100644
index 000000000000..c1465d9f9019
--- /dev/null
+++ b/net/devres.c
@@ -0,0 +1,36 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * This file contains all networking devres helpers.
+ */
+
+#include <linux/device.h>
+#include <linux/etherdevice.h>
+#include <linux/netdevice.h>
+
+static void devm_free_netdev(struct device *dev, void *res)
+{
+ free_netdev(*(struct net_device **)res);
+}
+
+struct net_device *devm_alloc_etherdev_mqs(struct device *dev, int sizeof_priv,
+ unsigned int txqs, unsigned int rxqs)
+{
+ struct net_device **dr;
+ struct net_device *netdev;
+
+ dr = devres_alloc(devm_free_netdev, sizeof(*dr), GFP_KERNEL);
+ if (!dr)
+ return NULL;
+
+ netdev = alloc_etherdev_mqs(sizeof_priv, txqs, rxqs);
+ if (!netdev) {
+ devres_free(dr);
+ return NULL;
+ }
+
+ *dr = netdev;
+ devres_add(dev, dr);
+
+ return netdev;
+}
+EXPORT_SYMBOL(devm_alloc_etherdev_mqs);
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
index c8b903302ff2..dac65180c4ef 100644
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -400,34 +400,6 @@ struct net_device *alloc_etherdev_mqs(int sizeof_priv, unsigned int txqs,
}
EXPORT_SYMBOL(alloc_etherdev_mqs);
-static void devm_free_netdev(struct device *dev, void *res)
-{
- free_netdev(*(struct net_device **)res);
-}
-
-struct net_device *devm_alloc_etherdev_mqs(struct device *dev, int sizeof_priv,
- unsigned int txqs, unsigned int rxqs)
-{
- struct net_device **dr;
- struct net_device *netdev;
-
- dr = devres_alloc(devm_free_netdev, sizeof(*dr), GFP_KERNEL);
- if (!dr)
- return NULL;
-
- netdev = alloc_etherdev_mqs(sizeof_priv, txqs, rxqs);
- if (!netdev) {
- devres_free(dr);
- return NULL;
- }
-
- *dr = netdev;
- devres_add(dev, dr);
-
- return netdev;
-}
-EXPORT_SYMBOL(devm_alloc_etherdev_mqs);
-
ssize_t sysfs_format_mac(char *buf, const unsigned char *addr, int len)
{
return scnprintf(buf, PAGE_SIZE, "%*phC\n", len, addr);
--
2.25.0
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v2 3/5] net: devres: define a separate devres structure for devm_alloc_etherdev()
2020-05-23 13:27 [PATCH v2 0/5] net: provide a devres variant of register_netdev() Bartosz Golaszewski
2020-05-23 13:27 ` [PATCH v2 1/5] Documentation: devres: add a missing section for networking helpers Bartosz Golaszewski
2020-05-23 13:27 ` [PATCH v2 2/5] net: move devres helpers into a separate source file Bartosz Golaszewski
@ 2020-05-23 13:27 ` Bartosz Golaszewski
2020-05-23 13:27 ` [PATCH v2 4/5] net: devres: provide devm_register_netdev() Bartosz Golaszewski
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Bartosz Golaszewski @ 2020-05-23 13:27 UTC (permalink / raw)
To: Jonathan Corbet, David S . Miller, Matthias Brugger,
John Crispin, Sean Wang, Mark Lee, Jakub Kicinski, Arnd Bergmann,
Fabien Parent, Heiner Kallweit, Edwin Peer
Cc: devicetree, Stephane Le Provost, netdev, linux-kernel,
Bartosz Golaszewski, linux-mediatek, Andrew Perepech, Pedro Tsai,
linux-arm-kernel
From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Not using a proxy structure to store struct net_device doesn't save
anything in terms of compiled code size or memory usage but significantly
decreases the readability of the code with all the pointer casting.
Define struct net_device_devres and use it in devm_alloc_etherdev_mqs().
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
net/devres.c | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/net/devres.c b/net/devres.c
index c1465d9f9019..b97b0c5a8216 100644
--- a/net/devres.c
+++ b/net/devres.c
@@ -7,30 +7,34 @@
#include <linux/etherdevice.h>
#include <linux/netdevice.h>
-static void devm_free_netdev(struct device *dev, void *res)
+struct net_device_devres {
+ struct net_device *ndev;
+};
+
+static void devm_free_netdev(struct device *dev, void *this)
{
- free_netdev(*(struct net_device **)res);
+ struct net_device_devres *res = this;
+
+ free_netdev(res->ndev);
}
struct net_device *devm_alloc_etherdev_mqs(struct device *dev, int sizeof_priv,
unsigned int txqs, unsigned int rxqs)
{
- struct net_device **dr;
- struct net_device *netdev;
+ struct net_device_devres *dr;
dr = devres_alloc(devm_free_netdev, sizeof(*dr), GFP_KERNEL);
if (!dr)
return NULL;
- netdev = alloc_etherdev_mqs(sizeof_priv, txqs, rxqs);
- if (!netdev) {
+ dr->ndev = alloc_etherdev_mqs(sizeof_priv, txqs, rxqs);
+ if (!dr->ndev) {
devres_free(dr);
return NULL;
}
- *dr = netdev;
devres_add(dev, dr);
- return netdev;
+ return dr->ndev;
}
EXPORT_SYMBOL(devm_alloc_etherdev_mqs);
--
2.25.0
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v2 4/5] net: devres: provide devm_register_netdev()
2020-05-23 13:27 [PATCH v2 0/5] net: provide a devres variant of register_netdev() Bartosz Golaszewski
` (2 preceding siblings ...)
2020-05-23 13:27 ` [PATCH v2 3/5] net: devres: define a separate devres structure for devm_alloc_etherdev() Bartosz Golaszewski
@ 2020-05-23 13:27 ` Bartosz Golaszewski
2020-05-23 13:27 ` [PATCH v2 5/5] net: ethernet: mtk_star_emac: use devm_register_netdev() Bartosz Golaszewski
2020-05-23 23:56 ` [PATCH v2 0/5] net: provide a devres variant of register_netdev() David Miller
5 siblings, 0 replies; 7+ messages in thread
From: Bartosz Golaszewski @ 2020-05-23 13:27 UTC (permalink / raw)
To: Jonathan Corbet, David S . Miller, Matthias Brugger,
John Crispin, Sean Wang, Mark Lee, Jakub Kicinski, Arnd Bergmann,
Fabien Parent, Heiner Kallweit, Edwin Peer
Cc: devicetree, Stephane Le Provost, netdev, linux-kernel,
Bartosz Golaszewski, linux-mediatek, Andrew Perepech, Pedro Tsai,
linux-arm-kernel
From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Provide devm_register_netdev() - a device resource managed variant
of register_netdev(). This new helper will only work for net_device
structs that are also already managed by devres.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
.../driver-api/driver-model/devres.rst | 1 +
include/linux/netdevice.h | 2 +
net/devres.c | 55 +++++++++++++++++++
3 files changed, 58 insertions(+)
diff --git a/Documentation/driver-api/driver-model/devres.rst b/Documentation/driver-api/driver-model/devres.rst
index 50df28d20fa7..fc242ed4bde5 100644
--- a/Documentation/driver-api/driver-model/devres.rst
+++ b/Documentation/driver-api/driver-model/devres.rst
@@ -375,6 +375,7 @@ MUX
NET
devm_alloc_etherdev()
devm_alloc_etherdev_mqs()
+ devm_register_netdev()
PER-CPU MEM
devm_alloc_percpu()
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index a18f8fdf4260..1a96e9c4ec36 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -4280,6 +4280,8 @@ struct net_device *alloc_netdev_mqs(int sizeof_priv, const char *name,
int register_netdev(struct net_device *dev);
void unregister_netdev(struct net_device *dev);
+int devm_register_netdev(struct device *dev, struct net_device *ndev);
+
/* General hardware address lists handling functions */
int __hw_addr_sync(struct netdev_hw_addr_list *to_list,
struct netdev_hw_addr_list *from_list, int addr_len);
diff --git a/net/devres.c b/net/devres.c
index b97b0c5a8216..57a6a88d11f6 100644
--- a/net/devres.c
+++ b/net/devres.c
@@ -38,3 +38,58 @@ struct net_device *devm_alloc_etherdev_mqs(struct device *dev, int sizeof_priv,
return dr->ndev;
}
EXPORT_SYMBOL(devm_alloc_etherdev_mqs);
+
+static void devm_netdev_release(struct device *dev, void *this)
+{
+ struct net_device_devres *res = this;
+
+ unregister_netdev(res->ndev);
+}
+
+static int netdev_devres_match(struct device *dev, void *this, void *match_data)
+{
+ struct net_device_devres *res = this;
+ struct net_device *ndev = match_data;
+
+ return ndev == res->ndev;
+}
+
+/**
+ * devm_register_netdev - resource managed variant of register_netdev()
+ * @dev: managing device for this netdev - usually the parent device
+ * @ndev: device to register
+ *
+ * This is a devres variant of register_netdev() for which the unregister
+ * function will be call automatically when the managing device is
+ * detached. Note: the net_device used must also be resource managed by
+ * the same struct device.
+ */
+int devm_register_netdev(struct device *dev, struct net_device *ndev)
+{
+ struct net_device_devres *dr;
+ int ret;
+
+ /* struct net_device must itself be managed. For now a managed netdev
+ * can only be allocated by devm_alloc_etherdev_mqs() so the check is
+ * straightforward.
+ */
+ if (WARN_ON(!devres_find(dev, devm_free_netdev,
+ netdev_devres_match, ndev)))
+ return -EINVAL;
+
+ 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);
--
2.25.0
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v2 5/5] net: ethernet: mtk_star_emac: use devm_register_netdev()
2020-05-23 13:27 [PATCH v2 0/5] net: provide a devres variant of register_netdev() Bartosz Golaszewski
` (3 preceding siblings ...)
2020-05-23 13:27 ` [PATCH v2 4/5] net: devres: provide devm_register_netdev() Bartosz Golaszewski
@ 2020-05-23 13:27 ` Bartosz Golaszewski
2020-05-23 23:56 ` [PATCH v2 0/5] net: provide a devres variant of register_netdev() David Miller
5 siblings, 0 replies; 7+ messages in thread
From: Bartosz Golaszewski @ 2020-05-23 13:27 UTC (permalink / raw)
To: Jonathan Corbet, David S . Miller, Matthias Brugger,
John Crispin, Sean Wang, Mark Lee, Jakub Kicinski, Arnd Bergmann,
Fabien Parent, Heiner Kallweit, Edwin Peer
Cc: devicetree, Stephane Le Provost, netdev, linux-kernel,
Bartosz Golaszewski, linux-mediatek, Andrew Perepech, Pedro Tsai,
linux-arm-kernel
From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
Use the new devres variant of register_netdev() in the mtk-star-emac
driver and shrink the code by a couple lines.
Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
---
drivers/net/ethernet/mediatek/mtk_star_emac.c | 17 +----------------
1 file changed, 1 insertion(+), 16 deletions(-)
diff --git a/drivers/net/ethernet/mediatek/mtk_star_emac.c b/drivers/net/ethernet/mediatek/mtk_star_emac.c
index 789c77af501f..b74349cede28 100644
--- a/drivers/net/ethernet/mediatek/mtk_star_emac.c
+++ b/drivers/net/ethernet/mediatek/mtk_star_emac.c
@@ -1519,13 +1519,6 @@ static void mtk_star_mdiobus_unregister(void *data)
mdiobus_unregister(priv->mii);
}
-static void mtk_star_unregister_netdev(void *data)
-{
- struct net_device *ndev = data;
-
- unregister_netdev(ndev);
-}
-
static int mtk_star_probe(struct platform_device *pdev)
{
struct device_node *of_node;
@@ -1641,15 +1634,7 @@ static int mtk_star_probe(struct platform_device *pdev)
netif_napi_add(ndev, &priv->napi, mtk_star_poll, MTK_STAR_NAPI_WEIGHT);
- ret = register_netdev(ndev);
- if (ret)
- return ret;
-
- ret = devm_add_action_or_reset(dev, mtk_star_unregister_netdev, ndev);
- if (ret)
- return ret;
-
- return 0;
+ return devm_register_netdev(dev, ndev);
}
static const struct of_device_id mtk_star_of_match[] = {
--
2.25.0
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v2 0/5] net: provide a devres variant of register_netdev()
2020-05-23 13:27 [PATCH v2 0/5] net: provide a devres variant of register_netdev() Bartosz Golaszewski
` (4 preceding siblings ...)
2020-05-23 13:27 ` [PATCH v2 5/5] net: ethernet: mtk_star_emac: use devm_register_netdev() Bartosz Golaszewski
@ 2020-05-23 23:56 ` David Miller
5 siblings, 0 replies; 7+ messages in thread
From: David Miller @ 2020-05-23 23:56 UTC (permalink / raw)
To: brgl
Cc: edwin.peer, devicetree, bgolaszewski, stephane.leprovost, arnd,
corbet, netdev, sean.wang, linux-kernel, fparent, pedro.tsai,
linux-mediatek, andrew.perepech, john, matthias.bgg, kuba,
Mark-MC.Lee, linux-arm-kernel, hkallweit1
From: Bartosz Golaszewski <brgl@bgdev.pl>
Date: Sat, 23 May 2020 15:27:06 +0200
> From: Bartosz Golaszewski <bgolaszewski@baylibre.com>
>
> Using devres helpers allows to shrink the probing code, avoid memory leaks in
> error paths make sure the order in which resources are freed is the exact
> opposite of their allocation. This series proposes to add a devres variant
> of register_netdev() that will only work with net_device structures whose
> memory is also managed.
>
> First we add the missing documentation entry for the only other networking
> devres helper: devm_alloc_etherdev().
>
> Next we move devm_alloc_etherdev() into a separate source file.
>
> We then use a proxy structure in devm_alloc_etherdev() to improve readability.
>
> Last: we implement devm_register_netdev() and use it in mtk-eth-mac driver.
>
> v1 -> v2:
> - rebase on top of net-next after driver rename, no functional changes
Series applied, thank you.
_______________________________________________
Linux-mediatek mailing list
Linux-mediatek@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-mediatek
^ permalink raw reply [flat|nested] 7+ messages in thread