This is an automatic generated email to let you know that the following patch 
were queued:

Subject: media: vb2: frame_vector.c: don't overwrite error code
Author:  Hans Verkuil <[email protected]>
Date:    Thu Nov 11 11:56:29 2021 +0100

get_vaddr_frames() first calls pin_user_pages_fast() and if
that fails tries follow_pfn(). But if that also fails, then
the error code from pin_user_pages_fast() is overwritten with
the error code from follow_pfn().

Specifically if pin_user_pages_fast() returns -ENOMEM, then
follow_pfn() will overwrite that with -EINVAL, which is very
confusing.

So store the error code from pin_user_pages_fast() and return
that if follow_pfn() returns -EINVAL. -EINVAL indicates that
the page is unsuitable for follow_pfn, so pin_user_pages_fast()
was the correct call to make, and that error code should be
returned instead.

Signed-off-by: Hans Verkuil <[email protected]>
Signed-off-by: Mauro Carvalho Chehab <[email protected]>

 drivers/media/common/videobuf2/frame_vector.c | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

---

diff --git a/drivers/media/common/videobuf2/frame_vector.c 
b/drivers/media/common/videobuf2/frame_vector.c
index ce879f6f8f82..542dde9d2609 100644
--- a/drivers/media/common/videobuf2/frame_vector.c
+++ b/drivers/media/common/videobuf2/frame_vector.c
@@ -37,6 +37,7 @@ int get_vaddr_frames(unsigned long start, unsigned int 
nr_frames,
 {
        struct mm_struct *mm = current->mm;
        struct vm_area_struct *vma;
+       int ret_pin_user_pages_fast = 0;
        int ret = 0;
        int err;
 
@@ -56,6 +57,7 @@ int get_vaddr_frames(unsigned long start, unsigned int 
nr_frames,
                vec->is_pfns = false;
                goto out_unlocked;
        }
+       ret_pin_user_pages_fast = ret;
 
        mmap_read_lock(mm);
        vec->got_ref = false;
@@ -71,7 +73,18 @@ int get_vaddr_frames(unsigned long start, unsigned int 
nr_frames,
                while (ret < nr_frames && start + PAGE_SIZE <= vma->vm_end) {
                        err = follow_pfn(vma, start, &nums[ret]);
                        if (err) {
-                               if (ret == 0)
+                               if (ret)
+                                       goto out;
+                               // If follow_pfn() returns -EINVAL, then this
+                               // is not an IO mapping or a raw PFN mapping.
+                               // In that case, return the original error from
+                               // pin_user_pages_fast(). Otherwise this
+                               // function would return -EINVAL when
+                               // pin_user_pages_fast() returned -ENOMEM,
+                               // which makes debugging hard.
+                               if (err == -EINVAL && ret_pin_user_pages_fast)
+                                       ret = ret_pin_user_pages_fast;
+                               else
                                        ret = err;
                                goto out;
                        }

_______________________________________________
linuxtv-commits mailing list
[email protected]
https://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits

Reply via email to