Netdev List
 help / color / mirror / Atom feed
* [PATCH net] xfrm: add NETDEV_UNREGISTER event process for xfrmi
@ 2019-08-26  8:25 Xin Long
  2019-08-27  6:58 ` Steffen Klassert
  0 siblings, 1 reply; 2+ messages in thread
From: Xin Long @ 2019-08-26  8:25 UTC (permalink / raw)
  To: network dev; +Cc: davem, Steffen Klassert

When creating a xfrmi dev, it always holds the phydev. The xfrmi dev should
be deleted when the phydev is being unregistered, so that the phydev can be
put on time. Otherwise the phydev's deleting will get stuck:

  # ip link add dummy10 type dummy
  # ip link add xfrmi10 type xfrm dev dummy10
  # ip link del dummy10

The last command blocks and dmesg shows:

  unregister_netdevice: waiting for dummy10 to become free. Usage count = 1

This patch fixes it by adding NETDEV_UNREGISTER event process for xfrmi.

Fixes: f203b76d7809 ("xfrm: Add virtual xfrm interfaces")
Reported-by: Xiumei Mu <xmu@redhat.com>
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
 net/xfrm/xfrm_interface.c | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)

diff --git a/net/xfrm/xfrm_interface.c b/net/xfrm/xfrm_interface.c
index 74868f9..f3de1f5 100644
--- a/net/xfrm/xfrm_interface.c
+++ b/net/xfrm/xfrm_interface.c
@@ -877,6 +877,35 @@ static const struct xfrm_if_cb xfrm_if_cb = {
 	.decode_session =	xfrmi_decode_session,
 };
 
+static int xfrmi_event(struct notifier_block *this, unsigned long e, void *ptr)
+{
+	struct net_device *dev = netdev_notifier_info_to_dev(ptr);
+	struct xfrmi_net *xfrmn = net_generic(dev_net(dev), xfrmi_net_id);
+	struct xfrm_if *xi;
+	LIST_HEAD(list);
+
+	if (e != NETDEV_UNREGISTER)
+		return NOTIFY_DONE;
+
+	rcu_read_lock();
+	for_each_xfrmi_rcu(xfrmn->xfrmi[0], xi) {
+		if (xi->phydev != dev)
+			continue;
+		unregister_netdevice_queue(xi->dev, &list);
+	}
+	rcu_read_unlock();
+
+	if (list_empty(&list))
+		return NOTIFY_DONE;
+
+	unregister_netdevice_many(&list);
+	return NOTIFY_OK;
+}
+
+static struct notifier_block xfrmi_notifier = {
+	.notifier_call  = xfrmi_event,
+};
+
 static int __init xfrmi_init(void)
 {
 	const char *msg;
@@ -906,6 +935,7 @@ static int __init xfrmi_init(void)
 		goto rtnl_link_failed;
 
 	xfrm_if_register_cb(&xfrm_if_cb);
+	register_netdevice_notifier(&xfrmi_notifier);
 
 	return err;
 
@@ -922,6 +952,7 @@ static int __init xfrmi_init(void)
 
 static void __exit xfrmi_fini(void)
 {
+	unregister_netdevice_notifier(&xfrmi_notifier);
 	xfrm_if_unregister_cb();
 	rtnl_link_unregister(&xfrmi_link_ops);
 	xfrmi4_fini();
-- 
2.1.0


^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2019-08-27  6:58 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-08-26  8:25 [PATCH net] xfrm: add NETDEV_UNREGISTER event process for xfrmi Xin Long
2019-08-27  6:58 ` Steffen Klassert

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox