Commit b7cb3821 authored by Mike Kravetz's avatar Mike Kravetz Committed by Andrew Morton

udmabuf: revert 'Add support for mapping hugepages (v4)'

This effectively reverts commit 16c243e9 ("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: 16c243e9 ("udmabuf: Add support for mapping hugepages (v4)")
Signed-off-by: default avatarMike Kravetz <mike.kravetz@oracle.com>
Acked-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Acked-by: default avatarVivek Kasireddy <vivek.kasireddy@intel.com>
Acked-by: default avatarGerd 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: default avatarAndrew Morton <akpm@linux-foundation.org>
parent c8a8f3b4
...@@ -12,7 +12,6 @@ ...@@ -12,7 +12,6 @@
#include <linux/shmem_fs.h> #include <linux/shmem_fs.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/udmabuf.h> #include <linux/udmabuf.h>
#include <linux/hugetlb.h>
#include <linux/vmalloc.h> #include <linux/vmalloc.h>
#include <linux/iosys-map.h> #include <linux/iosys-map.h>
...@@ -207,9 +206,7 @@ static long udmabuf_create(struct miscdevice *device, ...@@ -207,9 +206,7 @@ static long udmabuf_create(struct miscdevice *device,
struct udmabuf *ubuf; struct udmabuf *ubuf;
struct dma_buf *buf; struct dma_buf *buf;
pgoff_t pgoff, pgcnt, pgidx, pgbuf = 0, pglimit; pgoff_t pgoff, pgcnt, pgidx, pgbuf = 0, pglimit;
struct page *page, *hpage = NULL; struct page *page;
pgoff_t subpgoff, maxsubpgs;
struct hstate *hpstate;
int seals, ret = -EINVAL; int seals, ret = -EINVAL;
u32 i, flags; u32 i, flags;
...@@ -245,7 +242,7 @@ static long udmabuf_create(struct miscdevice *device, ...@@ -245,7 +242,7 @@ static long udmabuf_create(struct miscdevice *device,
if (!memfd) if (!memfd)
goto err; goto err;
mapping = memfd->f_mapping; mapping = memfd->f_mapping;
if (!shmem_mapping(mapping) && !is_file_hugepages(memfd)) if (!shmem_mapping(mapping))
goto err; goto err;
seals = memfd_fcntl(memfd, F_GET_SEALS, 0); seals = memfd_fcntl(memfd, F_GET_SEALS, 0);
if (seals == -EINVAL) if (seals == -EINVAL)
...@@ -256,48 +253,16 @@ static long udmabuf_create(struct miscdevice *device, ...@@ -256,48 +253,16 @@ static long udmabuf_create(struct miscdevice *device,
goto err; goto err;
pgoff = list[i].offset >> PAGE_SHIFT; pgoff = list[i].offset >> PAGE_SHIFT;
pgcnt = list[i].size >> 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++) { for (pgidx = 0; pgidx < pgcnt; pgidx++) {
if (is_file_hugepages(memfd)) { page = shmem_read_mapping_page(mapping, pgoff + pgidx);
if (!hpage) { if (IS_ERR(page)) {
hpage = find_get_page_flags(mapping, pgoff, ret = PTR_ERR(page);
FGP_ACCESSED); goto err;
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;
}
} }
ubuf->pages[pgbuf++] = page; ubuf->pages[pgbuf++] = page;
} }
fput(memfd); fput(memfd);
memfd = NULL; memfd = NULL;
if (hpage) {
put_page(hpage);
hpage = NULL;
}
} }
exp_info.ops = &udmabuf_ops; exp_info.ops = &udmabuf_ops;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment