drivers/gpu/drm/i915/gt/gen8_ppgtt.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/i915/gt/gen8_ppgtt.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/i915/gt/gen8_ppgtt.c- Extension
.c- Size
- 28015 bytes
- Lines
- 1086
- Domain
- Driver Families
- Bucket
- drivers/gpu
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- 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/log2.hgem/i915_gem_internal.hgem/i915_gem_lmem.hgen8_ppgtt.hi915_scatterlist.hi915_trace.hi915_pvinfo.hi915_vgpu.hintel_gt.hintel_gtt.h
Detected Declarations
function gen8_pde_encodefunction gen8_pte_encodefunction gen12_pte_encodefunction gen8_ppgtt_notify_vgtfunction gen8_pd_rangefunction gen8_pd_containsfunction gen8_pt_countfunction gen8_pd_top_countfunction gen8_pdp_for_page_indexfunction gen8_pdp_for_page_addressfunction __gen8_ppgtt_cleanupfunction gen8_ppgtt_cleanupfunction __gen8_ppgtt_clearfunction gen8_ppgtt_clearfunction __gen8_ppgtt_allocfunction gen8_ppgtt_allocfunction __gen8_ppgtt_foreachfunction gen8_ppgtt_foreachfunction gen8_ppgtt_insert_ptefunction xehp_ppgtt_insert_hugefunction gen8_ppgtt_insert_hugefunction gen8_ppgtt_insertfunction gen8_ppgtt_insert_entryfunction xehp_ppgtt_insert_entry_lmfunction xehp_ppgtt_insert_entryfunction gen8_init_scratchfunction gen8_preallocate_top_level_pdpfunction gen8_alloc_top_pdfunction gen8_init_rsvd
Annotated Snippet
gen8_pd_contains(start, end, lvl)) {
GTT_TRACE("%s(%p):{ lvl:%d, idx:%d, start:%llx, end:%llx } removing pd\n",
__func__, vm, lvl + 1, idx, start, end);
clear_pd_entry(pd, idx, scratch);
__gen8_ppgtt_cleanup(vm, as_pd(pt), I915_PDES, lvl);
start += (u64)I915_PDES << gen8_pd_shift(lvl);
continue;
}
if (lvl) {
start = __gen8_ppgtt_clear(vm, as_pd(pt),
start, end, lvl);
} else {
unsigned int count;
unsigned int pte = gen8_pd_index(start, 0);
unsigned int num_ptes;
u64 *vaddr;
count = gen8_pt_count(start, end);
GTT_TRACE("%s(%p):{ lvl:%d, start:%llx, end:%llx, idx:%d, len:%d, used:%d } removing pte\n",
__func__, vm, lvl, start, end,
gen8_pd_index(start, 0), count,
atomic_read(&pt->used));
GEM_BUG_ON(!count || count >= atomic_read(&pt->used));
num_ptes = count;
if (pt->is_compact) {
GEM_BUG_ON(num_ptes % 16);
GEM_BUG_ON(pte % 16);
num_ptes /= 16;
pte /= 16;
}
vaddr = px_vaddr(pt);
memset64(vaddr + pte,
vm->scratch[0]->encode,
num_ptes);
atomic_sub(count, &pt->used);
start += count;
}
if (release_pd_entry(pd, idx, pt, scratch))
free_px(vm, pt, lvl);
} while (idx++, --len);
return start;
}
static void gen8_ppgtt_clear(struct i915_address_space *vm,
u64 start, u64 length)
{
GEM_BUG_ON(!IS_ALIGNED(start, BIT_ULL(GEN8_PTE_SHIFT)));
GEM_BUG_ON(!IS_ALIGNED(length, BIT_ULL(GEN8_PTE_SHIFT)));
GEM_BUG_ON(range_overflows(start, length, vm->total));
start >>= GEN8_PTE_SHIFT;
length >>= GEN8_PTE_SHIFT;
GEM_BUG_ON(length == 0);
__gen8_ppgtt_clear(vm, i915_vm_to_ppgtt(vm)->pd,
start, start + length, vm->top);
}
static void __gen8_ppgtt_alloc(struct i915_address_space * const vm,
struct i915_vm_pt_stash *stash,
struct i915_page_directory * const pd,
u64 * const start, const u64 end, int lvl)
{
unsigned int idx, len;
GEM_BUG_ON(end > vm->total >> GEN8_PTE_SHIFT);
len = gen8_pd_range(*start, end, lvl--, &idx);
GTT_TRACE("%s(%p):{ lvl:%d, start:%llx, end:%llx, idx:%d, len:%d, used:%d }\n",
__func__, vm, lvl + 1, *start, end,
idx, len, atomic_read(px_used(pd)));
GEM_BUG_ON(!len || (idx + len - 1) >> gen8_pd_shift(1));
spin_lock(&pd->lock);
GEM_BUG_ON(!atomic_read(px_used(pd))); /* Must be pinned! */
do {
struct i915_page_table *pt = pd->entry[idx];
if (!pt) {
spin_unlock(&pd->lock);
GTT_TRACE("%s(%p):{ lvl:%d, idx:%d } allocating new tree\n",
__func__, vm, lvl + 1, idx);
Annotation
- Immediate include surface: `linux/log2.h`, `gem/i915_gem_internal.h`, `gem/i915_gem_lmem.h`, `gen8_ppgtt.h`, `i915_scatterlist.h`, `i915_trace.h`, `i915_pvinfo.h`, `i915_vgpu.h`.
- Detected declarations: `function gen8_pde_encode`, `function gen8_pte_encode`, `function gen12_pte_encode`, `function gen8_ppgtt_notify_vgt`, `function gen8_pd_range`, `function gen8_pd_contains`, `function gen8_pt_count`, `function gen8_pd_top_count`, `function gen8_pdp_for_page_index`, `function gen8_pdp_for_page_address`.
- Atlas domain: Driver Families / drivers/gpu.
- Implementation status: source 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.