From: Pravin Shelar <pshe...@nicira.com> Currently gre demultiplexer uses its own spin-lock. We should rather RTNL lock.
Suggested-by: Stephen Hemminger <shemmin...@vyatta.com> Signed-off-by: Pravin B Shelar <pshe...@nicira.com> --- drivers/net/ppp/pptp.c | 5 +++++ net/ipv4/gre.c | 18 +++++------------- net/ipv4/ip_gre.c | 5 +++++ 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/drivers/net/ppp/pptp.c b/drivers/net/ppp/pptp.c index 162464f..b76c151 100644 --- a/drivers/net/ppp/pptp.c +++ b/drivers/net/ppp/pptp.c @@ -673,11 +673,14 @@ static int __init pptp_init_module(void) if (!callid_sock) return -ENOMEM; + rtnl_lock(); err = gre_add_protocol(&gre_pptp_protocol, GREPROTO_PPTP); if (err) { + rtnl_unlock(); pr_err("PPTP: can't add gre protocol\n"); goto out_mem_free; } + rtnl_unlock(); err = proto_register(&pptp_sk_proto, 0); if (err) { @@ -707,7 +710,9 @@ static void __exit pptp_exit_module(void) { unregister_pppox_proto(PX_PROTO_PPTP); proto_unregister(&pptp_sk_proto); + rtnl_lock(); gre_del_protocol(&gre_pptp_protocol, GREPROTO_PPTP); + rtnl_unlock(); vfree(callid_sock); } diff --git a/net/ipv4/gre.c b/net/ipv4/gre.c index 42a4910..5a903dc 100644 --- a/net/ipv4/gre.c +++ b/net/ipv4/gre.c @@ -25,23 +25,19 @@ static const struct gre_protocol __rcu *gre_proto[GREPROTO_MAX] __read_mostly; -static DEFINE_SPINLOCK(gre_proto_lock); int gre_add_protocol(const struct gre_protocol *proto, u8 version) { + ASSERT_RTNL(); if (version >= GREPROTO_MAX) goto err_out; - spin_lock(&gre_proto_lock); if (gre_proto[version]) - goto err_out_unlock; + goto err_out; RCU_INIT_POINTER(gre_proto[version], proto); - spin_unlock(&gre_proto_lock); return 0; -err_out_unlock: - spin_unlock(&gre_proto_lock); err_out: return -1; } @@ -49,20 +45,16 @@ EXPORT_SYMBOL_GPL(gre_add_protocol); int gre_del_protocol(const struct gre_protocol *proto, u8 version) { + ASSERT_RTNL(); if (version >= GREPROTO_MAX) goto err_out; - spin_lock(&gre_proto_lock); - if (rcu_dereference_protected(gre_proto[version], - lockdep_is_held(&gre_proto_lock)) != proto) - goto err_out_unlock; + if (rtnl_dereference(gre_proto[version]) != proto) + goto err_out; RCU_INIT_POINTER(gre_proto[version], NULL); - spin_unlock(&gre_proto_lock); synchronize_rcu(); return 0; -err_out_unlock: - spin_unlock(&gre_proto_lock); err_out: return -1; } diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index a85ae2f..0d4eecd 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c @@ -1785,11 +1785,14 @@ static int __init ipgre_init(void) if (err < 0) return err; + rtnl_lock(); err = gre_add_protocol(&ipgre_protocol, GREPROTO_CISCO); if (err < 0) { + rtnl_unlock(); pr_info("%s: can't add protocol\n", __func__); goto add_proto_failed; } + rtnl_unlock(); err = rtnl_link_register(&ipgre_link_ops); if (err < 0) @@ -1815,8 +1818,10 @@ static void __exit ipgre_fini(void) { rtnl_link_unregister(&ipgre_tap_ops); rtnl_link_unregister(&ipgre_link_ops); + rtnl_lock(); if (gre_del_protocol(&ipgre_protocol, GREPROTO_CISCO) < 0) pr_info("%s: can't remove protocol\n", __func__); + rtnl_unlock(); unregister_pernet_device(&ipgre_net_ops); } -- 1.7.1 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev