drm_gpuvm_fo...a_range_safe(9)
π
drm_gpuvm_for_each_va_range_safe β the safe range-walker (Kernel API Manual, section 9, bestie β¨)
okay so real talk: this is a kernel macro from the Kernel API Manual, section 9, and it's literally the "walk a slice of the VA tree without things exploding mid-loop" icon. let's get into it π«Ά
β¨ NAME β¨
drm_gpuvm_for_each_va_range_safe β safely iterate over a range of &drm_gpuvas
πΈ SYNOPSIS πΈ
drm_gpuvm_for_each_va_range_safe (va__ , next__ , gpuvm__ , start__ ,
end__ );
π ARGUMENTS π
va__β thedrm_gpuvayou assign to on every iteration step. this is your main character of the loop πnext__β anotherdrm_gpuvathat you keep around as temporary storage. it's the understudy, the safety net, the reason you can delete stuff mid-loop without crying πgpuvm__β thedrm_gpuvmyou're walking overstart__β starting offset; the first gpuva will overlap thisend__β ending offset; the last gpuva will start before this (but it may overlap, no cap)
π¦ DESCRIPTION π¦
so basically this iterator walks over all the drm_gpuvas in the drm_gpuvm that lie between start__ and end__. it's built similarly to list_for_each_safe, but plot twist β it uses the drm_gpuvm's internal interval tree to accelerate the search for the starting drm_gpuva, which is exactly why it's safe against removal of elements. you can yeet a gpuva out of the collection while you're iterating and it will not catch fire π₯
β οΈ it assumes thatend__is within (or is the upper limit of) thedrm_gpuvm. don't come for this macro if you hand it anend__from somewhere else, fr fr π
π also important: this iterator does not skip over the drm_gpuvm's kernel_alloc_node. so yeah, that node will show up in your loop. known behaviour, not a bug, iykyk.
π SEE ALSO π
Kernel file ./include/drm/drm_gpuvm.h, plus the whole friend group:
enum drm_gpuva_flags(9)struct drm_gpuva(9)drm_gpuva_invalidate(9)drm_gpuva_invalidated(9)enum drm_gpuvm_flags(9)struct drm_gpuvm(9)drm_gpuvm_get(9)drm_gpuvm_resv_protected(9)drm_gpuvm_immediate_mode(9)drm_gpuvm_resv(9)drm_gpuvm_resv_obj(9)drm_gpuvm_is_extobj(9)drm_gpuvm_for_each_va_range(9)drm_gpuvm_for_each_va(9)drm_gpuvm_for_each_va_safe(9)struct drm_gpuvm_exec(9)drm_gpuvm_exec_unlock(9)drm_gpuvm_exec_resv_add_fence(9)drm_gpuvm_exec_validate(9)struct drm_gpuvm_bo(9)drm_gpuvm_bo_get(9)drm_gpuvm_bo_gem_evict(9)drm_gpuvm_bo_for_each_va(9)drm_gpuvm_bo_for_each_va_safe(9)enum drm_gpuva_op_type(9)struct drm_gpuva_op_map(9)struct drm_gpuva_op_unmap(9)struct drm_gpuva_op_remap(9)struct drm_gpuva_op_prefetch(9)struct drm_gpuva_op(9)struct drm_gpuva_ops(9)drm_gpuva_for_each_op(9)drm_gpuva_for_each_op_safe(9)drm_gpuva_for_each_op_from_reverse(9)drm_gpuva_for_each_op_reverse(9)drm_gpuva_first_op(9)drm_gpuva_last_op(9)drm_gpuva_prev_op(9)drm_gpuva_next_op(9)struct drm_gpuvm_map_req(9)struct drm_gpuvm_ops(9)drm_gpuva_op_remap_to_unmap_range(9)
and that's the whole vibe check bestie π this page lives in ./include/drm, dated October 2026, and it's serving drm_gpuvm_fo...a_range_safe(9) realness. go read your interval trees, ily, mwah πβ¨
π¦ where this page comes from
- nixpkgs unstable: linux-manual 7.3.1
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms