On 9/6/2016 12:25 PM, Vladyslav Buslov wrote:
> Allow binding KNI thread to specific core in single threaded mode
> by setting core_id and force_bind config parameters.

Thanks, patch does exactly what we talked, and as I tested it works fine.

1) There are a few comments, can you please find them inline.

2) Would you mind adding some document related this new feature?
Document path is: doc/guides/prog_guide/kernel_nic_interface.rst

> 
> Signed-off-by: Vladyslav Buslov <vladyslav.buslov at harmonicinc.com>
> ---
>  lib/librte_eal/linuxapp/kni/kni_misc.c | 48 
> ++++++++++++++++++++++------------
>  1 file changed, 32 insertions(+), 16 deletions(-)
> 
> diff --git a/lib/librte_eal/linuxapp/kni/kni_misc.c 
> b/lib/librte_eal/linuxapp/kni/kni_misc.c
> index 59d15ca..5e7cf21 100644
> --- a/lib/librte_eal/linuxapp/kni/kni_misc.c
> +++ b/lib/librte_eal/linuxapp/kni/kni_misc.c
> @@ -30,6 +30,7 @@
>  #include <linux/pci.h>
>  #include <linux/kthread.h>
>  #include <linux/rwsem.h>
> +#include <linux/mutex.h>
>  #include <linux/nsproxy.h>
>  #include <net/net_namespace.h>
>  #include <net/netns/generic.h>
> @@ -100,6 +101,7 @@ static int kni_net_id;
>  
>  struct kni_net {
>       unsigned long device_in_use; /* device in use flag */
> +     struct mutex kni_kthread_lock;
>       struct task_struct *kni_kthread;
>       struct rw_semaphore kni_list_lock;
>       struct list_head kni_list_head;
> @@ -123,6 +125,9 @@ static int __net_init kni_init_net(struct net *net)
>       /* Clear the bit of device in use */
>       clear_bit(KNI_DEV_IN_USE_BIT_NUM, &knet->device_in_use);
>  
> +     mutex_init(&knet->kni_kthread_lock);
> +     knet->kni_kthread = NULL;
> +
>       init_rwsem(&knet->kni_list_lock);
>       INIT_LIST_HEAD(&knet->kni_list_head);
>  
> @@ -139,9 +144,9 @@ static int __net_init kni_init_net(struct net *net)
>  
>  static void __net_exit kni_exit_net(struct net *net)
>  {
> -#ifndef HAVE_SIMPLIFIED_PERNET_OPERATIONS
>       struct kni_net *knet = net_generic(net, kni_net_id);
> -
> +     mutex_destroy(&knet->kni_kthread_lock);
> +#ifndef HAVE_SIMPLIFIED_PERNET_OPERATIONS
>       kfree(knet);
>  #endif
>  }
> @@ -236,16 +241,9 @@ kni_open(struct inode *inode, struct file *file)
>               return -EBUSY;
>  
>       /* Create kernel thread for single mode */
> -     if (multiple_kthread_on == 0) {
> +     if (multiple_kthread_on == 0)
>               KNI_PRINT("Single kernel thread for all KNI devices\n");
> -             /* Create kernel thread for RX */
> -             knet->kni_kthread = kthread_run(kni_thread_single, (void *)knet,
> -                                             "kni_single");
> -             if (IS_ERR(knet->kni_kthread)) {
> -                     KNI_ERR("Unable to create kernel threaed\n");
> -                     return PTR_ERR(knet->kni_kthread);
> -             }
> -     } else
> +     else
>               KNI_PRINT("Multiple kernel thread mode enabled\n");

Can move logs to where threads actually created (kni_ioctl_create)

>  
>       file->private_data = get_net(net);
> @@ -263,9 +261,13 @@ kni_release(struct inode *inode, struct file *file)
>  
>       /* Stop kernel thread for single mode */
>       if (multiple_kthread_on == 0) {
> +             mutex_lock(&knet->kni_kthread_lock);
>               /* Stop kernel thread */
> -             kthread_stop(knet->kni_kthread);
> -             knet->kni_kthread = NULL;
> +             if (knet->kni_kthread != NULL) {
> +                     kthread_stop(knet->kni_kthread);
> +                     knet->kni_kthread = NULL;
> +             }
> +             mutex_unlock(&knet->kni_kthread_lock);
>       }
>  
>       down_write(&knet->kni_list_lock);
> @@ -415,10 +417,9 @@ kni_ioctl_create(struct net *net,
>       }
>  
>       /**
> -      * Check if the cpu core id is valid for binding,
> -      * for multiple kernel thread mode.
> +      * Check if the cpu core id is valid for binding.
>        */
> -     if (multiple_kthread_on && dev_info.force_bind &&
> +     if (dev_info.force_bind &&
>                               !cpu_online(dev_info.core_id)) {
>               KNI_ERR("cpu %u is not online\n", dev_info.core_id);
>               return -EINVAL;
> @@ -581,6 +582,21 @@ kni_ioctl_create(struct net *net,
>               if (dev_info.force_bind)
>                       kthread_bind(kni->pthread, kni->core_id);
>               wake_up_process(kni->pthread);
> +     } else {
> +             mutex_lock(&knet->kni_kthread_lock);
> +             if (knet->kni_kthread == NULL) {

----->
> +                     knet->kni_kthread = kthread_create(kni_thread_single,
> +                                                                     (void 
> *)knet,
> +                                                                     
> "kni_single");

Syntax of this line is not proper, and I am aware above same call has
this syntax J But let's fix here..

> +                     if (IS_ERR(knet->kni_kthread)) {
> +                             kni_dev_remove(kni);
> +                             return -ECANCELED;
> +                     }
> +                     if (dev_info.force_bind)
> +                             kthread_bind(knet->kni_kthread, kni->core_id);
> +                     wake_up_process(knet->kni_kthread);
<----- This block is very common for multi and single process, what do
you think extracting this piece as a function, kni_ioctl_create already
longer than it should be.

> +             }
> +             mutex_unlock(&knet->kni_kthread_lock);
>       }
>  
>       down_write(&knet->kni_list_lock);
> 

Reply via email to