lists.linaro.org
Sign In
Sign Up
Sign In
Sign Up
Manage this list
×
Keyboard Shortcuts
Thread View
j
: Next unread message
k
: Previous unread message
j a
: Jump to all threads
j l
: Jump to MailingList overview
2025
October
September
August
July
June
May
April
March
February
January
2024
December
November
October
September
August
July
June
May
April
March
February
January
2023
December
November
October
September
August
July
June
May
April
March
February
January
2022
December
November
October
September
August
July
June
May
April
March
February
January
2021
December
November
October
September
August
July
June
May
April
March
February
January
2020
December
November
October
September
August
July
June
May
April
March
February
January
2019
December
November
October
September
August
July
June
May
April
March
February
January
2018
December
November
October
September
August
July
June
May
April
March
February
January
2017
December
November
List overview
Download
Linux-stable-mirror
October 2025
----- 2025 -----
October 2025
September 2025
August 2025
July 2025
June 2025
May 2025
April 2025
March 2025
February 2025
January 2025
----- 2024 -----
December 2024
November 2024
October 2024
September 2024
August 2024
July 2024
June 2024
May 2024
April 2024
March 2024
February 2024
January 2024
----- 2023 -----
December 2023
November 2023
October 2023
September 2023
August 2023
July 2023
June 2023
May 2023
April 2023
March 2023
February 2023
January 2023
----- 2022 -----
December 2022
November 2022
October 2022
September 2022
August 2022
July 2022
June 2022
May 2022
April 2022
March 2022
February 2022
January 2022
----- 2021 -----
December 2021
November 2021
October 2021
September 2021
August 2021
July 2021
June 2021
May 2021
April 2021
March 2021
February 2021
January 2021
----- 2020 -----
December 2020
November 2020
October 2020
September 2020
August 2020
July 2020
June 2020
May 2020
April 2020
March 2020
February 2020
January 2020
----- 2019 -----
December 2019
November 2019
October 2019
September 2019
August 2019
July 2019
June 2019
May 2019
April 2019
March 2019
February 2019
January 2019
----- 2018 -----
December 2018
November 2018
October 2018
September 2018
August 2018
July 2018
June 2018
May 2018
April 2018
March 2018
February 2018
January 2018
----- 2017 -----
December 2017
November 2017
linux-stable-mirror@lists.linaro.org
605 participants
1524 discussions
Start a n
N
ew thread
71d2893a235bf3b95baccead27b3d47f2f2cdc4c
by Gergo Koteles
Hey Greg, I think this commit should be applied to v6.16 stable, because without it some speakers may be damaged. Thanks, Gergo
3 weeks, 3 days
2
1
0
0
[STABLE 5.15.y] [PATCH] KVM: arm64: Fix softirq masking in FPSIMD register saving sequence
by Will Deacon
Stable commit 23249dade24e ("KVM: arm64: Fix kernel BUG() due to bad backport of FPSIMD/SVE/SME fix") fixed a kernel BUG() caused by a bad backport of upstream commit fbc7e61195e2 ("KVM: arm64: Unconditionally save+flush host FPSIMD/SVE/SME state") by ensuring that softirqs are disabled/enabled across the fpsimd register save operation. Unfortunately, although this fixes the original issue, it can now lead to deadlock when re-enabling softirqs causes pending softirqs to be handled with locks already held: | BUG: spinlock recursion on CPU#7, CPU 3/KVM/57616 | lock: 0xffff3045ef850240, .magic: dead4ead, .owner: CPU 3/KVM/57616, .owner_cpu: 7 | CPU: 7 PID: 57616 Comm: CPU 3/KVM Tainted: G O 6.1.152 #1 | Hardware name: SoftIron SoftIron Platform Mainboard/SoftIron Platform Mainboard, BIOS 1.31 May 11 2023 | Call trace: | dump_backtrace+0xe4/0x110 | show_stack+0x20/0x30 | dump_stack_lvl+0x6c/0x88 | dump_stack+0x18/0x34 | spin_dump+0x98/0xac | do_raw_spin_lock+0x70/0x128 | _raw_spin_lock+0x18/0x28 | raw_spin_rq_lock_nested+0x18/0x28 | update_blocked_averages+0x70/0x550 | run_rebalance_domains+0x50/0x70 | handle_softirqs+0x198/0x328 | __do_softirq+0x1c/0x28 | ____do_softirq+0x18/0x28 | call_on_irq_stack+0x30/0x48 | do_softirq_own_stack+0x24/0x30 | do_softirq+0x74/0x90 | __local_bh_enable_ip+0x64/0x80 | fpsimd_save_and_flush_cpu_state+0x5c/0x68 | kvm_arch_vcpu_put_fp+0x4c/0x88 | kvm_arch_vcpu_put+0x28/0x88 | kvm_sched_out+0x38/0x58 | __schedule+0x55c/0x6c8 | schedule+0x60/0xa8 Take a tiny step towards the upstream fix in 9b19700e623f ("arm64: fpsimd: Drop unneeded 'busy' flag") by additionally disabling hardirqs while saving the fpsimd registers. Cc: Ard Biesheuvel <ardb(a)kernel.org> Cc: Lee Jones <lee(a)kernel.org> Cc: Sasha Levin <sashal(a)kernel.org> Cc: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org Cc: <stable(a)vger.kernel.org> # 5.15.y Fixes: 23249dade24e ("KVM: arm64: Fix kernel BUG() due to bad backport of FPSIMD/SVE/SME fix") Reported-by: Kenneth Van Alstyne <kvanals(a)kvanals.org> Link:
https://lore.kernel.org/r/010001999bae0958-4d80d25d-8dda-4006-a6b9-798f3e77…
Signed-off-by: Will Deacon <will(a)kernel.org> --- arch/arm64/kernel/fpsimd.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c index fc51cdd5aaa7..db1ed940a6dc 100644 --- a/arch/arm64/kernel/fpsimd.c +++ b/arch/arm64/kernel/fpsimd.c @@ -1300,13 +1300,17 @@ static void fpsimd_flush_cpu_state(void) */ void fpsimd_save_and_flush_cpu_state(void) { + unsigned long flags; + if (!system_supports_fpsimd()) return; WARN_ON(preemptible()); - get_cpu_fpsimd_context(); + local_irq_save(flags); + __get_cpu_fpsimd_context(); fpsimd_save(); fpsimd_flush_cpu_state(); - put_cpu_fpsimd_context(); + __put_cpu_fpsimd_context(); + local_irq_restore(flags); } #ifdef CONFIG_KERNEL_MODE_NEON -- 2.51.0.618.g983fd99d29-goog
3 weeks, 3 days
3
3
0
0
Linux 6.17.1
by Greg Kroah-Hartman
I'm announcing the release of the 6.17.1 kernel. All users of the 6.17 kernel series must upgrade. The updated 6.17.y git tree can be found at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git
linux-6.17.y and can be browsed at the normal
kernel.org
git web browser:
https://git.kernel.org/?p=linux/kernel/git/stable/linux-stable.git;a=summary
thanks, greg k-h ------------ Makefile | 2 block/blk-mq-tag.c | 1 drivers/media/i2c/tc358743.c | 4 - drivers/media/pci/b2c2/flexcop-pci.c | 2 drivers/media/platform/qcom/iris/iris_buffer.c | 10 +++ drivers/media/platform/st/stm32/stm32-csi.c | 4 - drivers/media/rc/imon.c | 27 ++++++--- drivers/media/tuners/xc5000.c | 2 drivers/media/usb/uvc/uvc_driver.c | 73 +++++++++++++++---------- drivers/media/usb/uvc/uvcvideo.h | 2 drivers/net/wireless/ath/ath11k/qmi.c | 2 drivers/net/wireless/realtek/rtw89/core.c | 30 ++++++++-- drivers/net/wireless/realtek/rtw89/core.h | 35 +++++++++++ drivers/net/wireless/realtek/rtw89/pci.c | 3 - drivers/net/wireless/realtek/rtw89/ser.c | 2 drivers/target/target_core_configfs.c | 2 mm/swapfile.c | 3 + scripts/gcc-plugins/gcc-common.h | 7 ++ sound/soc/qcom/qdsp6/topology.c | 4 - sound/usb/midi.c | 9 +-- 20 files changed, 165 insertions(+), 59 deletions(-) Chandra Mohan Sundar (1): media: stm32-csi: Fix dereference before NULL check Charan Teja Kalla (1): mm: swap: check for stable address space before operating on the VMA Dikshita Agarwal (1): media: iris: Fix memory leak by freeing untracked persist buffer Duoming Zhou (3): media: b2c2: Fix use-after-free causing by irq_check_work in flexcop_pci_remove media: i2c: tc358743: Fix use-after-free bugs caused by orphan timer in probe media: tuner: xc5000: Fix use-after-free in xc5000_release Fedor Pchelkin (1): wifi: rtw89: fix use-after-free in rtw89_core_tx_kick_off_and_wait() Greg Kroah-Hartman (1): Linux 6.17.1 Jeongjun Park (1): ALSA: usb-audio: fix race condition to UAF in snd_usbmidi_free Kees Cook (1): gcc-plugins: Remove TODO_verify_il for GCC >= 16 Larshin Sergey (1): media: rc: fix races with imon_disconnect() Matvey Kovalev (1): wifi: ath11k: fix NULL dereference in ath11k_qmi_m3_load() Srinivas Kandagatla (1): ASoC: qcom: audioreach: fix potential null pointer dereference Thadeu Lima de Souza Cascardo (1): media: uvcvideo: Mark invalid entities with id UVC_INVALID_ENTITY_ID Wang Haoran (1): scsi: target: target_core_configfs: Add length check to avoid buffer overflow Yu Kuai (1): blk-mq: fix blk_mq_tags double free while nr_requests grown
3 weeks, 3 days
1
1
0
0
Linux 6.16.11
by Greg Kroah-Hartman
I'm announcing the release of the 6.16.11 kernel. All users of the 6.16 kernel series must upgrade. The updated 6.16.y git tree can be found at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git
linux-6.16.y and can be browsed at the normal
kernel.org
git web browser:
https://git.kernel.org/?p=linux/kernel/git/stable/linux-stable.git;a=summary
thanks, greg k-h ------------ Makefile | 2 block/blk-mq-tag.c | 1 drivers/media/i2c/tc358743.c | 4 - drivers/media/pci/b2c2/flexcop-pci.c | 2 drivers/media/platform/qcom/iris/iris_buffer.c | 10 +++ drivers/media/platform/st/stm32/stm32-csi.c | 4 - drivers/media/rc/imon.c | 27 ++++++--- drivers/media/tuners/xc5000.c | 2 drivers/media/usb/uvc/uvc_driver.c | 73 +++++++++++++++---------- drivers/media/usb/uvc/uvcvideo.h | 2 drivers/net/wireless/ath/ath11k/qmi.c | 2 drivers/target/target_core_configfs.c | 2 mm/swapfile.c | 3 + scripts/gcc-plugins/gcc-common.h | 7 ++ sound/soc/qcom/qdsp6/topology.c | 4 - sound/usb/midi.c | 9 +-- 16 files changed, 104 insertions(+), 50 deletions(-) Chandra Mohan Sundar (1): media: stm32-csi: Fix dereference before NULL check Charan Teja Kalla (1): mm: swap: check for stable address space before operating on the VMA Dikshita Agarwal (1): media: iris: Fix memory leak by freeing untracked persist buffer Duoming Zhou (3): media: b2c2: Fix use-after-free causing by irq_check_work in flexcop_pci_remove media: i2c: tc358743: Fix use-after-free bugs caused by orphan timer in probe media: tuner: xc5000: Fix use-after-free in xc5000_release Greg Kroah-Hartman (1): Linux 6.16.11 Jeongjun Park (1): ALSA: usb-audio: fix race condition to UAF in snd_usbmidi_free Kees Cook (1): gcc-plugins: Remove TODO_verify_il for GCC >= 16 Larshin Sergey (1): media: rc: fix races with imon_disconnect() Matvey Kovalev (1): wifi: ath11k: fix NULL dereference in ath11k_qmi_m3_load() Srinivas Kandagatla (1): ASoC: qcom: audioreach: fix potential null pointer dereference Thadeu Lima de Souza Cascardo (1): media: uvcvideo: Mark invalid entities with id UVC_INVALID_ENTITY_ID Wang Haoran (1): scsi: target: target_core_configfs: Add length check to avoid buffer overflow Yu Kuai (1): blk-mq: fix blk_mq_tags double free while nr_requests grown
3 weeks, 3 days
1
1
0
0
Linux 6.12.51
by Greg Kroah-Hartman
I'm announcing the release of the 6.12.51 kernel. All users of the 6.12 kernel series must upgrade. The updated 6.12.y git tree can be found at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git
linux-6.12.y and can be browsed at the normal
kernel.org
git web browser:
https://git.kernel.org/?p=linux/kernel/git/stable/linux-stable.git;a=summary
thanks, greg k-h ------------ Makefile | 2 drivers/media/pci/b2c2/flexcop-pci.c | 2 drivers/media/rc/imon.c | 27 +++++++++--- drivers/media/tuners/xc5000.c | 2 drivers/media/usb/uvc/uvc_driver.c | 73 +++++++++++++++++++++------------- drivers/media/usb/uvc/uvcvideo.h | 2 drivers/net/wireless/ath/ath11k/qmi.c | 2 drivers/target/target_core_configfs.c | 2 include/crypto/sha256_base.h | 2 mm/swapfile.c | 3 + scripts/gcc-plugins/gcc-common.h | 7 +++ sound/soc/qcom/qdsp6/topology.c | 4 - 12 files changed, 86 insertions(+), 42 deletions(-) Breno Leitao (1): crypto: sha256 - fix crash at kexec Charan Teja Kalla (1): mm: swap: check for stable address space before operating on the VMA Duoming Zhou (2): media: b2c2: Fix use-after-free causing by irq_check_work in flexcop_pci_remove media: tuner: xc5000: Fix use-after-free in xc5000_release Greg Kroah-Hartman (1): Linux 6.12.51 Kees Cook (1): gcc-plugins: Remove TODO_verify_il for GCC >= 16 Larshin Sergey (1): media: rc: fix races with imon_disconnect() Matvey Kovalev (1): wifi: ath11k: fix NULL dereference in ath11k_qmi_m3_load() Srinivas Kandagatla (1): ASoC: qcom: audioreach: fix potential null pointer dereference Thadeu Lima de Souza Cascardo (1): media: uvcvideo: Mark invalid entities with id UVC_INVALID_ENTITY_ID Wang Haoran (1): scsi: target: target_core_configfs: Add length check to avoid buffer overflow
3 weeks, 3 days
1
1
0
0
Linux 6.6.110
by Greg Kroah-Hartman
I'm announcing the release of the 6.6.110 kernel. All users of the 6.6 kernel series must upgrade. The updated 6.6.y git tree can be found at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.git
linux-6.6.y and can be browsed at the normal
kernel.org
git web browser:
https://git.kernel.org/?p=linux/kernel/git/stable/linux-stable.git;a=summary
thanks, greg k-h ------------ Makefile | 2 drivers/media/pci/b2c2/flexcop-pci.c | 2 drivers/media/rc/imon.c | 27 +++++++++--- drivers/media/usb/uvc/uvc_driver.c | 73 +++++++++++++++++++++------------- drivers/media/usb/uvc/uvcvideo.h | 2 drivers/target/target_core_configfs.c | 2 include/crypto/sha256_base.h | 2 scripts/gcc-plugins/gcc-common.h | 7 +++ sound/soc/qcom/qdsp6/topology.c | 4 - 9 files changed, 81 insertions(+), 40 deletions(-) Breno Leitao (1): crypto: sha256 - fix crash at kexec Duoming Zhou (1): media: b2c2: Fix use-after-free causing by irq_check_work in flexcop_pci_remove Greg Kroah-Hartman (1): Linux 6.6.110 Kees Cook (1): gcc-plugins: Remove TODO_verify_il for GCC >= 16 Larshin Sergey (1): media: rc: fix races with imon_disconnect() Srinivas Kandagatla (1): ASoC: qcom: audioreach: fix potential null pointer dereference Thadeu Lima de Souza Cascardo (1): media: uvcvideo: Mark invalid entities with id UVC_INVALID_ENTITY_ID Wang Haoran (1): scsi: target: target_core_configfs: Add length check to avoid buffer overflow
3 weeks, 3 days
1
1
0
0
[PATCH v8 1/3] drm/buddy: Optimize free block management with RB tree
by Arunpravin Paneer Selvam
Replace the freelist (O(n)) used for free block management with a red-black tree, providing more efficient O(log n) search, insert, and delete operations. This improves scalability and performance when managing large numbers of free blocks per order (e.g., hundreds or thousands). In the VK-CTS memory stress subtest, the buddy manager merges fragmented memory and inserts freed blocks into the freelist. Since freelist insertion is O(n), this becomes a bottleneck as fragmentation increases. Benchmarking shows list_insert_sorted() consumes ~52.69% CPU with the freelist, compared to just 0.03% with the RB tree (rbtree_insert.isra.0), despite performing the same sorted insert. This also improves performance in heavily fragmented workloads, such as games or graphics tests that stress memory. As the buddy allocator evolves with new features such as clear-page tracking, the resulting fragmentation and complexity have grown. These RB-tree based design changes are introduced to address that growth and ensure the allocator continues to perform efficiently under fragmented conditions. The RB tree implementation with separate clear/dirty trees provides: - O(n log n) aggregate complexity for all operations instead of O(n^2) - Elimination of soft lockups and system instability - Improved code maintainability and clarity - Better scalability for large memory systems - Predictable performance under fragmentation v3(Matthew): - Remove RB_EMPTY_NODE check in force_merge function. - Rename rb for loop macros to have less generic names and move to .c file. - Make the rb node rb and link field as union. v4(Jani Nikula): - The kernel-doc comment should be "/**" - Move all the rbtree macros to rbtree.h and add parens to ensure correct precedence. v5: - Remove the inline in a .c file (Jani Nikula). v6(Peter Zijlstra): - Add rb_add() function replacing the existing rbtree_insert() code. v7: - A full walk iteration in rbtree is slower than the list (Peter Zijlstra). - The existing rbtree_postorder_for_each_entry_safe macro should be used in scenarios where traversal order is not a critical factor (Christian). v8(Matthew): - Remove the rbtree_is_empty() check in this patch as well. Cc: stable(a)vger.kernel.org Fixes: a68c7eaa7a8f ("drm/amdgpu: Enable clear page functionality") Signed-off-by: Arunpravin Paneer Selvam <Arunpravin.PaneerSelvam(a)amd.com> Reviewed-by: Matthew Auld <matthew.auld(a)intel.com> --- drivers/gpu/drm/drm_buddy.c | 195 ++++++++++++++++++++++-------------- include/drm/drm_buddy.h | 11 +- 2 files changed, 126 insertions(+), 80 deletions(-) diff --git a/drivers/gpu/drm/drm_buddy.c b/drivers/gpu/drm/drm_buddy.c index a94061f373de..c87210a06c31 100644 --- a/drivers/gpu/drm/drm_buddy.c +++ b/drivers/gpu/drm/drm_buddy.c @@ -14,6 +14,8 @@ static struct kmem_cache *slab_blocks; +#define rbtree_get_free_block(node) rb_entry((node), struct drm_buddy_block, rb) + static struct drm_buddy_block *drm_block_alloc(struct drm_buddy *mm, struct drm_buddy_block *parent, unsigned int order, @@ -31,6 +33,8 @@ static struct drm_buddy_block *drm_block_alloc(struct drm_buddy *mm, block->header |= order; block->parent = parent; + RB_CLEAR_NODE(&block->rb); + BUG_ON(block->header & DRM_BUDDY_HEADER_UNUSED); return block; } @@ -41,23 +45,49 @@ static void drm_block_free(struct drm_buddy *mm, kmem_cache_free(slab_blocks, block); } -static void list_insert_sorted(struct drm_buddy *mm, - struct drm_buddy_block *block) +static bool drm_buddy_block_offset_less(const struct drm_buddy_block *block, + const struct drm_buddy_block *node) { - struct drm_buddy_block *node; - struct list_head *head; + return drm_buddy_block_offset(block) < drm_buddy_block_offset(node); +} - head = &mm->free_list[drm_buddy_block_order(block)]; - if (list_empty(head)) { - list_add(&block->link, head); - return; - } +static bool rbtree_block_offset_less(struct rb_node *block, + const struct rb_node *node) +{ + return drm_buddy_block_offset_less(rbtree_get_free_block(block), + rbtree_get_free_block(node)); +} - list_for_each_entry(node, head, link) - if (drm_buddy_block_offset(block) < drm_buddy_block_offset(node)) - break; +static void rbtree_insert(struct drm_buddy *mm, + struct drm_buddy_block *block) +{ + rb_add(&block->rb, + &mm->free_tree[drm_buddy_block_order(block)], + rbtree_block_offset_less); +} + +static void rbtree_remove(struct drm_buddy *mm, + struct drm_buddy_block *block) +{ + struct rb_root *root; + + root = &mm->free_tree[drm_buddy_block_order(block)]; + rb_erase(&block->rb, root); + + RB_CLEAR_NODE(&block->rb); +} + +static struct drm_buddy_block * +rbtree_last_entry(struct drm_buddy *mm, unsigned int order) +{ + struct rb_node *node = rb_last(&mm->free_tree[order]); + + return node ? rb_entry(node, struct drm_buddy_block, rb) : NULL; +} - __list_add(&block->link, node->link.prev, &node->link); +static bool rbtree_is_empty(struct drm_buddy *mm, unsigned int order) +{ + return RB_EMPTY_ROOT(&mm->free_tree[order]); } static void clear_reset(struct drm_buddy_block *block) @@ -70,12 +100,13 @@ static void mark_cleared(struct drm_buddy_block *block) block->header |= DRM_BUDDY_HEADER_CLEAR; } -static void mark_allocated(struct drm_buddy_block *block) +static void mark_allocated(struct drm_buddy *mm, + struct drm_buddy_block *block) { block->header &= ~DRM_BUDDY_HEADER_STATE; block->header |= DRM_BUDDY_ALLOCATED; - list_del(&block->link); + rbtree_remove(mm, block); } static void mark_free(struct drm_buddy *mm, @@ -84,15 +115,16 @@ static void mark_free(struct drm_buddy *mm, block->header &= ~DRM_BUDDY_HEADER_STATE; block->header |= DRM_BUDDY_FREE; - list_insert_sorted(mm, block); + rbtree_insert(mm, block); } -static void mark_split(struct drm_buddy_block *block) +static void mark_split(struct drm_buddy *mm, + struct drm_buddy_block *block) { block->header &= ~DRM_BUDDY_HEADER_STATE; block->header |= DRM_BUDDY_SPLIT; - list_del(&block->link); + rbtree_remove(mm, block); } static inline bool overlaps(u64 s1, u64 e1, u64 s2, u64 e2) @@ -148,7 +180,7 @@ static unsigned int __drm_buddy_free(struct drm_buddy *mm, mark_cleared(parent); } - list_del(&buddy->link); + rbtree_remove(mm, buddy); if (force_merge && drm_buddy_block_is_clear(buddy)) mm->clear_avail -= drm_buddy_block_size(mm, buddy); @@ -179,13 +211,19 @@ static int __force_merge(struct drm_buddy *mm, return -EINVAL; for (i = min_order - 1; i >= 0; i--) { - struct drm_buddy_block *block, *prev; + struct rb_root *root = &mm->free_tree[i]; + struct rb_node *iter; + + iter = rb_last(root); - list_for_each_entry_safe_reverse(block, prev, &mm->free_list[i], link) { - struct drm_buddy_block *buddy; + while (iter) { + struct drm_buddy_block *block, *buddy; u64 block_start, block_end; - if (!block->parent) + block = rbtree_get_free_block(iter); + iter = rb_prev(iter); + + if (!block || !block->parent) continue; block_start = drm_buddy_block_offset(block); @@ -201,15 +239,10 @@ static int __force_merge(struct drm_buddy *mm, WARN_ON(drm_buddy_block_is_clear(block) == drm_buddy_block_is_clear(buddy)); - /* - * If the prev block is same as buddy, don't access the - * block in the next iteration as we would free the - * buddy block as part of the free function. - */ - if (prev == buddy) - prev = list_prev_entry(prev, link); + if (iter == &buddy->rb) + iter = rb_prev(iter); - list_del(&block->link); + rbtree_remove(mm, block); if (drm_buddy_block_is_clear(block)) mm->clear_avail -= drm_buddy_block_size(mm, block); @@ -237,7 +270,7 @@ static int __force_merge(struct drm_buddy *mm, int drm_buddy_init(struct drm_buddy *mm, u64 size, u64 chunk_size) { unsigned int i; - u64 offset; + u64 offset = 0; if (size < chunk_size) return -EINVAL; @@ -258,14 +291,14 @@ int drm_buddy_init(struct drm_buddy *mm, u64 size, u64 chunk_size) BUG_ON(mm->max_order > DRM_BUDDY_MAX_ORDER); - mm->free_list = kmalloc_array(mm->max_order + 1, - sizeof(struct list_head), + mm->free_tree = kmalloc_array(mm->max_order + 1, + sizeof(struct rb_root), GFP_KERNEL); - if (!mm->free_list) + if (!mm->free_tree) return -ENOMEM; for (i = 0; i <= mm->max_order; ++i) - INIT_LIST_HEAD(&mm->free_list[i]); + mm->free_tree[i] = RB_ROOT; mm->n_roots = hweight64(size); @@ -273,9 +306,8 @@ int drm_buddy_init(struct drm_buddy *mm, u64 size, u64 chunk_size) sizeof(struct drm_buddy_block *), GFP_KERNEL); if (!mm->roots) - goto out_free_list; + goto out_free_tree; - offset = 0; i = 0; /* @@ -312,8 +344,8 @@ int drm_buddy_init(struct drm_buddy *mm, u64 size, u64 chunk_size) while (i--) drm_block_free(mm, mm->roots[i]); kfree(mm->roots); -out_free_list: - kfree(mm->free_list); +out_free_tree: + kfree(mm->free_tree); return -ENOMEM; } EXPORT_SYMBOL(drm_buddy_init); @@ -323,7 +355,7 @@ EXPORT_SYMBOL(drm_buddy_init); * * @mm: DRM buddy manager to free * - * Cleanup memory manager resources and the freelist + * Cleanup memory manager resources and the freetree */ void drm_buddy_fini(struct drm_buddy *mm) { @@ -350,7 +382,7 @@ void drm_buddy_fini(struct drm_buddy *mm) WARN_ON(mm->avail != mm->size); kfree(mm->roots); - kfree(mm->free_list); + kfree(mm->free_tree); } EXPORT_SYMBOL(drm_buddy_fini); @@ -383,7 +415,7 @@ static int split_block(struct drm_buddy *mm, clear_reset(block); } - mark_split(block); + mark_split(mm, block); return 0; } @@ -412,7 +444,7 @@ EXPORT_SYMBOL(drm_get_buddy); * @is_clear: blocks clear state * * Reset the clear state based on @is_clear value for each block - * in the freelist. + * in the freetree. */ void drm_buddy_reset_clear(struct drm_buddy *mm, bool is_clear) { @@ -431,9 +463,9 @@ void drm_buddy_reset_clear(struct drm_buddy *mm, bool is_clear) } for (i = 0; i <= mm->max_order; ++i) { - struct drm_buddy_block *block; + struct drm_buddy_block *block, *tmp; - list_for_each_entry_reverse(block, &mm->free_list[i], link) { + rbtree_postorder_for_each_entry_safe(block, tmp, &mm->free_tree[i], rb) { if (is_clear != drm_buddy_block_is_clear(block)) { if (is_clear) { mark_cleared(block); @@ -639,14 +671,18 @@ get_maxblock(struct drm_buddy *mm, unsigned int order, unsigned int i; for (i = order; i <= mm->max_order; ++i) { + struct rb_node *iter = rb_last(&mm->free_tree[i]); struct drm_buddy_block *tmp_block; - list_for_each_entry_reverse(tmp_block, &mm->free_list[i], link) { - if (block_incompatible(tmp_block, flags)) - continue; + while (iter) { + tmp_block = rbtree_get_free_block(iter); - block = tmp_block; - break; + if (!block_incompatible(tmp_block, flags)) { + block = tmp_block; + break; + } + + iter = rb_prev(iter); } if (!block) @@ -667,7 +703,7 @@ get_maxblock(struct drm_buddy *mm, unsigned int order, } static struct drm_buddy_block * -alloc_from_freelist(struct drm_buddy *mm, +alloc_from_freetree(struct drm_buddy *mm, unsigned int order, unsigned long flags) { @@ -682,14 +718,18 @@ alloc_from_freelist(struct drm_buddy *mm, tmp = drm_buddy_block_order(block); } else { for (tmp = order; tmp <= mm->max_order; ++tmp) { + struct rb_node *iter = rb_last(&mm->free_tree[tmp]); struct drm_buddy_block *tmp_block; - list_for_each_entry_reverse(tmp_block, &mm->free_list[tmp], link) { - if (block_incompatible(tmp_block, flags)) - continue; + while (iter) { + tmp_block = rbtree_get_free_block(iter); - block = tmp_block; - break; + if (!block_incompatible(tmp_block, flags)) { + block = tmp_block; + break; + } + + iter = rb_prev(iter); } if (block) @@ -700,13 +740,9 @@ alloc_from_freelist(struct drm_buddy *mm, if (!block) { /* Fallback method */ for (tmp = order; tmp <= mm->max_order; ++tmp) { - if (!list_empty(&mm->free_list[tmp])) { - block = list_last_entry(&mm->free_list[tmp], - struct drm_buddy_block, - link); - if (block) - break; - } + block = rbtree_last_entry(mm, tmp); + if (block) + break; } if (!block) @@ -771,7 +807,7 @@ static int __alloc_range(struct drm_buddy *mm, if (contains(start, end, block_start, block_end)) { if (drm_buddy_block_is_free(block)) { - mark_allocated(block); + mark_allocated(mm, block); total_allocated += drm_buddy_block_size(mm, block); mm->avail -= drm_buddy_block_size(mm, block); if (drm_buddy_block_is_clear(block)) @@ -849,8 +885,8 @@ static int __alloc_contig_try_harder(struct drm_buddy *mm, { u64 rhs_offset, lhs_offset, lhs_size, filled; struct drm_buddy_block *block; - struct list_head *list; LIST_HEAD(blocks_lhs); + struct rb_node *iter; unsigned long pages; unsigned int order; u64 modify_size; @@ -862,11 +898,14 @@ static int __alloc_contig_try_harder(struct drm_buddy *mm, if (order == 0) return -ENOSPC; - list = &mm->free_list[order]; - if (list_empty(list)) + if (rbtree_is_empty(mm, order)) return -ENOSPC; - list_for_each_entry_reverse(block, list, link) { + iter = rb_last(&mm->free_tree[order]); + + while (iter) { + block = rbtree_get_free_block(iter); + /* Allocate blocks traversing RHS */ rhs_offset = drm_buddy_block_offset(block); err = __drm_buddy_alloc_range(mm, rhs_offset, size, @@ -891,6 +930,8 @@ static int __alloc_contig_try_harder(struct drm_buddy *mm, } /* Free blocks for the next iteration */ drm_buddy_free_list_internal(mm, blocks); + + iter = rb_prev(iter); } return -ENOSPC; @@ -976,7 +1017,7 @@ int drm_buddy_block_trim(struct drm_buddy *mm, list_add(&block->tmp_link, &dfs); err = __alloc_range(mm, &dfs, new_start, new_size, blocks, NULL); if (err) { - mark_allocated(block); + mark_allocated(mm, block); mm->avail -= drm_buddy_block_size(mm, block); if (drm_buddy_block_is_clear(block)) mm->clear_avail -= drm_buddy_block_size(mm, block); @@ -999,8 +1040,8 @@ __drm_buddy_alloc_blocks(struct drm_buddy *mm, return __drm_buddy_alloc_range_bias(mm, start, end, order, flags); else - /* Allocate from freelist */ - return alloc_from_freelist(mm, order, flags); + /* Allocate from freetree */ + return alloc_from_freetree(mm, order, flags); } /** @@ -1017,8 +1058,8 @@ __drm_buddy_alloc_blocks(struct drm_buddy *mm, * alloc_range_bias() called on range limitations, which traverses * the tree and returns the desired block. * - * alloc_from_freelist() called when *no* range restrictions - * are enforced, which picks the block from the freelist. + * alloc_from_freetree() called when *no* range restrictions + * are enforced, which picks the block from the freetree. * * Returns: * 0 on success, error code on failure. @@ -1120,7 +1161,7 @@ int drm_buddy_alloc_blocks(struct drm_buddy *mm, } } while (1); - mark_allocated(block); + mark_allocated(mm, block); mm->avail -= drm_buddy_block_size(mm, block); if (drm_buddy_block_is_clear(block)) mm->clear_avail -= drm_buddy_block_size(mm, block); @@ -1201,10 +1242,10 @@ void drm_buddy_print(struct drm_buddy *mm, struct drm_printer *p) mm->chunk_size >> 10, mm->size >> 20, mm->avail >> 20, mm->clear_avail >> 20); for (order = mm->max_order; order >= 0; order--) { - struct drm_buddy_block *block; + struct drm_buddy_block *block, *tmp; u64 count = 0, free; - list_for_each_entry(block, &mm->free_list[order], link) { + rbtree_postorder_for_each_entry_safe(block, tmp, &mm->free_tree[order], rb) { BUG_ON(!drm_buddy_block_is_free(block)); count++; } diff --git a/include/drm/drm_buddy.h b/include/drm/drm_buddy.h index 513837632b7d..9ee105d4309f 100644 --- a/include/drm/drm_buddy.h +++ b/include/drm/drm_buddy.h @@ -10,6 +10,7 @@ #include <linux/list.h> #include <linux/slab.h> #include <linux/sched.h> +#include <linux/rbtree.h> #include <drm/drm_print.h> @@ -53,7 +54,11 @@ struct drm_buddy_block { * a list, if so desired. As soon as the block is freed with * drm_buddy_free* ownership is given back to the mm. */ - struct list_head link; + union { + struct rb_node rb; + struct list_head link; + }; + struct list_head tmp_link; }; @@ -68,7 +73,7 @@ struct drm_buddy_block { */ struct drm_buddy { /* Maintain a free list for each order. */ - struct list_head *free_list; + struct rb_root *free_tree; /* * Maintain explicit binary tree(s) to track the allocation of the @@ -94,7 +99,7 @@ struct drm_buddy { }; static inline u64 -drm_buddy_block_offset(struct drm_buddy_block *block) +drm_buddy_block_offset(const struct drm_buddy_block *block) { return block->header & DRM_BUDDY_HEADER_OFFSET; } base-commit: a31c6c50da013dcd4de4889d402b47bae552a2e2 -- 2.34.1
3 weeks, 3 days
1
1
0
0
[PATCH] drm/mediatek: Fix refcounting in mtk_drm_get_all_drm_priv
by Sjoerd Simons
dev_get_drvdata simply returns the driver data part of drm_dev, which has its lifetime bound to the drm_dev. So only drop the reference in the error paths, on success they will get dropped later. Cc: stable(a)vger.kernel.org Fixes: 9ba2556cef1df ("drm/mediatek: clean up driver data initialisation") Signed-off-by: Sjoerd Simons <sjoerd(a)collabora.com> --- drivers/gpu/drm/mediatek/mtk_drm_drv.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c index 7841f59c52ee772dba3de416f410604f5f13eef2..c85fbecce9d6f0ade700e047e067ee7f9250f037 100644 --- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c +++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c @@ -373,7 +373,7 @@ static int mtk_drm_match(struct device *dev, const void *data) static bool mtk_drm_get_all_drm_priv(struct device *dev) { struct mtk_drm_private *drm_priv = dev_get_drvdata(dev); - struct mtk_drm_private *all_drm_priv[MAX_CRTC]; + struct mtk_drm_private *all_drm_priv[MAX_CRTC] = { NULL, }; struct mtk_drm_private *temp_drm_priv; struct device_node *phandle = dev->parent->of_node; const struct of_device_id *of_id; @@ -399,16 +399,22 @@ static bool mtk_drm_get_all_drm_priv(struct device *dev) continue; temp_drm_priv = dev_get_drvdata(drm_dev); - put_device(drm_dev); - if (!temp_drm_priv) + if (!temp_drm_priv) { + put_device(drm_dev); continue; + } - if (temp_drm_priv->data->main_len) + if (temp_drm_priv->data->main_len) { all_drm_priv[CRTC_MAIN] = temp_drm_priv; - else if (temp_drm_priv->data->ext_len) + } else if (temp_drm_priv->data->ext_len) { all_drm_priv[CRTC_EXT] = temp_drm_priv; - else if (temp_drm_priv->data->third_len) + } else if (temp_drm_priv->data->third_len) { all_drm_priv[CRTC_THIRD] = temp_drm_priv; + } else { + dev_warn(drm_dev, "Could not determine crtc type"); + put_device(drm_dev); + continue; + } if (temp_drm_priv->mtk_drm_bound) cnt++; @@ -427,6 +433,10 @@ static bool mtk_drm_get_all_drm_priv(struct device *dev) return true; } + for (i = 0; i < MAX_CRTC; i++) + if (all_drm_priv[i]) + put_device(all_drm_priv[i]->dev); + return false; } --- base-commit: 22b5e8cde1db67c64b83fc0e4e1ab166cacff246 change-id: 20251002-mtk-drm-refcount-e0f718d9364a Best regards, -- Sjoerd Simons <sjoerd(a)collabora.com>
3 weeks, 3 days
3
2
0
0
Request for Vendor Questionnaire/EOI Form
by Farahiyah
3 weeks, 3 days
1
0
0
0
[PATCH] arm64: dts: rockchip: Fix broken tsadc pinctrl binding for rk3588
by Alexander Shiyan
There is no pinctrl "gpio" and "otpout" (probably designed as "output") handling in the tsadc driver. Let's use proper binding "default" and "sleep". Fixes: 32641b8ab1a5 ("arm64: dts: rockchip: add rk3588 thermal sensor") Cc: stable(a)vger.kernel.org Signed-off-by: Alexander Shiyan <eagle.alexander923(a)gmail.com> --- arch/arm64/boot/dts/rockchip/rk3588-base.dtsi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi index a337f3fb8377..f141065eb69d 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi @@ -2667,9 +2667,9 @@ tsadc: tsadc@fec00000 { rockchip,hw-tshut-temp = <120000>; rockchip,hw-tshut-mode = <0>; /* tshut mode 0:CRU 1:GPIO */ rockchip,hw-tshut-polarity = <0>; /* tshut polarity 0:LOW 1:HIGH */ - pinctrl-0 = <&tsadc_gpio_func>; - pinctrl-1 = <&tsadc_shut>; - pinctrl-names = "gpio", "otpout"; + pinctrl-0 = <&tsadc_shut>; + pinctrl-1 = <&tsadc_gpio_func>; + pinctrl-names = "default", "sleep"; #thermal-sensor-cells = <1>; status = "disabled"; }; -- 2.39.1
3 weeks, 4 days
4
23
0
0
← Newer
1
...
139
140
141
142
143
144
145
...
153
Older →
Jump to page:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
Results per page:
10
25
50
100
200