We count pinned_vm as follow in vhost-vDPA
lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
if (npages + atomic64_read(&dev->mm->pinned_vm) > lock_limit) {
ret = -ENOMEM;
goto unlock;
}
This means if we have two vDPA devices for the same VM the pages would be counted twice
So we add a tree to save the page that counted and we will not count it again
Signed-off-by: Cindy Lu <[email protected]>
---
drivers/vhost/vdpa.c | 79 ++++++++++++++++++++++++++++++++++++++--
include/linux/mm_types.h | 2 +
2 files changed, 78 insertions(+), 3 deletions(-)
diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c
index 05f5fd2af58f..48cb5c8264b5 100644
--- a/drivers/vhost/vdpa.c
+++ b/drivers/vhost/vdpa.c
@@ -24,6 +24,9 @@
#include <linux/vhost.h>
#include "vhost.h"
+#include <linux/rbtree.h>
+#include <linux/interval_tree.h>
+#include <linux/interval_tree_generic.h>
enum {
VHOST_VDPA_BACKEND_FEATURES =
@@ -505,6 +508,50 @@ static long vhost_vdpa_unlocked_ioctl(struct file *filep,
mutex_unlock(&d->mutex);
return r;
}
+int vhost_vdpa_add_range_ctx(struct rb_root_cached *root, u64 start, u64 last)
+{
+ struct interval_tree_node *new_node;
+
+ if (last < start)
+ return -EFAULT;
+
+ /* If the range being mapped is [0, ULONG_MAX], split it into two entries
+ * otherwise its size would overflow u64.
+ */
+ if (start == 0 && last == ULONG_MAX) {
+ u64 mid = last / 2;
+
+ vhost_vdpa_add_range_ctx(root, start, mid);
+ start = mid + 1;
+ }
+
+ new_node = kmalloc(sizeof(struct interval_tree_node), GFP_ATOMIC);
+ if (!new_node)
+ return -ENOMEM;
+
+ new_node->start = start;
+ new_node->last = last;
+
+ interval_tree_insert(new_node, root);
+
+ return 0;
+}
+
+void vhost_vdpa_del_range(struct rb_root_cached *root, u64 start, u64 last)
+{
+ struct interval_tree_node *new_node;
+
+ while ((new_node = interval_tree_iter_first(root, start, last))) {
+ interval_tree_remove(new_node, root);
+ kfree(new_node);
+ }
+}
+
+struct interval_tree_node *vhost_vdpa_search_range(struct rb_root_cached *root,
+ u64 start, u64 last)
+{
+ return interval_tree_iter_first(root, start, last);
+}
static void vhost_vdpa_pa_unmap(struct vhost_vdpa *v, u64 start, u64 last)
{
@@ -513,6 +560,7 @@ static void vhost_vdpa_pa_unmap(struct vhost_vdpa *v, u64 start, u64 last)
struct vhost_iotlb_map *map;
struct page *page;
unsigned long pfn, pinned;
+ struct interval_tree_node *new_node = NULL;
while ((map = vhost_iotlb_itree_first(iotlb, start, last)) != NULL) {
pinned = PFN_DOWN(map->size);
@@ -523,7 +571,18 @@ static void vhost_vdpa_pa_unmap(struct vhost_vdpa *v, u64 start, u64 last)
set_page_dirty_lock(page);
unpin_user_page(page);
}
- atomic64_sub(PFN_DOWN(map->size), &dev->mm->pinned_vm);
+
+ new_node = vhost_vdpa_search_range(&dev->mm->root_for_vdpa,
+ map->start,
+ map->start + map->size - 1);
+
+ if (new_node) {
+ vhost_vdpa_del_range(&dev->mm->root_for_vdpa,
+ map->start,
+ map->start + map->size - 1);
+ atomic64_sub(PFN_DOWN(map->size), &dev->mm->pinned_vm);
+ }
+
vhost_iotlb_map_free(iotlb, map);
}
}
@@ -591,6 +650,7 @@ static int vhost_vdpa_map(struct vhost_vdpa *v, u64 iova,
struct vdpa_device *vdpa = v->vdpa;
const struct vdpa_config_ops *ops = vdpa->config;
int r = 0;
+ struct interval_tree_node *new_node = NULL;
r = vhost_iotlb_add_range_ctx(dev->iotlb, iova, iova + size - 1,
pa, perm, opaque);
@@ -611,9 +671,22 @@ static int vhost_vdpa_map(struct vhost_vdpa *v, u64 iova,
return r;
}
- if (!vdpa->use_va)
- atomic64_add(PFN_DOWN(size), &dev->mm->pinned_vm);
+ if (!vdpa->use_va) {
+ new_node = vhost_vdpa_search_range(&dev->mm->root_for_vdpa,
+ iova, iova + size - 1);
+
+ if (new_node == 0) {
+ r = vhost_vdpa_add_range_ctx(&dev->mm->root_for_vdpa,
+ iova, iova + size - 1);
+ if (r) {
+ vhost_iotlb_del_range(dev->iotlb, iova,
+ iova + size - 1);
+ return r;
+ }
+ atomic64_add(PFN_DOWN(size), &dev->mm->pinned_vm);
+ }
+ }
return 0;
}
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index 5140e5feb486..46eaa6d0560b 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -634,6 +634,8 @@ struct mm_struct {
#ifdef CONFIG_IOMMU_SUPPORT
u32 pasid;
#endif
+ struct rb_root_cached root_for_vdpa;
+
} __randomize_layout;
/*
--
2.34.1
On Mon, May 9, 2022 at 3:15 PM Cindy Lu <[email protected]> wrote:
>
> We count pinned_vm as follow in vhost-vDPA
>
> lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT;
> if (npages + atomic64_read(&dev->mm->pinned_vm) > lock_limit) {
> ret = -ENOMEM;
> goto unlock;
> }
> This means if we have two vDPA devices for the same VM the pages would be counted twice
> So we add a tree to save the page that counted and we will not count it again
>
> Signed-off-by: Cindy Lu <[email protected]>
> ---
> drivers/vhost/vdpa.c | 79 ++++++++++++++++++++++++++++++++++++++--
> include/linux/mm_types.h | 2 +
> 2 files changed, 78 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c
> index 05f5fd2af58f..48cb5c8264b5 100644
> --- a/drivers/vhost/vdpa.c
> +++ b/drivers/vhost/vdpa.c
> @@ -24,6 +24,9 @@
> #include <linux/vhost.h>
>
> #include "vhost.h"
> +#include <linux/rbtree.h>
> +#include <linux/interval_tree.h>
> +#include <linux/interval_tree_generic.h>
>
> enum {
> VHOST_VDPA_BACKEND_FEATURES =
> @@ -505,6 +508,50 @@ static long vhost_vdpa_unlocked_ioctl(struct file *filep,
> mutex_unlock(&d->mutex);
> return r;
> }
> +int vhost_vdpa_add_range_ctx(struct rb_root_cached *root, u64 start, u64 last)
> +{
> + struct interval_tree_node *new_node;
> +
> + if (last < start)
> + return -EFAULT;
> +
> + /* If the range being mapped is [0, ULONG_MAX], split it into two entries
> + * otherwise its size would overflow u64.
> + */
> + if (start == 0 && last == ULONG_MAX) {
> + u64 mid = last / 2;
> +
> + vhost_vdpa_add_range_ctx(root, start, mid);
> + start = mid + 1;
> + }
> +
> + new_node = kmalloc(sizeof(struct interval_tree_node), GFP_ATOMIC);
> + if (!new_node)
> + return -ENOMEM;
> +
> + new_node->start = start;
> + new_node->last = last;
> +
> + interval_tree_insert(new_node, root);
> +
> + return 0;
> +}
> +
> +void vhost_vdpa_del_range(struct rb_root_cached *root, u64 start, u64 last)
> +{
> + struct interval_tree_node *new_node;
> +
> + while ((new_node = interval_tree_iter_first(root, start, last))) {
> + interval_tree_remove(new_node, root);
> + kfree(new_node);
> + }
> +}
> +
> +struct interval_tree_node *vhost_vdpa_search_range(struct rb_root_cached *root,
> + u64 start, u64 last)
> +{
> + return interval_tree_iter_first(root, start, last);
> +}
>
> static void vhost_vdpa_pa_unmap(struct vhost_vdpa *v, u64 start, u64 last)
> {
> @@ -513,6 +560,7 @@ static void vhost_vdpa_pa_unmap(struct vhost_vdpa *v, u64 start, u64 last)
> struct vhost_iotlb_map *map;
> struct page *page;
> unsigned long pfn, pinned;
> + struct interval_tree_node *new_node = NULL;
>
> while ((map = vhost_iotlb_itree_first(iotlb, start, last)) != NULL) {
> pinned = PFN_DOWN(map->size);
> @@ -523,7 +571,18 @@ static void vhost_vdpa_pa_unmap(struct vhost_vdpa *v, u64 start, u64 last)
> set_page_dirty_lock(page);
> unpin_user_page(page);
> }
> - atomic64_sub(PFN_DOWN(map->size), &dev->mm->pinned_vm);
> +
> + new_node = vhost_vdpa_search_range(&dev->mm->root_for_vdpa,
> + map->start,
> + map->start + map->size - 1);
> +
> + if (new_node) {
> + vhost_vdpa_del_range(&dev->mm->root_for_vdpa,
> + map->start,
> + map->start + map->size - 1);
> + atomic64_sub(PFN_DOWN(map->size), &dev->mm->pinned_vm);
> + }
> +
> vhost_iotlb_map_free(iotlb, map);
> }
> }
> @@ -591,6 +650,7 @@ static int vhost_vdpa_map(struct vhost_vdpa *v, u64 iova,
> struct vdpa_device *vdpa = v->vdpa;
> const struct vdpa_config_ops *ops = vdpa->config;
> int r = 0;
> + struct interval_tree_node *new_node = NULL;
>
> r = vhost_iotlb_add_range_ctx(dev->iotlb, iova, iova + size - 1,
> pa, perm, opaque);
> @@ -611,9 +671,22 @@ static int vhost_vdpa_map(struct vhost_vdpa *v, u64 iova,
> return r;
> }
>
> - if (!vdpa->use_va)
> - atomic64_add(PFN_DOWN(size), &dev->mm->pinned_vm);
> + if (!vdpa->use_va) {
> + new_node = vhost_vdpa_search_range(&dev->mm->root_for_vdpa,
> + iova, iova + size - 1);
> +
> + if (new_node == 0) {
> + r = vhost_vdpa_add_range_ctx(&dev->mm->root_for_vdpa,
> + iova, iova + size - 1);
> + if (r) {
> + vhost_iotlb_del_range(dev->iotlb, iova,
> + iova + size - 1);
> + return r;
> + }
>
> + atomic64_add(PFN_DOWN(size), &dev->mm->pinned_vm);
> + }
This seems not sufficient, consider:
vhost-vDPA-A: add [A, B)
vhost-vDPA-B: add [A, C) (C>B)
We lose the accounting for [B, C)?
> + }
> return 0;
> }
>
> diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
> index 5140e5feb486..46eaa6d0560b 100644
> --- a/include/linux/mm_types.h
> +++ b/include/linux/mm_types.h
> @@ -634,6 +634,8 @@ struct mm_struct {
> #ifdef CONFIG_IOMMU_SUPPORT
> u32 pasid;
> #endif
> + struct rb_root_cached root_for_vdpa;
> +
Let's avoid touching mm_structure unless it's a must.
We can allocate something like vhost_mm if needed during SET_OWNER.
Thanks
> } __randomize_layout;
>
> /*
> --
> 2.34.1
>
Hi Cindy,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on mst-vhost/linux-next]
[also build test WARNING on linux/master linus/master v5.18-rc6]
[cannot apply to next-20220506]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/intel-lab-lkp/linux/commits/Cindy-Lu/vdpa-Do-not-count-the-pages-that-were-already-pinned-in-the-vhost-vDPA/20220509-152644
base: https://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost.git linux-next
config: s390-randconfig-r044-20220509 (https://download.01.org/0day-ci/archive/20220509/[email protected]/config)
compiler: s390-linux-gcc (GCC) 11.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/4225cc2a756b75d1e0ff7ca2a593bada42def380
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Cindy-Lu/vdpa-Do-not-count-the-pages-that-were-already-pinned-in-the-vhost-vDPA/20220509-152644
git checkout 4225cc2a756b75d1e0ff7ca2a593bada42def380
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-11.3.0 make.cross W=1 O=build_dir ARCH=s390 SHELL=/bin/bash drivers/vhost/
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <[email protected]>
All warnings (new ones prefixed by >>):
>> drivers/vhost/vdpa.c:542:5: warning: no previous prototype for 'vhost_vdpa_add_range_ctx' [-Wmissing-prototypes]
542 | int vhost_vdpa_add_range_ctx(struct rb_root_cached *root, u64 start, u64 last)
| ^~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/vhost/vdpa.c:571:6: warning: no previous prototype for 'vhost_vdpa_del_range' [-Wmissing-prototypes]
571 | void vhost_vdpa_del_range(struct rb_root_cached *root, u64 start, u64 last)
| ^~~~~~~~~~~~~~~~~~~~
>> drivers/vhost/vdpa.c:581:28: warning: no previous prototype for 'vhost_vdpa_search_range' [-Wmissing-prototypes]
581 | struct interval_tree_node *vhost_vdpa_search_range(struct rb_root_cached *root,
| ^~~~~~~~~~~~~~~~~~~~~~~
vim +/vhost_vdpa_add_range_ctx +542 drivers/vhost/vdpa.c
464
465 static long vhost_vdpa_unlocked_ioctl(struct file *filep,
466 unsigned int cmd, unsigned long arg)
467 {
468 struct vhost_vdpa *v = filep->private_data;
469 struct vhost_dev *d = &v->vdev;
470 void __user *argp = (void __user *)arg;
471 u64 __user *featurep = argp;
472 u64 features;
473 long r = 0;
474
475 if (cmd == VHOST_SET_BACKEND_FEATURES) {
476 if (copy_from_user(&features, featurep, sizeof(features)))
477 return -EFAULT;
478 if (features & ~VHOST_VDPA_BACKEND_FEATURES)
479 return -EOPNOTSUPP;
480 vhost_set_backend_features(&v->vdev, features);
481 return 0;
482 }
483
484 mutex_lock(&d->mutex);
485
486 switch (cmd) {
487 case VHOST_VDPA_GET_DEVICE_ID:
488 r = vhost_vdpa_get_device_id(v, argp);
489 break;
490 case VHOST_VDPA_GET_STATUS:
491 r = vhost_vdpa_get_status(v, argp);
492 break;
493 case VHOST_VDPA_SET_STATUS:
494 r = vhost_vdpa_set_status(v, argp);
495 break;
496 case VHOST_VDPA_GET_CONFIG:
497 r = vhost_vdpa_get_config(v, argp);
498 break;
499 case VHOST_VDPA_SET_CONFIG:
500 r = vhost_vdpa_set_config(v, argp);
501 break;
502 case VHOST_GET_FEATURES:
503 r = vhost_vdpa_get_features(v, argp);
504 break;
505 case VHOST_SET_FEATURES:
506 r = vhost_vdpa_set_features(v, argp);
507 break;
508 case VHOST_VDPA_GET_VRING_NUM:
509 r = vhost_vdpa_get_vring_num(v, argp);
510 break;
511 case VHOST_SET_LOG_BASE:
512 case VHOST_SET_LOG_FD:
513 r = -ENOIOCTLCMD;
514 break;
515 case VHOST_VDPA_SET_CONFIG_CALL:
516 r = vhost_vdpa_set_config_call(v, argp);
517 break;
518 case VHOST_GET_BACKEND_FEATURES:
519 features = VHOST_VDPA_BACKEND_FEATURES;
520 if (copy_to_user(featurep, &features, sizeof(features)))
521 r = -EFAULT;
522 break;
523 case VHOST_VDPA_GET_IOVA_RANGE:
524 r = vhost_vdpa_get_iova_range(v, argp);
525 break;
526 case VHOST_VDPA_GET_CONFIG_SIZE:
527 r = vhost_vdpa_get_config_size(v, argp);
528 break;
529 case VHOST_VDPA_GET_VQS_COUNT:
530 r = vhost_vdpa_get_vqs_count(v, argp);
531 break;
532 default:
533 r = vhost_dev_ioctl(&v->vdev, cmd, argp);
534 if (r == -ENOIOCTLCMD)
535 r = vhost_vdpa_vring_ioctl(v, cmd, argp);
536 break;
537 }
538
539 mutex_unlock(&d->mutex);
540 return r;
541 }
> 542 int vhost_vdpa_add_range_ctx(struct rb_root_cached *root, u64 start, u64 last)
543 {
544 struct interval_tree_node *new_node;
545
546 if (last < start)
547 return -EFAULT;
548
549 /* If the range being mapped is [0, ULONG_MAX], split it into two entries
550 * otherwise its size would overflow u64.
551 */
552 if (start == 0 && last == ULONG_MAX) {
553 u64 mid = last / 2;
554
555 vhost_vdpa_add_range_ctx(root, start, mid);
556 start = mid + 1;
557 }
558
559 new_node = kmalloc(sizeof(struct interval_tree_node), GFP_ATOMIC);
560 if (!new_node)
561 return -ENOMEM;
562
563 new_node->start = start;
564 new_node->last = last;
565
566 interval_tree_insert(new_node, root);
567
568 return 0;
569 }
570
> 571 void vhost_vdpa_del_range(struct rb_root_cached *root, u64 start, u64 last)
572 {
573 struct interval_tree_node *new_node;
574
575 while ((new_node = interval_tree_iter_first(root, start, last))) {
576 interval_tree_remove(new_node, root);
577 kfree(new_node);
578 }
579 }
580
> 581 struct interval_tree_node *vhost_vdpa_search_range(struct rb_root_cached *root,
582 u64 start, u64 last)
583 {
584 return interval_tree_iter_first(root, start, last);
585 }
586
--
0-DAY CI Kernel Test Service
https://01.org/lkp
Hi Cindy,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on mst-vhost/linux-next]
[also build test WARNING on linux/master linus/master v5.18-rc6]
[cannot apply to next-20220506]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/intel-lab-lkp/linux/commits/Cindy-Lu/vdpa-Do-not-count-the-pages-that-were-already-pinned-in-the-vhost-vDPA/20220509-152644
base: https://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost.git linux-next
config: x86_64-randconfig-c007-20220509 (https://download.01.org/0day-ci/archive/20220509/[email protected]/config)
compiler: clang version 15.0.0 (https://github.com/llvm/llvm-project a385645b470e2d3a1534aae618ea56b31177639f)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/4225cc2a756b75d1e0ff7ca2a593bada42def380
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Cindy-Lu/vdpa-Do-not-count-the-pages-that-were-already-pinned-in-the-vhost-vDPA/20220509-152644
git checkout 4225cc2a756b75d1e0ff7ca2a593bada42def380
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash drivers/vhost/
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <[email protected]>
All warnings (new ones prefixed by >>):
>> drivers/vhost/vdpa.c:542:5: warning: no previous prototype for function 'vhost_vdpa_add_range_ctx' [-Wmissing-prototypes]
int vhost_vdpa_add_range_ctx(struct rb_root_cached *root, u64 start, u64 last)
^
drivers/vhost/vdpa.c:542:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
int vhost_vdpa_add_range_ctx(struct rb_root_cached *root, u64 start, u64 last)
^
static
>> drivers/vhost/vdpa.c:571:6: warning: no previous prototype for function 'vhost_vdpa_del_range' [-Wmissing-prototypes]
void vhost_vdpa_del_range(struct rb_root_cached *root, u64 start, u64 last)
^
drivers/vhost/vdpa.c:571:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
void vhost_vdpa_del_range(struct rb_root_cached *root, u64 start, u64 last)
^
static
>> drivers/vhost/vdpa.c:581:28: warning: no previous prototype for function 'vhost_vdpa_search_range' [-Wmissing-prototypes]
struct interval_tree_node *vhost_vdpa_search_range(struct rb_root_cached *root,
^
drivers/vhost/vdpa.c:581:1: note: declare 'static' if the function is not intended to be used outside of this translation unit
struct interval_tree_node *vhost_vdpa_search_range(struct rb_root_cached *root,
^
static
3 warnings generated.
vim +/vhost_vdpa_add_range_ctx +542 drivers/vhost/vdpa.c
464
465 static long vhost_vdpa_unlocked_ioctl(struct file *filep,
466 unsigned int cmd, unsigned long arg)
467 {
468 struct vhost_vdpa *v = filep->private_data;
469 struct vhost_dev *d = &v->vdev;
470 void __user *argp = (void __user *)arg;
471 u64 __user *featurep = argp;
472 u64 features;
473 long r = 0;
474
475 if (cmd == VHOST_SET_BACKEND_FEATURES) {
476 if (copy_from_user(&features, featurep, sizeof(features)))
477 return -EFAULT;
478 if (features & ~VHOST_VDPA_BACKEND_FEATURES)
479 return -EOPNOTSUPP;
480 vhost_set_backend_features(&v->vdev, features);
481 return 0;
482 }
483
484 mutex_lock(&d->mutex);
485
486 switch (cmd) {
487 case VHOST_VDPA_GET_DEVICE_ID:
488 r = vhost_vdpa_get_device_id(v, argp);
489 break;
490 case VHOST_VDPA_GET_STATUS:
491 r = vhost_vdpa_get_status(v, argp);
492 break;
493 case VHOST_VDPA_SET_STATUS:
494 r = vhost_vdpa_set_status(v, argp);
495 break;
496 case VHOST_VDPA_GET_CONFIG:
497 r = vhost_vdpa_get_config(v, argp);
498 break;
499 case VHOST_VDPA_SET_CONFIG:
500 r = vhost_vdpa_set_config(v, argp);
501 break;
502 case VHOST_GET_FEATURES:
503 r = vhost_vdpa_get_features(v, argp);
504 break;
505 case VHOST_SET_FEATURES:
506 r = vhost_vdpa_set_features(v, argp);
507 break;
508 case VHOST_VDPA_GET_VRING_NUM:
509 r = vhost_vdpa_get_vring_num(v, argp);
510 break;
511 case VHOST_SET_LOG_BASE:
512 case VHOST_SET_LOG_FD:
513 r = -ENOIOCTLCMD;
514 break;
515 case VHOST_VDPA_SET_CONFIG_CALL:
516 r = vhost_vdpa_set_config_call(v, argp);
517 break;
518 case VHOST_GET_BACKEND_FEATURES:
519 features = VHOST_VDPA_BACKEND_FEATURES;
520 if (copy_to_user(featurep, &features, sizeof(features)))
521 r = -EFAULT;
522 break;
523 case VHOST_VDPA_GET_IOVA_RANGE:
524 r = vhost_vdpa_get_iova_range(v, argp);
525 break;
526 case VHOST_VDPA_GET_CONFIG_SIZE:
527 r = vhost_vdpa_get_config_size(v, argp);
528 break;
529 case VHOST_VDPA_GET_VQS_COUNT:
530 r = vhost_vdpa_get_vqs_count(v, argp);
531 break;
532 default:
533 r = vhost_dev_ioctl(&v->vdev, cmd, argp);
534 if (r == -ENOIOCTLCMD)
535 r = vhost_vdpa_vring_ioctl(v, cmd, argp);
536 break;
537 }
538
539 mutex_unlock(&d->mutex);
540 return r;
541 }
> 542 int vhost_vdpa_add_range_ctx(struct rb_root_cached *root, u64 start, u64 last)
543 {
544 struct interval_tree_node *new_node;
545
546 if (last < start)
547 return -EFAULT;
548
549 /* If the range being mapped is [0, ULONG_MAX], split it into two entries
550 * otherwise its size would overflow u64.
551 */
552 if (start == 0 && last == ULONG_MAX) {
553 u64 mid = last / 2;
554
555 vhost_vdpa_add_range_ctx(root, start, mid);
556 start = mid + 1;
557 }
558
559 new_node = kmalloc(sizeof(struct interval_tree_node), GFP_ATOMIC);
560 if (!new_node)
561 return -ENOMEM;
562
563 new_node->start = start;
564 new_node->last = last;
565
566 interval_tree_insert(new_node, root);
567
568 return 0;
569 }
570
> 571 void vhost_vdpa_del_range(struct rb_root_cached *root, u64 start, u64 last)
572 {
573 struct interval_tree_node *new_node;
574
575 while ((new_node = interval_tree_iter_first(root, start, last))) {
576 interval_tree_remove(new_node, root);
577 kfree(new_node);
578 }
579 }
580
> 581 struct interval_tree_node *vhost_vdpa_search_range(struct rb_root_cached *root,
582 u64 start, u64 last)
583 {
584 return interval_tree_iter_first(root, start, last);
585 }
586
--
0-DAY CI Kernel Test Service
https://01.org/lkp
Hi Cindy,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on mst-vhost/linux-next]
[also build test ERROR on linux/master linus/master v5.18-rc6]
[cannot apply to next-20220506]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]
url: https://github.com/intel-lab-lkp/linux/commits/Cindy-Lu/vdpa-Do-not-count-the-pages-that-were-already-pinned-in-the-vhost-vDPA/20220509-152644
base: https://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost.git linux-next
config: x86_64-randconfig-a014-20220509 (https://download.01.org/0day-ci/archive/20220509/[email protected]/config)
compiler: gcc-11 (Debian 11.2.0-20) 11.2.0
reproduce (this is a W=1 build):
# https://github.com/intel-lab-lkp/linux/commit/4225cc2a756b75d1e0ff7ca2a593bada42def380
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Cindy-Lu/vdpa-Do-not-count-the-pages-that-were-already-pinned-in-the-vhost-vDPA/20220509-152644
git checkout 4225cc2a756b75d1e0ff7ca2a593bada42def380
# save the config file
mkdir build_dir && cp config build_dir/.config
make W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash
If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <[email protected]>
All errors (new ones prefixed by >>, old ones prefixed by <<):
>> ERROR: modpost: "interval_tree_remove" [drivers/vhost/vhost_vdpa.ko] undefined!
>> ERROR: modpost: "interval_tree_insert" [drivers/vhost/vhost_vdpa.ko] undefined!
>> ERROR: modpost: "interval_tree_iter_first" [drivers/vhost/vhost_vdpa.ko] undefined!
--
0-DAY CI Kernel Test Service
https://01.org/lkp