udmabuf: revert 'Add support for mapping hugepages (v4)'
authorMike Kravetz <mike.kravetz@oracle.com>
Thu, 8 Jun 2023 20:49:27 +0000 (13:49 -0700)
committerAndrew Morton <akpm@linux-foundation.org>
Mon, 19 Jun 2023 20:19:32 +0000 (13:19 -0700)
This effectively reverts commit 16c243e99d33 ("udmabuf: Add support for
mapping hugepages (v4)").  Recently, Junxiao Chang found a BUG with page
map counting as described here [1].  This issue pointed out that the
udmabuf driver was making direct use of subpages of hugetlb pages.  This
is not a good idea, and no other mm code attempts such use.  In addition
to the mapcount issue, this also causes issues with hugetlb vmemmap
optimization and page poisoning.

For now, remove hugetlb support.

If udmabuf wants to be used on hugetlb mappings, it should be changed to
only use complete hugetlb pages.  This will require different alignment
and size requirements on the UDMABUF_CREATE API.

[1] https://lore.kernel.org/linux-mm/20230512072036.1027784-1-junxiao.chang@intel.com/

Link: https://lkml.kernel.org/r/20230608204927.88711-1-mike.kravetz@oracle.com
Fixes: 16c243e99d33 ("udmabuf: Add support for mapping hugepages (v4)")
Signed-off-by: Mike Kravetz <mike.kravetz@oracle.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Acked-by: Vivek Kasireddy <vivek.kasireddy@intel.com>
Acked-by: Gerd Hoffmann <kraxel@redhat.com>
Cc: David Hildenbrand <david@redhat.com>
Cc: Dongwon Kim <dongwon.kim@intel.com>
Cc: James Houghton <jthoughton@google.com>
Cc: Jerome Marchand <jmarchan@redhat.com>
Cc: Junxiao Chang <junxiao.chang@intel.com>
Cc: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
drivers/dma-buf/udmabuf.c

index 01f2e86..12cf6bb 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/shmem_fs.h>
 #include <linux/slab.h>
 #include <linux/udmabuf.h>
-#include <linux/hugetlb.h>
 #include <linux/vmalloc.h>
 #include <linux/iosys-map.h>
 
@@ -207,9 +206,7 @@ static long udmabuf_create(struct miscdevice *device,
        struct udmabuf *ubuf;
        struct dma_buf *buf;
        pgoff_t pgoff, pgcnt, pgidx, pgbuf = 0, pglimit;
-       struct page *page, *hpage = NULL;
-       pgoff_t subpgoff, maxsubpgs;
-       struct hstate *hpstate;
+       struct page *page;
        int seals, ret = -EINVAL;
        u32 i, flags;
 
@@ -245,7 +242,7 @@ static long udmabuf_create(struct miscdevice *device,
                if (!memfd)
                        goto err;
                mapping = memfd->f_mapping;
-               if (!shmem_mapping(mapping) && !is_file_hugepages(memfd))
+               if (!shmem_mapping(mapping))
                        goto err;
                seals = memfd_fcntl(memfd, F_GET_SEALS, 0);
                if (seals == -EINVAL)
@@ -256,48 +253,16 @@ static long udmabuf_create(struct miscdevice *device,
                        goto err;
                pgoff = list[i].offset >> PAGE_SHIFT;
                pgcnt = list[i].size   >> PAGE_SHIFT;
-               if (is_file_hugepages(memfd)) {
-                       hpstate = hstate_file(memfd);
-                       pgoff = list[i].offset >> huge_page_shift(hpstate);
-                       subpgoff = (list[i].offset &
-                                   ~huge_page_mask(hpstate)) >> PAGE_SHIFT;
-                       maxsubpgs = huge_page_size(hpstate) >> PAGE_SHIFT;
-               }
                for (pgidx = 0; pgidx < pgcnt; pgidx++) {
-                       if (is_file_hugepages(memfd)) {
-                               if (!hpage) {
-                                       hpage = find_get_page_flags(mapping, pgoff,
-                                                                   FGP_ACCESSED);
-                                       if (!hpage) {
-                                               ret = -EINVAL;
-                                               goto err;
-                                       }
-                               }
-                               page = hpage + subpgoff;
-                               get_page(page);
-                               subpgoff++;
-                               if (subpgoff == maxsubpgs) {
-                                       put_page(hpage);
-                                       hpage = NULL;
-                                       subpgoff = 0;
-                                       pgoff++;
-                               }
-                       } else {
-                               page = shmem_read_mapping_page(mapping,
-                                                              pgoff + pgidx);
-                               if (IS_ERR(page)) {
-                                       ret = PTR_ERR(page);
-                                       goto err;
-                               }
+                       page = shmem_read_mapping_page(mapping, pgoff + pgidx);
+                       if (IS_ERR(page)) {
+                               ret = PTR_ERR(page);
+                               goto err;
                        }
                        ubuf->pages[pgbuf++] = page;
                }
                fput(memfd);
                memfd = NULL;
-               if (hpage) {
-                       put_page(hpage);
-                       hpage = NULL;
-               }
        }
 
        exp_info.ops  = &udmabuf_ops;