virt/kvm/dirty_ring.c
Source file repositories/reference/linux-study-clean/virt/kvm/dirty_ring.c
File Facts
- System
- Linux kernel
- Corpus path
virt/kvm/dirty_ring.c- Extension
.c- Size
- 7344 bytes
- Lines
- 273
- Domain
- Kernel Services
- Bucket
- virt
- Inferred role
- Kernel Services: implementation source
- Status
- source implementation candidate
Why This File Exists
Shared kernel service surface used by multiple subsystems, including helpers, cryptography, virtualization support, and async I/O infrastructure.
- Shared kernel service surface used by multiple subsystems, including helpers, cryptography, virtualization support, and async I/O infrastructure.
- 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/kvm_host.hlinux/kvm.hlinux/vmalloc.hlinux/kvm_dirty_ring.htrace/events/kvm.hkvm_mm.h
Detected Declarations
function kvm_cpu_dirty_log_sizefunction kvm_dirty_ring_get_rsvd_entriesfunction kvm_use_dirty_bitmapfunction kvm_arch_allow_write_without_running_vcpufunction kvm_dirty_ring_usedfunction kvm_dirty_ring_soft_fullfunction kvm_dirty_ring_fullfunction kvm_reset_dirty_gfnfunction kvm_dirty_ring_allocfunction kvm_dirty_gfn_set_invalidfunction kvm_dirty_gfn_set_dirtiedfunction kvm_dirty_gfn_harvestedfunction kvm_dirty_ring_resetfunction kvm_dirty_ring_pushfunction kvm_dirty_ring_check_requestfunction kvm_dirty_ring_free
Annotated Snippet
if (mask) {
/*
* While the size of each ring is fixed, it's possible
* for the ring to be constantly re-dirtied/harvested
* while the reset is in-progress (the hard limit exists
* only to guard against the count becoming negative).
*/
cond_resched();
/*
* Try to coalesce the reset operations when the guest
* is scanning pages in the same slot.
*/
if (next_slot == cur_slot) {
s64 delta = next_offset - cur_offset;
if (delta >= 0 && delta < BITS_PER_LONG) {
mask |= 1ull << delta;
continue;
}
/* Backwards visit, careful about overflows! */
if (delta > -BITS_PER_LONG && delta < 0 &&
(mask << -delta >> -delta) == mask) {
cur_offset = next_offset;
mask = (mask << -delta) | 1;
continue;
}
}
/*
* Reset the slot for all the harvested entries that
* have been gathered, but not yet fully processed.
*/
kvm_reset_dirty_gfn(kvm, cur_slot, cur_offset, mask);
}
/*
* The current slot was reset or this is the first harvested
* entry, (re)initialize the metadata.
*/
cur_slot = next_slot;
cur_offset = next_offset;
mask = 1;
}
/*
* Perform a final reset if there are harvested entries that haven't
* been processed, which is guaranteed if at least one harvested was
* found. The loop only performs a reset when the "next" entry can't
* be batched with the "current" entry(s), and that reset processes the
* _current_ entry(s); i.e. the last harvested entry, a.k.a. next, will
* always be left pending.
*/
if (mask)
kvm_reset_dirty_gfn(kvm, cur_slot, cur_offset, mask);
/*
* The request KVM_REQ_DIRTY_RING_SOFT_FULL will be cleared
* by the VCPU thread next time when it enters the guest.
*/
trace_kvm_dirty_ring_reset(ring);
return 0;
}
void kvm_dirty_ring_push(struct kvm_vcpu *vcpu, u32 slot, u64 offset)
{
struct kvm_dirty_ring *ring = &vcpu->dirty_ring;
struct kvm_dirty_gfn *entry;
/* It should never get full */
WARN_ON_ONCE(kvm_dirty_ring_full(ring));
entry = &ring->dirty_gfns[ring->dirty_index & (ring->size - 1)];
entry->slot = slot;
entry->offset = offset;
/*
* Make sure the data is filled in before we publish this to
* the userspace program. There's no paired kernel-side reader.
*/
smp_wmb();
kvm_dirty_gfn_set_dirtied(entry);
ring->dirty_index++;
trace_kvm_dirty_ring_push(ring, slot, offset);
if (kvm_dirty_ring_soft_full(ring))
kvm_make_request(KVM_REQ_DIRTY_RING_SOFT_FULL, vcpu);
Annotation
- Immediate include surface: `linux/kvm_host.h`, `linux/kvm.h`, `linux/vmalloc.h`, `linux/kvm_dirty_ring.h`, `trace/events/kvm.h`, `kvm_mm.h`.
- Detected declarations: `function kvm_cpu_dirty_log_size`, `function kvm_dirty_ring_get_rsvd_entries`, `function kvm_use_dirty_bitmap`, `function kvm_arch_allow_write_without_running_vcpu`, `function kvm_dirty_ring_used`, `function kvm_dirty_ring_soft_full`, `function kvm_dirty_ring_full`, `function kvm_reset_dirty_gfn`, `function kvm_dirty_ring_alloc`, `function kvm_dirty_gfn_set_invalid`.
- Atlas domain: Kernel Services / virt.
- Implementation status: source implementation candidate.
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.