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

Reply via email to