mm/mmu_notifier.c
Source file repositories/reference/linux-study-clean/mm/mmu_notifier.c
File Facts
- System
- Linux kernel
- Corpus path
mm/mmu_notifier.c- Extension
.c- Size
- 36114 bytes
- Lines
- 1147
- 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.
- Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/rculist.hlinux/mmu_notifier.hlinux/export.hlinux/mm.hlinux/err.hlinux/interval_tree.hlinux/srcu.hlinux/rcupdate.hlinux/sched.hlinux/sched/mm.hlinux/slab.hvma.h
Detected Declarations
struct mmu_notifier_subscriptionsfunction invalidate_range_startfunction mn_itree_inv_start_rangefunction mn_itree_inv_nextfunction mn_itree_inv_endfunction rtnl_unlockfunction mmu_iterval_read_beginfunction mn_itree_finish_passfunction mn_itree_releasefunction mn_hlist_releasefunction __mmu_notifier_releasefunction __mmu_notifier_clear_flush_youngfunction srcu_read_lock_heldfunction __mmu_notifier_clear_youngfunction srcu_read_lock_heldfunction __mmu_notifier_test_youngfunction srcu_read_lock_heldfunction mn_itree_invalidatefunction mn_hlist_invalidate_range_startfunction srcu_read_lock_heldfunction __mmu_notifier_invalidate_range_startfunction mn_hlist_invalidate_endfunction srcu_read_lock_heldfunction __mmu_notifier_invalidate_range_endfunction __mmu_notifier_arch_invalidate_secondary_tlbsfunction srcu_read_lock_heldfunction __mmu_notifier_registerfunction get_task_mmfunction find_get_mmu_notifierfunction lockdep_is_heldfunction mmu_notifier_getfunction __mmu_notifier_subscriptions_destroyfunction mmu_notifier_unregisterfunction mmu_notifier_free_rcufunction mmu_notifier_getfunction __mmu_interval_notifier_insertfunction mmu_interval_read_beginfunction mmu_interval_notifier_insert_lockedfunction mmu_interval_seq_releasedfunction mmu_interval_notifier_insertfunction mmu_notifier_putexport mmu_interval_read_beginexport __mmu_notifier_registerexport mmu_notifier_registerexport mmu_notifier_get_lockedexport mmu_notifier_unregisterexport mmu_notifier_putexport mmu_interval_notifier_insert
Annotated Snippet
struct mmu_notifier_subscriptions {
/* all mmu notifiers registered in this mm are queued in this list */
struct hlist_head list;
bool has_itree;
/* to serialize the list modifications and hlist_unhashed */
spinlock_t lock;
unsigned long invalidate_seq;
unsigned long active_invalidate_ranges;
struct rb_root_cached itree;
wait_queue_head_t wq;
struct hlist_head deferred_list;
};
/*
* This is a collision-retry read-side/write-side 'lock', a lot like a
* seqcount, however this allows multiple write-sides to hold it at
* once. Conceptually the write side is protecting the values of the PTEs in
* this mm, such that PTES cannot be read into SPTEs (shadow PTEs) while any
* writer exists.
*
* Note that the core mm creates nested invalidate_range_start()/end() regions
* within the same thread, and runs invalidate_range_start()/end() in parallel
* on multiple CPUs. This is designed to not reduce concurrency or block
* progress on the mm side.
*
* As a secondary function, holding the full write side also serves to prevent
* writers for the itree, this is an optimization to avoid extra locking
* during invalidate_range_start/end notifiers.
*
* The write side has two states, fully excluded:
* - mm->active_invalidate_ranges != 0
* - subscriptions->invalidate_seq & 1 == True (odd)
* - some range on the mm_struct is being invalidated
* - the itree is not allowed to change
*
* And partially excluded:
* - mm->active_invalidate_ranges != 0
* - subscriptions->invalidate_seq & 1 == False (even)
* - some range on the mm_struct is being invalidated
* - the itree is allowed to change
*
* Operations on notifier_subscriptions->invalidate_seq (under spinlock):
* seq |= 1 # Begin writing
* seq++ # Release the writing state
* seq & 1 # True if a writer exists
*
* The later state avoids some expensive work on inv_end in the common case of
* no mmu_interval_notifier monitoring the VA.
*/
static bool
mn_itree_is_invalidating(struct mmu_notifier_subscriptions *subscriptions)
{
lockdep_assert_held(&subscriptions->lock);
return subscriptions->invalidate_seq & 1;
}
static struct mmu_interval_notifier *
mn_itree_inv_start_range(struct mmu_notifier_subscriptions *subscriptions,
const struct mmu_notifier_range *range,
unsigned long *seq)
{
struct interval_tree_node *node;
struct mmu_interval_notifier *res = NULL;
spin_lock(&subscriptions->lock);
subscriptions->active_invalidate_ranges++;
node = interval_tree_iter_first(&subscriptions->itree, range->start,
range->end - 1);
if (node) {
subscriptions->invalidate_seq |= 1;
res = container_of(node, struct mmu_interval_notifier,
interval_tree);
}
*seq = subscriptions->invalidate_seq;
spin_unlock(&subscriptions->lock);
return res;
}
static struct mmu_interval_notifier *
mn_itree_inv_next(struct mmu_interval_notifier *interval_sub,
const struct mmu_notifier_range *range)
{
struct interval_tree_node *node;
node = interval_tree_iter_next(&interval_sub->interval_tree,
range->start, range->end - 1);
if (!node)
return NULL;
return container_of(node, struct mmu_interval_notifier, interval_tree);
Annotation
- Immediate include surface: `linux/rculist.h`, `linux/mmu_notifier.h`, `linux/export.h`, `linux/mm.h`, `linux/err.h`, `linux/interval_tree.h`, `linux/srcu.h`, `linux/rcupdate.h`.
- Detected declarations: `struct mmu_notifier_subscriptions`, `function invalidate_range_start`, `function mn_itree_inv_start_range`, `function mn_itree_inv_next`, `function mn_itree_inv_end`, `function rtnl_unlock`, `function mmu_iterval_read_begin`, `function mn_itree_finish_pass`, `function mn_itree_release`, `function mn_hlist_release`.
- Atlas domain: Core OS / Memory Management.
- Implementation status: integration implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.