[dpdk-dev,RFC,5/5] kni: support multiple userspace process working with kni module
Checks
Commit Message
in case of multiple application using the same KNI module,
protect that one application will only clean it's own devices.
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
lib/librte_eal/linuxapp/kni/kni_dev.h | 1 +
lib/librte_eal/linuxapp/kni/kni_misc.c | 21 +++++++++++++++------
2 files changed, 16 insertions(+), 6 deletions(-)
Comments
On 5/3/2017 12:21 PM, Hemant Agrawal wrote:
> in case of multiple application using the same KNI module,
> protect that one application will only clean it's own devices.
Idea looks OK, but there is already a check in the module that prevents
/dev/kni opened by more than one process [1], did you already removed
that limitation? Or is this something else?
[1]
kni_open(...) {
...
if (test_and_set_bit(KNI_DEV_IN_USE_BIT_NUM, &knet->device_in_use))
return -EBUSY;
...
}
>
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> ---
<...>
On 5/5/2017 6:38 PM, Ferruh Yigit wrote:
> On 5/3/2017 12:21 PM, Hemant Agrawal wrote:
>> in case of multiple application using the same KNI module,
>> protect that one application will only clean it's own devices.
>
> Idea looks OK, but there is already a check in the module that prevents
> /dev/kni opened by more than one process [1], did you already removed
> that limitation? Or is this something else?
>
> [1]
> kni_open(...) {
> ...
> if (test_and_set_bit(KNI_DEV_IN_USE_BIT_NUM, &knet->device_in_use))
> return -EBUSY;
> ...
> }
>
Yes! I have removed that. I will send that in next version.
>>
>> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
>> ---
> <...>
>
@@ -61,6 +61,7 @@ struct kni_dev {
uint32_t core_id; /* Core ID to bind */
char name[RTE_KNI_NAMESIZE]; /* Network device name */
struct task_struct *pthread;
+ void *usrctxt; /* User space process context*/
/* wait queue for req/resp */
wait_queue_head_t wq;
@@ -234,6 +234,9 @@ struct kni_net {
down_write(&knet->kni_list_lock);
list_for_each_entry_safe(dev, n, &knet->kni_list_head, list) {
+ /* check for the matching user context */
+ if (dev->usrctxt != inode)
+ continue;
/* Stop kernel thread for multiple mode */
if (multiple_kthread_on && dev->pthread != NULL) {
kthread_stop(dev->pthread);
@@ -311,9 +314,10 @@ struct kni_net {
}
static int
-kni_ioctl_create(struct net *net, uint32_t ioctl_num,
+kni_ioctl_create(struct inode *inode, uint32_t ioctl_num,
unsigned long ioctl_param)
{
+ struct net *net = current->nsproxy->net_ns;
struct kni_net *knet = net_generic(net, kni_net_id);
int ret;
struct rte_kni_device_info dev_info;
@@ -374,7 +378,8 @@ struct kni_net {
dev_net_set(net_dev, net);
kni = netdev_priv(net_dev);
-
+
+ kni->usrctxt = inode;
kni->net_dev = net_dev;
kni->group_id = dev_info.group_id;
kni->core_id = dev_info.core_id;
@@ -493,9 +498,10 @@ struct kni_net {
}
static int
-kni_ioctl_release(struct net *net, uint32_t ioctl_num,
+kni_ioctl_release(struct inode *inode, uint32_t ioctl_num,
unsigned long ioctl_param)
{
+ struct net *net = current->nsproxy->net_ns;
struct kni_net *knet = net_generic(net, kni_net_id);
int ret = -EINVAL;
struct kni_dev *dev, *n;
@@ -516,6 +522,10 @@ struct kni_net {
down_write(&knet->kni_list_lock);
list_for_each_entry_safe(dev, n, &knet->kni_list_head, list) {
+ /* only the owner user process can remove it*/
+ if (dev->usrctxt != inode)
+ continue;
+
if (strncmp(dev->name, dev_info.name, RTE_KNI_NAMESIZE) != 0)
continue;
@@ -540,7 +550,6 @@ struct kni_net {
kni_ioctl(struct inode *inode, uint32_t ioctl_num, unsigned long ioctl_param)
{
int ret = -EINVAL;
- struct net *net = current->nsproxy->net_ns;
pr_debug("IOCTL num=0x%0x param=0x%0lx\n", ioctl_num, ioctl_param);
@@ -552,10 +561,10 @@ struct kni_net {
/* For test only, not used */
break;
case _IOC_NR(RTE_KNI_IOCTL_CREATE):
- ret = kni_ioctl_create(net, ioctl_num, ioctl_param);
+ ret = kni_ioctl_create(inode, ioctl_num, ioctl_param);
break;
case _IOC_NR(RTE_KNI_IOCTL_RELEASE):
- ret = kni_ioctl_release(net, ioctl_num, ioctl_param);
+ ret = kni_ioctl_release(inode, ioctl_num, ioctl_param);
break;
default:
pr_debug("IOCTL default\n");