tools/testing/vma/tests/merge.c

Source file repositories/reference/linux-study-clean/tools/testing/vma/tests/merge.c

File Facts

System
Linux kernel
Corpus path
tools/testing/vma/tests/merge.c
Extension
.c
Size
41197 bytes
Lines
1487
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0-or-later

/* Helper function which provides a wrapper around a merge new VMA operation. */
static struct vm_area_struct *merge_new(struct vma_merge_struct *vmg)
{
	struct vm_area_struct *vma;
	/*
	 * For convenience, get prev and next VMAs. Which the new VMA operation
	 * requires.
	 */
	vmg->next = vma_next(vmg->vmi);
	vmg->prev = vma_prev(vmg->vmi);
	vma_iter_next_range(vmg->vmi);

	vma = vma_merge_new_range(vmg);
	if (vma)
		vma_assert_attached(vma);

	return vma;
}

/*
 * Helper function which provides a wrapper around the expansion of an existing
 * VMA.
 */
static int expand_existing(struct vma_merge_struct *vmg)
{
	return vma_expand(vmg);
}

/*
 * Helper function to reset merge state the associated VMA iterator to a
 * specified new range.
 */
void vmg_set_range(struct vma_merge_struct *vmg, unsigned long start,
		   unsigned long end, pgoff_t pgoff, vma_flags_t vma_flags)
{
	vma_iter_set(vmg->vmi, start);

	vmg->prev = NULL;
	vmg->middle = NULL;
	vmg->next = NULL;
	vmg->target = NULL;

	vmg->start = start;
	vmg->end = end;
	vmg->pgoff = pgoff;
	vmg->vma_flags = vma_flags;

	vmg->just_expand = false;
	vmg->__remove_middle = false;
	vmg->__remove_next = false;
	vmg->__adjust_middle_start = false;
	vmg->__adjust_next_start = false;
}

/* Helper function to set both the VMG range and its anon_vma. */
static void vmg_set_range_anon_vma(struct vma_merge_struct *vmg, unsigned long start,
		unsigned long end, pgoff_t pgoff, vma_flags_t vma_flags,
		struct anon_vma *anon_vma)
{
	vmg_set_range(vmg, start, end, pgoff, vma_flags);
	vmg->anon_vma = anon_vma;
}

/*
 * Helper function to try to merge a new VMA.
 *
 * Update vmg and the iterator for it and try to merge, otherwise allocate a new
 * VMA, link it to the maple tree and return it.
 */
static struct vm_area_struct *try_merge_new_vma(struct mm_struct *mm,
		struct vma_merge_struct *vmg, unsigned long start,
		unsigned long end, pgoff_t pgoff, vma_flags_t vma_flags,
		bool *was_merged)
{
	struct vm_area_struct *merged;

	vmg_set_range(vmg, start, end, pgoff, vma_flags);

	merged = merge_new(vmg);
	if (merged) {
		*was_merged = true;
		ASSERT_EQ(vmg->state, VMA_MERGE_SUCCESS);
		return merged;
	}

	*was_merged = false;

	ASSERT_EQ(vmg->state, VMA_MERGE_NOMERGE);

Annotation

Implementation Notes