mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
Merge branch 'mpls-remove-rtnl-dependency'
Kuniyuki Iwashima says:
====================
mpls: Remove RTNL dependency.
MPLS uses RTNL
1) to guarantee the lifetime of struct mpls_nh.nh_dev
2) to protect net->mpls.platform_label
, but neither actually requires RTNL.
If struct mpls_nh holds a refcnt for nh_dev, we do not need RTNL,
and it can be replaced with a dedicated mutex.
The series removes RTNL from net/mpls/.
Overview:
Patch 1 is misc cleanup.
Patch 2 - 9 are prep to drop RTNL for RTM_{NEW,DEL,GET}ROUTE
handlers.
Patch 10 & 11 converts mpls_dump_routes() and RTM_GETNETCONF to RCU.
Patch 12 replaces RTNL with a new per-netns mutex.
Patch 13 drops RTNL from RTM_{NEW,DEL,GET}ROUTE.
====================
Link: https://patch.msgid.link/20251029173344.2934622-1-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
@@ -347,6 +347,11 @@ static inline struct inet6_dev *__in6_dev_get(const struct net_device *dev)
|
||||
return rcu_dereference_rtnl(dev->ip6_ptr);
|
||||
}
|
||||
|
||||
static inline struct inet6_dev *in6_dev_rcu(const struct net_device *dev)
|
||||
{
|
||||
return rcu_dereference(dev->ip6_ptr);
|
||||
}
|
||||
|
||||
static inline struct inet6_dev *__in6_dev_get_rtnl_net(const struct net_device *dev)
|
||||
{
|
||||
return rtnl_net_dereference(dev_net(dev), dev->ip6_ptr);
|
||||
|
||||
@@ -16,6 +16,7 @@ struct netns_mpls {
|
||||
int default_ttl;
|
||||
size_t platform_labels;
|
||||
struct mpls_route __rcu * __rcu *platform_label;
|
||||
struct mutex platform_mutex;
|
||||
|
||||
struct ctl_table_header *ctl;
|
||||
};
|
||||
|
||||
+199
-122
File diff suppressed because it is too large
Load Diff
+16
-3
@@ -88,6 +88,7 @@ enum mpls_payload_type {
|
||||
|
||||
struct mpls_nh { /* next hop label forwarding entry */
|
||||
struct net_device *nh_dev;
|
||||
netdevice_tracker nh_dev_tracker;
|
||||
|
||||
/* nh_flags is accessed under RCU in the packet path; it is
|
||||
* modified handling netdev events with rtnl lock held
|
||||
@@ -184,9 +185,20 @@ static inline struct mpls_entry_decoded mpls_entry_decode(struct mpls_shim_hdr *
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline struct mpls_dev *mpls_dev_get(const struct net_device *dev)
|
||||
#define mpls_dereference(net, p) \
|
||||
rcu_dereference_protected( \
|
||||
(p), \
|
||||
lockdep_is_held(&(net)->mpls.platform_mutex))
|
||||
|
||||
static inline struct mpls_dev *mpls_dev_rcu(const struct net_device *dev)
|
||||
{
|
||||
return rcu_dereference_rtnl(dev->mpls_ptr);
|
||||
return rcu_dereference(dev->mpls_ptr);
|
||||
}
|
||||
|
||||
static inline struct mpls_dev *mpls_dev_get(const struct net *net,
|
||||
const struct net_device *dev)
|
||||
{
|
||||
return mpls_dereference(net, dev->mpls_ptr);
|
||||
}
|
||||
|
||||
int nla_put_labels(struct sk_buff *skb, int attrtype, u8 labels,
|
||||
@@ -196,7 +208,8 @@ int nla_get_labels(const struct nlattr *nla, u8 max_labels, u8 *labels,
|
||||
bool mpls_output_possible(const struct net_device *dev);
|
||||
unsigned int mpls_dev_mtu(const struct net_device *dev);
|
||||
bool mpls_pkt_too_big(const struct sk_buff *skb, unsigned int mtu);
|
||||
void mpls_stats_inc_outucastpkts(struct net_device *dev,
|
||||
void mpls_stats_inc_outucastpkts(struct net *net,
|
||||
struct net_device *dev,
|
||||
const struct sk_buff *skb);
|
||||
|
||||
#endif /* MPLS_INTERNAL_H */
|
||||
|
||||
@@ -53,7 +53,7 @@ static int mpls_xmit(struct sk_buff *skb)
|
||||
|
||||
/* Find the output device */
|
||||
out_dev = dst->dev;
|
||||
net = dev_net(out_dev);
|
||||
net = dev_net_rcu(out_dev);
|
||||
|
||||
if (!mpls_output_possible(out_dev) ||
|
||||
!dst->lwtstate || skb_warn_if_lro(skb))
|
||||
@@ -128,7 +128,7 @@ static int mpls_xmit(struct sk_buff *skb)
|
||||
bos = false;
|
||||
}
|
||||
|
||||
mpls_stats_inc_outucastpkts(out_dev, skb);
|
||||
mpls_stats_inc_outucastpkts(net, out_dev, skb);
|
||||
|
||||
if (rt) {
|
||||
if (rt->rt_gw_family == AF_INET6)
|
||||
@@ -153,7 +153,7 @@ static int mpls_xmit(struct sk_buff *skb)
|
||||
return LWTUNNEL_XMIT_DONE;
|
||||
|
||||
drop:
|
||||
out_mdev = out_dev ? mpls_dev_get(out_dev) : NULL;
|
||||
out_mdev = out_dev ? mpls_dev_rcu(out_dev) : NULL;
|
||||
if (out_mdev)
|
||||
MPLS_INC_STATS(out_mdev, tx_errors);
|
||||
kfree_skb(skb);
|
||||
|
||||
Reference in New Issue
Block a user