[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20221001060145.3199964-5-jiri@resnulli.us>
Date: Sat, 1 Oct 2022 08:01:36 +0200
From: Jiri Pirko <jiri@...nulli.us>
To: netdev@...r.kernel.org
Cc: davem@...emloft.net, kuba@...nel.org, pabeni@...hat.com,
edumazet@...gle.com, tariqt@...dia.com, moshe@...dia.com,
saeedm@...dia.com
Subject: [patch net-next 04/13] net: devlink: take RTNL in port_fill() function only if it is not held
From: Jiri Pirko <jiri@...dia.com>
Follow-up patch is going to introduce a netdevice notifier event
processing which is called with RTNL mutex held. Processing of this will
eventually lead to call to port_notity() and port_fill() which currently
takes RTNL mutex internally. So as a temporary solution, propagate a
bool indicating if the mutex is already held. This will go away in one
of the follow-up patches.
Signed-off-by: Jiri Pirko <jiri@...dia.com>
---
net/core/devlink.c | 46 +++++++++++++++++++++++++++++++---------------
1 file changed, 31 insertions(+), 15 deletions(-)
diff --git a/net/core/devlink.c b/net/core/devlink.c
index e49ec10d613f..ee14520d4690 100644
--- a/net/core/devlink.c
+++ b/net/core/devlink.c
@@ -1278,7 +1278,8 @@ devlink_nl_port_function_attrs_put(struct sk_buff *msg, struct devlink_port *por
static int devlink_nl_port_fill(struct sk_buff *msg,
struct devlink_port *devlink_port,
enum devlink_command cmd, u32 portid, u32 seq,
- int flags, struct netlink_ext_ack *extack)
+ int flags, struct netlink_ext_ack *extack,
+ bool rtnl_held)
{
struct devlink *devlink = devlink_port->devlink;
void *hdr;
@@ -1293,7 +1294,8 @@ static int devlink_nl_port_fill(struct sk_buff *msg,
goto nla_put_failure;
/* Hold rtnl lock while accessing port's netdev attributes. */
- rtnl_lock();
+ if (!rtnl_held)
+ rtnl_lock();
spin_lock_bh(&devlink_port->type_lock);
if (nla_put_u16(msg, DEVLINK_ATTR_PORT_TYPE, devlink_port->type))
goto nla_put_failure_type_locked;
@@ -1321,7 +1323,8 @@ static int devlink_nl_port_fill(struct sk_buff *msg,
goto nla_put_failure_type_locked;
}
spin_unlock_bh(&devlink_port->type_lock);
- rtnl_unlock();
+ if (!rtnl_held)
+ rtnl_unlock();
if (devlink_nl_port_attrs_put(msg, devlink_port))
goto nla_put_failure;
if (devlink_nl_port_function_attrs_put(msg, devlink_port, extack))
@@ -1336,14 +1339,15 @@ static int devlink_nl_port_fill(struct sk_buff *msg,
nla_put_failure_type_locked:
spin_unlock_bh(&devlink_port->type_lock);
- rtnl_unlock();
+ if (!rtnl_held)
+ rtnl_unlock();
nla_put_failure:
genlmsg_cancel(msg, hdr);
return -EMSGSIZE;
}
-static void devlink_port_notify(struct devlink_port *devlink_port,
- enum devlink_command cmd)
+static void __devlink_port_notify(struct devlink_port *devlink_port,
+ enum devlink_command cmd, bool rtnl_held)
{
struct devlink *devlink = devlink_port->devlink;
struct sk_buff *msg;
@@ -1358,7 +1362,8 @@ static void devlink_port_notify(struct devlink_port *devlink_port,
if (!msg)
return;
- err = devlink_nl_port_fill(msg, devlink_port, cmd, 0, 0, 0, NULL);
+ err = devlink_nl_port_fill(msg, devlink_port, cmd, 0, 0, 0, NULL,
+ rtnl_held);
if (err) {
nlmsg_free(msg);
return;
@@ -1368,6 +1373,12 @@ static void devlink_port_notify(struct devlink_port *devlink_port,
0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
}
+static void devlink_port_notify(struct devlink_port *devlink_port,
+ enum devlink_command cmd)
+{
+ __devlink_port_notify(devlink_port, cmd, false);
+}
+
static void devlink_rate_notify(struct devlink_rate *devlink_rate,
enum devlink_command cmd)
{
@@ -1531,7 +1542,7 @@ static int devlink_nl_cmd_port_get_doit(struct sk_buff *skb,
err = devlink_nl_port_fill(msg, devlink_port, DEVLINK_CMD_PORT_NEW,
info->snd_portid, info->snd_seq, 0,
- info->extack);
+ info->extack, false);
if (err) {
nlmsg_free(msg);
return err;
@@ -1561,7 +1572,8 @@ static int devlink_nl_cmd_port_get_dumpit(struct sk_buff *msg,
DEVLINK_CMD_NEW,
NETLINK_CB(cb->skb).portid,
cb->nlh->nlmsg_seq,
- NLM_F_MULTI, cb->extack);
+ NLM_F_MULTI, cb->extack,
+ false);
if (err) {
devl_unlock(devlink);
devlink_put(devlink);
@@ -1773,7 +1785,8 @@ static int devlink_port_new_notify(struct devlink *devlink,
}
err = devlink_nl_port_fill(msg, devlink_port, DEVLINK_CMD_NEW,
- info->snd_portid, info->snd_seq, 0, NULL);
+ info->snd_portid, info->snd_seq, 0, NULL,
+ false);
if (err)
goto out;
@@ -10033,7 +10046,7 @@ static void devlink_port_type_netdev_checks(struct devlink_port *devlink_port,
static void __devlink_port_type_set(struct devlink_port *devlink_port,
enum devlink_port_type type,
- void *type_dev)
+ void *type_dev, bool rtnl_held)
{
struct net_device *netdev = type_dev;
@@ -10060,7 +10073,7 @@ static void __devlink_port_type_set(struct devlink_port *devlink_port,
break;
}
spin_unlock_bh(&devlink_port->type_lock);
- devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
+ __devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW, rtnl_held);
}
/**
@@ -10077,7 +10090,8 @@ void devlink_port_type_eth_set(struct devlink_port *devlink_port,
"devlink port type for port %d set to Ethernet without a software interface reference, device type not supported by the kernel?\n",
devlink_port->index);
- __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_ETH, netdev);
+ __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_ETH, netdev,
+ false);
}
EXPORT_SYMBOL_GPL(devlink_port_type_eth_set);
@@ -10090,7 +10104,8 @@ EXPORT_SYMBOL_GPL(devlink_port_type_eth_set);
void devlink_port_type_ib_set(struct devlink_port *devlink_port,
struct ib_device *ibdev)
{
- __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_IB, ibdev);
+ __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_IB, ibdev,
+ false);
}
EXPORT_SYMBOL_GPL(devlink_port_type_ib_set);
@@ -10101,7 +10116,8 @@ EXPORT_SYMBOL_GPL(devlink_port_type_ib_set);
*/
void devlink_port_type_clear(struct devlink_port *devlink_port)
{
- __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_NOTSET, NULL);
+ __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_NOTSET, NULL,
+ false);
}
EXPORT_SYMBOL_GPL(devlink_port_type_clear);
--
2.37.1
Powered by blists - more mailing lists