Hi Dex Two comments inlined. Thank you very much for the really good contribution to KNI!
Regards, Helin > -----Original Message----- > From: dev [mailto:dev-bounces at dpdk.org] On Behalf Of Dex Chen > Sent: Thursday, July 2, 2015 6:12 PM > To: dev at dpdk.org > Subject: [dpdk-dev] [PATCH] kni: allow per-net instances > > There is a global variable 'device_in_use' which is used to make sure only one > instance is using /dev/kni device. If you were using LXC, you will find there > is only > one instance of KNI example could be run even differnt namespaces were > created. > > In order to have /dev/kni used simultaneously in different namespaces, making > all of global variables as per network namespace variables. > > With regard to single kernel thread mode, there will be one kernel thread for > each of network namespace. > > Signed-off-by: Dex Chen <dex.chen at ruckuswireless.com> > --- > lib/librte_eal/linuxapp/kni/kni_misc.c | 129 > ++++++++++++++++++++++----------- > 1 file changed, 85 insertions(+), 44 deletions(-) > > diff --git a/lib/librte_eal/linuxapp/kni/kni_misc.c > b/lib/librte_eal/linuxapp/kni/kni_misc.c > index 2e9fa89..5ba8ab8 100644 > --- a/lib/librte_eal/linuxapp/kni/kni_misc.c > +++ b/lib/librte_eal/linuxapp/kni/kni_misc.c > @@ -28,6 +28,9 @@ > #include <linux/pci.h> > #include <linux/kthread.h> > #include <linux/rwsem.h> > +#include <linux/nsproxy.h> > +#include <net/net_namespace.h> > +#include <net/netns/generic.h> > > #include <exec-env/rte_kni_common.h> > #include "kni_dev.h" > @@ -90,18 +93,48 @@ static unsigned multiple_kthread_on = 0; > > #define KNI_DEV_IN_USE_BIT_NUM 0 /* Bit number for device in use */ > > -static volatile unsigned long device_in_use; /* device in use flag */ > -static struct > task_struct *kni_kthread; > +static int kni_net_id; > > -/* kni list lock */ > -static DECLARE_RWSEM(kni_list_lock); > +struct kni_net { > + volatile unsigned long device_in_use; /* device in use flag */ > + struct task_struct *kni_kthread; > + struct rw_semaphore kni_list_lock; > + struct list_head kni_list_head; > +}; > + > +static __net_init int kni_init_net(struct net *net) { > + struct kni_net *knet = net_generic(net, kni_net_id); > > -/* kni list */ > -static struct list_head kni_list_head = LIST_HEAD_INIT(kni_list_head); > + /* Clear the bit of device in use */ > + clear_bit(KNI_DEV_IN_USE_BIT_NUM, &knet->device_in_use); > + > + init_rwsem(&knet->kni_list_lock); > + INIT_LIST_HEAD(&knet->kni_list_head); > + > + return 0; > +} > + > +static __net_exit void kni_exit_net(struct net *net) { > + /* > + * Nothing to do here. > + * Assuming all cleanup jobs were done in kni_release(). > + */ > +} Agree with Stephen, kernel should handle it well. > + > +static struct pernet_operations kni_net_ops = { > + .init = kni_init_net, > + .exit = kni_exit_net, > + .id = &kni_net_id, > + .size = sizeof(struct kni_net), > +}; > > static int __init > kni_init(void) > { > + int rc; > + > KNI_PRINT("######## DPDK kni module loading ########\n"); > > if (kni_parse_kthread_mode() < 0) { > @@ -114,8 +147,9 @@ kni_init(void) > return -EPERM; > } > > - /* Clear the bit of device in use */ > - clear_bit(KNI_DEV_IN_USE_BIT_NUM, &device_in_use); > + rc = register_pernet_subsys(&kni_net_ops); > + if (rc) > + goto out; > > /* Configure the lo mode according to the input parameter */ > kni_net_config_lo_mode(lo_mode); > @@ -123,11 +157,16 @@ kni_init(void) > KNI_PRINT("######## DPDK kni module loaded ########\n"); > > return 0; > + > +out: > + misc_deregister(&kni_misc); > + return rc; > } > > static void __exit > kni_exit(void) > { > + unregister_pernet_subsys(&kni_net_ops); Should above 'unregsiter' be moved after 'misc_deregister()'? > misc_deregister(&kni_misc); > KNI_PRINT("####### DPDK kni module unloaded #######\n"); } @@ > -151,19 +190,22 @@ kni_parse_kthread_mode(void) static int