[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <174265444685.356712.759621883553836976.stgit@pro.pro>
Date: Sat, 22 Mar 2025 17:40:46 +0300
From: Kirill Tkhai <tkhai@...ru>
To: netdev@...r.kernel.org,
linux-kernel@...r.kernel.org
Cc: tkhai@...ru
Subject: [PATCH NET-PREV 23/51] hdlc_fr: Use __register_netdevice
The objective is to make dependent devices share
the same nd_lock.
Finaly, taking nd_lock should be moved to ioctl
caller, but now we can't do this at least because
netdevice notifiers are not converted.
Signed-off-by: Kirill Tkhai <tkhai@...ru>
---
drivers/net/wan/hdlc_fr.c | 18 ++++++++++++------
net/core/dev_ioctl.c | 1 +
2 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c
index 81e72bc1891f..93c61083de76 100644
--- a/drivers/net/wan/hdlc_fr.c
+++ b/drivers/net/wan/hdlc_fr.c
@@ -1106,7 +1106,9 @@ static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type)
dev->priv_flags |= IFF_NO_QUEUE;
dev->ml_priv = pvc;
- if (register_netdevice(dev) != 0) {
+ attach_nd_lock(dev, rcu_dereference_protected(frad->nd_lock, true));
+ if (__register_netdevice(dev) != 0) {
+ detach_nd_lock(dev);
free_netdev(dev);
delete_unused_pvcs(hdlc);
return -EIO;
@@ -1187,8 +1189,9 @@ static int fr_ioctl(struct net_device *dev, struct if_settings *ifs)
const size_t size = sizeof(fr_proto);
fr_proto new_settings;
hdlc_device *hdlc = dev_to_hdlc(dev);
+ struct nd_lock *nd_lock;
fr_proto_pvc pvc;
- int result;
+ int result, err;
switch (ifs->type) {
case IF_GET_PROTO:
@@ -1272,10 +1275,13 @@ static int fr_ioctl(struct net_device *dev, struct if_settings *ifs)
result = ARPHRD_DLCI;
if (ifs->type == IF_PROTO_FR_ADD_PVC ||
- ifs->type == IF_PROTO_FR_ADD_ETH_PVC)
- return fr_add_pvc(dev, pvc.dlci, result);
- else
- return fr_del_pvc(hdlc, pvc.dlci, result);
+ ifs->type == IF_PROTO_FR_ADD_ETH_PVC) {
+ lock_netdev(dev, &nd_lock);
+ err = fr_add_pvc(dev, pvc.dlci, result);
+ unlock_netdev(nd_lock);
+ } else {
+ err = fr_del_pvc(hdlc, pvc.dlci, result);
+ }
}
return -EINVAL;
diff --git a/net/core/dev_ioctl.c b/net/core/dev_ioctl.c
index 8592c052c0f4..dc2a0f513bac 100644
--- a/net/core/dev_ioctl.c
+++ b/net/core/dev_ioctl.c
@@ -496,6 +496,7 @@ static int dev_siocwandev(struct net_device *dev, struct if_settings *ifs)
{
const struct net_device_ops *ops = dev->netdev_ops;
+ /* This may take nd_lock. See fr_add_pvc() */
if (ops->ndo_siocwandev) {
if (netif_device_present(dev))
return ops->ndo_siocwandev(dev, ifs);
Powered by blists - more mailing lists