net_namespace-device can get registered after module init, e.g. vxlan registers name-space-device on port add. On kernel without namespace support __net_init is defined as __init which cause panic on vxlan port add. Following patch fixes it.
BUG: unable to handle kernel paging request at ffffffffa02b6293 IP: [<ffffffffa02b6293>] 0xffffffffa02b6293 PGD 1a87067 PUD 1a8b063 PMD 8371de067 PTE 0 Oops: 0010 [#1] SMP Process ovs-vswitchd (pid: 10330, threadinfo ffff8808367fe000, task f880839e16aa0) Stack: Call Trace: [<ffffffff8144b254>] ? register_pernet_gen_device+0x74/0xd0 [<ffffffffa027e220>] ? vxlan_rcv+0x0/0x60 [openvswitch] [<ffffffffa0280a7b>] vxlan_handler_add+0x3cb/0x480 [openvswitch] [<ffffffffa027e1f4>] vxlan_tnl_create+0xc4/0xf0 [openvswitch] [<ffffffffa027b6f3>] ovs_vport_add+0x53/0xb0 [openvswitch] [<ffffffffa0273bc6>] new_vport+0x16/0x60 [openvswitch] [<ffffffffa0276399>] ovs_vport_cmd_new+0x109/0x210 [openvswitch] [<ffffffff81478f80>] genl_rcv_msg+0x1d0/0x210 [<ffffffff81477e29>] netlink_rcv_skb+0xa9/0xd0 [<ffffffff81478d95>] genl_rcv+0x25/0x40 [<ffffffff81477a63>] netlink_unicast+0x283/0x2d0 [<ffffffff814783de>] netlink_sendmsg+0x1fe/0x2e0 [<ffffffff8143c8d3>] sock_sendmsg+0x123/0x150 [<ffffffff8143e0b6>] __sys_sendmsg+0x406/0x420 [<ffffffff8143e2d9>] sys_sendmsg+0x49/0x90 [<ffffffff8100b072>] system_call_fastpath+0x16/0x1b Code: Bad RIP value. RIP [<ffffffffa02b6293>] 0xffffffffa02b6293 Signed-off-by: Pravin B Shelar <pshe...@nicira.com> Bug #19178 --- datapath/linux/compat/include/net/net_namespace.h | 14 ++++++-------- datapath/linux/compat/net_namespace.c | 4 ++-- datapath/linux/compat/vxlan.c | 2 +- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/datapath/linux/compat/include/net/net_namespace.h b/datapath/linux/compat/include/net/net_namespace.h index 85dee1a..27e22f6 100644 --- a/datapath/linux/compat/include/net/net_namespace.h +++ b/datapath/linux/compat/include/net/net_namespace.h @@ -17,8 +17,6 @@ static inline void release_net(struct net *net) { } -#define __net_init __init -#define __net_exit __exit #endif /* 2.6.24 */ #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,26) @@ -82,23 +80,23 @@ extern void rpl_unregister_pernet_gen_device(struct rpl_pernet_operations *ops); #else /* for 2.6.32* */ -int __net_init compat_init_net(struct net *net, struct rpl_pernet_operations *pnet); -void __net_exit compat_exit_net(struct net *net, struct rpl_pernet_operations *pnet); +int compat_init_net(struct net *net, struct rpl_pernet_operations *pnet); +void compat_exit_net(struct net *net, struct rpl_pernet_operations *pnet); #define DEFINE_COMPAT_PNET_REG_FUNC(TYPE) \ \ static struct rpl_pernet_operations *pnet_gen_##TYPE; \ -static int __net_init compat_init_net_gen_##TYPE(struct net *net) \ +static int compat_init_net_gen_##TYPE(struct net *net) \ { \ return compat_init_net(net, pnet_gen_##TYPE); \ } \ \ -static void __net_exit compat_exit_net_gen_##TYPE(struct net *net) \ +static void compat_exit_net_gen_##TYPE(struct net *net) \ { \ compat_exit_net(net, pnet_gen_##TYPE); \ } \ \ -static int __net_init rpl_register_pernet_gen_##TYPE(struct rpl_pernet_operations *rpl_pnet) \ +static int rpl_register_pernet_gen_##TYPE(struct rpl_pernet_operations *rpl_pnet) \ { \ pnet_gen_##TYPE = rpl_pnet; \ rpl_pnet->ops.init = compat_init_net_gen_##TYPE; \ @@ -106,7 +104,7 @@ static int __net_init rpl_register_pernet_gen_##TYPE(struct rpl_pernet_operation return register_pernet_gen_##TYPE(pnet_gen_##TYPE->id, &rpl_pnet->ops); \ } \ \ -static void __net_exit rpl_unregister_pernet_gen_##TYPE(struct rpl_pernet_operations *rpl_pnet) \ +static void rpl_unregister_pernet_gen_##TYPE(struct rpl_pernet_operations *rpl_pnet) \ { \ unregister_pernet_gen_##TYPE(*pnet_gen_##TYPE->id, &rpl_pnet->ops); \ } diff --git a/datapath/linux/compat/net_namespace.c b/datapath/linux/compat/net_namespace.c index 82404af..843e6c1 100644 --- a/datapath/linux/compat/net_namespace.c +++ b/datapath/linux/compat/net_namespace.c @@ -8,7 +8,7 @@ static int net_assign_generic(struct net *net, int id, void *data); #endif -int __net_init compat_init_net(struct net *net, struct rpl_pernet_operations *pnet) +int compat_init_net(struct net *net, struct rpl_pernet_operations *pnet) { int err; void *ovs_net = kzalloc(pnet->size, GFP_KERNEL); @@ -32,7 +32,7 @@ err: return err; } -void __net_exit compat_exit_net(struct net *net, struct rpl_pernet_operations *pnet) +void compat_exit_net(struct net *net, struct rpl_pernet_operations *pnet) { void *ovs_net = net_generic(net, *pnet->id); diff --git a/datapath/linux/compat/vxlan.c b/datapath/linux/compat/vxlan.c index 6e6b945..f3df4e3 100644 --- a/datapath/linux/compat/vxlan.c +++ b/datapath/linux/compat/vxlan.c @@ -429,7 +429,7 @@ void vxlan_handler_put(struct vxlan_handler *vh) queue_work(&vh->del_work); } -static __net_init int vxlan_init_net(struct net *net) +static int vxlan_init_net(struct net *net) { struct vxlan_net *vn = net_generic(net, vxlan_net_id); unsigned int h; -- 1.7.1 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev