Commit 87fcafc4 authored by Andrew Morton's avatar Andrew Morton
Browse files

Merge branch 'mm-hotfixes-stable' into mm-stable in order to merge

"mm/huge_memory: only get folio_order() once during __folio_split()" into
mm-stable.
parents c7ba92bc 7c9580f4
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -689,6 +689,8 @@ Sachin Mokashi <sachin.mokashi@intel.com> <sachinx.mokashi@intel.com>
Sachin P Sant <ssant@in.ibm.com>
Sai Prakash Ranjan <quic_saipraka@quicinc.com> <saiprakash.ranjan@codeaurora.org>
Sakari Ailus <sakari.ailus@linux.intel.com> <sakari.ailus@iki.fi>
Sam Protsenko <semen.protsenko@linaro.org>
Sam Protsenko <semen.protsenko@linaro.org> <semen.protsenko@globallogic.com>
Sam Ravnborg <sam@mars.ravnborg.org>
Sankeerth Billakanti <quic_sbillaka@quicinc.com> <sbillaka@codeaurora.org>
Santosh Shilimkar <santosh.shilimkar@oracle.org>
+1 −0
Original line number Diff line number Diff line
@@ -13801,6 +13801,7 @@ F: Documentation/admin-guide/mm/kho.rst
F:	Documentation/core-api/kho/*
F:	include/linux/kexec_handover.h
F:	kernel/kexec_handover.c
F:	lib/test_kho.c
F:	tools/testing/selftests/kho/
KEYS-ENCRYPTED
+14 −13
Original line number Diff line number Diff line
@@ -3691,8 +3691,9 @@ static vm_fault_t filemap_map_folio_range(struct vm_fault *vmf,
			struct folio *folio, unsigned long start,
			unsigned long addr, unsigned int nr_pages,
			unsigned long *rss, unsigned short *mmap_miss,
			bool can_map_large)
			pgoff_t file_end)
{
	struct address_space *mapping = folio->mapping;
	unsigned int ref_from_caller = 1;
	vm_fault_t ret = 0;
	struct page *page = folio_page(folio, start);
@@ -3701,12 +3702,16 @@ static vm_fault_t filemap_map_folio_range(struct vm_fault *vmf,
	unsigned long addr0;

	/*
	 * Map the large folio fully where possible.
	 * Map the large folio fully where possible:
	 *
	 * The folio must not cross VMA or page table boundary.
	 *  - The folio is fully within size of the file or belong
	 *    to shmem/tmpfs;
	 *  - The folio doesn't cross VMA boundary;
	 *  - The folio doesn't cross page table boundary;
	 */
	addr0 = addr - start * PAGE_SIZE;
	if (can_map_large && folio_within_vma(folio, vmf->vma) &&
	if ((file_end >= folio_next_index(folio) || shmem_mapping(mapping)) &&
	    folio_within_vma(folio, vmf->vma) &&
	    (addr0 & PMD_MASK) == ((addr0 + folio_size(folio) - 1) & PMD_MASK)) {
		vmf->pte -= start;
		page -= start;
@@ -3821,7 +3826,6 @@ vm_fault_t filemap_map_pages(struct vm_fault *vmf,
	unsigned long rss = 0;
	unsigned int nr_pages = 0, folio_type;
	unsigned short mmap_miss = 0, mmap_miss_saved;
	bool can_map_large;

	rcu_read_lock();
	folio = next_uptodate_folio(&xas, mapping, end_pgoff);
@@ -3832,16 +3836,14 @@ vm_fault_t filemap_map_pages(struct vm_fault *vmf,
	end_pgoff = min(end_pgoff, file_end);

	/*
	 * Do not allow to map with PTEs beyond i_size and with PMD
	 * across i_size to preserve SIGBUS semantics.
	 * Do not allow to map with PMD across i_size to preserve
	 * SIGBUS semantics.
	 *
	 * Make an exception for shmem/tmpfs that for long time
	 * intentionally mapped with PMDs across i_size.
	 */
	can_map_large = shmem_mapping(mapping) ||
		file_end >= folio_next_index(folio);

	if (can_map_large && filemap_map_pmd(vmf, folio, start_pgoff)) {
	if ((file_end >= folio_next_index(folio) || shmem_mapping(mapping)) &&
	    filemap_map_pmd(vmf, folio, start_pgoff)) {
		ret = VM_FAULT_NOPAGE;
		goto out;
	}
@@ -3870,8 +3872,7 @@ vm_fault_t filemap_map_pages(struct vm_fault *vmf,
		else
			ret |= filemap_map_folio_range(vmf, folio,
					xas.xa_index - folio->index, addr,
					nr_pages, &rss, &mmap_miss,
					can_map_large);
					nr_pages, &rss, &mmap_miss, file_end);

		folio_unlock(folio);
	} while ((folio = next_uptodate_folio(&xas, mapping, end_pgoff)) != NULL);
+10 −12
Original line number Diff line number Diff line
@@ -3560,6 +3560,16 @@ static int __folio_split(struct folio *folio, unsigned int new_order,
	if (folio != page_folio(split_at) || folio != page_folio(lock_at))
		return -EINVAL;

	/*
	 * Folios that just got truncated cannot get split. Signal to the
	 * caller that there was a race.
	 *
	 * TODO: this will also currently refuse shmem folios that are in the
	 * swapcache.
	 */
	if (!is_anon && !folio->mapping)
		return -EBUSY;

	if (new_order >= folio_order(folio))
		return -EINVAL;

@@ -3600,18 +3610,6 @@ static int __folio_split(struct folio *folio, unsigned int new_order,
		gfp_t gfp;

		mapping = folio->mapping;

		/* Truncated ? */
		/*
		 * TODO: add support for large shmem folio in swap cache.
		 * When shmem is in swap cache, mapping is NULL and
		 * folio_test_swapcache() is true.
		 */
		if (!mapping) {
			ret = -EBUSY;
			goto out;
		}

		min_order = mapping_min_folio_order(folio->mapping);
		if (new_order < min_order) {
			ret = -EINVAL;
+27 −0
Original line number Diff line number Diff line
@@ -96,9 +96,36 @@ struct folio *memfd_alloc_folio(struct file *memfd, pgoff_t idx)
						    NULL,
						    gfp_mask);
		if (folio) {
			u32 hash;

			/*
			 * Zero the folio to prevent information leaks to userspace.
			 * Use folio_zero_user() which is optimized for huge/gigantic
			 * pages. Pass 0 as addr_hint since this is not a faulting path
			 *  and we don't have a user virtual address yet.
			 */
			folio_zero_user(folio, 0);

			/*
			 * Mark the folio uptodate before adding to page cache,
			 * as required by filemap.c and other hugetlb paths.
			 */
			__folio_mark_uptodate(folio);

			/*
			 * Serialize hugepage allocation and instantiation to prevent
			 * races with concurrent allocations, as required by all other
			 * callers of hugetlb_add_to_page_cache().
			 */
			hash = hugetlb_fault_mutex_hash(memfd->f_mapping, idx);
			mutex_lock(&hugetlb_fault_mutex_table[hash]);

			err = hugetlb_add_to_page_cache(folio,
							memfd->f_mapping,
							idx);

			mutex_unlock(&hugetlb_fault_mutex_table[hash]);

			if (err) {
				folio_put(folio);
				goto err_unresv;
Loading