linuxkpi: is_vmalloc_addr() is true inside a live vmap() mapping #20

Merged
toasterson merged 1 commit from x230-lkpi-is-vmalloc-addr into main 2026-10-05 18:41:59 +00:00
Owner

is_vmalloc_addr() was false. i915 unmaps a GEM object's kernel mapping only when it is true (unmap_object() in __i915_gem_object_put_pages()), so every pinned mapping of an object outlived the object's pages: the pages were freed and their kernel mapping stayed.

On a ThinkPad X230 (HD 4000, i915n) each attach left seven such mappings. A DTrace of vmap()/vmap_pfn() and lkpi_vmap_remove() over attach, a GL client and detach showed seven maps and no removal:

3 i915_gem_object_pin_map <- intel_ring_pin <- intel_ring_submission_setup <- intel_engines_init <- intel_gt_init
2 i915_gem_object_pin_map <- ring_context_init_default_state <- ring_context_pre_pin <- __intel_context_do_pin_ww <- eb_pin_engine
1 i915_gem_object_pin_map <- gen7_setup_clear_gpr_bb <- gen7_ctx_switch_bb_setup <- gen7_ctx_switch_bb_init
1 i915_gem_object_pin_map <- copy_batch <- intel_engine_cmd_parser <- eb_parse <- i915_gem_do_execbuffer

and unloading misc/linuxkpi after three attach cycles reported linuxkpi: 26 vmap() ranges left, while lkpi_page showed no page in use.

lkpi_is_vmap_addr() looks the address up in the layer's vmap index (a mapping that starts there, or the nearest one below that covers it, contiguous mappings at the pages' own address included), and is_vmalloc_addr() is that. vmalloc() memory is kmem here and stays false; vfree()/kvfree() free either kind, and the only other user in the build, i915's shrinker (I915_SHRINK_VMAPS), wants vmap mappings. The self-test (st_vmap) checks a live mapping, the contiguous case, a removed mapping and kmalloc() memory (compiled; not run on the X230, which has no spare PCI function for the self-test driver). Host tests: 30 tests, 777 checks pass.

Tested on the X230 (branch x230-test at fb919c6): attach, 2000-frame GL run, detach: 7 maps, 7 removals; unloading linuxkpi reports no ranges left.

`is_vmalloc_addr()` was `false`. i915 unmaps a GEM object's kernel mapping only when it is true (`unmap_object()` in `__i915_gem_object_put_pages()`), so every pinned mapping of an object outlived the object's pages: the pages were freed and their kernel mapping stayed. On a ThinkPad X230 (HD 4000, i915n) each attach left seven such mappings. A DTrace of `vmap()`/`vmap_pfn()` and `lkpi_vmap_remove()` over attach, a GL client and detach showed seven maps and no removal: ``` 3 i915_gem_object_pin_map <- intel_ring_pin <- intel_ring_submission_setup <- intel_engines_init <- intel_gt_init 2 i915_gem_object_pin_map <- ring_context_init_default_state <- ring_context_pre_pin <- __intel_context_do_pin_ww <- eb_pin_engine 1 i915_gem_object_pin_map <- gen7_setup_clear_gpr_bb <- gen7_ctx_switch_bb_setup <- gen7_ctx_switch_bb_init 1 i915_gem_object_pin_map <- copy_batch <- intel_engine_cmd_parser <- eb_parse <- i915_gem_do_execbuffer ``` and unloading misc/linuxkpi after three attach cycles reported `linuxkpi: 26 vmap() ranges left`, while `lkpi_page` showed no page in use. `lkpi_is_vmap_addr()` looks the address up in the layer's vmap index (a mapping that starts there, or the nearest one below that covers it, contiguous mappings at the pages' own address included), and `is_vmalloc_addr()` is that. `vmalloc()` memory is kmem here and stays `false`; `vfree()`/`kvfree()` free either kind, and the only other user in the build, i915's shrinker (`I915_SHRINK_VMAPS`), wants vmap mappings. The self-test (`st_vmap`) checks a live mapping, the contiguous case, a removed mapping and kmalloc() memory (compiled; not run on the X230, which has no spare PCI function for the self-test driver). Host tests: 30 tests, 777 checks pass. **Tested on the X230** (branch `x230-test` at `fb919c6`): attach, 2000-frame GL run, detach: 7 maps, 7 removals; unloading linuxkpi reports no ranges left.
linuxkpi: is_vmalloc_addr() is true inside a live vmap() mapping
Some checks failed
ci / kmod-illumos (pull_request) Failing after 13m16s
ci / check-hosted (pull_request) Successful in 1h4m27s
9c6cc7b1ff
is_vmalloc_addr() was "false". i915 unmaps a GEM object's kernel
mapping only when it is true (unmap_object() in
__i915_gem_object_put_pages()), so every pinned mapping of an object
outlived the object's pages: the pages were freed, their kernel mapping
stayed. On a ThinkPad X230 (HD 4000, i915n) each attach left seven:
three ring buffers (intel_ring_pin), two context default states
(ring_context_init_default_state), the gen7 clear-GPR batch and a
command-parser shadow batch (copy_batch). A DTrace of vmap() and
lkpi_vmap_remove() over attach, a GL client and detach showed seven maps
and no removal, and misc/linuxkpi reported "26 vmap() ranges left" when
it was unloaded after three attach cycles, while lkpi_page showed no page
in use.

lkpi_is_vmap_addr() looks the address up in the layer's vmap index (a
mapping that starts there, or the nearest one below that covers it,
contiguous mappings at the pages' own address included), and
is_vmalloc_addr() is that. vmalloc() memory is kmem here and stays
"false"; vfree() and kvfree() free either kind, and the only other user
in the build, i915's shrinker (I915_SHRINK_VMAPS), wants vmap mappings.
The self-test checks a live mapping, the contiguous case, a removed
mapping and kmalloc() memory.
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
illumos/illumos-drm!20
No description provided.