mm/migrate_device.c

Source file repositories/reference/linux-study-clean/mm/migrate_device.c

File Facts

System
Linux kernel
Corpus path
mm/migrate_device.c
Extension
.c
Size
41056 bytes
Lines
1489
Domain
Core OS
Bucket
Memory Management
Inferred role
Core OS: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

IS_ALIGNED(end, HPAGE_PMD_SIZE))) {
		migrate->src[migrate->npages] = MIGRATE_PFN_MIGRATE |
						MIGRATE_PFN_COMPOUND;
		migrate->dst[migrate->npages] = 0;
		migrate->npages++;
		migrate->cpages++;

		/*
		 * Collect the remaining entries as holes, in case we
		 * need to split later
		 */
		return migrate_vma_collect_skip(start + PAGE_SIZE, end, walk);
	}

	for (addr = start; addr < end; addr += PAGE_SIZE) {
		migrate->src[migrate->npages] = MIGRATE_PFN_MIGRATE;
		migrate->dst[migrate->npages] = 0;
		migrate->npages++;
		migrate->cpages++;
	}

	return 0;
}

/**
 * migrate_vma_split_folio() - Helper function to split a THP folio
 * @folio: the folio to split
 * @fault_page: struct page associated with the fault if any
 *
 * Returns 0 on success
 */
static int migrate_vma_split_folio(struct folio *folio,
				   struct page *fault_page)
{
	int ret;
	struct folio *fault_folio = fault_page ? page_folio(fault_page) : NULL;
	struct folio *new_fault_folio = NULL;

	if (folio != fault_folio) {
		folio_get(folio);
		folio_lock(folio);
	}

	ret = split_folio(folio);
	if (ret) {
		if (folio != fault_folio) {
			folio_unlock(folio);
			folio_put(folio);
		}
		return ret;
	}

	new_fault_folio = fault_page ? page_folio(fault_page) : NULL;

	/*
	 * Ensure the lock is held on the correct
	 * folio after the split
	 */
	if (!new_fault_folio) {
		folio_unlock(folio);
		folio_put(folio);
	} else if (folio != new_fault_folio) {
		if (new_fault_folio != fault_folio) {
			folio_get(new_fault_folio);
			folio_lock(new_fault_folio);
		}
		folio_unlock(folio);
		folio_put(folio);
	}

	return 0;
}

/** migrate_vma_collect_huge_pmd - collect THP pages without splitting the
 * folio for device private pages.
 * @pmdp: pointer to pmd entry
 * @start: start address of the range for migration
 * @end: end address of the range for migration
 * @walk: mm_walk callback structure
 * @fault_folio: folio associated with the fault if any
 *
 * Collect the huge pmd entry at @pmdp for migration and set the
 * MIGRATE_PFN_COMPOUND flag in the migrate src entry to indicate that
 * migration will occur at HPAGE_PMD granularity
 */
static int migrate_vma_collect_huge_pmd(pmd_t *pmdp, unsigned long start,
					unsigned long end, struct mm_walk *walk,
					struct folio *fault_folio)
{
	struct mm_struct *mm = walk->mm;

Annotation

Implementation Notes