summaryrefslogtreecommitdiff
path: root/drivers/gpu
AgeCommit message (Collapse)Author
2026-08-24drm/ttm: make ttm_swap_ops staticSean Chang
ttm_swap_ops is not used outside ttm_bo.c and is not exported via EXPORT_SYMBOL(), so give it static linkage to keep it file-local and avoid polluting the global symbol namespace. Signed-off-by: Sean Chang <seanwascoding@gmail.com> Link: https://lore.kernel.org/r/20260818160914.108313-3-seanwascoding@gmail.com Reviewed-by: Christian König <christian.koenig@amd.com> Signed-off-by: Christian König <christian.koenig@amd.com>
2026-08-24drm/ttm: drop stale @ctx kernel-doc entrySean Chang
ttm_bo_alloc_state no longer has a ctx member, but its kernel-doc comment still documents @ctx. Remove the stale entry so the documentation matches the struct. Signed-off-by: Sean Chang <seanwascoding@gmail.com> Link: https://lore.kernel.org/r/20260818160914.108313-2-seanwascoding@gmail.com Reviewed-by: Christian König <christian.koenig@amd.com> Signed-off-by: Christian König <christian.koenig@amd.com>
2026-08-24drm_hyperv: Remove support for synth video protocol of old Hyper-V hostsMichael Kelley
With the overall removal of Linux support for running on Hyper-V hosts earlier than WS2016 and Windows 10, it's no longer necessary to support older synthetic video protocols. Remove the support. Signed-off-by: Michael Kelley <mhklinux@outlook.com> Signed-off-by: Hamza Mahfooz <hamzamahfooz@linux.microsoft.com> Link: https://patch.msgid.link/20260805203751.2678-5-mhklinux@outlook.com
2026-08-24drm/prime: use dma_buf_fd_install() to preserve export tracingBaineng Shou
drm_gem_prime_handle_to_fd() open-codes fd reservation and install using get_unused_fd_flags() + fd_install() directly. This bypasses the DMA_BUF_TRACE() call that dma_buf_fd() emits, so observability tools relying on the trace_dma_buf_fd tracepoint silently miss all DRM PRIME exports. Replace the bare fd_install() with dma_buf_fd_install(), which wraps fd_install() together with DMA_BUF_TRACE(), restoring full tracepoint coverage. No functional change; the fd lifecycle (get_unused_fd_flags → work → install) is already correct. Note: this patch depends on dma_buf_fd_install() introduced in "dma-buf: dma-heap: don't publish fd before copy_to_user() succeeds" [1]. [1] https://lore.kernel.org/dri-devel/20260714114654.3885457-2-shoubaineng@gmail.com/ Suggested-by: Christian König <christian.koenig@amd.com> Acked-by: Sumit Semwal <sumit.semwal@linaro.org> Reviewed-by: Christian König <christian.koenig@amd.com> Signed-off-by: Baineng Shou <shoubaineng@gmail.com> Link: https://lore.kernel.org/r/20260817050457.1005285-4-shoubaineng@gmail.com Signed-off-by: Christian König <christian.koenig@amd.com>
2026-08-24Merge tag 'drm-xe-next-fixes-2026-08-20' of ↵Dave Airlie
https://gitlab.freedesktop.org/drm/xe/kernel into drm-next Couple commits cleaning up error messages. Signed-off-by: Dave Airlie <airlied@redhat.com> From: Rodrigo Vivi <rodrigo.vivi@intel.com> Link: https://patch.msgid.link/aocSC19By5UIIbTZ@intel.com
2026-08-24Merge tag 'drm-msm-next-2026-08-01' of ↵Dave Airlie
https://gitlab.freedesktop.org/drm/msm into drm-next Changes for v7.3 Bindings: - Added Shikra support - Document a840, a704, a722 Core: - Use drm_client buffers for fbdev emulation - teardown fixes - ARM32 DMA fixup - Remove objects from evict list when re-validated - Bunch of corner case and error path fixes DPU: - Dropped dev_pm_opp_set_rate(0) preventing burnout - Fixed SSPP offsets of Kaanapali DP: - Dropped dev_pm_opp_set_rate(0) preventing burnout - Cleaned up core code in preparation for MST support - Fixed prepare() to let Pipewire continue in case of the unplugged cable GPU: - Add support for a704 - Add support for a722 HDMI: - Simplifed register access Signed-off-by: Dave Airlie <airlied@redhat.com> From: Rob Clark <rob.clark@oss.qualcomm.com> Link: https://patch.msgid.link/CACSVV02Kp=J+w_RjEJbBbQnBYRb+SWdwMvVbCaAL70bq9EBagQ@mail.gmail.com
2026-08-24Merge tag 'drm-misc-next-fixes-2026-08-20' of ↵Dave Airlie
https://gitlab.freedesktop.org/drm/misc/kernel into drm-next One patch to remove a WARN in favour of drm_warn. Signed-off-by: Dave Airlie <airlied@redhat.com> From: Maxime Ripard <mripard@redhat.com> Link: https://patch.msgid.link/20260820-fabulous-nimble-woodpecker-ffa695@houat
2026-08-24Merge tag 'amd-drm-next-7.3-2026-08-19' of ↵Dave Airlie
https://gitlab.freedesktop.org/agd5f/linux into drm-next amd-drm-next-7.3-2026-08-19: amdgpu: - eGPU fixes - Runtime PM fix - UserQ fixes - Backlight fix - Discovery sysfs fix - Reset handling fixes - Buffer func handling fix for xgmi - VCN boundary check fix - DC lut handling fixes amdkfd: - Fix return value radeon: - iMac display fix Signed-off-by: Dave Airlie <airlied@redhat.com> From: Alex Deucher <alexander.deucher@amd.com> Link: https://patch.msgid.link/20260819183622.2406038-1-alexander.deucher@amd.com
2026-08-23drm/gud: validate GUD_ROTATION_0 is present in supported rotationsSajal Gupta
The rotation argument to drm_plane_create_rotation_property() is set to DRM_MODE_ROTATE_0, and the device reported rotation bitmask is used as the supported_rotations argument. The driver never validates that GUD_ROTATION_0 is present, so a device that omits it from its GUD_PROPERTY_ROTATION triggers the WARN_ON(rotation & ~supported_rotations) in drm_plane_create_rotation_property() Fix this by skipping the creation of rotation property if the device doesn't have the GUD_ROTATION_0 bit Fixes: 40e1a70b4aed ("drm: Add GUD USB Display driver") Reported-by: syzbot+efe2810681f1b065d3a8@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=efe2810681f1b065d3a8 Tested-by: syzbot+efe2810681f1b065d3a8@syzkaller.appspotmail.com Signed-off-by: Sajal Gupta <sajal2005gupta@gmail.com> Acked-by: Ruben Wauters <rubenru09@aol.com> Signed-off-by: Ruben Wauters <rubenru09@aol.com> Link: https://patch.msgid.link/20260821071812.16500-1-sajal2005gupta@gmail.com
2026-08-23drm/gud: validate TV mode names before creating enum propertyTao Yu
The GUD protocol returns TV mode names as fixed-size GUD_CONNECTOR_TV_MODE_NAME_LEN entries and requires each name to be NUL-terminated. gud_connector_add_tv_mode() currently passes each fixed-size entry directly to drm_mode_create_tv_properties_legacy(), which eventually reaches drm_property_add_enum() and strlen(). If a device returns an entry without a terminating NUL byte, strlen() reads past the end of the slot and can run beyond the allocated buffer, triggering an out-of-bounds read. Validate that each returned TV mode name contains a NUL terminator within its fixed-size slot before passing it to the DRM property code. If a malformed entry is found, reject the device response with -EIO. This fixes the out-of-bounds read without changing the handling of valid devices, and avoids silently truncating malformed protocol data. Reported-by: syzbot+9ae8e7884e451eaed5b4@syzkaller.appspotmail.com Fixes: 40e1a70b4aed ("drm: Add GUD USB Display driver") Signed-off-by: Tao Yu <tao1.yu@intel.com> Reviewed-by: Ruben Wauters <rubenru09@aol.com> Cc: <stable@vger.kernel.org> Signed-off-by: Ruben Wauters <rubenru09@aol.com> Link: https://patch.msgid.link/20260819072835.4074130-1-tao1.yu@intel.com
2026-08-23drm/gud: NUL-terminate TV mode names read from the deviceDeepanshu Kartikey
gud_connector_add_tv_mode() reads a buffer of fixed-size mode names from the USB device and passes pointers into it to drm_mode_create_tv_properties_legacy(), which calls strlen() on each one. Nothing guarantees the device NUL-terminates a name, so strlen() can run past the end of a slot and, for the last mode, past the end of the allocation. Terminate each name at the end of its slot before use. Fixes: 40e1a70b4aed ("drm: Add GUD USB Display driver") Reported-by: syzbot+916c888ba5f1a54c9526@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=916c888ba5f1a54c9526 Tested-by: syzbot+916c888ba5f1a54c9526@syzkaller.appspotmail.com Signed-off-by: Deepanshu Kartikey <kartikey406@gmail.com> Acked-by: Ruben Wauters <rubenru09@aol.com> Cc: <stable@vger.kernel.org> Signed-off-by: Ruben Wauters <rubenru09@aol.com> Link: https://patch.msgid.link/20260816085234.22053-1-kartikey406@gmail.com
2026-08-23Merge tag 'mm-nonmm-stable-2026-08-22-16-57' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm Pull non-MM updates from Andrew Morton: - "ocfs2/dlm: bound peer-controlled lengths in the o2dlm" (Bryam Vargas) Validate and bound all input lengths and count fields in the o2dlm migration and recovery receive handlers to prevent memory corruption and kernel panics from malformed cluster messages - "ocfs2: validate xattr entry bounds" (Cen Zhang) Validate OCFS2 extended attribute entry name and value bounds during metadata reads to prevent out-of-range memory accesses during retrieval or listing operations. - "taskstats: fix cgroupstats invalid fd handling and add selftests" (Yiyang Chen) Return -EBADF when cgroupstats receives an invalid file descriptor to prevent caller hangs and misleading success ACKs. Add a kselftest to validate valid cgroup v1 queries and verify proper error handling across different Netlink flag combinations. - "misc lib/raid/ improvements v2" (Christoph Hellwig) Improve benchmark-based algorithm selection for the XOR and RAID6 libraries, add KUnit benchmark tests, and cleanup minor implementation details. - "ocfs2: cluster: o2hb_region_pin() fixes" (Joseph Qi) Fix sleeping-in-atomic, lock order inversion and error-path cleanup bugs in o2hb_region_pin() by releasing o2hb_live_lock across sleeping configfs_depend_item() calls and using unlocked variants from callback context. Ensure failed pin attempts properly decrement user counts and unpin partially initialized heartbeat regions to prevent memory leaks and unprotected states. - "lib/ucs2_string.c: fix out-of-bounds read in ucs2_strnlen()" (Vincent Mailhol) Fix an off-by-one which could cause an out-of-bounds read. - "ocfs2: harden heartbeat teardown races" (Cen Zhang) Fix two OCFS2 heartbeat/o2net teardown races found by KASAN. - "taskstats: tidy up the cpumask command path" *Bradley Morgan) make two small cleanups in kernel/taskstats.c. - "ocfs2: validate active orphan slots during inode read" (ZhengYuan Huang) Validate active ordinary and append-DIO orphan slots read from OCFS2 dinodes at the metadata boundary to prevent corrupted slot indices from causing out-of-bounds array accesses. - "ocfs2: bound-check both readdir re-validation scans" (Zhan Xusheng) Enforce strict boundary checks on directory entry record lengths and offset calculations during OCFS2 directory re-scans to prevent out-of-bounds memory reads and directory position corruption. * tag 'mm-nonmm-stable-2026-08-22-16-57' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm: (95 commits) mailmap: fix bouncing address for Taniya Das ocfs2: bound-check dir entries in the inline-data re-validation scan ocfs2: bound-check dir entries in the readdir re-validation scan squashfs: avoid thundering-herd cache wakeups prctl: fix PR_SET_MM_AUXV losing the forced AT_NULL terminator mailmap: update email address for Linfeng Sun lib/interval_tree: fix allocation warning messages checkpatch: add NOKPROBE_SYMBOL to the whitelist of lines that can occur immediately after functions Squashfs: check block offset is not negative signal: factor out the kernel reserved si_code check ocfs2: fix readdir position truncation on 32-bit kernels ocfs2: fix cached cluster count after suballocator reclaim ocfs2: fix circular locking dependency in ocfs2_init_acl() ocfs2: validate DIO orphan slot during inode read ocfs2: validate orphan slot during inode read selftests/prctl: fix non-anonymous VMA mapping in set-anon-vma-name test MAINTAINERS: add IRC and patchwork for LTP include/linux/list.h: mark list_add and __list_add as __always_inline tools/mm: prevent page_owner_sort from truncating input hung_task: update DETECT_HUNG_TASK_BLOCKER Kconfig help ...
2026-08-23gpu: nova-core: Extract PMC registers definitionsAntonin Malzieu Ridolfi
Move PMC register definitions (NV_PMC_BOOT_0, NV_PMC_BOOT_42) and their associated implementations from the root regs.rs file into the gpu module that own them, in the new gpu/regs.rs file. This follows the same pattern established by previous commits for GSP, PDISP, PFB, and PBUS registers: register definitions move to the module that owns them, visibility changes to pub(super), and cross-module access is provided via pub(crate) helper functions. Since falcon.rs (outside the gpu module) also reads NV_PMC_BOOT_0 for its raw value, a pub(crate) helper function boot_0_raw() is added in gpu.rs to provide that access without exposing the register type directly. Suggested-by: Alexandre Courbot <acourbot@nvidia.com> Suggested-by: Danilo Krummrich <dakr@kernel.org> Signed-off-by: Antonin Malzieu Ridolfi <dev@nanonej.com> Link: https://patch.msgid.link/20260817-b4-extract-pmc-registers-to-gpu-mod-v2-1-9dd1d599deb4@nanonej.com Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
2026-08-23gpu: nova-core: write initial RPCs before booting GSP-RMTimur Tabi
Make sure that the two setup RPCs, SetSystemInfo and SetRegistry, are in the command queue before booting GSP-RM. These message are expected to already be present, because GSP-RM will process the queue early in boot but will silently ignore the error if absent. GSP-RM then continues booting, but since the registry is not set up, it fails to initialize. Fixes: 0e42ec83d46a ("gpu: nova-core: gsp: shuffle boot code a bit to keep chipset-specific parts close") Signed-off-by: Timur Tabi <ttabi@nvidia.com> Reviewed-by: Alexandre Courbot <acourbot@nvidia.com> Reviewed-by: John Hubbard <jhubbard@nvidia.com> Link: https://patch.msgid.link/20260810181243.3036669-1-ttabi@nvidia.com Signed-off-by: Alexandre Courbot <acourbot@nvidia.com>
2026-08-21drm/xe: Reject page faults from non-fault-mode scratch VMsArvind Yadav
Having scratch enabled does not make a VM capable of handling recoverable page faults. Allowing scratch VMs through the ASID lookup also admits dma-fence mode VMs. If such a VM faults on an already valid VMA, the handler reports success without fixing the fault, causing the GPU to retry indefinitely. Only allow fault-mode VMs through the ASID lookup. Fault-mode VMs using scratch remain supported, while faults from 3D VMs are rejected. Fixes: ad9843aac91a ("drm/xe/madvise: Implement purgeable buffer object support") Cc: Matthew Brost <matthew.brost@intel.com> Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com> Cc: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com> Suggested-by: Matthew Brost <matthew.brost@intel.com> Signed-off-by: Arvind Yadav <arvind.yadav@intel.com> Reviewed-by: Matthew Brost <matthew.brost@intel.com> Signed-off-by: Matthew Brost <matthew.brost@intel.com> Link: https://patch.msgid.link/20260820065445.567228-1-arvind.yadav@intel.com
2026-08-21drm/panel-edp: Support MNE007QS3-F and TM140VDXP15 edp panelHaikun Zhou
MNE007QS3-F raw edid: 00 ff ff ff ff ff ff 00 0e 77 87 14 00 00 00 00 0f 24 01 04 a5 1e 13 78 03 2c c5 94 5c 59 95 29 1e 50 54 00 00 00 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 35 30 80 a0 70 b0 24 40 30 20 66 00 2d bc 10 00 00 1a 00 00 00 fd 00 28 3c 4b 4b 10 01 0a 20 20 20 20 20 20 00 00 00 fe 00 3d 4c 20 20 20 20 20 20 20 20 20 20 ff 00 00 00 fc 00 4d 4e 45 30 30 37 51 53 33 2d 46 0a 20 01 41 70 20 79 02 00 21 00 1d c8 0b 5d 07 80 07 b0 04 80 3f 79 5c 9e 05 95 9c f2 1d 02 45 54 b0 5c b0 5c 00 42 12 78 22 00 14 8c 5a 02 85 7f 07 9f 00 2f 80 1f 00 af 04 23 00 05 00 05 00 2b 00 0c 27 00 28 3b 00 00 27 00 28 3b 00 00 2e 00 06 00 42 b0 5c b0 5c 81 00 1e 72 1a 00 00 03 01 28 3c 00 00 53 ff 53 ff 3c 00 00 00 00 e3 05 04 00 e6 06 01 01 53 53 ff 00 00 00 00 00 00 00 00 00 7e 90 TM140VDXP15 raw edid: 00 ff ff ff ff ff ff 00 51 a1 37 21 00 00 00 00 0b 24 01 04 a5 1e 13 78 03 2b a5 97 5b 57 8c 28 20 50 54 00 00 00 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 01 24 31 80 a0 70 b0 3c 40 30 20 a6 00 2d bc 10 00 00 1a 00 00 00 fd 00 28 3c 4c 4c 10 01 0a 20 20 20 20 20 20 00 00 00 fe 00 3d 4c 20 20 20 20 20 20 20 20 20 20 ff 00 00 00 fc 00 54 4d 31 34 30 56 44 58 50 31 35 0a 20 01 dd 70 20 79 02 00 21 01 1d c2 0b 58 07 80 07 b0 04 80 71 69 5b 79 d5 8c 87 82 20 02 45 54 b0 5c b0 5c 00 42 12 78 22 00 14 3f 66 02 85 7f 07 9f 00 2f 80 1f 00 af 04 3b 00 05 00 05 00 2b 00 0c 27 00 28 3b 00 00 27 00 28 3b 00 00 2e 00 06 00 42 b0 5c b0 5c 81 00 17 72 1a 00 00 03 01 28 3c 00 00 53 ff 53 ff 3c 00 00 00 00 e3 05 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0a 90 Signed-off-by: Haikun Zhou <zhouhaikun5@huaqin.corp-partner.google.com> Reviewed-by: Douglas Anderson <dianders@chromium.org> Signed-off-by: Douglas Anderson <dianders@chromium.org> Link: https://patch.msgid.link/20260820012554.4038893-1-zhouhaikun5@huaqin.corp-partner.google.com
2026-08-21Merge tag 'drm-next-2026-08-20' of https://gitlab.freedesktop.org/drm/kernelLinus Torvalds
Pull drm updates from Dave Airlie: "Highlights: - dmemcg eviction support is good for low VRAM things like Steam Machine - AMD adds gfx6-8 modifier support for older GPUs that enables a bunch of wayland stuff - i915/xe has some new hw support but also a lot of display refactoring Everything: perf: - export perf_allow_ APIs for xe udmabuf: - remove default size limit of 64MB rust: - i/o rework (signed tag from driver-core tree) - add registration guard and registration data - fix unbounded lifetimes in ioctl handler args - fix a drm_dev_register race - gem_shmem: add DmaResvGuard helper - gpuvm: require send/sync for driver data - implement send/sync for GpuVaAlloc and GpuVmBo - add SmContext lifetime - rename dma_handle to dma_address - change pci_sriov_get_totalvfs return to unsigned int core: - create drm_of_get_panel_orientation - send per-connector hotplug events - add thunderbolt UBHR tunneling support connector: - add color format property dmem: - introduce a peak file - accept one region per limit - add dmemcg support for eviction gpusvm: - reorg code to give drivers more flexibility atomic: - add create_state callback and helper - add documentation on atomic commit lifetime buddy: - add per-order free - add used block scoreboard - fix UAF - test buffer clearance on resume - add phys_addr->block helper gem: - drop DRIVER_GEM_GPUVA flag ttm: - be more aggressive allocating below protection limit sched: - add test suite for concurrent job submissions hdmi: - hook the color format property in helpers mipi-dsi: - add MIPI_DSI_MODE_DSC_ALL_SLICES_IN_PKT bridge: - add atomic create callbacks - drop atomic reset - display-connector: don't autoenable HPD IRQ - trigger initial HPD for DP - ti-sn65dsi83: remove NO_HFP and NO_HBP mode flags - analogix_dp: switch to DP link training helpers dp: - add support for DSC max delta BPP edid: - parse panel type from DisplayID 2.x Display Parameters sysfb: - improve panel, stride, framebuffer size validation panel: - implement ref counting for struct drm_panel - himax-hx83121a: add backlight regulator support - novatek-nt36672a: Inline panel init sequences - visionox-vtdr6130: enable DSC - novatek-nt37801: Use mipi_dsi_*_multi() functions - samsung-s6d16d0: Fix prepare error handling - support Novatek NT36536 plus DT bindings - sofef00: fix backlight updates - osd101t2587: use mipi_dsi_*_multi interface - panel-edp: adjust timing for AUO displays - panel-lvds: support Opto Logic SCX1001511GGC49 - panel-simple: support Kyocera tcg070wvlq - panel-edp: quirks - AUO B116XAT04.3, CMN N116BCP-EA2, CSW MNB601LS1-8 - BOE NV116WH2-M30, BOE NT116WHM-N21, BOE NV116FH1-M31 - BOE NV116FH1-M30, NV140FHM-N5B, TM156VDXP25 - BOE NE160QDM-NY1, MB116AS01 - new: - Samsung ATNA40HQ08-0, Anbernic TD4310 - Chipone ICNA35XX, Ilitek ILI9488 - Ilitek ILI7807S, Renesas R63419 - MNE001BS6-2, MNF601BS4-1, Sharp LQ120P1JX51 virtio: - add support for save/restore virtio_gpu_objects - abort vq wait on device removal amdgpu: - add color format DRM property - initial compute pipe reset support - add GFX 6-8 modifier support - initial DCN 6.0.0 support - dmemcg eviction support - improved boundary checking for bios parsing - RAS updates and rework - VCN secure submission fixes - 8K panel fix - Display KUNIT tests - parse panel type from DisplayID - Align IP discovery to pci device lifetime - SOC15 register macro cleanups - UVD memory placement fixes - GFX9 mode2 reset fixes - drop unnecessary BUG/BUG_ON - GFX8 soft reset rework - enable soft reset on GFX8 - PSP/SMU 15.0.9 update - VI ASPM fix - userq fixes - amdgpu_vm_get_task_info_pasid lifetime fix - DC CACP support - change system_unbound_wq with system_dfl_wq - Loosen VFCT bios parsing to deal with pci=realloc - SI/SMU7 AC/DC switch fix - VM fence handling fix - GEM close optimisation - Apple Studio Display fixes - DC FRL fixes amdkfd: - initial compute pipe reset support - allow applications to opt out of sigbus on fatal errors - improve CRIU boundary checks - MQD handling rework - move TBA/TMA from system to device memory - avoid topology-lock in kfd_mmap - SVM eviction fixes radeon: - fix unset CONFIG_ACPI build i915: - Novalake (NVL display version 35) timing generator enabling - NVL DC3CO enabling - enable UBHR link rates on thunderbolt tunnels - Reduce Xe3+ PM demand peak bandwidth - enable pipe DMC error interrupts for display 30+ - add kunit tests for DP link config selection - refactor and document DP link recovery - i915/xe driver display probe/remove/suspend/resume/shutdown cleanup and unification - i915/xe display runtime PM unified - Break i915 and xe panic dependency on struct intel_framebuffer - Streamline Pre/Post-CSC LUT loops - drop TGL DC3DO support - CDCLK santization - fix HDMI scrambling enable - fix phys bo pread/pwrite with offset - add missing nospec on parallel submit slot - fix some NULL derefs xe: - drop force_execlist module param - gate observation streams with perf_allow_cpu - skip FORCE_WC and vm_bound check for external dma-bufs - dmemcg eviction support - remove unused NVL-S GuC - TLB invalidation improvements - NVL-S updated PCI-IDs and w/a - madvise: optimise invalidation path - fix infinite gt-reset loop in timeout recovery - update TTM device benefical_order - wait on external BO kernel fences in exec ioctl - add/use more KLV helpers - sriov: disable display in admin only PF mode - add RAS GPU health indicator - optimise TTM populate for DONTNEED BO - drop force_probe for NVL-s - add debugfs for pcode info amdxdna: - disable device buffer export nova: - build nova-core/nova-drm from drivers/gpu - export nova-core rust symbols (workaround) - GSP boot process consolidation - Boot GSP with vGPU enabled - TLV firmware image format support - Hopper/Blackwell fixes and cleanups - I/O projection adoption tyr: - firmware loading and MCU boot - add generic slot manager + MMU - GPU VM support ARM64 LPAE page tables - add kernel buffer object for internal allocations - add parser for Mali CSF - add MCU booting nouveau: - race fixes - check instmem iomapping at first use - add dmemcg support - expose NVDEC channels - add scanline position/head state support for GSP qxl: - convert simple encoder to regular ethosu: - add perf counter support etnaviv: - force flush on power register ops msm: - support DSC configuration with slice_per_pkt > 1 mxsfb: - fix disable sequence panthor: - support sparse mappings rockchip: - switch away from simple helpers - support YUV background color - fix layer config timeout - add edp support for rk3576 - add batch command submission function rocket: - error handling and NULL ptr deref fixes sun4i: - switch away from simple helpers imagination: - mark BXM-4-64 MC1 as support host1x: - support tegra264 tegra: - add DSI for tegra 20/30 v3d: - reduce PM runtime autosuspend delay - scheduler fixes and refactoring - deprecate v3d 3.3 and 4.1 - validate CPU job query boundaries hibmc: - improve plane format handling - switch to gem shmem mediatek: - cec: correct compat for mt7623-8167? exynos: - remove simple dependency - add error handling to encoder paths - take i2c adapter module reference" * tag 'drm-next-2026-08-20' of https://gitlab.freedesktop.org/drm/kernel: (2074 commits) drm/xe/mcr: Take vcs1/vecs1 into account for first media slice drm/xe: Fix a bug in pc_adjust_freq_bounds() drm/xe: Fix xe_device_probe() failure drm/xe/drm_ras: Move has_drm_ras check to drm_ras layer drm/xe/ras: Fix boot-time ras error processing drm/amd/display: make DC_RUN_WITH_PREEMPTION_ENABLED misuse a build error drm/amd/pm: silence uninitialized variable warnings drm/amdgpu: skip BOs being torn down during GTT recovery drm/amdgpu: Reject UVD message with invalid number of h265 refs drm/amdgpu: keep PRT mappings off the vm_bo state lists drm/amdgpu: fix nbif 6.3.1 l1 low power not functional drm/amd/display: fix BT.2020 YCbCr output CSC matrices for DCE drm/amd/display: fix BT.2020 YCbCr limited output CSC matrix drm/amdgpu: Implement insert_end for VCE 3 drm/amdgpu: Fix UVD min buffer sizes drm/amdgpu: Fix UVD decode image min size calculation drm/amdgpu: Fix UVD dpb min size calculation for H264 drm/amdgpu: Reject UVD message with dimensions above 4096 drm/amdgpu: check ASPM on the dGPU host link drm/radeon: fix autosuspend cleanup during teardown ...
2026-08-21drm/tegra: Convert to atomic_create_stateMaxime Ripard
The plane reset implementation creates a custom state subclass, but only initializes a pristine state without resetting any hardware. This is equivalent to what atomic_create_state expects. Convert to it. Reviewed-by: Mikko Perttunen <mperttunen@nvidia.com> Link: https://patch.msgid.link/20260814-drm-no-more-plane-reset-v2-60-82d2963dd134@kernel.org Signed-off-by: Maxime Ripard <mripard@kernel.org>
2026-08-21drm/vc4: Convert to atomic_create_stateMaxime Ripard
The plane reset implementation creates a custom state subclass, but only initializes a pristine state without resetting any hardware. This is equivalent to what atomic_create_state expects. Convert to it. The conversion was done using the following Coccinelle semantic patch: @@ identifier funcs; symbol drm_atomic_helper_plane_reset; symbol drm_atomic_helper_plane_create_state; @@ struct drm_plane_funcs funcs = { ..., - .reset = drm_atomic_helper_plane_reset, + .atomic_create_state = drm_atomic_helper_plane_create_state, ..., }; @match_struct_reset@ identifier funcs, reset_func; @@ struct drm_plane_funcs funcs = { ..., .reset = reset_func, ..., }; @reset_uses_helpers depends on match_struct_reset@ identifier match_struct_reset.reset_func; @@ void reset_func(...) { <+... ( __drm_atomic_helper_plane_reset(...); | __drm_gem_reset_shadow_plane(...); ) ...+> } @match_struct_destroy@ identifier funcs, destroy_func; @@ struct drm_plane_funcs funcs = { ..., .atomic_destroy_state = destroy_func, ..., }; @script:python renamed_func@ old_name << match_struct_reset.reset_func; new_name; @@ if old_name.endswith("_reset"): coccinelle.new_name = old_name.replace("_reset", "_create_state") else: coccinelle.new_name = old_name @update_struct depends on match_struct_reset && reset_uses_helpers@ identifier match_struct_reset.funcs, match_struct_reset.reset_func; identifier renamed_func.new_name; @@ struct drm_plane_funcs funcs = { ..., - .reset = reset_func, + .atomic_create_state = new_name, ..., }; @drop_destroy depends on update_struct && match_struct_destroy@ identifier match_struct_reset.reset_func; identifier match_struct_destroy.destroy_func; identifier container_func; identifier P; symbol drm_atomic_helper_plane_destroy_state; symbol __drm_atomic_helper_plane_destroy_state; @@ void reset_func(struct drm_plane *P) { ... ( - if (P->state) { - <+... ( - drm_atomic_helper_plane_destroy_state(P, P->state); | - __drm_atomic_helper_plane_destroy_state(P->state); | - P->funcs->atomic_destroy_state(P, P->state); | - destroy_func(P, P->state); ) - ...+> - } | - drm_WARN_ON_ONCE(P->dev, P->state); | - WARN_ON(P->state); ) ... ( - kfree(P->state); | - kfree(container_func(P->state)); | // kfree is optional ) ( - P->state = NULL; | // plane->state clearing is optional ) ... } @drop_destroy_mtk depends on update_struct@ identifier P; symbol __drm_atomic_helper_plane_destroy_state; symbol to_mtk_plane_state; @@ void mtk_plane_reset(struct drm_plane *P) { ... - if (P->state) { - __drm_atomic_helper_plane_destroy_state(P->state); - ... - } else { ... - } ... } @transform_nv50_wndw depends on update_struct@ identifier S; @@ void nv50_wndw_reset(...) { ... - if (WARN_ON(!(S = kzalloc_obj(*S)))) + S = kzalloc_obj(*S); + if (WARN_ON(!S)) return; ... } @transform_kzalloc depends on update_struct@ identifier match_struct_reset.reset_func; identifier P, S; statement ST; statement list STL; @@ void reset_func(struct drm_plane *P) { <... S = kzalloc_obj(*S); ( - if (S) - { - STL - } + if (!S) return; + + STL | - if (S) ST + if (!S) return; + + ST ) ...> } @transform_body depends on update_struct@ identifier match_struct_reset.reset_func; identifier renamed_func.new_name; identifier S, P; expression PS; @@ - void reset_func(struct drm_plane *P) + struct drm_plane_state *new_name(struct drm_plane *P) { ... S = kzalloc_obj(*S); ... ( if (!S) { ... - return; + return ERR_PTR(-ENOMEM); } | if (WARN_ON(!S)) { ... - return; + return ERR_PTR(-ENOMEM); } | if (S == NULL) { ... - return; + return ERR_PTR(-ENOMEM); } ) ... ( - __drm_atomic_helper_plane_reset(P, PS); + __drm_atomic_helper_plane_state_init(PS, P); | - __drm_gem_reset_shadow_plane(P, PS); + __drm_gem_shadow_plane_state_init(P, PS); ) ... } @update_early_return depends on update_struct@ identifier match_struct_reset.reset_func; identifier renamed_func.new_name; identifier P; expression PS; @@ struct drm_plane_state *new_name(struct drm_plane *P) { <+... - return; + return ERR_PTR(-EINVAL); ...+> } @update_return_plane depends on update_struct@ identifier match_struct_reset.reset_func; identifier renamed_func.new_name; identifier P; expression PS; @@ struct drm_plane_state *new_name(struct drm_plane *P) { ... __drm_atomic_helper_plane_state_init(PS, P); ... + + return PS; } @update_return_shadow depends on update_struct@ identifier renamed_func.new_name; identifier P; expression PS; @@ struct drm_plane_state *new_name(struct drm_plane *P) { ... __drm_gem_shadow_plane_state_init(P, PS); ... + + return &PS->base; } Reviewed-by: Maíra Canal <mcanal@igalia.com> Link: https://patch.msgid.link/20260814-drm-no-more-plane-reset-v2-57-82d2963dd134@kernel.org Signed-off-by: Maxime Ripard <mripard@kernel.org>
2026-08-21drm/msm/mdp5: Convert to atomic_create_stateMaxime Ripard
The plane reset implementation creates a custom state subclass, but only initializes a pristine state without resetting any hardware. This is equivalent to what atomic_create_state expects. Convert to it. The conversion was done using the following Coccinelle semantic patch: @@ identifier funcs; symbol drm_atomic_helper_plane_reset; symbol drm_atomic_helper_plane_create_state; @@ struct drm_plane_funcs funcs = { ..., - .reset = drm_atomic_helper_plane_reset, + .atomic_create_state = drm_atomic_helper_plane_create_state, ..., }; @match_struct_reset@ identifier funcs, reset_func; @@ struct drm_plane_funcs funcs = { ..., .reset = reset_func, ..., }; @reset_uses_helpers depends on match_struct_reset@ identifier match_struct_reset.reset_func; @@ void reset_func(...) { <+... ( __drm_atomic_helper_plane_reset(...); | __drm_gem_reset_shadow_plane(...); ) ...+> } @match_struct_destroy@ identifier funcs, destroy_func; @@ struct drm_plane_funcs funcs = { ..., .atomic_destroy_state = destroy_func, ..., }; @script:python renamed_func@ old_name << match_struct_reset.reset_func; new_name; @@ if old_name.endswith("_reset"): coccinelle.new_name = old_name.replace("_reset", "_create_state") else: coccinelle.new_name = old_name @update_struct depends on match_struct_reset && reset_uses_helpers@ identifier match_struct_reset.funcs, match_struct_reset.reset_func; identifier renamed_func.new_name; @@ struct drm_plane_funcs funcs = { ..., - .reset = reset_func, + .atomic_create_state = new_name, ..., }; @drop_destroy depends on update_struct && match_struct_destroy@ identifier match_struct_reset.reset_func; identifier match_struct_destroy.destroy_func; identifier container_func; identifier P; symbol drm_atomic_helper_plane_destroy_state; symbol __drm_atomic_helper_plane_destroy_state; @@ void reset_func(struct drm_plane *P) { ... ( - if (P->state) { - <+... ( - drm_atomic_helper_plane_destroy_state(P, P->state); | - __drm_atomic_helper_plane_destroy_state(P->state); | - P->funcs->atomic_destroy_state(P, P->state); | - destroy_func(P, P->state); ) - ...+> - } | - drm_WARN_ON_ONCE(P->dev, P->state); | - WARN_ON(P->state); ) ... ( - kfree(P->state); | - kfree(container_func(P->state)); | // kfree is optional ) ( - P->state = NULL; | // plane->state clearing is optional ) ... } @drop_destroy_mtk depends on update_struct@ identifier P; symbol __drm_atomic_helper_plane_destroy_state; symbol to_mtk_plane_state; @@ void mtk_plane_reset(struct drm_plane *P) { ... - if (P->state) { - __drm_atomic_helper_plane_destroy_state(P->state); - ... - } else { ... - } ... } @transform_nv50_wndw depends on update_struct@ identifier S; @@ void nv50_wndw_reset(...) { ... - if (WARN_ON(!(S = kzalloc_obj(*S)))) + S = kzalloc_obj(*S); + if (WARN_ON(!S)) return; ... } @transform_kzalloc depends on update_struct@ identifier match_struct_reset.reset_func; identifier P, S; statement ST; statement list STL; @@ void reset_func(struct drm_plane *P) { <... S = kzalloc_obj(*S); ( - if (S) - { - STL - } + if (!S) return; + + STL | - if (S) ST + if (!S) return; + + ST ) ...> } @transform_body depends on update_struct@ identifier match_struct_reset.reset_func; identifier renamed_func.new_name; identifier S, P; expression PS; @@ - void reset_func(struct drm_plane *P) + struct drm_plane_state *new_name(struct drm_plane *P) { ... S = kzalloc_obj(*S); ... ( if (!S) { ... - return; + return ERR_PTR(-ENOMEM); } | if (WARN_ON(!S)) { ... - return; + return ERR_PTR(-ENOMEM); } | if (S == NULL) { ... - return; + return ERR_PTR(-ENOMEM); } ) ... ( - __drm_atomic_helper_plane_reset(P, PS); + __drm_atomic_helper_plane_state_init(PS, P); | - __drm_gem_reset_shadow_plane(P, PS); + __drm_gem_shadow_plane_state_init(P, PS); ) ... } @update_early_return depends on update_struct@ identifier match_struct_reset.reset_func; identifier renamed_func.new_name; identifier P; expression PS; @@ struct drm_plane_state *new_name(struct drm_plane *P) { <+... - return; + return ERR_PTR(-EINVAL); ...+> } @update_return_plane depends on update_struct@ identifier match_struct_reset.reset_func; identifier renamed_func.new_name; identifier P; expression PS; @@ struct drm_plane_state *new_name(struct drm_plane *P) { ... __drm_atomic_helper_plane_state_init(PS, P); ... + + return PS; } @update_return_shadow depends on update_struct@ identifier renamed_func.new_name; identifier P; expression PS; @@ struct drm_plane_state *new_name(struct drm_plane *P) { ... __drm_gem_shadow_plane_state_init(P, PS); ... + + return &PS->base; } Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> Link: https://patch.msgid.link/20260814-drm-no-more-plane-reset-v2-50-82d2963dd134@kernel.org Signed-off-by: Maxime Ripard <mripard@kernel.org>
2026-08-21drm/msm/dpu1: Convert to atomic_create_stateMaxime Ripard
The plane reset implementation creates a custom state subclass, but only initializes a pristine state without resetting any hardware. This is equivalent to what atomic_create_state expects. Convert to it. The conversion was done using the following Coccinelle semantic patch: @@ identifier funcs; symbol drm_atomic_helper_plane_reset; symbol drm_atomic_helper_plane_create_state; @@ struct drm_plane_funcs funcs = { ..., - .reset = drm_atomic_helper_plane_reset, + .atomic_create_state = drm_atomic_helper_plane_create_state, ..., }; @match_struct_reset@ identifier funcs, reset_func; @@ struct drm_plane_funcs funcs = { ..., .reset = reset_func, ..., }; @reset_uses_helpers depends on match_struct_reset@ identifier match_struct_reset.reset_func; @@ void reset_func(...) { <+... ( __drm_atomic_helper_plane_reset(...); | __drm_gem_reset_shadow_plane(...); ) ...+> } @match_struct_destroy@ identifier funcs, destroy_func; @@ struct drm_plane_funcs funcs = { ..., .atomic_destroy_state = destroy_func, ..., }; @script:python renamed_func@ old_name << match_struct_reset.reset_func; new_name; @@ if old_name.endswith("_reset"): coccinelle.new_name = old_name.replace("_reset", "_create_state") else: coccinelle.new_name = old_name @update_struct depends on match_struct_reset && reset_uses_helpers@ identifier match_struct_reset.funcs, match_struct_reset.reset_func; identifier renamed_func.new_name; @@ struct drm_plane_funcs funcs = { ..., - .reset = reset_func, + .atomic_create_state = new_name, ..., }; @drop_destroy depends on update_struct && match_struct_destroy@ identifier match_struct_reset.reset_func; identifier match_struct_destroy.destroy_func; identifier container_func; identifier P; symbol drm_atomic_helper_plane_destroy_state; symbol __drm_atomic_helper_plane_destroy_state; @@ void reset_func(struct drm_plane *P) { ... ( - if (P->state) { - <+... ( - drm_atomic_helper_plane_destroy_state(P, P->state); | - __drm_atomic_helper_plane_destroy_state(P->state); | - P->funcs->atomic_destroy_state(P, P->state); | - destroy_func(P, P->state); ) - ...+> - } | - drm_WARN_ON_ONCE(P->dev, P->state); | - WARN_ON(P->state); ) ... ( - kfree(P->state); | - kfree(container_func(P->state)); | // kfree is optional ) ( - P->state = NULL; | // plane->state clearing is optional ) ... } @drop_destroy_mtk depends on update_struct@ identifier P; symbol __drm_atomic_helper_plane_destroy_state; symbol to_mtk_plane_state; @@ void mtk_plane_reset(struct drm_plane *P) { ... - if (P->state) { - __drm_atomic_helper_plane_destroy_state(P->state); - ... - } else { ... - } ... } @transform_nv50_wndw depends on update_struct@ identifier S; @@ void nv50_wndw_reset(...) { ... - if (WARN_ON(!(S = kzalloc_obj(*S)))) + S = kzalloc_obj(*S); + if (WARN_ON(!S)) return; ... } @transform_kzalloc depends on update_struct@ identifier match_struct_reset.reset_func; identifier P, S; statement ST; statement list STL; @@ void reset_func(struct drm_plane *P) { <... S = kzalloc_obj(*S); ( - if (S) - { - STL - } + if (!S) return; + + STL | - if (S) ST + if (!S) return; + + ST ) ...> } @transform_body depends on update_struct@ identifier match_struct_reset.reset_func; identifier renamed_func.new_name; identifier S, P; expression PS; @@ - void reset_func(struct drm_plane *P) + struct drm_plane_state *new_name(struct drm_plane *P) { ... S = kzalloc_obj(*S); ... ( if (!S) { ... - return; + return ERR_PTR(-ENOMEM); } | if (WARN_ON(!S)) { ... - return; + return ERR_PTR(-ENOMEM); } | if (S == NULL) { ... - return; + return ERR_PTR(-ENOMEM); } ) ... ( - __drm_atomic_helper_plane_reset(P, PS); + __drm_atomic_helper_plane_state_init(PS, P); | - __drm_gem_reset_shadow_plane(P, PS); + __drm_gem_shadow_plane_state_init(P, PS); ) ... } @update_early_return depends on update_struct@ identifier match_struct_reset.reset_func; identifier renamed_func.new_name; identifier P; expression PS; @@ struct drm_plane_state *new_name(struct drm_plane *P) { <+... - return; + return ERR_PTR(-EINVAL); ...+> } @update_return_plane depends on update_struct@ identifier match_struct_reset.reset_func; identifier renamed_func.new_name; identifier P; expression PS; @@ struct drm_plane_state *new_name(struct drm_plane *P) { ... __drm_atomic_helper_plane_state_init(PS, P); ... + + return PS; } @update_return_shadow depends on update_struct@ identifier renamed_func.new_name; identifier P; expression PS; @@ struct drm_plane_state *new_name(struct drm_plane *P) { ... __drm_gem_shadow_plane_state_init(P, PS); ... + + return &PS->base; } Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> Link: https://patch.msgid.link/20260814-drm-no-more-plane-reset-v2-49-82d2963dd134@kernel.org Signed-off-by: Maxime Ripard <mripard@kernel.org>
2026-08-21drm/malidp: Convert to atomic_create_stateMaxime Ripard
The plane reset implementation creates a custom state subclass, but only initializes a pristine state without resetting any hardware. This is equivalent to what atomic_create_state expects. Convert to it. The conversion was done using the following Coccinelle semantic patch: @@ identifier funcs; symbol drm_atomic_helper_plane_reset; symbol drm_atomic_helper_plane_create_state; @@ struct drm_plane_funcs funcs = { ..., - .reset = drm_atomic_helper_plane_reset, + .atomic_create_state = drm_atomic_helper_plane_create_state, ..., }; @match_struct_reset@ identifier funcs, reset_func; @@ struct drm_plane_funcs funcs = { ..., .reset = reset_func, ..., }; @reset_uses_helpers depends on match_struct_reset@ identifier match_struct_reset.reset_func; @@ void reset_func(...) { <+... ( __drm_atomic_helper_plane_reset(...); | __drm_gem_reset_shadow_plane(...); ) ...+> } @match_struct_destroy@ identifier funcs, destroy_func; @@ struct drm_plane_funcs funcs = { ..., .atomic_destroy_state = destroy_func, ..., }; @script:python renamed_func@ old_name << match_struct_reset.reset_func; new_name; @@ if old_name.endswith("_reset"): coccinelle.new_name = old_name.replace("_reset", "_create_state") else: coccinelle.new_name = old_name @update_struct depends on match_struct_reset && reset_uses_helpers@ identifier match_struct_reset.funcs, match_struct_reset.reset_func; identifier renamed_func.new_name; @@ struct drm_plane_funcs funcs = { ..., - .reset = reset_func, + .atomic_create_state = new_name, ..., }; @drop_destroy depends on update_struct && match_struct_destroy@ identifier match_struct_reset.reset_func; identifier match_struct_destroy.destroy_func; identifier container_func; identifier P; symbol drm_atomic_helper_plane_destroy_state; symbol __drm_atomic_helper_plane_destroy_state; @@ void reset_func(struct drm_plane *P) { ... ( - if (P->state) { - <+... ( - drm_atomic_helper_plane_destroy_state(P, P->state); | - __drm_atomic_helper_plane_destroy_state(P->state); | - P->funcs->atomic_destroy_state(P, P->state); | - destroy_func(P, P->state); ) - ...+> - } | - drm_WARN_ON_ONCE(P->dev, P->state); | - WARN_ON(P->state); ) ... ( - kfree(P->state); | - kfree(container_func(P->state)); | // kfree is optional ) ( - P->state = NULL; | // plane->state clearing is optional ) ... } @drop_destroy_mtk depends on update_struct@ identifier P; symbol __drm_atomic_helper_plane_destroy_state; symbol to_mtk_plane_state; @@ void mtk_plane_reset(struct drm_plane *P) { ... - if (P->state) { - __drm_atomic_helper_plane_destroy_state(P->state); - ... - } else { ... - } ... } @transform_nv50_wndw depends on update_struct@ identifier S; @@ void nv50_wndw_reset(...) { ... - if (WARN_ON(!(S = kzalloc_obj(*S)))) + S = kzalloc_obj(*S); + if (WARN_ON(!S)) return; ... } @transform_kzalloc depends on update_struct@ identifier match_struct_reset.reset_func; identifier P, S; statement ST; statement list STL; @@ void reset_func(struct drm_plane *P) { <... S = kzalloc_obj(*S); ( - if (S) - { - STL - } + if (!S) return; + + STL | - if (S) ST + if (!S) return; + + ST ) ...> } @transform_body depends on update_struct@ identifier match_struct_reset.reset_func; identifier renamed_func.new_name; identifier S, P; expression PS; @@ - void reset_func(struct drm_plane *P) + struct drm_plane_state *new_name(struct drm_plane *P) { ... S = kzalloc_obj(*S); ... ( if (!S) { ... - return; + return ERR_PTR(-ENOMEM); } | if (WARN_ON(!S)) { ... - return; + return ERR_PTR(-ENOMEM); } | if (S == NULL) { ... - return; + return ERR_PTR(-ENOMEM); } ) ... ( - __drm_atomic_helper_plane_reset(P, PS); + __drm_atomic_helper_plane_state_init(PS, P); | - __drm_gem_reset_shadow_plane(P, PS); + __drm_gem_shadow_plane_state_init(P, PS); ) ... } @update_early_return depends on update_struct@ identifier match_struct_reset.reset_func; identifier renamed_func.new_name; identifier P; expression PS; @@ struct drm_plane_state *new_name(struct drm_plane *P) { <+... - return; + return ERR_PTR(-EINVAL); ...+> } @update_return_plane depends on update_struct@ identifier match_struct_reset.reset_func; identifier renamed_func.new_name; identifier P; expression PS; @@ struct drm_plane_state *new_name(struct drm_plane *P) { ... __drm_atomic_helper_plane_state_init(PS, P); ... + + return PS; } @update_return_shadow depends on update_struct@ identifier renamed_func.new_name; identifier P; expression PS; @@ struct drm_plane_state *new_name(struct drm_plane *P) { ... __drm_gem_shadow_plane_state_init(P, PS); ... + + return &PS->base; } Reviewed-by: Liviu Dudau <liviu.dudau@arm.com> Link: https://patch.msgid.link/20260814-drm-no-more-plane-reset-v2-42-82d2963dd134@kernel.org Signed-off-by: Maxime Ripard <mripard@kernel.org>
2026-08-21drm/komeda: Convert to atomic_create_stateMaxime Ripard
The plane reset implementation creates a custom state subclass, but only initializes a pristine state without resetting any hardware. This is equivalent to what atomic_create_state expects. Convert to it. The conversion was done using the following Coccinelle semantic patch: @@ identifier funcs; symbol drm_atomic_helper_plane_reset; symbol drm_atomic_helper_plane_create_state; @@ struct drm_plane_funcs funcs = { ..., - .reset = drm_atomic_helper_plane_reset, + .atomic_create_state = drm_atomic_helper_plane_create_state, ..., }; @match_struct_reset@ identifier funcs, reset_func; @@ struct drm_plane_funcs funcs = { ..., .reset = reset_func, ..., }; @reset_uses_helpers depends on match_struct_reset@ identifier match_struct_reset.reset_func; @@ void reset_func(...) { <+... ( __drm_atomic_helper_plane_reset(...); | __drm_gem_reset_shadow_plane(...); ) ...+> } @match_struct_destroy@ identifier funcs, destroy_func; @@ struct drm_plane_funcs funcs = { ..., .atomic_destroy_state = destroy_func, ..., }; @script:python renamed_func@ old_name << match_struct_reset.reset_func; new_name; @@ if old_name.endswith("_reset"): coccinelle.new_name = old_name.replace("_reset", "_create_state") else: coccinelle.new_name = old_name @update_struct depends on match_struct_reset && reset_uses_helpers@ identifier match_struct_reset.funcs, match_struct_reset.reset_func; identifier renamed_func.new_name; @@ struct drm_plane_funcs funcs = { ..., - .reset = reset_func, + .atomic_create_state = new_name, ..., }; @drop_destroy depends on update_struct && match_struct_destroy@ identifier match_struct_reset.reset_func; identifier match_struct_destroy.destroy_func; identifier container_func; identifier P; symbol drm_atomic_helper_plane_destroy_state; symbol __drm_atomic_helper_plane_destroy_state; @@ void reset_func(struct drm_plane *P) { ... ( - if (P->state) { - <+... ( - drm_atomic_helper_plane_destroy_state(P, P->state); | - __drm_atomic_helper_plane_destroy_state(P->state); | - P->funcs->atomic_destroy_state(P, P->state); | - destroy_func(P, P->state); ) - ...+> - } | - drm_WARN_ON_ONCE(P->dev, P->state); | - WARN_ON(P->state); ) ... ( - kfree(P->state); | - kfree(container_func(P->state)); | // kfree is optional ) ( - P->state = NULL; | // plane->state clearing is optional ) ... } @drop_destroy_mtk depends on update_struct@ identifier P; symbol __drm_atomic_helper_plane_destroy_state; symbol to_mtk_plane_state; @@ void mtk_plane_reset(struct drm_plane *P) { ... - if (P->state) { - __drm_atomic_helper_plane_destroy_state(P->state); - ... - } else { ... - } ... } @transform_nv50_wndw depends on update_struct@ identifier S; @@ void nv50_wndw_reset(...) { ... - if (WARN_ON(!(S = kzalloc_obj(*S)))) + S = kzalloc_obj(*S); + if (WARN_ON(!S)) return; ... } @transform_kzalloc depends on update_struct@ identifier match_struct_reset.reset_func; identifier P, S; statement ST; statement list STL; @@ void reset_func(struct drm_plane *P) { <... S = kzalloc_obj(*S); ( - if (S) - { - STL - } + if (!S) return; + + STL | - if (S) ST + if (!S) return; + + ST ) ...> } @transform_body depends on update_struct@ identifier match_struct_reset.reset_func; identifier renamed_func.new_name; identifier S, P; expression PS; @@ - void reset_func(struct drm_plane *P) + struct drm_plane_state *new_name(struct drm_plane *P) { ... S = kzalloc_obj(*S); ... ( if (!S) { ... - return; + return ERR_PTR(-ENOMEM); } | if (WARN_ON(!S)) { ... - return; + return ERR_PTR(-ENOMEM); } | if (S == NULL) { ... - return; + return ERR_PTR(-ENOMEM); } ) ... ( - __drm_atomic_helper_plane_reset(P, PS); + __drm_atomic_helper_plane_state_init(PS, P); | - __drm_gem_reset_shadow_plane(P, PS); + __drm_gem_shadow_plane_state_init(P, PS); ) ... } @update_early_return depends on update_struct@ identifier match_struct_reset.reset_func; identifier renamed_func.new_name; identifier P; expression PS; @@ struct drm_plane_state *new_name(struct drm_plane *P) { <+... - return; + return ERR_PTR(-EINVAL); ...+> } @update_return_plane depends on update_struct@ identifier match_struct_reset.reset_func; identifier renamed_func.new_name; identifier P; expression PS; @@ struct drm_plane_state *new_name(struct drm_plane *P) { ... __drm_atomic_helper_plane_state_init(PS, P); ... + + return PS; } @update_return_shadow depends on update_struct@ identifier renamed_func.new_name; identifier P; expression PS; @@ struct drm_plane_state *new_name(struct drm_plane *P) { ... __drm_gem_shadow_plane_state_init(P, PS); ... + + return &PS->base; } Reviewed-by: Liviu Dudau <liviu.dudau@arm.com> Link: https://patch.msgid.link/20260814-drm-no-more-plane-reset-v2-41-82d2963dd134@kernel.org Signed-off-by: Maxime Ripard <mripard@kernel.org>
2026-08-21drm/sun4i: sun8i: Convert to atomic_create_stateMaxime Ripard
The plane only initializes a pristine state in its reset hook using drm_atomic_helper_plane_reset(), which is equivalent to what atomic_create_state expects. Convert to it. The conversion was done using the following Coccinelle semantic patch: @@ identifier funcs; symbol drm_atomic_helper_plane_reset; symbol drm_atomic_helper_plane_create_state; @@ struct drm_plane_funcs funcs = { ..., - .reset = drm_atomic_helper_plane_reset, + .atomic_create_state = drm_atomic_helper_plane_create_state, ..., }; @match_struct_reset@ identifier funcs, reset_func; @@ struct drm_plane_funcs funcs = { ..., .reset = reset_func, ..., }; @reset_uses_helpers depends on match_struct_reset@ identifier match_struct_reset.reset_func; @@ void reset_func(...) { <+... ( __drm_atomic_helper_plane_reset(...); | __drm_gem_reset_shadow_plane(...); ) ...+> } @match_struct_destroy@ identifier funcs, destroy_func; @@ struct drm_plane_funcs funcs = { ..., .atomic_destroy_state = destroy_func, ..., }; @script:python renamed_func@ old_name << match_struct_reset.reset_func; new_name; @@ if old_name.endswith("_reset"): coccinelle.new_name = old_name.replace("_reset", "_create_state") else: coccinelle.new_name = old_name @update_struct depends on match_struct_reset && reset_uses_helpers@ identifier match_struct_reset.funcs, match_struct_reset.reset_func; identifier renamed_func.new_name; @@ struct drm_plane_funcs funcs = { ..., - .reset = reset_func, + .atomic_create_state = new_name, ..., }; @drop_destroy depends on update_struct && match_struct_destroy@ identifier match_struct_reset.reset_func; identifier match_struct_destroy.destroy_func; identifier container_func; identifier P; symbol drm_atomic_helper_plane_destroy_state; symbol __drm_atomic_helper_plane_destroy_state; @@ void reset_func(struct drm_plane *P) { ... ( - if (P->state) { - <+... ( - drm_atomic_helper_plane_destroy_state(P, P->state); | - __drm_atomic_helper_plane_destroy_state(P->state); | - P->funcs->atomic_destroy_state(P, P->state); | - destroy_func(P, P->state); ) - ...+> - } | - drm_WARN_ON_ONCE(P->dev, P->state); | - WARN_ON(P->state); ) ... ( - kfree(P->state); | - kfree(container_func(P->state)); | // kfree is optional ) ( - P->state = NULL; | // plane->state clearing is optional ) ... } @drop_destroy_mtk depends on update_struct@ identifier P; symbol __drm_atomic_helper_plane_destroy_state; symbol to_mtk_plane_state; @@ void mtk_plane_reset(struct drm_plane *P) { ... - if (P->state) { - __drm_atomic_helper_plane_destroy_state(P->state); - ... - } else { ... - } ... } @transform_nv50_wndw depends on update_struct@ identifier S; @@ void nv50_wndw_reset(...) { ... - if (WARN_ON(!(S = kzalloc_obj(*S)))) + S = kzalloc_obj(*S); + if (WARN_ON(!S)) return; ... } @transform_kzalloc depends on update_struct@ identifier match_struct_reset.reset_func; identifier P, S; statement ST; statement list STL; @@ void reset_func(struct drm_plane *P) { <... S = kzalloc_obj(*S); ( - if (S) - { - STL - } + if (!S) return; + + STL | - if (S) ST + if (!S) return; + + ST ) ...> } @transform_body depends on update_struct@ identifier match_struct_reset.reset_func; identifier renamed_func.new_name; identifier S, P; expression PS; @@ - void reset_func(struct drm_plane *P) + struct drm_plane_state *new_name(struct drm_plane *P) { ... S = kzalloc_obj(*S); ... ( if (!S) { ... - return; + return ERR_PTR(-ENOMEM); } | if (WARN_ON(!S)) { ... - return; + return ERR_PTR(-ENOMEM); } | if (S == NULL) { ... - return; + return ERR_PTR(-ENOMEM); } ) ... ( - __drm_atomic_helper_plane_reset(P, PS); + __drm_atomic_helper_plane_state_init(PS, P); | - __drm_gem_reset_shadow_plane(P, PS); + __drm_gem_shadow_plane_state_init(P, PS); ) ... } @update_early_return depends on update_struct@ identifier match_struct_reset.reset_func; identifier renamed_func.new_name; identifier P; expression PS; @@ struct drm_plane_state *new_name(struct drm_plane *P) { <+... - return; + return ERR_PTR(-EINVAL); ...+> } @update_return_plane depends on update_struct@ identifier match_struct_reset.reset_func; identifier renamed_func.new_name; identifier P; expression PS; @@ struct drm_plane_state *new_name(struct drm_plane *P) { ... __drm_atomic_helper_plane_state_init(PS, P); ... + + return PS; } @update_return_shadow depends on update_struct@ identifier renamed_func.new_name; identifier P; expression PS; @@ struct drm_plane_state *new_name(struct drm_plane *P) { ... __drm_gem_shadow_plane_state_init(P, PS); ... + + return &PS->base; } Acked-by: Chen-Yu Tsai <wens@kernel.org> Link: https://patch.msgid.link/20260814-drm-no-more-plane-reset-v2-32-82d2963dd134@kernel.org Signed-off-by: Maxime Ripard <mripard@kernel.org>
2026-08-21drm/msm/mdp4: Convert to atomic_create_stateMaxime Ripard
The plane only initializes a pristine state in its reset hook using drm_atomic_helper_plane_reset(), which is equivalent to what atomic_create_state expects. Convert to it. The conversion was done using the following Coccinelle semantic patch: @@ identifier funcs; symbol drm_atomic_helper_plane_reset; symbol drm_atomic_helper_plane_create_state; @@ struct drm_plane_funcs funcs = { ..., - .reset = drm_atomic_helper_plane_reset, + .atomic_create_state = drm_atomic_helper_plane_create_state, ..., }; @match_struct_reset@ identifier funcs, reset_func; @@ struct drm_plane_funcs funcs = { ..., .reset = reset_func, ..., }; @reset_uses_helpers depends on match_struct_reset@ identifier match_struct_reset.reset_func; @@ void reset_func(...) { <+... ( __drm_atomic_helper_plane_reset(...); | __drm_gem_reset_shadow_plane(...); ) ...+> } @match_struct_destroy@ identifier funcs, destroy_func; @@ struct drm_plane_funcs funcs = { ..., .atomic_destroy_state = destroy_func, ..., }; @script:python renamed_func@ old_name << match_struct_reset.reset_func; new_name; @@ if old_name.endswith("_reset"): coccinelle.new_name = old_name.replace("_reset", "_create_state") else: coccinelle.new_name = old_name @update_struct depends on match_struct_reset && reset_uses_helpers@ identifier match_struct_reset.funcs, match_struct_reset.reset_func; identifier renamed_func.new_name; @@ struct drm_plane_funcs funcs = { ..., - .reset = reset_func, + .atomic_create_state = new_name, ..., }; @drop_destroy depends on update_struct && match_struct_destroy@ identifier match_struct_reset.reset_func; identifier match_struct_destroy.destroy_func; identifier container_func; identifier P; symbol drm_atomic_helper_plane_destroy_state; symbol __drm_atomic_helper_plane_destroy_state; @@ void reset_func(struct drm_plane *P) { ... ( - if (P->state) { - <+... ( - drm_atomic_helper_plane_destroy_state(P, P->state); | - __drm_atomic_helper_plane_destroy_state(P->state); | - P->funcs->atomic_destroy_state(P, P->state); | - destroy_func(P, P->state); ) - ...+> - } | - drm_WARN_ON_ONCE(P->dev, P->state); | - WARN_ON(P->state); ) ... ( - kfree(P->state); | - kfree(container_func(P->state)); | // kfree is optional ) ( - P->state = NULL; | // plane->state clearing is optional ) ... } @drop_destroy_mtk depends on update_struct@ identifier P; symbol __drm_atomic_helper_plane_destroy_state; symbol to_mtk_plane_state; @@ void mtk_plane_reset(struct drm_plane *P) { ... - if (P->state) { - __drm_atomic_helper_plane_destroy_state(P->state); - ... - } else { ... - } ... } @transform_nv50_wndw depends on update_struct@ identifier S; @@ void nv50_wndw_reset(...) { ... - if (WARN_ON(!(S = kzalloc_obj(*S)))) + S = kzalloc_obj(*S); + if (WARN_ON(!S)) return; ... } @transform_kzalloc depends on update_struct@ identifier match_struct_reset.reset_func; identifier P, S; statement ST; statement list STL; @@ void reset_func(struct drm_plane *P) { <... S = kzalloc_obj(*S); ( - if (S) - { - STL - } + if (!S) return; + + STL | - if (S) ST + if (!S) return; + + ST ) ...> } @transform_body depends on update_struct@ identifier match_struct_reset.reset_func; identifier renamed_func.new_name; identifier S, P; expression PS; @@ - void reset_func(struct drm_plane *P) + struct drm_plane_state *new_name(struct drm_plane *P) { ... S = kzalloc_obj(*S); ... ( if (!S) { ... - return; + return ERR_PTR(-ENOMEM); } | if (WARN_ON(!S)) { ... - return; + return ERR_PTR(-ENOMEM); } | if (S == NULL) { ... - return; + return ERR_PTR(-ENOMEM); } ) ... ( - __drm_atomic_helper_plane_reset(P, PS); + __drm_atomic_helper_plane_state_init(PS, P); | - __drm_gem_reset_shadow_plane(P, PS); + __drm_gem_shadow_plane_state_init(P, PS); ) ... } @update_early_return depends on update_struct@ identifier match_struct_reset.reset_func; identifier renamed_func.new_name; identifier P; expression PS; @@ struct drm_plane_state *new_name(struct drm_plane *P) { <+... - return; + return ERR_PTR(-EINVAL); ...+> } @update_return_plane depends on update_struct@ identifier match_struct_reset.reset_func; identifier renamed_func.new_name; identifier P; expression PS; @@ struct drm_plane_state *new_name(struct drm_plane *P) { ... __drm_atomic_helper_plane_state_init(PS, P); ... + + return PS; } @update_return_shadow depends on update_struct@ identifier renamed_func.new_name; identifier P; expression PS; @@ struct drm_plane_state *new_name(struct drm_plane *P) { ... __drm_gem_shadow_plane_state_init(P, PS); ... + + return &PS->base; } Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com> Link: https://patch.msgid.link/20260814-drm-no-more-plane-reset-v2-24-82d2963dd134@kernel.org Signed-off-by: Maxime Ripard <mripard@kernel.org>
2026-08-21drm/meson: Convert to atomic_create_stateMaxime Ripard
The plane only initializes a pristine state in its reset hook using drm_atomic_helper_plane_reset(), which is equivalent to what atomic_create_state expects. Convert to it. The conversion was done using the following Coccinelle semantic patch: @@ identifier funcs; symbol drm_atomic_helper_plane_reset; symbol drm_atomic_helper_plane_create_state; @@ struct drm_plane_funcs funcs = { ..., - .reset = drm_atomic_helper_plane_reset, + .atomic_create_state = drm_atomic_helper_plane_create_state, ..., }; @match_struct_reset@ identifier funcs, reset_func; @@ struct drm_plane_funcs funcs = { ..., .reset = reset_func, ..., }; @reset_uses_helpers depends on match_struct_reset@ identifier match_struct_reset.reset_func; @@ void reset_func(...) { <+... ( __drm_atomic_helper_plane_reset(...); | __drm_gem_reset_shadow_plane(...); ) ...+> } @match_struct_destroy@ identifier funcs, destroy_func; @@ struct drm_plane_funcs funcs = { ..., .atomic_destroy_state = destroy_func, ..., }; @script:python renamed_func@ old_name << match_struct_reset.reset_func; new_name; @@ if old_name.endswith("_reset"): coccinelle.new_name = old_name.replace("_reset", "_create_state") else: coccinelle.new_name = old_name @update_struct depends on match_struct_reset && reset_uses_helpers@ identifier match_struct_reset.funcs, match_struct_reset.reset_func; identifier renamed_func.new_name; @@ struct drm_plane_funcs funcs = { ..., - .reset = reset_func, + .atomic_create_state = new_name, ..., }; @drop_destroy depends on update_struct && match_struct_destroy@ identifier match_struct_reset.reset_func; identifier match_struct_destroy.destroy_func; identifier container_func; identifier P; symbol drm_atomic_helper_plane_destroy_state; symbol __drm_atomic_helper_plane_destroy_state; @@ void reset_func(struct drm_plane *P) { ... ( - if (P->state) { - <+... ( - drm_atomic_helper_plane_destroy_state(P, P->state); | - __drm_atomic_helper_plane_destroy_state(P->state); | - P->funcs->atomic_destroy_state(P, P->state); | - destroy_func(P, P->state); ) - ...+> - } | - drm_WARN_ON_ONCE(P->dev, P->state); | - WARN_ON(P->state); ) ... ( - kfree(P->state); | - kfree(container_func(P->state)); | // kfree is optional ) ( - P->state = NULL; | // plane->state clearing is optional ) ... } @drop_destroy_mtk depends on update_struct@ identifier P; symbol __drm_atomic_helper_plane_destroy_state; symbol to_mtk_plane_state; @@ void mtk_plane_reset(struct drm_plane *P) { ... - if (P->state) { - __drm_atomic_helper_plane_destroy_state(P->state); - ... - } else { ... - } ... } @transform_nv50_wndw depends on update_struct@ identifier S; @@ void nv50_wndw_reset(...) { ... - if (WARN_ON(!(S = kzalloc_obj(*S)))) + S = kzalloc_obj(*S); + if (WARN_ON(!S)) return; ... } @transform_kzalloc depends on update_struct@ identifier match_struct_reset.reset_func; identifier P, S; statement ST; statement list STL; @@ void reset_func(struct drm_plane *P) { <... S = kzalloc_obj(*S); ( - if (S) - { - STL - } + if (!S) return; + + STL | - if (S) ST + if (!S) return; + + ST ) ...> } @transform_body depends on update_struct@ identifier match_struct_reset.reset_func; identifier renamed_func.new_name; identifier S, P; expression PS; @@ - void reset_func(struct drm_plane *P) + struct drm_plane_state *new_name(struct drm_plane *P) { ... S = kzalloc_obj(*S); ... ( if (!S) { ... - return; + return ERR_PTR(-ENOMEM); } | if (WARN_ON(!S)) { ... - return; + return ERR_PTR(-ENOMEM); } | if (S == NULL) { ... - return; + return ERR_PTR(-ENOMEM); } ) ... ( - __drm_atomic_helper_plane_reset(P, PS); + __drm_atomic_helper_plane_state_init(PS, P); | - __drm_gem_reset_shadow_plane(P, PS); + __drm_gem_shadow_plane_state_init(P, PS); ) ... } @update_early_return depends on update_struct@ identifier match_struct_reset.reset_func; identifier renamed_func.new_name; identifier P; expression PS; @@ struct drm_plane_state *new_name(struct drm_plane *P) { <+... - return; + return ERR_PTR(-EINVAL); ...+> } @update_return_plane depends on update_struct@ identifier match_struct_reset.reset_func; identifier renamed_func.new_name; identifier P; expression PS; @@ struct drm_plane_state *new_name(struct drm_plane *P) { ... __drm_atomic_helper_plane_state_init(PS, P); ... + + return PS; } @update_return_shadow depends on update_struct@ identifier renamed_func.new_name; identifier P; expression PS; @@ struct drm_plane_state *new_name(struct drm_plane *P) { ... __drm_gem_shadow_plane_state_init(P, PS); ... + + return &PS->base; } Reviewed-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com> Link: https://patch.msgid.link/20260814-drm-no-more-plane-reset-v2-23-82d2963dd134@kernel.org Signed-off-by: Maxime Ripard <mripard@kernel.org>
2026-08-21drm/ingenic: Convert to atomic_create_stateMaxime Ripard
The plane only initializes a pristine state in its reset hook using drm_atomic_helper_plane_reset(), which is equivalent to what atomic_create_state expects. Convert to it. The conversion was done using the following Coccinelle semantic patch: @@ identifier funcs; symbol drm_atomic_helper_plane_reset; symbol drm_atomic_helper_plane_create_state; @@ struct drm_plane_funcs funcs = { ..., - .reset = drm_atomic_helper_plane_reset, + .atomic_create_state = drm_atomic_helper_plane_create_state, ..., }; @match_struct_reset@ identifier funcs, reset_func; @@ struct drm_plane_funcs funcs = { ..., .reset = reset_func, ..., }; @reset_uses_helpers depends on match_struct_reset@ identifier match_struct_reset.reset_func; @@ void reset_func(...) { <+... ( __drm_atomic_helper_plane_reset(...); | __drm_gem_reset_shadow_plane(...); ) ...+> } @match_struct_destroy@ identifier funcs, destroy_func; @@ struct drm_plane_funcs funcs = { ..., .atomic_destroy_state = destroy_func, ..., }; @script:python renamed_func@ old_name << match_struct_reset.reset_func; new_name; @@ if old_name.endswith("_reset"): coccinelle.new_name = old_name.replace("_reset", "_create_state") else: coccinelle.new_name = old_name @update_struct depends on match_struct_reset && reset_uses_helpers@ identifier match_struct_reset.funcs, match_struct_reset.reset_func; identifier renamed_func.new_name; @@ struct drm_plane_funcs funcs = { ..., - .reset = reset_func, + .atomic_create_state = new_name, ..., }; @drop_destroy depends on update_struct && match_struct_destroy@ identifier match_struct_reset.reset_func; identifier match_struct_destroy.destroy_func; identifier container_func; identifier P; symbol drm_atomic_helper_plane_destroy_state; symbol __drm_atomic_helper_plane_destroy_state; @@ void reset_func(struct drm_plane *P) { ... ( - if (P->state) { - <+... ( - drm_atomic_helper_plane_destroy_state(P, P->state); | - __drm_atomic_helper_plane_destroy_state(P->state); | - P->funcs->atomic_destroy_state(P, P->state); | - destroy_func(P, P->state); ) - ...+> - } | - drm_WARN_ON_ONCE(P->dev, P->state); | - WARN_ON(P->state); ) ... ( - kfree(P->state); | - kfree(container_func(P->state)); | // kfree is optional ) ( - P->state = NULL; | // plane->state clearing is optional ) ... } @drop_destroy_mtk depends on update_struct@ identifier P; symbol __drm_atomic_helper_plane_destroy_state; symbol to_mtk_plane_state; @@ void mtk_plane_reset(struct drm_plane *P) { ... - if (P->state) { - __drm_atomic_helper_plane_destroy_state(P->state); - ... - } else { ... - } ... } @transform_nv50_wndw depends on update_struct@ identifier S; @@ void nv50_wndw_reset(...) { ... - if (WARN_ON(!(S = kzalloc_obj(*S)))) + S = kzalloc_obj(*S); + if (WARN_ON(!S)) return; ... } @transform_kzalloc depends on update_struct@ identifier match_struct_reset.reset_func; identifier P, S; statement ST; statement list STL; @@ void reset_func(struct drm_plane *P) { <... S = kzalloc_obj(*S); ( - if (S) - { - STL - } + if (!S) return; + + STL | - if (S) ST + if (!S) return; + + ST ) ...> } @transform_body depends on update_struct@ identifier match_struct_reset.reset_func; identifier renamed_func.new_name; identifier S, P; expression PS; @@ - void reset_func(struct drm_plane *P) + struct drm_plane_state *new_name(struct drm_plane *P) { ... S = kzalloc_obj(*S); ... ( if (!S) { ... - return; + return ERR_PTR(-ENOMEM); } | if (WARN_ON(!S)) { ... - return; + return ERR_PTR(-ENOMEM); } | if (S == NULL) { ... - return; + return ERR_PTR(-ENOMEM); } ) ... ( - __drm_atomic_helper_plane_reset(P, PS); + __drm_atomic_helper_plane_state_init(PS, P); | - __drm_gem_reset_shadow_plane(P, PS); + __drm_gem_shadow_plane_state_init(P, PS); ) ... } @update_early_return depends on update_struct@ identifier match_struct_reset.reset_func; identifier renamed_func.new_name; identifier P; expression PS; @@ struct drm_plane_state *new_name(struct drm_plane *P) { <+... - return; + return ERR_PTR(-EINVAL); ...+> } @update_return_plane depends on update_struct@ identifier match_struct_reset.reset_func; identifier renamed_func.new_name; identifier P; expression PS; @@ struct drm_plane_state *new_name(struct drm_plane *P) { ... __drm_atomic_helper_plane_state_init(PS, P); ... + + return PS; } @update_return_shadow depends on update_struct@ identifier renamed_func.new_name; identifier P; expression PS; @@ struct drm_plane_state *new_name(struct drm_plane *P) { ... __drm_gem_shadow_plane_state_init(P, PS); ... + + return &PS->base; } Acked-by: Paul Cercueil <paul@crapouillou.net> Link: https://patch.msgid.link/20260814-drm-no-more-plane-reset-v2-19-82d2963dd134@kernel.org Signed-off-by: Maxime Ripard <mripard@kernel.org>
2026-08-21drm/imx/dcss: Convert to atomic_create_stateMaxime Ripard
The plane only initializes a pristine state in its reset hook using drm_atomic_helper_plane_reset(), which is equivalent to what atomic_create_state expects. Convert to it. The conversion was done using the following Coccinelle semantic patch: @@ identifier funcs; symbol drm_atomic_helper_plane_reset; symbol drm_atomic_helper_plane_create_state; @@ struct drm_plane_funcs funcs = { ..., - .reset = drm_atomic_helper_plane_reset, + .atomic_create_state = drm_atomic_helper_plane_create_state, ..., }; @match_struct_reset@ identifier funcs, reset_func; @@ struct drm_plane_funcs funcs = { ..., .reset = reset_func, ..., }; @reset_uses_helpers depends on match_struct_reset@ identifier match_struct_reset.reset_func; @@ void reset_func(...) { <+... ( __drm_atomic_helper_plane_reset(...); | __drm_gem_reset_shadow_plane(...); ) ...+> } @match_struct_destroy@ identifier funcs, destroy_func; @@ struct drm_plane_funcs funcs = { ..., .atomic_destroy_state = destroy_func, ..., }; @script:python renamed_func@ old_name << match_struct_reset.reset_func; new_name; @@ if old_name.endswith("_reset"): coccinelle.new_name = old_name.replace("_reset", "_create_state") else: coccinelle.new_name = old_name @update_struct depends on match_struct_reset && reset_uses_helpers@ identifier match_struct_reset.funcs, match_struct_reset.reset_func; identifier renamed_func.new_name; @@ struct drm_plane_funcs funcs = { ..., - .reset = reset_func, + .atomic_create_state = new_name, ..., }; @drop_destroy depends on update_struct && match_struct_destroy@ identifier match_struct_reset.reset_func; identifier match_struct_destroy.destroy_func; identifier container_func; identifier P; symbol drm_atomic_helper_plane_destroy_state; symbol __drm_atomic_helper_plane_destroy_state; @@ void reset_func(struct drm_plane *P) { ... ( - if (P->state) { - <+... ( - drm_atomic_helper_plane_destroy_state(P, P->state); | - __drm_atomic_helper_plane_destroy_state(P->state); | - P->funcs->atomic_destroy_state(P, P->state); | - destroy_func(P, P->state); ) - ...+> - } | - drm_WARN_ON_ONCE(P->dev, P->state); | - WARN_ON(P->state); ) ... ( - kfree(P->state); | - kfree(container_func(P->state)); | // kfree is optional ) ( - P->state = NULL; | // plane->state clearing is optional ) ... } @drop_destroy_mtk depends on update_struct@ identifier P; symbol __drm_atomic_helper_plane_destroy_state; symbol to_mtk_plane_state; @@ void mtk_plane_reset(struct drm_plane *P) { ... - if (P->state) { - __drm_atomic_helper_plane_destroy_state(P->state); - ... - } else { ... - } ... } @transform_nv50_wndw depends on update_struct@ identifier S; @@ void nv50_wndw_reset(...) { ... - if (WARN_ON(!(S = kzalloc_obj(*S)))) + S = kzalloc_obj(*S); + if (WARN_ON(!S)) return; ... } @transform_kzalloc depends on update_struct@ identifier match_struct_reset.reset_func; identifier P, S; statement ST; statement list STL; @@ void reset_func(struct drm_plane *P) { <... S = kzalloc_obj(*S); ( - if (S) - { - STL - } + if (!S) return; + + STL | - if (S) ST + if (!S) return; + + ST ) ...> } @transform_body depends on update_struct@ identifier match_struct_reset.reset_func; identifier renamed_func.new_name; identifier S, P; expression PS; @@ - void reset_func(struct drm_plane *P) + struct drm_plane_state *new_name(struct drm_plane *P) { ... S = kzalloc_obj(*S); ... ( if (!S) { ... - return; + return ERR_PTR(-ENOMEM); } | if (WARN_ON(!S)) { ... - return; + return ERR_PTR(-ENOMEM); } | if (S == NULL) { ... - return; + return ERR_PTR(-ENOMEM); } ) ... ( - __drm_atomic_helper_plane_reset(P, PS); + __drm_atomic_helper_plane_state_init(PS, P); | - __drm_gem_reset_shadow_plane(P, PS); + __drm_gem_shadow_plane_state_init(P, PS); ) ... } @update_early_return depends on update_struct@ identifier match_struct_reset.reset_func; identifier renamed_func.new_name; identifier P; expression PS; @@ struct drm_plane_state *new_name(struct drm_plane *P) { <+... - return; + return ERR_PTR(-EINVAL); ...+> } @update_return_plane depends on update_struct@ identifier match_struct_reset.reset_func; identifier renamed_func.new_name; identifier P; expression PS; @@ struct drm_plane_state *new_name(struct drm_plane *P) { ... __drm_atomic_helper_plane_state_init(PS, P); ... + + return PS; } @update_return_shadow depends on update_struct@ identifier renamed_func.new_name; identifier P; expression PS; @@ struct drm_plane_state *new_name(struct drm_plane *P) { ... __drm_gem_shadow_plane_state_init(P, PS); ... + + return &PS->base; } Reviewed-by: Laurentiu Palcu <laurentiu.palcu@oss.nxp.com> Link: https://patch.msgid.link/20260814-drm-no-more-plane-reset-v2-18-82d2963dd134@kernel.org Signed-off-by: Maxime Ripard <mripard@kernel.org>
2026-08-21drm/hdlcd: Convert to atomic_create_stateMaxime Ripard
The plane only initializes a pristine state in its reset hook using drm_atomic_helper_plane_reset(), which is equivalent to what atomic_create_state expects. Convert to it. The conversion was done using the following Coccinelle semantic patch: @@ identifier funcs; symbol drm_atomic_helper_plane_reset; symbol drm_atomic_helper_plane_create_state; @@ struct drm_plane_funcs funcs = { ..., - .reset = drm_atomic_helper_plane_reset, + .atomic_create_state = drm_atomic_helper_plane_create_state, ..., }; @match_struct_reset@ identifier funcs, reset_func; @@ struct drm_plane_funcs funcs = { ..., .reset = reset_func, ..., }; @reset_uses_helpers depends on match_struct_reset@ identifier match_struct_reset.reset_func; @@ void reset_func(...) { <+... ( __drm_atomic_helper_plane_reset(...); | __drm_gem_reset_shadow_plane(...); ) ...+> } @match_struct_destroy@ identifier funcs, destroy_func; @@ struct drm_plane_funcs funcs = { ..., .atomic_destroy_state = destroy_func, ..., }; @script:python renamed_func@ old_name << match_struct_reset.reset_func; new_name; @@ if old_name.endswith("_reset"): coccinelle.new_name = old_name.replace("_reset", "_create_state") else: coccinelle.new_name = old_name @update_struct depends on match_struct_reset && reset_uses_helpers@ identifier match_struct_reset.funcs, match_struct_reset.reset_func; identifier renamed_func.new_name; @@ struct drm_plane_funcs funcs = { ..., - .reset = reset_func, + .atomic_create_state = new_name, ..., }; @drop_destroy depends on update_struct && match_struct_destroy@ identifier match_struct_reset.reset_func; identifier match_struct_destroy.destroy_func; identifier container_func; identifier P; symbol drm_atomic_helper_plane_destroy_state; symbol __drm_atomic_helper_plane_destroy_state; @@ void reset_func(struct drm_plane *P) { ... ( - if (P->state) { - <+... ( - drm_atomic_helper_plane_destroy_state(P, P->state); | - __drm_atomic_helper_plane_destroy_state(P->state); | - P->funcs->atomic_destroy_state(P, P->state); | - destroy_func(P, P->state); ) - ...+> - } | - drm_WARN_ON_ONCE(P->dev, P->state); | - WARN_ON(P->state); ) ... ( - kfree(P->state); | - kfree(container_func(P->state)); | // kfree is optional ) ( - P->state = NULL; | // plane->state clearing is optional ) ... } @drop_destroy_mtk depends on update_struct@ identifier P; symbol __drm_atomic_helper_plane_destroy_state; symbol to_mtk_plane_state; @@ void mtk_plane_reset(struct drm_plane *P) { ... - if (P->state) { - __drm_atomic_helper_plane_destroy_state(P->state); - ... - } else { ... - } ... } @transform_nv50_wndw depends on update_struct@ identifier S; @@ void nv50_wndw_reset(...) { ... - if (WARN_ON(!(S = kzalloc_obj(*S)))) + S = kzalloc_obj(*S); + if (WARN_ON(!S)) return; ... } @transform_kzalloc depends on update_struct@ identifier match_struct_reset.reset_func; identifier P, S; statement ST; statement list STL; @@ void reset_func(struct drm_plane *P) { <... S = kzalloc_obj(*S); ( - if (S) - { - STL - } + if (!S) return; + + STL | - if (S) ST + if (!S) return; + + ST ) ...> } @transform_body depends on update_struct@ identifier match_struct_reset.reset_func; identifier renamed_func.new_name; identifier S, P; expression PS; @@ - void reset_func(struct drm_plane *P) + struct drm_plane_state *new_name(struct drm_plane *P) { ... S = kzalloc_obj(*S); ... ( if (!S) { ... - return; + return ERR_PTR(-ENOMEM); } | if (WARN_ON(!S)) { ... - return; + return ERR_PTR(-ENOMEM); } | if (S == NULL) { ... - return; + return ERR_PTR(-ENOMEM); } ) ... ( - __drm_atomic_helper_plane_reset(P, PS); + __drm_atomic_helper_plane_state_init(PS, P); | - __drm_gem_reset_shadow_plane(P, PS); + __drm_gem_shadow_plane_state_init(P, PS); ) ... } @update_early_return depends on update_struct@ identifier match_struct_reset.reset_func; identifier renamed_func.new_name; identifier P; expression PS; @@ struct drm_plane_state *new_name(struct drm_plane *P) { <+... - return; + return ERR_PTR(-EINVAL); ...+> } @update_return_plane depends on update_struct@ identifier match_struct_reset.reset_func; identifier renamed_func.new_name; identifier P; expression PS; @@ struct drm_plane_state *new_name(struct drm_plane *P) { ... __drm_atomic_helper_plane_state_init(PS, P); ... + + return PS; } @update_return_shadow depends on update_struct@ identifier renamed_func.new_name; identifier P; expression PS; @@ struct drm_plane_state *new_name(struct drm_plane *P) { ... __drm_gem_shadow_plane_state_init(P, PS); ... + + return &PS->base; } Reviewed-by: Liviu Dudau <liviu.dudau@arm.com> Link: https://patch.msgid.link/20260814-drm-no-more-plane-reset-v2-14-82d2963dd134@kernel.org Signed-off-by: Maxime Ripard <mripard@kernel.org>
2026-08-21drm/appletbdrm: Convert to atomic_create_stateMaxime Ripard
The plane reset implementation creates a custom state subclass, but only initializes a pristine state without resetting any hardware. This is equivalent to what atomic_create_state expects. Convert to it. The conversion was done using the following Coccinelle semantic patch: @@ identifier funcs; symbol drm_atomic_helper_plane_reset; symbol drm_atomic_helper_plane_create_state; @@ struct drm_plane_funcs funcs = { ..., - .reset = drm_atomic_helper_plane_reset, + .atomic_create_state = drm_atomic_helper_plane_create_state, ..., }; @match_struct_reset@ identifier funcs, reset_func; @@ struct drm_plane_funcs funcs = { ..., .reset = reset_func, ..., }; @reset_uses_helpers depends on match_struct_reset@ identifier match_struct_reset.reset_func; @@ void reset_func(...) { <+... ( __drm_atomic_helper_plane_reset(...); | __drm_gem_reset_shadow_plane(...); ) ...+> } @match_struct_destroy@ identifier funcs, destroy_func; @@ struct drm_plane_funcs funcs = { ..., .atomic_destroy_state = destroy_func, ..., }; @script:python renamed_func@ old_name << match_struct_reset.reset_func; new_name; @@ if old_name.endswith("_reset"): coccinelle.new_name = old_name.replace("_reset", "_create_state") else: coccinelle.new_name = old_name @update_struct depends on match_struct_reset && reset_uses_helpers@ identifier match_struct_reset.funcs, match_struct_reset.reset_func; identifier renamed_func.new_name; @@ struct drm_plane_funcs funcs = { ..., - .reset = reset_func, + .atomic_create_state = new_name, ..., }; @drop_destroy depends on update_struct && match_struct_destroy@ identifier match_struct_reset.reset_func; identifier match_struct_destroy.destroy_func; identifier container_func; identifier P; symbol drm_atomic_helper_plane_destroy_state; symbol __drm_atomic_helper_plane_destroy_state; @@ void reset_func(struct drm_plane *P) { ... ( - if (P->state) { - <+... ( - drm_atomic_helper_plane_destroy_state(P, P->state); | - __drm_atomic_helper_plane_destroy_state(P->state); | - P->funcs->atomic_destroy_state(P, P->state); | - destroy_func(P, P->state); ) - ...+> - } | - drm_WARN_ON_ONCE(P->dev, P->state); | - WARN_ON(P->state); ) ... ( - kfree(P->state); | - kfree(container_func(P->state)); | // kfree is optional ) ( - P->state = NULL; | // plane->state clearing is optional ) ... } @drop_destroy_mtk depends on update_struct@ identifier P; symbol __drm_atomic_helper_plane_destroy_state; symbol to_mtk_plane_state; @@ void mtk_plane_reset(struct drm_plane *P) { ... - if (P->state) { - __drm_atomic_helper_plane_destroy_state(P->state); - ... - } else { ... - } ... } @transform_nv50_wndw depends on update_struct@ identifier S; @@ void nv50_wndw_reset(...) { ... - if (WARN_ON(!(S = kzalloc_obj(*S)))) + S = kzalloc_obj(*S); + if (WARN_ON(!S)) return; ... } @transform_kzalloc depends on update_struct@ identifier match_struct_reset.reset_func; identifier P, S; statement ST; statement list STL; @@ void reset_func(struct drm_plane *P) { <... S = kzalloc_obj(*S); ( - if (S) - { - STL - } + if (!S) return; + + STL | - if (S) ST + if (!S) return; + + ST ) ...> } @transform_body depends on update_struct@ identifier match_struct_reset.reset_func; identifier renamed_func.new_name; identifier S, P; expression PS; @@ - void reset_func(struct drm_plane *P) + struct drm_plane_state *new_name(struct drm_plane *P) { ... S = kzalloc_obj(*S); ... ( if (!S) { ... - return; + return ERR_PTR(-ENOMEM); } | if (WARN_ON(!S)) { ... - return; + return ERR_PTR(-ENOMEM); } | if (S == NULL) { ... - return; + return ERR_PTR(-ENOMEM); } ) ... ( - __drm_atomic_helper_plane_reset(P, PS); + __drm_atomic_helper_plane_state_init(PS, P); | - __drm_gem_reset_shadow_plane(P, PS); + __drm_gem_shadow_plane_state_init(P, PS); ) ... } @update_early_return depends on update_struct@ identifier match_struct_reset.reset_func; identifier renamed_func.new_name; identifier P; expression PS; @@ struct drm_plane_state *new_name(struct drm_plane *P) { <+... - return; + return ERR_PTR(-EINVAL); ...+> } @update_return_plane depends on update_struct@ identifier match_struct_reset.reset_func; identifier renamed_func.new_name; identifier P; expression PS; @@ struct drm_plane_state *new_name(struct drm_plane *P) { ... __drm_atomic_helper_plane_state_init(PS, P); ... + + return PS; } @update_return_shadow depends on update_struct@ identifier renamed_func.new_name; identifier P; expression PS; @@ struct drm_plane_state *new_name(struct drm_plane *P) { ... __drm_gem_shadow_plane_state_init(P, PS); ... + + return &PS->base; } Acked-by: Aditya Garg <gargaditya08@proton.me> Link: https://patch.msgid.link/20260814-drm-no-more-plane-reset-v2-10-82d2963dd134@kernel.org Signed-off-by: Maxime Ripard <mripard@kernel.org>
2026-08-21drm/st7920: Convert to atomic_create_stateMaxime Ripard
The plane reset implementation creates a custom state subclass, but only initializes a pristine state without resetting any hardware. This is equivalent to what atomic_create_state expects. Convert to it. The conversion was done using the following Coccinelle semantic patch: @@ identifier funcs; symbol drm_atomic_helper_plane_reset; symbol drm_atomic_helper_plane_create_state; @@ struct drm_plane_funcs funcs = { ..., - .reset = drm_atomic_helper_plane_reset, + .atomic_create_state = drm_atomic_helper_plane_create_state, ..., }; @match_struct_reset@ identifier funcs, reset_func; @@ struct drm_plane_funcs funcs = { ..., .reset = reset_func, ..., }; @reset_uses_helpers depends on match_struct_reset@ identifier match_struct_reset.reset_func; @@ void reset_func(...) { <+... ( __drm_atomic_helper_plane_reset(...); | __drm_gem_reset_shadow_plane(...); ) ...+> } @match_struct_destroy@ identifier funcs, destroy_func; @@ struct drm_plane_funcs funcs = { ..., .atomic_destroy_state = destroy_func, ..., }; @script:python renamed_func@ old_name << match_struct_reset.reset_func; new_name; @@ if old_name.endswith("_reset"): coccinelle.new_name = old_name.replace("_reset", "_create_state") else: coccinelle.new_name = old_name @update_struct depends on match_struct_reset && reset_uses_helpers@ identifier match_struct_reset.funcs, match_struct_reset.reset_func; identifier renamed_func.new_name; @@ struct drm_plane_funcs funcs = { ..., - .reset = reset_func, + .atomic_create_state = new_name, ..., }; @drop_destroy depends on update_struct && match_struct_destroy@ identifier match_struct_reset.reset_func; identifier match_struct_destroy.destroy_func; identifier container_func; identifier P; symbol drm_atomic_helper_plane_destroy_state; symbol __drm_atomic_helper_plane_destroy_state; @@ void reset_func(struct drm_plane *P) { ... ( - if (P->state) { - <+... ( - drm_atomic_helper_plane_destroy_state(P, P->state); | - __drm_atomic_helper_plane_destroy_state(P->state); | - P->funcs->atomic_destroy_state(P, P->state); | - destroy_func(P, P->state); ) - ...+> - } | - drm_WARN_ON_ONCE(P->dev, P->state); | - WARN_ON(P->state); ) ... ( - kfree(P->state); | - kfree(container_func(P->state)); | // kfree is optional ) ( - P->state = NULL; | // plane->state clearing is optional ) ... } @drop_destroy_mtk depends on update_struct@ identifier P; symbol __drm_atomic_helper_plane_destroy_state; symbol to_mtk_plane_state; @@ void mtk_plane_reset(struct drm_plane *P) { ... - if (P->state) { - __drm_atomic_helper_plane_destroy_state(P->state); - ... - } else { ... - } ... } @transform_nv50_wndw depends on update_struct@ identifier S; @@ void nv50_wndw_reset(...) { ... - if (WARN_ON(!(S = kzalloc_obj(*S)))) + S = kzalloc_obj(*S); + if (WARN_ON(!S)) return; ... } @transform_kzalloc depends on update_struct@ identifier match_struct_reset.reset_func; identifier P, S; statement ST; statement list STL; @@ void reset_func(struct drm_plane *P) { <... S = kzalloc_obj(*S); ( - if (S) - { - STL - } + if (!S) return; + + STL | - if (S) ST + if (!S) return; + + ST ) ...> } @transform_body depends on update_struct@ identifier match_struct_reset.reset_func; identifier renamed_func.new_name; identifier S, P; expression PS; @@ - void reset_func(struct drm_plane *P) + struct drm_plane_state *new_name(struct drm_plane *P) { ... S = kzalloc_obj(*S); ... ( if (!S) { ... - return; + return ERR_PTR(-ENOMEM); } | if (WARN_ON(!S)) { ... - return; + return ERR_PTR(-ENOMEM); } | if (S == NULL) { ... - return; + return ERR_PTR(-ENOMEM); } ) ... ( - __drm_atomic_helper_plane_reset(P, PS); + __drm_atomic_helper_plane_state_init(PS, P); | - __drm_gem_reset_shadow_plane(P, PS); + __drm_gem_shadow_plane_state_init(P, PS); ) ... } @update_early_return depends on update_struct@ identifier match_struct_reset.reset_func; identifier renamed_func.new_name; identifier P; expression PS; @@ struct drm_plane_state *new_name(struct drm_plane *P) { <+... - return; + return ERR_PTR(-EINVAL); ...+> } @update_return_plane depends on update_struct@ identifier match_struct_reset.reset_func; identifier renamed_func.new_name; identifier P; expression PS; @@ struct drm_plane_state *new_name(struct drm_plane *P) { ... __drm_atomic_helper_plane_state_init(PS, P); ... + + return PS; } @update_return_shadow depends on update_struct@ identifier renamed_func.new_name; identifier P; expression PS; @@ struct drm_plane_state *new_name(struct drm_plane *P) { ... __drm_gem_shadow_plane_state_init(P, PS); ... + + return &PS->base; } Reviewed-by: Iker Pedrosa <ikerpedrosam@gmail.com> Link: https://patch.msgid.link/20260814-drm-no-more-plane-reset-v2-9-82d2963dd134@kernel.org Signed-off-by: Maxime Ripard <mripard@kernel.org>
2026-08-21drm/ssd130x: Convert to atomic_create_stateMaxime Ripard
The plane reset implementation creates a custom state subclass, but only initializes a pristine state without resetting any hardware. This is equivalent to what atomic_create_state expects. Convert to it. The conversion was done using the following Coccinelle semantic patch: @@ identifier funcs; symbol drm_atomic_helper_plane_reset; symbol drm_atomic_helper_plane_create_state; @@ struct drm_plane_funcs funcs = { ..., - .reset = drm_atomic_helper_plane_reset, + .atomic_create_state = drm_atomic_helper_plane_create_state, ..., }; @match_struct_reset@ identifier funcs, reset_func; @@ struct drm_plane_funcs funcs = { ..., .reset = reset_func, ..., }; @reset_uses_helpers depends on match_struct_reset@ identifier match_struct_reset.reset_func; @@ void reset_func(...) { <+... ( __drm_atomic_helper_plane_reset(...); | __drm_gem_reset_shadow_plane(...); ) ...+> } @match_struct_destroy@ identifier funcs, destroy_func; @@ struct drm_plane_funcs funcs = { ..., .atomic_destroy_state = destroy_func, ..., }; @script:python renamed_func@ old_name << match_struct_reset.reset_func; new_name; @@ if old_name.endswith("_reset"): coccinelle.new_name = old_name.replace("_reset", "_create_state") else: coccinelle.new_name = old_name @update_struct depends on match_struct_reset && reset_uses_helpers@ identifier match_struct_reset.funcs, match_struct_reset.reset_func; identifier renamed_func.new_name; @@ struct drm_plane_funcs funcs = { ..., - .reset = reset_func, + .atomic_create_state = new_name, ..., }; @drop_destroy depends on update_struct && match_struct_destroy@ identifier match_struct_reset.reset_func; identifier match_struct_destroy.destroy_func; identifier container_func; identifier P; symbol drm_atomic_helper_plane_destroy_state; symbol __drm_atomic_helper_plane_destroy_state; @@ void reset_func(struct drm_plane *P) { ... ( - if (P->state) { - <+... ( - drm_atomic_helper_plane_destroy_state(P, P->state); | - __drm_atomic_helper_plane_destroy_state(P->state); | - P->funcs->atomic_destroy_state(P, P->state); | - destroy_func(P, P->state); ) - ...+> - } | - drm_WARN_ON_ONCE(P->dev, P->state); | - WARN_ON(P->state); ) ... ( - kfree(P->state); | - kfree(container_func(P->state)); | // kfree is optional ) ( - P->state = NULL; | // plane->state clearing is optional ) ... } @drop_destroy_mtk depends on update_struct@ identifier P; symbol __drm_atomic_helper_plane_destroy_state; symbol to_mtk_plane_state; @@ void mtk_plane_reset(struct drm_plane *P) { ... - if (P->state) { - __drm_atomic_helper_plane_destroy_state(P->state); - ... - } else { ... - } ... } @transform_nv50_wndw depends on update_struct@ identifier S; @@ void nv50_wndw_reset(...) { ... - if (WARN_ON(!(S = kzalloc_obj(*S)))) + S = kzalloc_obj(*S); + if (WARN_ON(!S)) return; ... } @transform_kzalloc depends on update_struct@ identifier match_struct_reset.reset_func; identifier P, S; statement ST; statement list STL; @@ void reset_func(struct drm_plane *P) { <... S = kzalloc_obj(*S); ( - if (S) - { - STL - } + if (!S) return; + + STL | - if (S) ST + if (!S) return; + + ST ) ...> } @transform_body depends on update_struct@ identifier match_struct_reset.reset_func; identifier renamed_func.new_name; identifier S, P; expression PS; @@ - void reset_func(struct drm_plane *P) + struct drm_plane_state *new_name(struct drm_plane *P) { ... S = kzalloc_obj(*S); ... ( if (!S) { ... - return; + return ERR_PTR(-ENOMEM); } | if (WARN_ON(!S)) { ... - return; + return ERR_PTR(-ENOMEM); } | if (S == NULL) { ... - return; + return ERR_PTR(-ENOMEM); } ) ... ( - __drm_atomic_helper_plane_reset(P, PS); + __drm_atomic_helper_plane_state_init(PS, P); | - __drm_gem_reset_shadow_plane(P, PS); + __drm_gem_shadow_plane_state_init(P, PS); ) ... } @update_early_return depends on update_struct@ identifier match_struct_reset.reset_func; identifier renamed_func.new_name; identifier P; expression PS; @@ struct drm_plane_state *new_name(struct drm_plane *P) { <+... - return; + return ERR_PTR(-EINVAL); ...+> } @update_return_plane depends on update_struct@ identifier match_struct_reset.reset_func; identifier renamed_func.new_name; identifier P; expression PS; @@ struct drm_plane_state *new_name(struct drm_plane *P) { ... __drm_atomic_helper_plane_state_init(PS, P); ... + + return PS; } @update_return_shadow depends on update_struct@ identifier renamed_func.new_name; identifier P; expression PS; @@ struct drm_plane_state *new_name(struct drm_plane *P) { ... __drm_gem_shadow_plane_state_init(P, PS); ... + + return &PS->base; } Reviewed-by: Javier Martinez Canillas <javierm@redhat.com> Link: https://patch.msgid.link/20260814-drm-no-more-plane-reset-v2-8-82d2963dd134@kernel.org Signed-off-by: Maxime Ripard <mripard@kernel.org>
2026-08-21drm/simple-kms: Switch to atomic_create_stateMaxime Ripard
drm_simple_kms_plane_reset() handled three cases: delegating to reset_plane, using create_plane_state with manual teardown, or falling back to the default helper. This complexity existed to bridge the old reset hook with the new create_plane_state hook during the transition. Now that all simple-kms drivers implement create_plane_state instead of reset_plane, replace drm_simple_kms_plane_reset() with drm_simple_kms_plane_create_state() which only dispatches between create_plane_state and drm_atomic_helper_plane_create_state(). Wire it to .atomic_create_state instead of .reset. Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de> Link: https://patch.msgid.link/20260814-drm-no-more-plane-reset-v2-7-82d2963dd134@kernel.org Signed-off-by: Maxime Ripard <mripard@kernel.org>
2026-08-21drm/sysfb: Convert to atomic_create_stateMaxime Ripard
drm_sysfb_plane_reset() handles both state creation and teardown of the previous state through the reset hook, which conflates initial state allocation with hardware and software reset at resume. Convert it to drm_sysfb_plane_atomic_create_state(), which only allocates and initializes a pristine state using __drm_gem_shadow_plane_state_init(). Update DRM_SYSFB_PLANE_FUNCS to use .atomic_create_state instead of .reset. Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de> Link: https://patch.msgid.link/20260814-drm-no-more-plane-reset-v2-6-82d2963dd134@kernel.org Signed-off-by: Maxime Ripard <mripard@kernel.org>
2026-08-21drm/gem-atomic-helper: Remove drm_gem_reset_shadow_plane()Maxime Ripard
drm_gem_reset_shadow_plane() is no longer used: all callers now go through drm_gem_create_shadow_plane_state() via the atomic_create_state hook. Remove it. Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de> Link: https://patch.msgid.link/20260814-drm-no-more-plane-reset-v2-5-82d2963dd134@kernel.org Signed-off-by: Maxime Ripard <mripard@kernel.org>
2026-08-21drm/gem-atomic-helper: Convert simple-kms shadow helpers to create_plane_stateMaxime Ripard
drm_gem_simple_kms_reset_shadow_plane() implements the reset_plane hook for simple-kms shadow-buffered planes. Since the reset hook conflates initial state creation with hardware and software reset during suspend/resume, convert it to the create_plane_state pattern. Replace it with drm_gem_simple_kms_create_shadow_plane_state(), which implements the create_plane_state hook using drm_gem_create_shadow_plane_state(). Update DRM_GEM_SIMPLE_DISPLAY_PIPE_SHADOW_PLANE_FUNCS accordingly. Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de> Link: https://patch.msgid.link/20260814-drm-no-more-plane-reset-v2-3-82d2963dd134@kernel.org Signed-off-by: Maxime Ripard <mripard@kernel.org>
2026-08-21drm/gem-atomic-helper: Create drm_gem_create_shadow_plane_state()Maxime Ripard
The GEM shadow-plane helpers only expose reset functions (drm_gem_reset_shadow_plane and __drm_gem_reset_shadow_plane) that handle both the initial state allocation and the reset path. The new atomic_create_state hook requires a function that only allocates and initializes a pristine state without any side effect. Create __drm_gem_shadow_plane_state_init() to initialize a pre-allocated shadow plane state, and drm_gem_create_shadow_plane_state() to allocate and initialize one from scratch. Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de> Link: https://patch.msgid.link/20260814-drm-no-more-plane-reset-v2-2-82d2963dd134@kernel.org Signed-off-by: Maxime Ripard <mripard@kernel.org>
2026-08-21drm/simple-kms: Add create_plane_state hookMaxime Ripard
The simple-kms helper provides a reset_plane hook to let drivers override the default plane reset. However, the reset hook is overloaded: it is used to create the initial software state at probe time, but also to reset both the hardware and software state during suspend/resume. These two roles have different expectations, and reset is not fallible which makes error handling difficult. The atomic_create_state pattern was introduced to untangle this by providing a hook that only allocates and initializes a pristine state without any side effect. Add a create_plane_state hook to struct drm_simple_display_pipe_funcs. When provided, drm_simple_kms_plane_reset() will use it to allocate a fresh state, falling back to reset_plane and then to the default drm_atomic_helper_plane_reset(). This will allow simple-kms drivers to be converted to the atomic_create_state pattern. Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de> Link: https://patch.msgid.link/20260814-drm-no-more-plane-reset-v2-1-82d2963dd134@kernel.org Signed-off-by: Maxime Ripard <mripard@kernel.org>
2026-08-21drm/i915/cdclk: Introduce has_cd2x_pipe_select()Ville Syrjälä
We have several open coded checks for the platform's cd2x pipe select capability, each written slightly differently. Move it all into a common has_cd2x_pipe_select() helper. No functional changes as the previous 'DISPLAY_VER < 30' checks were in codepaths that already exclude pre-bxt platforms, and intel_cdclk_can_cd2x_update() already rejects PTL+ via the later HAS_CDCLK_SQUASH() check. Also update the docs for the register bitfield while at it. Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patch.msgid.link/20260717155107.17801-2-ville.syrjala@linux.intel.com Reviewed-by: Suraj Kandpal <suraj.kandpal@intel.com>
2026-08-21drm/i915/cdclk: Avoid spurious cdclk sanitization on PTL+Ville Syrjälä
Apparently PTL+ no longer has the cd2x pipe select field in CDCLK_CTL. Take that into account during CDCLK sanitization. This currently triggers a spurious CDCLK sanitization during driver load on PTL+ which will causes a visible glitch on all active displays. Cc: stable@vger.kernel.org Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/work_items/8550 Fixes: 3f9de66f8acb ("drm/i915/cdclk: Fix up CDCLK_FREQ_DECIMAL without a full PLL re-enable") Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patch.msgid.link/20260717155107.17801-1-ville.syrjala@linux.intel.com Reviewed-by: Suraj Kandpal <suraj.kandpal@intel.com>
2026-08-21drm/i915/selftests: Report missing RC0 power as an errorSk Anirban
The RC0 no-power case is a hard failure (-EINVAL); log it via pr_err instead of pr_debug so it is captured in default kernel logs. Signed-off-by: Sk Anirban <sk.anirban@intel.com> Reviewed-by: Badal Nilawar <badal.nilawar@intel.com> Reviewed-by: Andi Shyti <andi.shyti@linux.intel.com> Signed-off-by: Andi Shyti <andi.shyti@linux.intel.com> Link: https://patch.msgid.link/20260729112446.2919206-2-sk.anirban@intel.com
2026-08-21drm: of: Fix drm_of_get_data_lanes_count_ep() return value documentationMarek Vasut
Update drm_of_get_data_lanes_count_ep() return value documentation to match the drm_of_get_data_lanes_count() return value documentation. The drm_of_get_data_lanes_count_ep() is only a wrapper around the drm_of_get_data_lanes_count() and therefore returns the same error codes. Simplify the return code description of drm_of_get_data_lanes_count() and drm_of_get_data_lanes_count_ep() to -ENODATA and -EINVAL. Fixes: fc801750b197 ("drm: of: Add drm_of_get_data_lanes_count and drm_of_get_data_lanes_ep") Reported-by: Geert Uytterhoeven <geert+renesas@glider.be> Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org> Reviewed-by: Maxime Ripard <mripard@kernel.org> Link: https://patch.msgid.link/20260305205840.95978-1-marek.vasut+renesas@mailbox.org Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
2026-08-21drm/omap: Report HDMI hotplug events to the ASoC HDMI codecIvaylo Dimitrov
The OMAP HDMI audio driver currently has no way of reporting HDMI cable hotplug events to ASoC. As a result, user space cannot detect HDMI audio availability through the standard jack mechanism and audio policy managers cannot automatically route audio to or from the HDMI output. Add an optional HPD callback to `omap_hdmi_audio_pdata` and invoke it from the DRM HDMI bridge whenever the connector status changes. The HDMI audio driver registers an ASoC jack and reports `SND_JACK_AVOUT` state changes in response to these notifications. Also fix the disconnect path by taking a runtime PM reference before updating the CEC physical address. Signed-off-by: Ivaylo Dimitrov <ivo.g.dimitrov.75@gmail.com> Acked-by: Mark Brown <broonie@kernel.org> Acked-by: Jarkko Nikula <jarkko.nikula@bitmer.com> Tested-by: Jarkko Nikula <jarkko.nikula@bitmer.com> Link: https://patch.msgid.link/20260819171935.233946-1-ivo.g.dimitrov.75@gmail.com Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
2026-08-21drm/omap: dsi: avoid sending bta sync all the time in writesAndreas Kemnade
Some chips need configuration commands to be sent first, before they can send data. TC358762 for example needs PPI_LPTXTIMECNT configured and PPI_STARTPPI set to 1 to be able to transmit anything. To be able to configure such chips, do not send bta sync during writes if no acks are requested. Instead just wait for the packet to be sent to avoid FIFO overflows. There might be more to do about acks, but there seem to be virtually no users of that flag. This came to light when fiddling with the Epson Moverio BT-200 display which consists of 2 TC358762 bridges with SPI funneled through to the unknown display chip. With that patch the bridge can be accessed, Reading back registers works, when the above-mentioned registers are set. In Command-Mode update, there was a nop sent, apparently the most relevant part was the bta sync to actually force low power mode. Video mode panel at OMAP4 (BT-200) and video mode at OMAP5 was tested. Fixes: e70965386353e ("drm/omap: dsi: simplify write function") Signed-off-by: Andreas Kemnade <andreas@kemnade.info> Link: https://patch.msgid.link/20260629-vm-upstr-v4-1-9f0c62d8808e@kemnade.info Link: https://patch.msgid.link/20260628-vm-upstr-v3-1-9e9add93378b@kemnade.info Link: https://patch.msgid.link/20260529-vm-upstr-v2-1-24c30671719f@kernel.org Link: https://lore.gitlab.freedesktop.org/drm-ai-reviews/review-patch1-20260529-vm-upstr-v2-1-24c30671719f@kernel.org/ Link: https://patch.msgid.link/20260528-vm-upstr-v1-1-fb93ef8cbe47@kernel.org Link: https://patch.msgid.link/20260804-vm-upstr-v6-1-1bf3748b2fa3@kemnade.info Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ideasonboard.com>
2026-08-20drm/xe: Don't hand out the flat CCS storage as usable VRAMLinus Torvalds
get_flat_ccs_offset() reads the base of the flat CCS storage from the hardware, scales it by the number of enabled L3 nodes, and rounds the result up to 128K. Everything below that offset is then handed to the VRAM allocator as usable memory. Rounding a limit that means "usable memory ends here" upwards publishes whatever lies between the real base and the rounded one as free memory, and that memory belongs to the compression hardware. The scaled value has no reason to be 128K aligned, and on a Battlemage G21 with 16 GiB it is not: flat CCS base: raw 0x3fafff800, rounded 0x3fb000000 so the last 2 KiB of page 0x3fafff000 is CCS storage, in the allocator's pool. Whatever is allocated there gets that tail overwritten by the compression hardware, which needs no page-table entry, no buffer object and no GPU submission to do it, and does it before userspace exists. On this machine a Mesa VM's level-3 page table landed on that page on every cold boot. It lost the entry covering the compositor's batch-buffer heap, so the compositor's first submission faulted fetching its batch and gdm restarted it forever: a black screen on an otherwise working machine. Restarting gdm cleared it because the next VM's page tables were allocated somewhere else. Round down instead, to the page size the allocator works in. On this machine that excludes exactly one page. Reading the reserved page afterwards shows what had been writing it: [369] 0xcccc000000000000 [371] 0xcc77000000000000 [373] 0xcccc000000000000 [375] 0xcc77000000000000 compression metadata, two bytes per sixteen, sitting where the driver used to hand out memory. The assertion that should have caught this compares the offset against GSMBASE - ccs_size for equality. That value is 128K aligned, so it agrees with the rounded-up offset precisely when the base is not aligned - the check cannot fail in the case it exists to catch, and is compiled out unless CONFIG_DRM_XE_DEBUG is set. Replace it with one that can fail: CCS storage must not run into GSM. [ And this was a debug session from hell, enormously helped by an AI doing much of the grunt-work. I'd like to call it my tireless helper, but the AI several times stated flat out that this was impossible and unsolvable and that we should just write a report about it. I suspect those things have been trained by people who may not be quite as stubborn as I am. But while the AI was ready to give up several times, it did keep adding debug code and analyzing it faithfully when I pushed. So credit where credit is due and I let the AI write the commit message above. This is basically a one-liner fixing a bogus "round_up()" to a "round_down()", but there were 24 patches adding more and more debug information to this, and 18 kernel boot to finally narrow it down to this. - Linus ] Fixes: 37173392741c ("drm/xe/vram: fix ccs offset calculation") Cc: stable@kernel.org Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2026-08-20Merge tag 'mm-stable-2026-08-18-18-39' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm Pull MM updates from Andrew Morton: - "mm: drop "sub" prefix from various places" (Dev Jain) page->folio conversion and a naming cleanup - "mm/kasan: remove redundant initialization for kasan_flag_write_only" (Igor Putko) KASAN cleanup work - "mm/filemap: reduce unnecessary xarray lookups" (Chi Zhiling) Small speedup in the pagecaache read code - "mm/percpu: Fix possible NOFS/NOIO reclaim recursion" (Kaitao Cheng) Improve the vmalloc code - mainly the avoidance of GFP_KERNEL allocations when the caller asked for GFP_NOFS or GFP_NOIO - "mm/kmemleak: avoid soft lockup when scanning task stacks" (Breno Leitao) Avoid a soft lockup watchdog trigger from the kmemleak scanning code in extreme situations - "mm/page_owner: misc cleanups" (Ye Liu) Cleanups to the page_owner code. For some reason lots of people have been working on the page_owner code this cycle. - "mm: convert to walk_page_range_vma() to eliminate find_vma()" (Kefeng Wang) Simplify and accelerate the page walking library function - "mm/migrate: preparatory cleanups for batch copy and offload" (Shivank Garg) Cleanups in the migration code - "mm/page_owner: add per-fd filter infrastructure for print_mode and NUMA filtering" (Zhen Ni) Per-fd filtering to page_owner in order to reduce the sometimes vast amount of output it can produce - "mm: Refactor bootmem gigantic hugepage allocation" (Muchun Song) Fixes and preparatory cleanups around bootmem HugeTLB handling, sparse initialization ordering, and related vmemmap setup - "mm/zsmalloc: reduce lock contention in zs_free()" (Wenchao Hao) Reduce lock contention in zs_free(), which dominates the unmap path under memory pressure on Android (LMK kills) and on x86 servers running zswap-heavy workloads. Up to 1.83x improvement in microbenchmarking. - "move alloc_tag.c file under mm/" (Suren Baghdasaryan) - "samples/damon: handle damon_{start,stop}() failures" (SJ Park) Fix improper handling of damon_start(), damon_stop(), and damon_call() failures across DAMON sample modules to prevent potential memory leaks, operation disruptions and use-after-free bugs - "mm/damon/sysfs: kobject_del() directories that users can create/remove" (SJ Park) Fix delayed sysfs directory removal under DEBUG_KOBJECT_RELEASE causeing creation failures due to duplicate directory names by adding missing kobject_del() calls before creating new directories - "mm: cleanup clear_not_present_full_ptes()" (David Hildenbrand) Clean up the core pte handling code - "selftests/damon: misc fixes for test bugs" (Kunwu Chan) Fix several bugs in the DAMON selftests - "selftests/damon: fix memcg_path staging handling" (Cheng Nie) Fix a bug in _damon_sysfs.py for damos_filter memcg_path setup, and add a test case for it in sysfs.py. - "selftests/damon: test kdamond refresh_ms" (Ruslan Valiyev) Selftest coverage for DAMON's refresh_ms sysfs feature by updating the test control module and verifying that scheme stats update automatically without manual intervention - "mm/damon: five misc fixups" (Akinobu Mita) Miscellaneous DAMON fixups. - "mm/damon/core: detect internal variation above max_nr_regions/2" (Jiayuan Chen) Fix DAMON's region splitting behavior when region counts exceed half the maximum budget by dynamically scaling down the split fraction as the limit approaches, preventing large regions from staying un-split, and add corresponding KUnit test coverage - "mm: preparatory patches for PMD level swap entries" (Usama Arif) Refactor and clean up PMD softleaf helpers, call sites, and architecture flags to lay the groundwork for a follow-up series that introduces PMD page table swap entries - "mm/damon: update, optimize, and clean up doc, tests, and code" (SJ Park) Update DAMON design and ABI documentation, expands unit and selftest coverage, optimize damon_commit_target_regions(), and clean up recently added sysfs interface code for better readability - "mm/vmpressure: reduce CPU, memory and code overhead on cgroup v2" (Usama Arif) Optimize vmpressure() by skipping unnecessary work on cgroup v2 for userspace event notifications and refactor v1-only eventfd handling into mm/memcontrol-v1.c to reduce memory overhead and code complexity - "selftests/mm: refactor pkey helpers and fix mmap error handling" (Hongfu Li) Refactor pkeys shared tracing and assertion helpers into a common file, unify protection key selftests to use consistent diagnostic logging and assertions, and enforce standardized MAP_FAILED return checks for mmap() calls across the tests - "mm/damon: optimize out nr_accesses_bp" (SJ Park) Replace the error-prone, continuously updated nr_accesses_bp field in damon_region with an on-demand moving sum function, reducing structure memory overhead and avoiding state corruption bugs - "Open HugeTLB allocation routine for more generic use" (Ackerley Tng) Decouple HugeTLB folio allocation from VMA dependencies by introducing hugetlb_alloc_folio(), enabling subsystems like guest_memfd to allocate HugeTLB folios without standard VMA reservations or pseudo-VMAs - "mm/damon: provide pseudo moving sum probe_hits" (SJ Park) Integrate DAMON's probe_hits attribute counter into the pseudo moving sum infrastructure, enabling real-time, online monitoring without waiting for full aggregation intervals - "mm: Some cleanups for page allocator APIs" (Brendan Jackman) Simplify and refactor the page allocator entry points and flags by unifying allocation paths, adding internal alloc_flags arguments, and eliminating redundant __ prefixed alloc_pages variants. - "Fix incorrect access of hugetlb pte entries" (Dev Jain) Enforce the consistent use of huge_ptep_get() instead of ptep_get() for HugeTLB entries and fixes an unaligned address issue in arm64's huge_ptep_get() implementation - "mm/damon: validate all parameters in the core" (SJ Park) Consolidate parameter validation into the DAMON core specifically within damon_start() and damon_commit_ctx() to centralize error checking, eliminate caller-side redundant checks and to improve maintenance efficiency - "tools/mm/page_owner_sort: fix filtering and cleanup issues" (Yichong Chen) Rename is_need() to filter_record() for clearer return semantics, fix per-record allocation memory leaks and bound output copies in search_pattern() to address an existing buffer issue - "memcg: bail out reclaim when memcg is dying" (Jiayuan Chen) Mitigate a system-wide stall which occurs when a cgroup is removed while one of its memory control files is doing synchronous reclaim - "mm/memory-failure: add panic option for unrecoverable pages" (Breno Leitao) Introduce an opt-in vm.panic_on_unrecoverable_memory_failure sysctl that immediately panics the kernel on unrecoverable memory errors in kernel-owned pages to preserve error context and prevent delayed, silent data corruption - "mm/damon: refactor damon_{start,stop,commit}() for simple error handling" (SJ Park) Refactor the DAMON core API functions to guarantee that all contexts are fully stopped when damon_start(), damon_stop(), or damon_commit() fail, eliminating the need for complex and error-prone caller-side cleanup code - "Keep tail page private zero at free and folio split" (Zi Yan) Add checks to ensure tail_page->private is zero when freeing compound or high-order pages and when promoting tail pages during large folio splits. By validating these fields at free and split time, it allows the removal of redundant private field clearing inside prep_compound_tail() - "mm: drop redundant lru_add_drain in anon folio reuse paths" (Barry Song) Eliminate redundant lru_add_drain() calls in wp_can_reuse_anon_folio() and do_swap_page() to reduce LRU lock contention and system overhead By validating folio refcounts against the LRU cache before draining and removing unnecessary drains in the swap path, it achieves up to a 30.5% reduction in drain calls during heavy swap workloads - "mm: clean up folio LRU and swap declarations" (Jianyue Wu) Reorganize folio LRU and swap code by relocating page-cluster state to mm/swap_state.c, renaming mm/swap.c to mm/folio.c, and moving MM-internal reclaim declarations into mm/internal.h. - "userfaultfd: working set tracking for VM guest memory" (Kiryl Shutsemau) Add userfaultfd support for tracking the working set of VM guest memory, so a VMM can identify hot pages and reclaim cold ones to tiered or remote storage - "mm: remove CONFIG_HAVE_BOOTMEM_INFO_NODE (Part 2)" (David Hildenbrand) Remove the remaining pieces of CONFIG_HAVE_BOOTMEM_INFO_NODE, performing some smaller cleanups around freeing of reserved vmemmap pages on the way. - "mm/damon: update probe hits for runtime parameter commits" (SJ Park) Ensure that DAMON's probe_hits attribute counter is properly updated when monitoring intervals are changed at runtime, matching the behavior of nr_accesses. To achieve this, it refactors and renames existing helper functions for shared use, applies the updates to probe_hits, and handles edge cases in damon_probe_hits_mvsum() to maintain measurement accuracy. - "KSM: performance optimizations for rmap_walk_ksm" (xu xin) Resolve a severe KSM reverse-mapping performance bottleneck where thousands of split VMAs sharing a single anon_vma cause extended lock contention. By adding an interval-filtering check during the rmap walk, it reduces worst-case anon_vma lock hold times from over 500ms down to under 2ms, preventing application freezes and latency spikes under memory pressure. - "mm: split a couple of headers from internal.h" (Mike Rapoport) Split declarations related to mm_init, memblock, vmalloc and sparse into new headers - "KSM: use linear_page_index in collect_procs_ksm()" (xu xin) Apply the interval tree optimization from rmap_walk_ksm() to collect_procs_ksm() to avoid iterating over non-matching VMAs during KSM memory error handling. It hoists loop-invariant address initialization and restricts the anon_vma_interval_tree_foreach walk to a targeted page offset range, reducing redundant checks and improving lookup efficiency. - "selftests/mm: avoid false failures in hugetlb and KSM tests" (Sayali Patil) Fix issues in the hugetlb and KSM MM selftest categories that can report failures when the prerequisites for the tests are not satisfied - "mm/damon: introduce data attributes only monitoring" (SJ Park) Introduce attribute-weighted region management in DAMON, allowing users to prioritize specific data attributes (such as page sizes or cgroups) over or instead of access monitoring. By assigning weights to attribute probes, DAMON can completely disable access tracking and adjust monitoring regions based on weighted probe-hit counters to optimize monitoring quality for attribute-focused workloads. - "mm/hmm: Add mmap lock-drop support for userfaultfd-backed mappings" (Stanislav Kinsburskii) Extend hmm_range_fault() to support userfaultfd-backed regions by allowing the mmap lock to be dropped during fault handling via a new hmm_range_fault_locked() helper. By accepting a locked pointer and signaling retry status when lock release occurs, it enables page fault resolution in userfaultfd regions while preserving backward compatibility for existing callers. - "mm: make VMA page offset handling more consistent" (Lorenzo Stoakes) Clean up and standardize how vma->vm_pgoff is accessed and manipulated across file-backed and anonymous mappings in the kernel It introduces dedicated helper functions such as vma_start_pgoff(), vma_end_pgoff(), vma_set_pgoff() and linear_page_delta() while renaming rmap interval tree helpers to better reflect their functionality. These changes establish a cleaner foundation for future work that will unify virtual page offset indexing for all anonymous and CoW'd folios. - "mm: handle device-private PMDs in walk callbacks" (Usama Arif) Address kernel panics and state corruption caused by MM walk callbacks reaching non-present device-private PMD swap entries created during HMM migrations It ensures that functions which acquire pmd_trans_huge_lock() properly recognize device-private PMDs instead of assuming a present THP or a standard migration entry. - "mm/rmap: Refactor try_to_unmap_one" (Dev Jain) Refactor try_to_unmap_one by modularizing Hugetlb, anonymous-lazyfree, and anonymous-swapbacked logic into dedicated functions, laying the structural groundwork for batched anonymous large folio unmapping. - "Docs/ABI/damon: sysfs ABI document fixes and additions" (Song Hu) Fix typos and fills in missing entries in the DAMON sysfs ABI document - "dax/kmem: atomic whole-device hotplug via sysfs" (Gregory Price) Introduce an atomic sysfs state attribute and supporting DAX/MM infrastructure to prevent userland races when offlining and removing entire memory regions By adding an unplugged state alongside standard online modes, it enables whole-device atomic hotplug control while preserving backward compatibility. - "mm: convert more vm_flags_t users to vma_flags_t" (Lorenzo Stoakes) Continue transitioning the kernel from the deprecated vm_flags_t type to vma_flags_t across core memory management infrastructure. It replaces legacy type usage in core functions such as do_mmap(), unmapped area allocation, mm->def_vma_flags, and VMA operations like mlock, mprotect, and mremap. - "Two small patches to clean up mm/mm_slot.h" (xu xin) Refactor mm_slot.h by introducing mm_slot_remove() to unify duplicate slot deletion sequences in khugepaged and KSM. It also adds code documentation explaining why mm_slot_lookup and mm_slot_insert must remain as preprocessor macros rather than static inline functions. - "mm/damon/core: hide core-private struct fields" (SJ Park) Clean up DAMON core structures by consistently marking internal-only fields with private: comment tags to prevent improper direct access from outer layers. It enforces encapsulation across core structures including damon_region, damon_target, and damon_ctx and updates DAMON_SYSFS to interact through approved access APIs instead of exposing raw struct members. - "mm/damon: unurgent fixes for infinite loop, NULL de-ref and races" (SJ Park) Address potential infinite loops, NULL dereferences, and race conditions identified in DAMON It fixes an infinite loop triggered by extreme user configurations, a NULL pointer dereference within unit tests and minor monitoring accuracy degradation caused by subtle runtime races. - "mm/page_alloc: fixes for free_pages_nolock() on RT/UP" (Brendan Jackman) Fix an NMI safety flaw in __free_frozen_pages() where freeing pages on non-SMP or PREEMPT_RT kernels can bypass can_spin_trylock() checks via non-PCP or isolated migration paths. It also resolves potential kernel crashes and privilege escalation risks triggered when BPF tracing runs in NMI context alongside memory hotplug or large allocation frees. - "mm/page_alloc: couple of followups for recent cleanups" (Brendan Jackman) Clean up and update page allocator nomenclature, documentation, and debug assertions. It aligns internal FPI_ flags with the public "nolock" naming convention, removes outdated internal implementation details from high-level page allocator comments, and eliminates obsolete VM_BUG_ON() assertions in allocation paths. - "mm/mseal: further cleanups" (Lorenzo Stoakes) Refactor and simplify the mseal implementation by clarifying API boundaries and removing unnecessary code complexity. It replaces generic do_mseal() usage outside the syscall with a dedicated mseal_mmap_page_zero() helper for MMAP_PAGE_ZERO, eliminates mm_struct parameters to enforce that sealing applies only to current->mm, and streamlines overall logic and comments with no functional changes intended. - "mm/vmscan: fix swappiness=max and clean up per-node proactive reclaim" (Ridong Chen) Resolve reclaim behavior bugs and clean up function parameters across memory reclaim paths It fixes swappiness=max in both standard reclaim and MGLRU so unswappable anonymous memory no longer falls back to evicting page cache, ensures reclaim_store() returns accurate error codes instead of collapsing all failures into -EAGAIN, and removes the obsolete gfp_mask parameter from __node_reclaim(). - "mm: mincore: misc cleanups" (Kefeng Wang) Clean up and simplifies the mincore code. Most importantly, it removes the historical special behavior that always reports VM_PFNMAP pages as non-resident. - "mm/huge_memory: drop dead split helper variants" (Kiryl Shutsemau) Two trivial cleanups in the folio split API - "mm/damon: fix uninitialized DAMOS field and kunit exec expectation bugs" (SJ Park) Resolve minor operational and testing bugs in DAMON identified by Sashiko. It initializes the damos->last_applied field to prevent occasional efficiency degradation and fixes invalid memory accesses in DAMON KUnit tests during test failure handling. - "cleanup for stable_page_flags()" (Jinjiang Tu) Clean up and refactor stable_page_flags() used by /proc/kpageflags without altering functionality. It uses BIT_ULL() to prevent shift-overflow warnings on 64-bit flag bits, converts folio-specific flag checks to standard folio_test_*() helpers, and removes redundant CONFIG_PAGE_IDLE_FLAG handling. - "Batch unmap of uffd-wp file folios" (Dev Jain) Extend batched folio unmapping support to file folios within userfaultfd write-protect (uffd-wp) VMAs by adding batching capabilities to pte_install_uffd_wp_if_needed(). This removes special-case restrictions on uffd-wp VMAs in try_to_unmap_one(), significantly simplifying the function's control flow and complexity. - "mm/early_ioremap: clarify and clean up early_ioremap_reset()" (Sang-Heon Jeon) Clarify and clean up the architecture-specific usage of __late_set_fixmap() and __late_clear_fixmap() after early_ioremap_reset() It adds explicit documentation regarding when early_ioremap_reset() must be called and removes redundant macro definitions and reset calls in the RISC-V and ARM64 architectures. - "mm: fix reclaim storms in defrag_mode" (Johannes Weiner) Address severe performance regressions, swap storms, and spurious OOMs caused by vm.defrag_mode=1 under high memory pressure in Meta production It updates the page allocator slowpath so non-movable allocation requests actively trigger direct reclaim and direct compaction at pageblock_order scale, allowing them to claim whole pageblocks rather than spinning unproductively. - "zram: lockmap tweaks" (Sebastian Siewior) Optimize and fix lockdep tracking for zram devices by consolidating per-entry lockmaps and isolate lock classes across multiple instances This reduces memory overhead by replacing per-entry lockdep_map instances with a single map per struct zram, and assigns a dynamic lock_class_key to each instance to prevent false deadlock reports when different zram devices are backed by distinct filesystems. * tag 'mm-stable-2026-08-18-18-39' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm: (501 commits) selftests/mm: thuge-gen: fix test_shmget() for PAGE_SIZE check selftests/mm: unpoison pages in memory-failure teardown mm/shmem: downgrade final i_blocks check in shmem_evict_inode() to pr_warn() mm/khugepaged: replace mutex_lock/mutex_unlock usage with guard macro mm/zsmalloc: fix release order of locks in zs_page_migrate() Documentation: zram: remove sections numbering ksm: stop iterating VMAs when ksm_test_exit returns true mm: fold userfaultfd_rwp() to false without CONFIG_ARCH_HAS_PTE_PROTNONE mm/migrate: report RCU-tasks quiescent states in migrate_pages_batch() zram: use a custom key for each zram object zram: move lockmap to be per-zram instead per table selftests/mm: fix gup_longterm EINVAL error message mm: page_alloc: fix non-movable reclaim storm in defrag_mode mm: page_alloc: move capture_control to the page allocator mm: compaction: support non-movable compaction for pageblock requests mm: page_alloc: __GFP_FS lockdep annotation for direct compaction hugetlb: evaluate subpool free state while locked mm/damon: remove trailing semicolons after function definitions mm/damon/ops-common: prevent migration fallback to non-target nodes mm/damon: update outdated comment about DAMOS filter handling ...
2026-08-20drm/nouveau: unsubscribe the channel-kill event before the fence contextMarek Czernohous
nouveau_channel_del() tears the fence context down first and only drops the channel-kill subscription later, in the middle of the nvif object teardown: if (chan->fence) nouveau_fence(chan->cli->drm)->context_del(chan); ... nvif_object_dtor(&chan->vram); nvif_event_dtor(&chan->kill); The subscribed handler is nouveau_channel_killed(), which calls nouveau_channel_kill() and from there nouveau_fence_context_kill() on chan->fence. A kill event delivered in that window takes fctx->lock and walks fctx->pending on a fence context that context_del() has already freed. Nothing reaches this below Fermi today, because the subscription is gated on FERMI_CHANNEL_GPFIFO and nothing kills a channel there. On Fermi and newer the window is real but narrow, since a kill has to land exactly while the channel is being destroyed. That is reason enough on its own, which is why this carries a Fixes: tag. The last patch in this series subscribes Tesla channels as well; nothing kills those today, so it does not widen the exposure now, but it is the groundwork for a recovery path that would, and the ordering is better fixed before that lands than alongside it. Drop the subscription before anything it depends on is torn down. Fixes: ea13e5abf807 ("drm/nouveau: signal pending fences when channel has been killed") Cc: stable@vger.kernel.org Assisted-by: Claude:claude-opus-5 Signed-off-by: Marek Czernohous <marek@czernohous.de> Fixes: ea13e5abf807 ("drm/nouveau: signal pending fences when channel has been killed") Reviewed-by: Lyude Paul <lyude@redhat.com> Signed-off-by: Lyude Paul <lyude@redhat.com> Link: https://patch.msgid.link/20260812231330.705425-2-mczernohous@gmail.com
2026-08-20drm/xe/xe_gt_idle: Add CCS to the powergating info printBalasubramani Vivekanandan
While reading the main GT powergating info from debugfs, include both RCS and CCS engine masks. Fixes: 0914c1e45d3a1 ("drm/xe/xe_gt_idle: add debugfs entry for powergating info") Signed-off-by: Balasubramani Vivekanandan <balasubramani.vivekanandan@intel.com> Link: https://patch.msgid.link/20260819073457.1812722-2-balasubramani.vivekanandan@intel.com Reviewed-by: Matt Roper <matthew.d.roper@intel.com> Signed-off-by: Matt Roper <matthew.d.roper@intel.com>
2026-08-20drm/nouveau: don't dereference outp before checking it in nouveau_dp_irqMarek Czernohous
nouveau_dp_irq() looks the encoder up and dereferences it in the same breath, five lines before testing it: struct nouveau_encoder *outp = find_encoder(connector, DCB_OUTPUT_DP); struct nouveau_drm *drm = nouveau_drm(outp->base.base.dev); ... if (!outp) return; find_encoder() walks the connector's possible encoders and returns NULL when none of them matches the requested type, so the NULL test is not decoration: it is the author saying this can happen. The initialiser above it dereferences the same pointer regardless. The NULL test predates the dereference. commit 773eb04d14a1 ("drm/nouveau/disp: expose conn event class") turned nouveau_dp_irq() into a work callback, and since the drm pointer was no longer passed in as an argument it was recovered from the encoder in the declaration block, which put the dereference above the existing test. Move the drm lookup below the test. No functional change when outp is non-NULL. Fixes: 773eb04d14a1 ("drm/nouveau/disp: expose conn event class") Cc: stable@vger.kernel.org Assisted-by: Claude:claude-opus-5 Signed-off-by: Marek Czernohous <marek@czernohous.de> Reviewed-by: Lyude Paul <lyude@redhat.com> Signed-off-by: Lyude Paul <lyude@redhat.com> Link: https://patch.msgid.link/178682366004.3748010.14933649768375463967@gmail.com
2026-08-20drm/nouveau: cancel the DP IRQ work before freeing the connectorMarek Czernohous
nouveau_connector_destroy() tears the two nvif events down and then frees the connector, but never cancels the work the IRQ event queues: nvif_event_dtor(&nv_connector->irq); nvif_event_dtor(&nv_connector->hpd); kfree(nv_connector->edid); ... kfree(connector); nouveau_connector_irq() queues that work unconditionally: schedule_work(&nv_connector->irq_work); return NVIF_EVENT_KEEP; A DP IRQ arriving just before nvif_event_dtor() therefore leaves nv_connector->irq_work on the system queue past the kfree(). When it runs, nouveau_dp_irq() derives both nv_connector and connector from the work_struct and dereferences them, and goes on to take outp->dp.hpd_irq_lock. There is no cancel_work_sync() for irq_work anywhere in the driver, so nothing else covers this. Add it after the event teardown, where no further work can be queued, and before anything is freed. Reported by the Sashiko review bot as a pre-existing issue, in its review of an earlier nv04 FIFO series of mine, and confirmed against the source. Reported-by: sashiko-bot <sashiko-bot@kernel.org> Link: https://sashiko.dev/#/patchset/20260812231330.705425-1-mczernohous@gmail.com?part=1 Fixes: 773eb04d14a1 ("drm/nouveau/disp: expose conn event class") Cc: stable@vger.kernel.org Assisted-by: Claude:claude-opus-5 Signed-off-by: Marek Czernohous <marek@czernohous.de> Reviewed-by: Lyude Paul <lyude@redhat.com> Signed-off-by: Lyude Paul <lyude@redhat.com> Link: https://patch.msgid.link/178682366002.3748010.4096452389040554615@gmail.com