* Re: [PATCH] mm/page_alloc: fix initialization of tags of the huge zero folio with init_on_free
From: Dev Jain @ 2026-04-21 7:06 UTC (permalink / raw)
To: David Hildenbrand (Arm), Catalin Marinas, Will Deacon,
Andrew Morton, Lorenzo Stoakes, Liam R. Howlett, Vlastimil Babka,
Mike Rapoport, Suren Baghdasaryan, Michal Hocko, Brendan Jackman,
Johannes Weiner, Zi Yan, Lance Yang, Ryan Roberts
Cc: linux-arm-kernel, linux-kernel, linux-mm, stable
In-Reply-To: <20260420-zerotags-v1-1-3edc93e95bb4@kernel.org>
On 21/04/26 2:46 am, David Hildenbrand (Arm) wrote:
> __GFP_ZEROTAGS semantics are currently a bit weird, but effectively this
> flag is only ever set alongside __GFP_ZERO and __GFP_SKIP_KASAN.
>
> If we run with init_on_free, we will zero out pages during
> __free_pages_prepare(), to skip zeroing on the allocation path.
>
> However, when allocating with __GFP_ZEROTAG set, post_alloc_hook() will
> consequently not only skip clearing page content, but also skip
> clearing tag memory.
>
> Not clearing tags through __GFP_ZEROTAGS is irrelevant for most pages that
> will get mapped to user space through set_pte_at() later: set_pte_at() and
> friends will detect that the tags have not been initialized yet
> (PG_mte_tagged not set), and initialize them.
>
> However, for the huge zero folio, which will be mapped through a PMD
> marked as special, this initialization will not be performed, ending up
> exposing whatever tags were still set for the pages.
>
> The docs (Documentation/arch/arm64/memory-tagging-extension.rst) state
> that allocation tags are set to 0 when a page is first mapped to user
> space. That no longer holds with the huge zero folio when init_on_free
> is enabled.
>
> Fix it by decoupling __GFP_ZEROTAGS from __GFP_ZERO, passing to
> tag_clear_highpages() whether we want to also clear page content.
>
> As we are touching the interface either way, just clean it up by
> only calling it when HW tags are enabled, dropping the return value, and
> dropping the common code stub.
>
> Reproduced with the huge zero folio by modifying the check_buffer_fill
> arm64/mte selftest to use a 2 MiB area, after making sure that pages have
> a non-0 tag set when freeing (note that, during boot, we will not
> actually initialize tags, but only set KASAN_TAG_KERNEL in the page
> flags).
>
> $ ./check_buffer_fill
> 1..20
> ...
> not ok 17 Check initial tags with private mapping, sync error mode and mmap memory
> not ok 18 Check initial tags with private mapping, sync error mode and mmap/mprotect memory
> ...
>
> This code needs more cleanups; we'll tackle that next, like
> decoupling __GFP_ZEROTAGS from __GFP_SKIP_KASAN, moving all the
> KASAN magic into a separate helper, and consolidating HW-tag handling.
>
> Fixes: adfb6609c680 ("mm/huge_memory: initialise the tags of the huge zero folio")
> Cc: stable@vger.kernel.org
> Signed-off-by: David Hildenbrand (Arm) <david@kernel.org>
> ---
> arch/arm64/include/asm/page.h | 3 ---
> arch/arm64/mm/fault.c | 16 +++++-----------
> include/linux/gfp_types.h | 10 +++++-----
> include/linux/highmem.h | 10 +---------
> mm/page_alloc.c | 12 +++++++-----
> 5 files changed, 18 insertions(+), 33 deletions(-)
>
> diff --git a/arch/arm64/include/asm/page.h b/arch/arm64/include/asm/page.h
> index e25d0d18f6d7..5c6cbfbbd34c 100644
> --- a/arch/arm64/include/asm/page.h
> +++ b/arch/arm64/include/asm/page.h
> @@ -33,9 +33,6 @@ struct folio *vma_alloc_zeroed_movable_folio(struct vm_area_struct *vma,
> unsigned long vaddr);
> #define vma_alloc_zeroed_movable_folio vma_alloc_zeroed_movable_folio
>
> -bool tag_clear_highpages(struct page *to, int numpages);
> -#define __HAVE_ARCH_TAG_CLEAR_HIGHPAGES
> -
> #define copy_user_page(to, from, vaddr, pg) copy_page(to, from)
>
> typedef struct page *pgtable_t;
> diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c
> index 0f3c5c7ca054..32a3723f2d34 100644
> --- a/arch/arm64/mm/fault.c
> +++ b/arch/arm64/mm/fault.c
> @@ -1018,21 +1018,15 @@ struct folio *vma_alloc_zeroed_movable_folio(struct vm_area_struct *vma,
> return vma_alloc_folio(flags, 0, vma, vaddr);
> }
>
> -bool tag_clear_highpages(struct page *page, int numpages)
> +void tag_clear_highpages(struct page *page, int numpages, bool clear_pages)
> {
> - /*
> - * Check if MTE is supported and fall back to clear_highpage().
> - * get_huge_zero_folio() unconditionally passes __GFP_ZEROTAGS and
> - * post_alloc_hook() will invoke tag_clear_highpages().
> - */
> - if (!system_supports_mte())
> - return false;
> -
> /* Newly allocated pages, shouldn't have been tagged yet */
> for (int i = 0; i < numpages; i++, page++) {
> WARN_ON_ONCE(!try_page_mte_tagging(page));
> - mte_zero_clear_page_tags(page_address(page));
> + if (clear_pages)
> + mte_zero_clear_page_tags(page_address(page));
> + else
> + mte_clear_page_tags(page_address(page));
> set_page_mte_tagged(page);
> }
> - return true;
> }
> diff --git a/include/linux/gfp_types.h b/include/linux/gfp_types.h
> index 6c75df30a281..fd53a6fba33f 100644
> --- a/include/linux/gfp_types.h
> +++ b/include/linux/gfp_types.h
> @@ -273,11 +273,11 @@ enum {
> *
> * %__GFP_ZERO returns a zeroed page on success.
> *
> - * %__GFP_ZEROTAGS zeroes memory tags at allocation time if the memory itself
> - * is being zeroed (either via __GFP_ZERO or via init_on_alloc, provided that
> - * __GFP_SKIP_ZERO is not set). This flag is intended for optimization: setting
> - * memory tags at the same time as zeroing memory has minimal additional
> - * performance impact.
> + * %__GFP_ZEROTAGS zeroes memory tags at allocation time. This flag is intended
> + * for optimization: setting memory tags at the same time as zeroing memory
> + * (e.g., with __GPF_ZERO) has minimal additional performance impact. However,
> + * __GFP_ZEROTAGS also zeroes the tags even if memory is not getting zeroed at
> + * allocation time (e.g., with init_on_free).
> *
> * %__GFP_SKIP_KASAN makes KASAN skip unpoisoning on page allocation.
> * Used for userspace and vmalloc pages; the latter are unpoisoned by
> diff --git a/include/linux/highmem.h b/include/linux/highmem.h
> index af03db851a1d..62f589baa343 100644
> --- a/include/linux/highmem.h
> +++ b/include/linux/highmem.h
> @@ -345,15 +345,7 @@ static inline void clear_highpage_kasan_tagged(struct page *page)
> kunmap_local(kaddr);
> }
>
> -#ifndef __HAVE_ARCH_TAG_CLEAR_HIGHPAGES
> -
> -/* Return false to let people know we did not initialize the pages */
> -static inline bool tag_clear_highpages(struct page *page, int numpages)
> -{
> - return false;
> -}
> -
> -#endif
> +void tag_clear_highpages(struct page *to, int numpages, bool clear_pages);
>
> /*
> * If we pass in a base or tail page, we can zero up to PAGE_SIZE.
> diff --git a/mm/page_alloc.c b/mm/page_alloc.c
> index 65e205111553..8c6821d25a00 100644
> --- a/mm/page_alloc.c
> +++ b/mm/page_alloc.c
> @@ -1808,9 +1808,9 @@ static inline bool should_skip_init(gfp_t flags)
> inline void post_alloc_hook(struct page *page, unsigned int order,
> gfp_t gfp_flags)
> {
> + const bool zero_tags = kasan_hw_tags_enabled() && (gfp_flags & __GFP_ZEROTAGS);
Sashiko:
https://sashiko.dev/#/patchset/20260420-zerotags-v1-1-3edc93e95bb4%40kernel.org
PROT_MTE works without KASAN_HW_TAGS, so probably just retain the
system_supports_mte() check in tag_clear_highpages(), and document
that GFP_ZEROTAGS is only for MTE?
> bool init = !want_init_on_free() && want_init_on_alloc(gfp_flags) &&
> !should_skip_init(gfp_flags);
> - bool zero_tags = init && (gfp_flags & __GFP_ZEROTAGS);
> int i;
>
> set_page_private(page, 0);
> @@ -1832,11 +1832,13 @@ inline void post_alloc_hook(struct page *page, unsigned int order,
> */
>
> /*
> - * If memory tags should be zeroed
> - * (which happens only when memory should be initialized as well).
> + * Clearing tags can efficiently clear the memory for us as well, if
> + * required.
> */
> - if (zero_tags)
> - init = !tag_clear_highpages(page, 1 << order);
> + if (zero_tags) {
> + tag_clear_highpages(page, 1 << order, /* clear_pages= */init);
Micro-nit: ^ space
> + init = false;
> + }
>
> if (!should_skip_kasan_unpoison(gfp_flags) &&
> kasan_unpoison_pages(page, order, init)) {
>
> ---
> base-commit: f1541b40cd422d7e22273be9b7e9edfc9ea4f0d7
> change-id: 20260417-zerotags-343a3673e18d
>
> Best regards,
^ permalink raw reply
* Re: [RFC PATCH 4/4] firmware: arm_ffa: check pkvm initailised when initailise ffa driver
From: Yeoreum Yun @ 2026-04-21 6:57 UTC (permalink / raw)
To: Marc Zyngier
Cc: linux-security-module, linux-kernel, linux-integrity,
linux-arm-kernel, kvmarm, paul, jmorris, serge, zohar,
roberto.sassu, dmitry.kasatkin, eric.snowberg, peterhuewe, jarkko,
jgg, sudeep.holla, oupton, joey.gouly, suzuki.poulose, yuzenghui,
catalin.marinas, will
In-Reply-To: <87pl3vb5bm.wl-maz@kernel.org>
Hi Marc,
> On Sat, 18 Apr 2026 11:34:30 +0100,
> Yeoreum Yun <yeoreum.yun@arm.com> wrote:
> >
> > > > @@ -2035,6 +2037,16 @@ static int __init ffa_init(void)
> > > > u32 buf_sz;
> > > > size_t rxtx_bufsz = SZ_4K;
> > > >
> > > > + /*
> > > > + * When pKVM is enabled, the FF-A driver must be initialized
> > > > + * after pKVM initialization. Otherwise, pKVM cannot negotiate
> > > > + * the FF-A version or obtain RX/TX buffer information,
> > > > + * which leads to failures in FF-A calls.
> > > > + */
> > > > + if (IS_ENABLED(CONFIG_KVM) && is_protected_kvm_enabled() &&
> > > > + !is_kvm_arm_initialised())
> > > > + return -EPROBE_DEFER;
> > > > +
> > >
> > > That's still fundamentally wrong: pkvm is not ready until
> > > finalize_pkvm() has finished, and that's not indicated by
> > > is_kvm_arm_initialised().
> >
> > Thanks. I miss the TSC bit set in here.
>
> That's the least of the problems. None of the infrastructure is in
> place at this stage...
>
> > IMHO, I'd like to make an new state check function --
> > is_pkvm_arm_initialised() so that ff-a driver to know whether
> > pkvm is initialised.
>
> Doesn't sound great, TBH.
>
> > or any other suggestion?
>
> Instead of adding more esoteric predicates, I'd rather you build on an
> existing infrastructure. You have a dependency on KVM, use something
> that is designed to enforce dependencies. Device links spring to mind
> as something designed for that.
>
> Can you look into enabling this for KVM? If that's possible, then it
> should be easy enough to delay the actual KVM registration after pKVM
> is finalised.
Hmm, I also considered moving kvm_init() into finalised_pkvm() and
then handling the remaining ffa_init() work after /dev/kvm is registered.
However, this approach seems awkward in practice,
because misc has neither a bus nor a dedicated class notifier that we can hook into.
Also, the FF-A initialization is not driven by a device probe, but rather
happens as part of the bus registration itself,
so it does not fit well with a device_link or probe deferral based approach.
Instead, perhaps we could go with the idea I mentioned previously:
either introduce a notifier, or create a pseudo ffa_device
once pKVM initialization has completed, and
then let the ffa driver perform the additional initialization from there.
Am I missing something?
--
Sincerely,
Yeoreum Yun
^ permalink raw reply
* Re: [patch 32/38] powerpc/spufs: Use mftb() directly
From: Mukesh Kumar Chaurasiya @ 2026-04-21 6:48 UTC (permalink / raw)
To: Thomas Gleixner
Cc: LKML, Michael Ellerman, linuxppc-dev, Arnd Bergmann, x86,
Lu Baolu, iommu, Michael Grzeschik, netdev, linux-wireless,
Herbert Xu, linux-crypto, Vlastimil Babka, linux-mm,
David Woodhouse, Bernie Thompson, linux-fbdev, Theodore Tso,
linux-ext4, Andrew Morton, Uladzislau Rezki, Marco Elver,
Dmitry Vyukov, kasan-dev, Andrey Ryabinin, Thomas Sailer,
linux-hams, Jason A. Donenfeld, Richard Henderson, linux-alpha,
Russell King, linux-arm-kernel, Catalin Marinas, Huacai Chen,
loongarch, Geert Uytterhoeven, linux-m68k, Dinh Nguyen,
Jonas Bonn, linux-openrisc, Helge Deller, linux-parisc,
Paul Walmsley, linux-riscv, Heiko Carstens, linux-s390,
David S. Miller, sparclinux
In-Reply-To: <20260410120319.723429844@kernel.org>
On Fri, Apr 10, 2026 at 02:21:04PM +0200, Thomas Gleixner wrote:
> There is no reason to indirect via get_cycles(), which is about to be
> removed.
>
> Use mftb() directly.
>
> Signed-off-by: Thomas Gleixner <tglx@kernel.org>
> Cc: Michael Ellerman <mpe@ellerman.id.au>
> Cc: linuxppc-dev@lists.ozlabs.org
> ---
> arch/powerpc/platforms/cell/spufs/switch.c | 5 +++--
> 1 file changed, 3 insertions(+), 2 deletions(-)
>
> --- a/arch/powerpc/platforms/cell/spufs/switch.c
> +++ b/arch/powerpc/platforms/cell/spufs/switch.c
> @@ -34,6 +34,7 @@
> #include <asm/spu_priv1.h>
> #include <asm/spu_csa.h>
> #include <asm/mmu_context.h>
> +#include <asm/time.h>
>
> #include "spufs.h"
>
> @@ -279,7 +280,7 @@ static inline void save_timebase(struct
> * Read PPE Timebase High and Timebase low registers
> * and save in CSA. TBD.
> */
> - csa->suspend_time = get_cycles();
> + csa->suspend_time = mftb();
> }
>
> static inline void remove_other_spu_access(struct spu_state *csa,
> @@ -1261,7 +1262,7 @@ static inline void setup_decr(struct spu
> * in LSCSA.
> */
> if (csa->priv2.mfc_control_RW & MFC_CNTL_DECREMENTER_RUNNING) {
> - cycles_t resume_time = get_cycles();
> + cycles_t resume_time = mftb();
> cycles_t delta_time = resume_time - csa->suspend_time;
>
> csa->lscsa->decr_status.slot[0] = SPU_DECR_STATUS_RUNNING;
>
Reviewed-by: Mukesh Kumar Chaurasiya (IBM) <mkchauras@gmail.com>
^ permalink raw reply
* [PATCH net] net: airoha: stop net_device TX queue before updating CPU index
From: Lorenzo Bianconi @ 2026-04-21 6:43 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni
Cc: Simon Horman, linux-arm-kernel, linux-mediatek, netdev,
Lorenzo Bianconi
Currently, airoha_eth driver updates the CPU index register prior of
verifying whether the number of free descriptors has fallen below the
threshold.
Move net_device TX queue length check before updating the TX CPU index
in order to update TX CPU index even if there are more packets to be
transmitted but the net_device TX queue is going to be stopped
accounting the inflight packets.
Fixes: 1d304174106c ("net: airoha: Implement BQL support")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/ethernet/airoha/airoha_eth.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index 19f67c7dd8e1..5d327237e274 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -2058,17 +2058,16 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
skb_tx_timestamp(skb);
netdev_tx_sent_queue(txq, skb->len);
+ if (q->ndesc - q->queued < q->free_thr) {
+ netif_tx_stop_queue(txq);
+ q->txq_stopped = true;
+ }
if (netif_xmit_stopped(txq) || !netdev_xmit_more())
airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(qid),
TX_RING_CPU_IDX_MASK,
FIELD_PREP(TX_RING_CPU_IDX_MASK, index));
- if (q->ndesc - q->queued < q->free_thr) {
- netif_tx_stop_queue(txq);
- q->txq_stopped = true;
- }
-
spin_unlock_bh(&q->lock);
return NETDEV_TX_OK;
---
base-commit: a663bac71a2f0b3ac6c373168ca57b2a6e6381aa
change-id: 20260421-airoha-xmit-stop-condition-344dc0292a19
Best regards,
--
Lorenzo Bianconi <lorenzo@kernel.org>
^ permalink raw reply related
* Re: [PATCH v5 05/12] coresight: etm4x: remove redundant fields in etmv4_save_state
From: Leo Yan @ 2026-04-21 6:41 UTC (permalink / raw)
To: Yeoreum Yun
Cc: coresight, linux-arm-kernel, linux-kernel, suzuki.poulose,
mike.leach, james.clark, alexander.shishkin, jie.gan
In-Reply-To: <20260415165528.3369607-6-yeoreum.yun@arm.com>
On Wed, Apr 15, 2026 at 05:55:21PM +0100, Yeoreum Yun wrote:
> Some of fields are redundant in etmv4_save_state and never used:
>
> ss_status => trcsscsr
> seq_state => trcseqstr
> cntr_val => trccntvr
> vinst_ctrl => trcvictlr
>
> Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
Reviewed-by: Leo Yan <leo.yan@arm.com>
^ permalink raw reply
* Re: [PATCH v2 4/4] arm64: dts: amlogic: t7: Add clk measure support
From: Jian Hu @ 2026-04-21 6:40 UTC (permalink / raw)
To: Neil Armstrong, Ronald Claveau
Cc: devicetree, linux-arm-kernel, linux-amlogic, linux-kernel,
Rob Herring, Krzysztof Kozlowski, Conor Dooley, Kevin Hilman,
Jerome Brunet, Martin Blumenstingl
In-Reply-To: <f2074119-7b4b-4481-8e39-c822dd67000e@linaro.org>
Hi Ronald and Neil,
Thank you for your patient explanation.
On 4/20/2026 4:52 PM, Neil Armstrong wrote:
> [ EXTERNAL EMAIL ]
>
> On 4/20/26 05:25, Jian Hu wrote:
>> Hi Ronald,
>>
>>
>> Thanks for your review.
>>
>> On 4/17/2026 5:48 PM, Ronald Claveau wrote:
>>> [ EXTERNAL EMAIL ]
>>>
>>> Hello Jian,
>>>
>>> On 4/15/26 10:33 AM, Jian Hu via B4 Relay wrote:
>>>> From: Jian Hu <jian.hu@amlogic.com>
>>>>
>>>> Add the clock measure device to the T7 SoC family.
>>>>
>>>> Signed-off-by: Jian Hu <jian.hu@amlogic.com>
>>>> ---
>>>> arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi | 5 +++++
>>>> 1 file changed, 5 insertions(+)
>>>>
>>>> diff --git a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
>>>> b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
>>>> index 7fe72c94ed62..cec2ea74850d 100644
>>>> --- a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
>>>> +++ b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
>>>> @@ -701,6 +701,11 @@ pwm_ao_cd: pwm@60000 {
>>>> status = "disabled";
>>>> };
>>>>
>>>> + clock-measurer@48000 {
>>>> + compatible = "amlogic,t7-clk-measure";
>>>> + reg = <0x0 0x48000 0x0 0x1c>;
>>>> + };
>>>> +
>>> Can you please order by reg, it should be between pwm_ao_gh and pwm_ab.
>>> Thank you.
>>
>>
>> According to the "Order of Nodes" chapter in
>> Documentation/devicetree/bindings/dts-coding-style.rst,
>>
>> nodes of the same type should be grouped together, and this takes
>> higher priority.
>>
>> So I have placed the clock-measure node after all PWM nodes to avoid
>> splitting the PWM group.
>
> This is not something we ever followed in the past, and I don't think
> it makes sens here.
>
>
> """
> Alternatively for some subarchitectures, nodes of the same type can be
> grouped together, e.g. all I2C controllers one after another even if this
> breaks unit address ordering.
> """
>
> This doesn't apply here, so order strictly by address.
>
> Neil
>
Ok, I will order it by address in the next version.
Best regards,
Jian
^ permalink raw reply
* [PATCH net] net: airoha: fix BQL imbalance in TX path
From: Lorenzo Bianconi @ 2026-04-21 6:35 UTC (permalink / raw)
To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Hariprasad Kelam
Cc: Simon Horman, linux-arm-kernel, linux-mediatek, netdev,
Lorenzo Bianconi
Fix a possible BQL imbalance in airoha_dev_xmit(), where inflight
packets are accounted only for the AIROHA_NUM_TX_RING netdev TX
queues. The queue index is computed as:
qid = skb_get_queue_mapping(skb) % ARRAY_SIZE(qdma->q_tx)
txq = netdev_get_tx_queue(dev, qid);
However, airoha_qdma_tx_napi_poll() accounts completions across all
netdev TX queues (num_tx_queues), leading to inconsistent BQL
accounting.
Also reset all netdev TX queues in the ndo_stop callback.
Fixes: 1d304174106c ("net: airoha: Implement BQL support")
Fixes: c9f947769b77 ("net: airoha: Reset BQL stopping the netdevice")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/ethernet/airoha/airoha_eth.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.c b/drivers/net/ethernet/airoha/airoha_eth.c
index 19f67c7dd8e1..6c7390f0de5d 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.c
+++ b/drivers/net/ethernet/airoha/airoha_eth.c
@@ -929,10 +929,9 @@ static int airoha_qdma_tx_napi_poll(struct napi_struct *napi, int budget)
q->queued--;
if (skb) {
- u16 queue = skb_get_queue_mapping(skb);
struct netdev_queue *txq;
- txq = netdev_get_tx_queue(skb->dev, queue);
+ txq = skb_get_tx_queue(skb->dev, skb);
netdev_tx_completed_queue(txq, 1, skb->len);
dev_kfree_skb_any(skb);
}
@@ -1711,7 +1710,7 @@ static int airoha_dev_stop(struct net_device *dev)
if (err)
return err;
- for (i = 0; i < ARRAY_SIZE(qdma->q_tx); i++)
+ for (i = 0; i < dev->num_tx_queues; i++)
netdev_tx_reset_subqueue(dev, i);
airoha_set_gdm_port_fwd_cfg(qdma->eth, REG_GDM_FWD_CFG(port->id),
@@ -2002,7 +2001,7 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb,
spin_lock_bh(&q->lock);
- txq = netdev_get_tx_queue(dev, qid);
+ txq = skb_get_tx_queue(dev, skb);
nr_frags = 1 + skb_shinfo(skb)->nr_frags;
if (q->queued + nr_frags >= q->ndesc) {
---
base-commit: a663bac71a2f0b3ac6c373168ca57b2a6e6381aa
change-id: 20260421-airoha-fix-bql-7fff7cebbc9a
Best regards,
--
Lorenzo Bianconi <lorenzo@kernel.org>
^ permalink raw reply related
* Re: [PATCH v2 1/2] kernel: param: handle NULL module_kset in lookup_or_create_module_kobject()
From: Greg Kroah-Hartman @ 2026-04-21 6:27 UTC (permalink / raw)
To: Shashank Balaji
Cc: Kay Sievers, Rafael J. Wysocki, Danilo Krummrich,
Suzuki K Poulose, Mike Leach, James Clark, Alexander Shishkin,
Maxime Coquelin, Alexandre Torgue, Miguel Ojeda, Boqun Feng,
Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Alice Ryhl, Trevor Gross, Richard Cochran, Jonathan Corbet,
Shuah Khan, Rahul Bukte, Daniel Palmer, Tim Bird, linux-kernel,
driver-core, coresight, linux-arm-kernel, rust-for-linux,
linux-doc
In-Reply-To: <20260421-acpi_mod_name-v2-1-e73f9310dad3@sony.com>
On Tue, Apr 21, 2026 at 03:02:34PM +0900, Shashank Balaji wrote:
> module_kset is initialized in a subsys_initcall. If a built-in driver tries to
> register before subsys_initcall with its struct device_driver's mod_name set,
> then a null module_kset is dereferenced via this call trace:
>
> [ 0.095865] Call trace:
> [ 0.095999] _raw_spin_lock+0x4c/0x6c (P)
> [ 0.096150] kset_find_obj+0x24/0x104
> [ 0.096209] lookup_or_create_module_kobject+0x2c/0xd8
> [ 0.096274] module_add_driver+0xd4/0x138
> [ 0.096328] bus_add_driver+0x16c/0x268
> [ 0.096380] driver_register+0x68/0x100
> [ 0.096428] __platform_driver_register+0x24/0x30
> [ 0.096486] tegra194_cbb_init+0x24/0x30
> [ 0.096540] do_one_initcall+0xdc/0x250
> [ 0.096608] do_initcall_level+0x9c/0xd0
> [ 0.096660] do_initcalls+0x54/0x94
> [ 0.096706] do_basic_setup+0x20/0x2c
> [ 0.096753] kernel_init_freeable+0xc8/0x154
> [ 0.096807] kernel_init+0x20/0x1a0
> [ 0.096851] ret_from_fork+0x10/0x20
>
> So, return null in lookup_or_create_module_kobject() if module_kset is null.
> Existing callers handle null already.
>
> Fixes: f30c53a873d0 ("MODULES: add the module name for built in kernel drivers")
This isn't a bugfix.
> Co-developed-by: Rahul Bukte <rahul.bukte@sony.com>
> Signed-off-by: Rahul Bukte <rahul.bukte@sony.com>
> Signed-off-by: Shashank Balaji <shashank.mahadasyam@sony.com>
> ---
> This bug is triggered by the next patch on arm64 defconfig: tegra194-cbb tries
> to register from a pure_initcall, and with the next patch adding mod_name, this
> null deref is hit.
So this isn't a bug, it's a "don't do that" type of thing :)
> ---
> kernel/params.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/kernel/params.c b/kernel/params.c
> index 74d620bc2521..881c7328c059 100644
> --- a/kernel/params.c
> +++ b/kernel/params.c
> @@ -752,6 +752,9 @@ lookup_or_create_module_kobject(const char *name)
> struct kobject *kobj;
> int err;
>
> + if (!module_kset)
> + return NULL;
Are you sure that making this change is going to be ok?
mod_sysfs_init() should have been called first as the module has to be
created before it can be looked up.
As you are wanting "built in" drivers to show up here, you are going to
beat the call to param_sysfs_init(), so don't do that. Make sure that
the drivers are NOT called before then.
thanks,
greg k-h
^ permalink raw reply
* Re: [PATCH v2 2/2] driver core: platform: set mod_name in driver registration
From: Greg Kroah-Hartman @ 2026-04-21 6:24 UTC (permalink / raw)
To: Shashank Balaji
Cc: Kay Sievers, Rafael J. Wysocki, Danilo Krummrich,
Suzuki K Poulose, Mike Leach, James Clark, Alexander Shishkin,
Maxime Coquelin, Alexandre Torgue, Miguel Ojeda, Boqun Feng,
Gary Guo, Björn Roy Baron, Benno Lossin, Andreas Hindborg,
Alice Ryhl, Trevor Gross, Richard Cochran, Jonathan Corbet,
Shuah Khan, Rahul Bukte, Daniel Palmer, Tim Bird, linux-kernel,
driver-core, coresight, linux-arm-kernel, rust-for-linux,
linux-doc
In-Reply-To: <20260421-acpi_mod_name-v2-2-e73f9310dad3@sony.com>
On Tue, Apr 21, 2026 at 03:02:35PM +0900, Shashank Balaji wrote:
> Pass KBUILD_MODNAME through the driver registration macro so that
> the driver core can create the module symlink in sysfs for built-in
> drivers, and fixup all callers.
>
> The Rust platform adapter is updated to pass the module name through to the new
> parameter.
>
> Tested on qemu with:
> - x86 defconfig + CONFIG_RUST
> - arm64 defconfig + CONFIG_RUST + CONFIG_CORESIGHT
>
> Examples after this patch:
>
> /sys/bus/platform/drivers/...
> coresight-itnoc/module -> coresight_tnoc
> coresight-static-tpdm/module -> coresight_tpdm
> coresight-catu-platform/module -> coresight_catu
> serial8250/module -> 8250
> acpi-ged/module -> acpi
> vmclock/module -> ptp_vmclock
>
> Co-developed-by: Rahul Bukte <rahul.bukte@sony.com>
> Signed-off-by: Rahul Bukte <rahul.bukte@sony.com>
> Signed-off-by: Shashank Balaji <shashank.mahadasyam@sony.com>
> ---
> Depends on the previous patch, without which the kernel fails to boot on arm64
> defconfig.
> ---
> Documentation/driver-api/driver-model/platform.rst | 3 ++-
> drivers/base/platform.c | 21 ++++++++++++++-------
> drivers/hwtracing/coresight/coresight-catu.c | 3 ++-
> drivers/hwtracing/coresight/coresight-core.c | 5 +++--
> drivers/hwtracing/coresight/coresight-cpu-debug.c | 2 +-
> drivers/hwtracing/coresight/coresight-funnel.c | 2 +-
> drivers/hwtracing/coresight/coresight-replicator.c | 2 +-
> drivers/hwtracing/coresight/coresight-stm.c | 3 ++-
> drivers/hwtracing/coresight/coresight-tmc-core.c | 3 ++-
> drivers/hwtracing/coresight/coresight-tnoc.c | 3 ++-
> drivers/hwtracing/coresight/coresight-tpdm.c | 2 +-
> drivers/hwtracing/coresight/coresight-tpiu.c | 3 ++-
> include/linux/coresight.h | 3 ++-
> include/linux/platform_device.h | 17 +++++++++--------
> rust/kernel/platform.rs | 4 +++-
> 15 files changed, 47 insertions(+), 29 deletions(-)
That's a lot of different things all in one change, please break this up
into smaller bits, this is not going to work.
Especially as the coresight changes are incorrect, no individual module
should EVER have to list THIS_MODULE or KBUILD_MODNAME in a function, it
should happen automatically by the compiler using a helper #define, like
is done for other busses.
Please fix that up first, then you can worry about the other ones.
thanks,
greg k-h
^ permalink raw reply
* Re: [PATCH v7 1/3] dt-bindings: pinctrl: Add aspeed,ast2700-soc0-pinctrl
From: Billy Tsai @ 2026-04-21 6:15 UTC (permalink / raw)
To: Conor Dooley
Cc: Lee Jones, Rob Herring, Krzysztof Kozlowski, Conor Dooley,
Joel Stanley, Andrew Jeffery, Linus Walleij, Bartosz Golaszewski,
Ryan Chen, Andrew Jeffery, devicetree@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
linux-aspeed@lists.ozlabs.org, linux-kernel@vger.kernel.org,
openbmc@lists.ozlabs.org, linux-gpio@vger.kernel.org,
linux-clk@vger.kernel.org
In-Reply-To: <20260420-footprint-both-967ccd6c120c@spud>
> > > > > > + properties:
> > > > > > + function:
> > > > > > + enum:
> > > > > > + - EMMC
> > > > > > + - JTAGDDR
> > > > > > + - JTAGM0
> > > > > > + - JTAGPCIEA
> > > > > > + - JTAGPCIEB
> > > > > > + - JTAGPSP
> > > > > > + - JTAGSSP
> > > > > > + - JTAGTSP
> > > > > > + - JTAGUSB3A
> > > > > > + - JTAGUSB3B
> > > > > > + - PCIERC0PERST
> > > > > > + - PCIERC1PERST
> > > > > > + - TSPRSTN
> > > > > > + - UFSCLKI
> > > > > > + - USB2AD0
> > > > > > + - USB2AD1
> > > > > > + - USB2AH
> > > > > > + - USB2AHP
> > > > > > + - USB2AHPD0
> > > > > > + - USB2AXH
> > > > > > + - USB2AXH2B
> > > > > > + - USB2AXHD1
> > > > > > + - USB2AXHP
> > > > > > + - USB2AXHP2B
> > > > > > + - USB2AXHPD1
> > > > > > + - USB2BD0
> > > > > > + - USB2BD1
> > > > > > + - USB2BH
> > > > > > + - USB2BHP
> > > > > > + - USB2BHPD0
> > > > > > + - USB2BXH
> > > > > > + - USB2BXH2A
> > > > > > + - USB2BXHD1
> > > > > > + - USB2BXHP
> > > > > > + - USB2BXHP2A
> > > > > > + - USB2BXHPD1
> > > > > > + - USB3AXH
> > > > > > + - USB3AXH2B
> > > > > > + - USB3AXHD
> > > > > > + - USB3AXHP
> > > > > > + - USB3AXHP2B
> > > > > > + - USB3AXHPD
> > > > > > + - USB3BXH
> > > > > > + - USB3BXH2A
> > > > > > + - USB3BXHD
> > > > > > + - USB3BXHP
> > > > > > + - USB3BXHP2A
> > > > > > + - USB3BXHPD
> > > > > > + - VB
> > > > > > + - VGADDC
> > > > > > +
> > > > > > + groups:
> > > > > > + enum:
> > > > > > + - EMMCCDN
> > > > > > + - EMMCG1
> > > > > > + - EMMCG4
> > > > > > + - EMMCG8
> > > > > > + - EMMCWPN
> > > > > > + - JTAG0
> > > > > > + - PCIERC0PERST
> > > > > > + - PCIERC1PERST
> > > > > > + - TSPRSTN
> > > > > > + - UFSCLKI
> > > > > > + - USB2A
> > > > > > + - USB2AAP
> > > > > > + - USB2ABP
> > > > > > + - USB2ADAP
> > > > > > + - USB2AH
> > > > > > + - USB2AHAP
> > > > > > + - USB2B
> > > > > > + - USB2BAP
> > > > > > + - USB2BBP
> > > > > > + - USB2BDBP
> > > > > > + - USB2BH
> > > > > > + - USB2BHBP
> > > > > > + - USB3A
> > > > > > + - USB3AAP
> > > > > > + - USB3ABP
> > > > > > + - USB3B
> > > > > > + - USB3BAP
> > > > > > + - USB3BBP
> > > > > > + - VB0
> > > > > > + - VB1
> > > > > > + - VGADDC
> > > > > > + pins:
> > > > > > + enum:
> > > > > > + - AB13
> > > > > > + - AB14
> > > > > > + - AC13
> > > > > > + - AC14
> > > > > > + - AD13
> > > > > > + - AD14
> > > > > > + - AE13
> > > > > > + - AE14
> > > > > > + - AE15
> > > > > > + - AF13
> > > > > > + - AF14
> > > > > > + - AF15
> > > > > Why do you have groups and pins?
> > > > > Is it valid in your device to have groups and pins in the same node?
> > > > The intent is to support both group-based mux selection and
> > > > configuration, as well as per-pin configuration.
> > > > In our hardware:
> > > > - `function` + `groups` are used for pinmux selection.
> > > > - `pins` is used for per-pin configuration (e.g. drive strength,
> > > > bias settings).
> > > > - `groups` may also be used for group-level configuration.
> > > > As a result, both `groups` and `pins` may appear in the same node,
> > > > but they serve different purposes and do not conflict:
> > > > - `groups` selects the mux function and may apply configuration to
> > > > the entire group.
> > > > - `pins` allows overriding or specifying configuration for individual
> > > > pins.
> > > > In most cases, only one of them is needed, but both are allowed when
> > > > both group-level and per-pin configuration are required.
> > > To be honest, that sounds like your groups are not sufficiently
> > > granular and should be reduced such that you can use them for pin
> > > settings.
> > The intent was to keep the binding flexible, but in practice the mixed
> > use of `groups` and `pins` in the same node is not expected to be used.
> >
> > Given that, I agree this flexibility is unnecessary and makes the
> > binding semantics less clear. I'll rework the binding to make the
> > expected usage explicit rather than allowing combinations that do not
> > correspond to a real use case.
> >
> > In particular, I'll split the constraints as follows:
> >
> > - For pinmux, the presence of `function` will require `groups`, and
> > `pins` will not be allowed. This reflects the hardware design, where
> > the groups are defined by the pins affected by a given mux expression
> >
> > - For pin configuration, exactly one of `groups` or `pins` will be
> > required (using oneOf), so that configuration is applied either at
> > group level or per-pin, but not both.
> >
> >
> > - if:
> > required:
> > - function
> > then:
> > required:
> > - groups
> > not:
> > required:
> > - pins
> > else:
> > oneOf:
> > - required:
> > - groups
> > not:
> > required:
> > - pins
> > - required:
> > - pins
> > not:
> > required:
> > - groups
> > Does this match what you had in mind?
> It's an improvement I think, but I am wondering why you cannot do
> without pins entirely and apply pinconf stuff at the group level?
> Of course that may not be possible with the current groups, but if you
> made the groups more granular, would it be possible?
Within a given group, it is not always the case that all pins share the
same configuration requirements (e.g. drive strength or bias settings),
so applying pinconf purely at the group level would be too restrictive.
Making the groups more granular to match all possible configuration
combinations would not reflect the actual mux granularity and would
significantly increase the number of groups.
For example, we have encountered a timing issue due to the PCB layout,
where only the eMMC clock pin requires a different drive strength:
# The EMMCG4 group includes pins AC14, AE15, AD14, AE14, AF14, AB13
# AC14: clock
# AE15: command
# AD14–AB13: data
pinconf_emmc_clk: emmc-clk-pinconf {
pins = "AC14";
drive-strength = <8>;
};
In this case, applying pin configuration at the group level would affect
all pins in the group, which is not desirable. Allowing per-pin
configuration via `pins` is therefore necessary.
For this reason, `groups` is used for mux selection, while `pins` is
required to express per-pin configuration where needed.
Thanks
Billy Tsai
^ permalink raw reply
* [PATCH v2 2/2] driver core: platform: set mod_name in driver registration
From: Shashank Balaji @ 2026-04-21 6:02 UTC (permalink / raw)
To: Kay Sievers, Greg Kroah-Hartman, Rafael J. Wysocki,
Danilo Krummrich, Suzuki K Poulose, Mike Leach, James Clark,
Alexander Shishkin, Maxime Coquelin, Alexandre Torgue,
Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
Richard Cochran, Jonathan Corbet, Shuah Khan
Cc: Shashank Balaji, Rahul Bukte, Daniel Palmer, Tim Bird,
linux-kernel, driver-core, coresight, linux-arm-kernel,
rust-for-linux, linux-doc
In-Reply-To: <20260421-acpi_mod_name-v2-0-e73f9310dad3@sony.com>
Pass KBUILD_MODNAME through the driver registration macro so that
the driver core can create the module symlink in sysfs for built-in
drivers, and fixup all callers.
The Rust platform adapter is updated to pass the module name through to the new
parameter.
Tested on qemu with:
- x86 defconfig + CONFIG_RUST
- arm64 defconfig + CONFIG_RUST + CONFIG_CORESIGHT
Examples after this patch:
/sys/bus/platform/drivers/...
coresight-itnoc/module -> coresight_tnoc
coresight-static-tpdm/module -> coresight_tpdm
coresight-catu-platform/module -> coresight_catu
serial8250/module -> 8250
acpi-ged/module -> acpi
vmclock/module -> ptp_vmclock
Co-developed-by: Rahul Bukte <rahul.bukte@sony.com>
Signed-off-by: Rahul Bukte <rahul.bukte@sony.com>
Signed-off-by: Shashank Balaji <shashank.mahadasyam@sony.com>
---
Depends on the previous patch, without which the kernel fails to boot on arm64
defconfig.
---
Documentation/driver-api/driver-model/platform.rst | 3 ++-
drivers/base/platform.c | 21 ++++++++++++++-------
drivers/hwtracing/coresight/coresight-catu.c | 3 ++-
drivers/hwtracing/coresight/coresight-core.c | 5 +++--
drivers/hwtracing/coresight/coresight-cpu-debug.c | 2 +-
drivers/hwtracing/coresight/coresight-funnel.c | 2 +-
drivers/hwtracing/coresight/coresight-replicator.c | 2 +-
drivers/hwtracing/coresight/coresight-stm.c | 3 ++-
drivers/hwtracing/coresight/coresight-tmc-core.c | 3 ++-
drivers/hwtracing/coresight/coresight-tnoc.c | 3 ++-
drivers/hwtracing/coresight/coresight-tpdm.c | 2 +-
drivers/hwtracing/coresight/coresight-tpiu.c | 3 ++-
include/linux/coresight.h | 3 ++-
include/linux/platform_device.h | 17 +++++++++--------
rust/kernel/platform.rs | 4 +++-
15 files changed, 47 insertions(+), 29 deletions(-)
diff --git a/Documentation/driver-api/driver-model/platform.rst b/Documentation/driver-api/driver-model/platform.rst
index cf5ff48d3115..9673470bded2 100644
--- a/Documentation/driver-api/driver-model/platform.rst
+++ b/Documentation/driver-api/driver-model/platform.rst
@@ -70,7 +70,8 @@ Kernel modules can be composed of several platform drivers. The platform core
provides helpers to register and unregister an array of drivers::
int __platform_register_drivers(struct platform_driver * const *drivers,
- unsigned int count, struct module *owner);
+ unsigned int count, struct module *owner,
+ const char *mod_name);
void platform_unregister_drivers(struct platform_driver * const *drivers,
unsigned int count);
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 75b4698d0e58..2b0cc0889386 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -901,11 +901,14 @@ EXPORT_SYMBOL_GPL(platform_device_register_full);
* __platform_driver_register - register a driver for platform-level devices
* @drv: platform driver structure
* @owner: owning module/driver
+ * @mod_name: module name string
*/
-int __platform_driver_register(struct platform_driver *drv, struct module *owner)
+int __platform_driver_register(struct platform_driver *drv, struct module *owner,
+ const char *mod_name)
{
drv->driver.owner = owner;
drv->driver.bus = &platform_bus_type;
+ drv->driver.mod_name = mod_name;
return driver_register(&drv->driver);
}
@@ -938,6 +941,7 @@ static int is_bound_to_driver(struct device *dev, void *driver)
* @drv: platform driver structure
* @probe: the driver probe routine, probably from an __init section
* @module: module which will be the owner of the driver
+ * @mod_name: module name string
*
* Use this instead of platform_driver_register() when you know the device
* is not hotpluggable and has already been registered, and you want to
@@ -955,7 +959,8 @@ static int is_bound_to_driver(struct device *dev, void *driver)
*/
int __init_or_module __platform_driver_probe(struct platform_driver *drv,
int (*probe)(struct platform_device *),
- struct module *module)
+ struct module *module,
+ const char *mod_name)
{
int retval;
@@ -983,7 +988,7 @@ int __init_or_module __platform_driver_probe(struct platform_driver *drv,
/* temporary section violation during probe() */
drv->probe = probe;
- retval = __platform_driver_register(drv, module);
+ retval = __platform_driver_register(drv, module, mod_name);
if (retval)
return retval;
@@ -1011,6 +1016,7 @@ EXPORT_SYMBOL_GPL(__platform_driver_probe);
* @data: platform specific data for this platform device
* @size: size of platform specific data
* @module: module which will be the owner of the driver
+ * @mod_name: module name string
*
* Use this in legacy-style modules that probe hardware directly and
* register a single platform device and corresponding platform driver.
@@ -1021,7 +1027,7 @@ struct platform_device * __init_or_module
__platform_create_bundle(struct platform_driver *driver,
int (*probe)(struct platform_device *),
struct resource *res, unsigned int n_res,
- const void *data, size_t size, struct module *module)
+ const void *data, size_t size, struct module *module, const char *mod_name)
{
struct platform_device *pdev;
int error;
@@ -1044,7 +1050,7 @@ __platform_create_bundle(struct platform_driver *driver,
if (error)
goto err_pdev_put;
- error = __platform_driver_probe(driver, probe, module);
+ error = __platform_driver_probe(driver, probe, module, mod_name);
if (error)
goto err_pdev_del;
@@ -1064,6 +1070,7 @@ EXPORT_SYMBOL_GPL(__platform_create_bundle);
* @drivers: an array of drivers to register
* @count: the number of drivers to register
* @owner: module owning the drivers
+ * @mod_name: module name string
*
* Registers platform drivers specified by an array. On failure to register a
* driver, all previously registered drivers will be unregistered. Callers of
@@ -1073,7 +1080,7 @@ EXPORT_SYMBOL_GPL(__platform_create_bundle);
* Returns: 0 on success or a negative error code on failure.
*/
int __platform_register_drivers(struct platform_driver * const *drivers,
- unsigned int count, struct module *owner)
+ unsigned int count, struct module *owner, const char *mod_name)
{
unsigned int i;
int err;
@@ -1081,7 +1088,7 @@ int __platform_register_drivers(struct platform_driver * const *drivers,
for (i = 0; i < count; i++) {
pr_debug("registering platform driver %ps\n", drivers[i]);
- err = __platform_driver_register(drivers[i], owner);
+ err = __platform_driver_register(drivers[i], owner, mod_name);
if (err < 0) {
pr_err("failed to register platform driver %ps: %d\n",
drivers[i], err);
diff --git a/drivers/hwtracing/coresight/coresight-catu.c b/drivers/hwtracing/coresight/coresight-catu.c
index dfd035852b12..3e4df832f02a 100644
--- a/drivers/hwtracing/coresight/coresight-catu.c
+++ b/drivers/hwtracing/coresight/coresight-catu.c
@@ -708,7 +708,8 @@ static int __init catu_init(void)
{
int ret;
- ret = coresight_init_driver("catu", &catu_driver, &catu_platform_driver, THIS_MODULE);
+ ret = coresight_init_driver("catu", &catu_driver, &catu_platform_driver,
+ THIS_MODULE, KBUILD_MODNAME);
tmc_etr_set_catu_ops(&etr_catu_buf_ops);
return ret;
}
diff --git a/drivers/hwtracing/coresight/coresight-core.c b/drivers/hwtracing/coresight/coresight-core.c
index 80e26396ad0a..b88bc053ab58 100644
--- a/drivers/hwtracing/coresight/coresight-core.c
+++ b/drivers/hwtracing/coresight/coresight-core.c
@@ -1645,7 +1645,8 @@ module_init(coresight_init);
module_exit(coresight_exit);
int coresight_init_driver(const char *drv, struct amba_driver *amba_drv,
- struct platform_driver *pdev_drv, struct module *owner)
+ struct platform_driver *pdev_drv, struct module *owner,
+ const char *mod_name)
{
int ret;
@@ -1655,7 +1656,7 @@ int coresight_init_driver(const char *drv, struct amba_driver *amba_drv,
return ret;
}
- ret = __platform_driver_register(pdev_drv, owner);
+ ret = __platform_driver_register(pdev_drv, owner, mod_name);
if (!ret)
return 0;
diff --git a/drivers/hwtracing/coresight/coresight-cpu-debug.c b/drivers/hwtracing/coresight/coresight-cpu-debug.c
index 629614278e46..00b7c52d3ab9 100644
--- a/drivers/hwtracing/coresight/coresight-cpu-debug.c
+++ b/drivers/hwtracing/coresight/coresight-cpu-debug.c
@@ -758,7 +758,7 @@ static struct platform_driver debug_platform_driver = {
static int __init debug_init(void)
{
return coresight_init_driver("debug", &debug_driver, &debug_platform_driver,
- THIS_MODULE);
+ THIS_MODULE, KBUILD_MODNAME);
}
static void __exit debug_exit(void)
diff --git a/drivers/hwtracing/coresight/coresight-funnel.c b/drivers/hwtracing/coresight/coresight-funnel.c
index 3b248e54471a..8ee5b42bb475 100644
--- a/drivers/hwtracing/coresight/coresight-funnel.c
+++ b/drivers/hwtracing/coresight/coresight-funnel.c
@@ -415,7 +415,7 @@ static struct amba_driver dynamic_funnel_driver = {
static int __init funnel_init(void)
{
return coresight_init_driver("funnel", &dynamic_funnel_driver, &funnel_driver,
- THIS_MODULE);
+ THIS_MODULE, KBUILD_MODNAME);
}
static void __exit funnel_exit(void)
diff --git a/drivers/hwtracing/coresight/coresight-replicator.c b/drivers/hwtracing/coresight/coresight-replicator.c
index e6472658235d..9af67100f1fd 100644
--- a/drivers/hwtracing/coresight/coresight-replicator.c
+++ b/drivers/hwtracing/coresight/coresight-replicator.c
@@ -421,7 +421,7 @@ static struct amba_driver dynamic_replicator_driver = {
static int __init replicator_init(void)
{
return coresight_init_driver("replicator", &dynamic_replicator_driver, &replicator_driver,
- THIS_MODULE);
+ THIS_MODULE, KBUILD_MODNAME);
}
static void __exit replicator_exit(void)
diff --git a/drivers/hwtracing/coresight/coresight-stm.c b/drivers/hwtracing/coresight/coresight-stm.c
index e68529bf89c9..b140069e07b5 100644
--- a/drivers/hwtracing/coresight/coresight-stm.c
+++ b/drivers/hwtracing/coresight/coresight-stm.c
@@ -1052,7 +1052,8 @@ static struct platform_driver stm_platform_driver = {
static int __init stm_init(void)
{
- return coresight_init_driver("stm", &stm_driver, &stm_platform_driver, THIS_MODULE);
+ return coresight_init_driver("stm", &stm_driver, &stm_platform_driver,
+ THIS_MODULE, KBUILD_MODNAME);
}
static void __exit stm_exit(void)
diff --git a/drivers/hwtracing/coresight/coresight-tmc-core.c b/drivers/hwtracing/coresight/coresight-tmc-core.c
index 36599c431be6..bef0a9d1fa1b 100644
--- a/drivers/hwtracing/coresight/coresight-tmc-core.c
+++ b/drivers/hwtracing/coresight/coresight-tmc-core.c
@@ -1051,7 +1051,8 @@ static struct platform_driver tmc_platform_driver = {
static int __init tmc_init(void)
{
- return coresight_init_driver("tmc", &tmc_driver, &tmc_platform_driver, THIS_MODULE);
+ return coresight_init_driver("tmc", &tmc_driver, &tmc_platform_driver,
+ THIS_MODULE, KBUILD_MODNAME);
}
static void __exit tmc_exit(void)
diff --git a/drivers/hwtracing/coresight/coresight-tnoc.c b/drivers/hwtracing/coresight/coresight-tnoc.c
index 1128612e70a7..1c7c7a062600 100644
--- a/drivers/hwtracing/coresight/coresight-tnoc.c
+++ b/drivers/hwtracing/coresight/coresight-tnoc.c
@@ -346,7 +346,8 @@ static struct platform_driver itnoc_driver = {
static int __init tnoc_init(void)
{
- return coresight_init_driver("tnoc", &trace_noc_driver, &itnoc_driver, THIS_MODULE);
+ return coresight_init_driver("tnoc", &trace_noc_driver, &itnoc_driver,
+ THIS_MODULE, KBUILD_MODNAME);
}
static void __exit tnoc_exit(void)
diff --git a/drivers/hwtracing/coresight/coresight-tpdm.c b/drivers/hwtracing/coresight/coresight-tpdm.c
index 06e0a905a67d..2a735f797c8e 100644
--- a/drivers/hwtracing/coresight/coresight-tpdm.c
+++ b/drivers/hwtracing/coresight/coresight-tpdm.c
@@ -1534,7 +1534,7 @@ static struct platform_driver static_tpdm_driver = {
static int __init tpdm_init(void)
{
return coresight_init_driver("tpdm", &dynamic_tpdm_driver, &static_tpdm_driver,
- THIS_MODULE);
+ THIS_MODULE, KBUILD_MODNAME);
}
static void __exit tpdm_exit(void)
diff --git a/drivers/hwtracing/coresight/coresight-tpiu.c b/drivers/hwtracing/coresight/coresight-tpiu.c
index aaa44bc521c3..3ddabb81b946 100644
--- a/drivers/hwtracing/coresight/coresight-tpiu.c
+++ b/drivers/hwtracing/coresight/coresight-tpiu.c
@@ -312,7 +312,8 @@ static struct platform_driver tpiu_platform_driver = {
static int __init tpiu_init(void)
{
- return coresight_init_driver("tpiu", &tpiu_driver, &tpiu_platform_driver, THIS_MODULE);
+ return coresight_init_driver("tpiu", &tpiu_driver, &tpiu_platform_driver,
+ THIS_MODULE, KBUILD_MODNAME);
}
static void __exit tpiu_exit(void)
diff --git a/include/linux/coresight.h b/include/linux/coresight.h
index 2b48be97fcd0..382341f587d0 100644
--- a/include/linux/coresight.h
+++ b/include/linux/coresight.h
@@ -698,7 +698,8 @@ coresight_find_output_type(struct coresight_platform_data *pdata,
union coresight_dev_subtype subtype);
int coresight_init_driver(const char *drv, struct amba_driver *amba_drv,
- struct platform_driver *pdev_drv, struct module *owner);
+ struct platform_driver *pdev_drv, struct module *owner,
+ const char *mod_name);
void coresight_remove_driver(struct amba_driver *amba_drv,
struct platform_driver *pdev_drv);
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index 975400a472e3..26e6a43358e2 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -293,18 +293,19 @@ struct platform_driver {
* use a macro to avoid include chaining to get THIS_MODULE
*/
#define platform_driver_register(drv) \
- __platform_driver_register(drv, THIS_MODULE)
+ __platform_driver_register(drv, THIS_MODULE, KBUILD_MODNAME)
extern int __platform_driver_register(struct platform_driver *,
- struct module *);
+ struct module *, const char *mod_name);
extern void platform_driver_unregister(struct platform_driver *);
/* non-hotpluggable platform devices may use this so that probe() and
* its support may live in __init sections, conserving runtime memory.
*/
#define platform_driver_probe(drv, probe) \
- __platform_driver_probe(drv, probe, THIS_MODULE)
+ __platform_driver_probe(drv, probe, THIS_MODULE, KBUILD_MODNAME)
extern int __platform_driver_probe(struct platform_driver *driver,
- int (*probe)(struct platform_device *), struct module *module);
+ int (*probe)(struct platform_device *), struct module *module,
+ const char *mod_name);
static inline void *platform_get_drvdata(const struct platform_device *pdev)
{
@@ -368,19 +369,19 @@ static int __init __platform_driver##_init(void) \
device_initcall(__platform_driver##_init); \
#define platform_create_bundle(driver, probe, res, n_res, data, size) \
- __platform_create_bundle(driver, probe, res, n_res, data, size, THIS_MODULE)
+ __platform_create_bundle(driver, probe, res, n_res, data, size, THIS_MODULE, KBUILD_MODNAME)
extern struct platform_device *__platform_create_bundle(
struct platform_driver *driver, int (*probe)(struct platform_device *),
struct resource *res, unsigned int n_res,
- const void *data, size_t size, struct module *module);
+ const void *data, size_t size, struct module *module, const char *mod_name);
int __platform_register_drivers(struct platform_driver * const *drivers,
- unsigned int count, struct module *owner);
+ unsigned int count, struct module *owner, const char *mod_name);
void platform_unregister_drivers(struct platform_driver * const *drivers,
unsigned int count);
#define platform_register_drivers(drivers, count) \
- __platform_register_drivers(drivers, count, THIS_MODULE)
+ __platform_register_drivers(drivers, count, THIS_MODULE, KBUILD_MODNAME)
#ifdef CONFIG_SUSPEND
extern int platform_pm_suspend(struct device *dev);
diff --git a/rust/kernel/platform.rs b/rust/kernel/platform.rs
index 8917d4ee499f..2d626eecc450 100644
--- a/rust/kernel/platform.rs
+++ b/rust/kernel/platform.rs
@@ -82,7 +82,9 @@ unsafe fn register(
}
// SAFETY: `pdrv` is guaranteed to be a valid `DriverType`.
- to_result(unsafe { bindings::__platform_driver_register(pdrv.get(), module.0) })
+ to_result(unsafe {
+ bindings::__platform_driver_register(pdrv.get(), module.0, name.as_char_ptr())
+ })
}
unsafe fn unregister(pdrv: &Opaque<Self::DriverType>) {
--
2.43.0
^ permalink raw reply related
* [PATCH v2 1/2] kernel: param: handle NULL module_kset in lookup_or_create_module_kobject()
From: Shashank Balaji @ 2026-04-21 6:02 UTC (permalink / raw)
To: Kay Sievers, Greg Kroah-Hartman, Rafael J. Wysocki,
Danilo Krummrich, Suzuki K Poulose, Mike Leach, James Clark,
Alexander Shishkin, Maxime Coquelin, Alexandre Torgue,
Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
Richard Cochran, Jonathan Corbet, Shuah Khan
Cc: Shashank Balaji, Rahul Bukte, Daniel Palmer, Tim Bird,
linux-kernel, driver-core, coresight, linux-arm-kernel,
rust-for-linux, linux-doc
In-Reply-To: <20260421-acpi_mod_name-v2-0-e73f9310dad3@sony.com>
module_kset is initialized in a subsys_initcall. If a built-in driver tries to
register before subsys_initcall with its struct device_driver's mod_name set,
then a null module_kset is dereferenced via this call trace:
[ 0.095865] Call trace:
[ 0.095999] _raw_spin_lock+0x4c/0x6c (P)
[ 0.096150] kset_find_obj+0x24/0x104
[ 0.096209] lookup_or_create_module_kobject+0x2c/0xd8
[ 0.096274] module_add_driver+0xd4/0x138
[ 0.096328] bus_add_driver+0x16c/0x268
[ 0.096380] driver_register+0x68/0x100
[ 0.096428] __platform_driver_register+0x24/0x30
[ 0.096486] tegra194_cbb_init+0x24/0x30
[ 0.096540] do_one_initcall+0xdc/0x250
[ 0.096608] do_initcall_level+0x9c/0xd0
[ 0.096660] do_initcalls+0x54/0x94
[ 0.096706] do_basic_setup+0x20/0x2c
[ 0.096753] kernel_init_freeable+0xc8/0x154
[ 0.096807] kernel_init+0x20/0x1a0
[ 0.096851] ret_from_fork+0x10/0x20
So, return null in lookup_or_create_module_kobject() if module_kset is null.
Existing callers handle null already.
Fixes: f30c53a873d0 ("MODULES: add the module name for built in kernel drivers")
Co-developed-by: Rahul Bukte <rahul.bukte@sony.com>
Signed-off-by: Rahul Bukte <rahul.bukte@sony.com>
Signed-off-by: Shashank Balaji <shashank.mahadasyam@sony.com>
---
This bug is triggered by the next patch on arm64 defconfig: tegra194-cbb tries
to register from a pure_initcall, and with the next patch adding mod_name, this
null deref is hit.
---
kernel/params.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/kernel/params.c b/kernel/params.c
index 74d620bc2521..881c7328c059 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -752,6 +752,9 @@ lookup_or_create_module_kobject(const char *name)
struct kobject *kobj;
int err;
+ if (!module_kset)
+ return NULL;
+
kobj = kset_find_obj(module_kset, name);
if (kobj)
return to_module_kobject(kobj);
--
2.43.0
^ permalink raw reply related
* [PATCH v2 0/2] Enable sysfs module symlink for more built-in drivers
From: Shashank Balaji @ 2026-04-21 6:02 UTC (permalink / raw)
To: Kay Sievers, Greg Kroah-Hartman, Rafael J. Wysocki,
Danilo Krummrich, Suzuki K Poulose, Mike Leach, James Clark,
Alexander Shishkin, Maxime Coquelin, Alexandre Torgue,
Miguel Ojeda, Boqun Feng, Gary Guo, Björn Roy Baron,
Benno Lossin, Andreas Hindborg, Alice Ryhl, Trevor Gross,
Richard Cochran, Jonathan Corbet, Shuah Khan
Cc: Shashank Balaji, Rahul Bukte, Daniel Palmer, Tim Bird,
linux-kernel, driver-core, coresight, linux-arm-kernel,
rust-for-linux, linux-doc
struct device_driver's mod_name is not set by a number of bus' driver registration
functions. Without that, built-in drivers don't have the module symlink in sysfs.
We want this to go from unbound driver name -> module name -> kernel config name.
This is useful on embedded platforms to minimize kernel config, reduce kernel size,
and reduce boot time.
In order to achieve this, mod_name has to be set to KBUILD_MODNAME, and this has
to be done for all buses which don't yet do this.
Here are some treewide stats:
- 110 registration functions across all bus types
- 20 of them set mod_name
- Remaining 90 do not set mod_name:
1. 36 functions under pattern 1:
They have a __register function + register macro. KBUILD_MODNAME needs to
be passed and the function needs to take mod_name as input.
2. 42 functions under pattern 2:
These have no macro wrapper. They need a double-underscore rename + macro
wrapper to make them similar to pattern 1.
3. Remaining 12 do not have such a clean registration interface. More analysis
is required.
We plan to start with pattern 1, since it's the easiest category of changes.
Within that, for now we're only sending the platform patch. If we get the go-ahead
on that, we'll send the remaining ones.
Patch 2 depends on patch 1, without which arm64 defconfig fails to boot with
patch 2.
Co-developed-by: Rahul Bukte <rahul.bukte@sony.com>
Signed-off-by: Rahul Bukte <rahul.bukte@sony.com>
Signed-off-by: Shashank Balaji <shashank.mahadasyam@sony.com>
---
Changes in v2:
- Drop acpi patch, send platform instead (Rafael)
- Link to v1: https://patch.msgid.link/20260416-acpi_mod_name-v1-0-1a4d96fd86c9@sony.com
To: Kay Sievers <kay.sievers@vrfy.org>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: "Rafael J. Wysocki" <rafael@kernel.org>
To: Danilo Krummrich <dakr@kernel.org>
To: Suzuki K Poulose <suzuki.poulose@arm.com>
To: Mike Leach <mike.leach@linaro.org>
To: James Clark <james.clark@linaro.org>
To: Alexander Shishkin <alexander.shishkin@linux.intel.com>
To: Maxime Coquelin <mcoquelin.stm32@gmail.com>
To: Alexandre Torgue <alexandre.torgue@foss.st.com>
To: Miguel Ojeda <ojeda@kernel.org>
To: Boqun Feng <boqun@kernel.org>
To: Gary Guo <gary@garyguo.net>
To: Björn Roy Baron <bjorn3_gh@protonmail.com>
To: Benno Lossin <lossin@kernel.org>
To: Andreas Hindborg <a.hindborg@kernel.org>
To: Alice Ryhl <aliceryhl@google.com>
To: Trevor Gross <tmgross@umich.edu>
To: Richard Cochran <richardcochran@gmail.com>
To: Jonathan Corbet <corbet@lwn.net>
To: Shuah Khan <skhan@linuxfoundation.org>
Cc: linux-kernel@vger.kernel.org
Cc: driver-core@lists.linux.dev
Cc: coresight@lists.linaro.org
Cc: linux-arm-kernel@lists.infradead.org
Cc: rust-for-linux@vger.kernel.org
Cc: linux-doc@vger.kernel.org
---
Shashank Balaji (2):
kernel: param: handle NULL module_kset in lookup_or_create_module_kobject()
driver core: platform: set mod_name in driver registration
Documentation/driver-api/driver-model/platform.rst | 3 ++-
drivers/base/platform.c | 21 ++++++++++++++-------
drivers/hwtracing/coresight/coresight-catu.c | 3 ++-
drivers/hwtracing/coresight/coresight-core.c | 5 +++--
drivers/hwtracing/coresight/coresight-cpu-debug.c | 2 +-
drivers/hwtracing/coresight/coresight-funnel.c | 2 +-
drivers/hwtracing/coresight/coresight-replicator.c | 2 +-
drivers/hwtracing/coresight/coresight-stm.c | 3 ++-
drivers/hwtracing/coresight/coresight-tmc-core.c | 3 ++-
drivers/hwtracing/coresight/coresight-tnoc.c | 3 ++-
drivers/hwtracing/coresight/coresight-tpdm.c | 2 +-
drivers/hwtracing/coresight/coresight-tpiu.c | 3 ++-
include/linux/coresight.h | 3 ++-
include/linux/platform_device.h | 17 +++++++++--------
kernel/params.c | 3 +++
rust/kernel/platform.rs | 4 +++-
16 files changed, 50 insertions(+), 29 deletions(-)
---
base-commit: b4e07588e743c989499ca24d49e752c074924a9a
change-id: 20260416-acpi_mod_name-f645a76e337b
Best regards,
--
Shashank Balaji <shashank.mahadasyam@sony.com>
^ permalink raw reply
* Re: [PATCH 00/30] KVM: arm64: Add support for protected guest memory with pKVM
From: Pavan Kondeti @ 2026-04-21 4:15 UTC (permalink / raw)
To: Pavan Kondeti
Cc: Will Deacon, kvmarm, linux-arm-kernel, Marc Zyngier, Oliver Upton,
Joey Gouly, Suzuki K Poulose, Zenghui Yu, Catalin Marinas,
Quentin Perret, Fuad Tabba, Vincent Donnefort, Mostafa Saleh
In-Reply-To: <573483a8-7cb7-479f-a96d-67416ef1f6db@quicinc.com>
On Mon, Apr 20, 2026 at 04:56:57PM +0530, Pavan Kondeti wrote:
> On Mon, Apr 20, 2026 at 11:00:35AM +0100, Will Deacon wrote:
> > On Mon, Apr 20, 2026 at 01:32:03PM +0530, Pavan Kondeti wrote:
> > > Hi Will,
> > >
> > > On Mon, Jan 05, 2026 at 03:49:08PM +0000, Will Deacon wrote:
> > > > Hi folks,
> > > >
> > > > Although pKVM has been shipping in Android kernels for a while now,
> > > > protected guest (pVM) support has been somewhat languishing upstream.
> > > > This has partly been because we've been waiting for guest_memfd() but
> > > > also because it hasn't been clear how to expose pVMs to userspace (which
> > > > is necessary for testing) without getting everything in place beforehand.
> > > > This has led to frustration on both sides of the fence [1] and so this
> > > > patch series attempts to get things moving again by exposing pVM
> > > > features in an incremental fashion based on top of anonymous memory,
> > > > which is what we have been using in Android. The big difference between
> > > > this series and the Android implementation is the graceful handling of
> > > > host stage-2 faults arising from accesses made using kernel mappings.
> > > > The hope is that this will unblock pKVM upstreaming efforts while the
> > > > guest_memfd() work continues to evolve.
> > > >
> > > > Specifically, this patch series implements support for protected guest
> > > > memory with pKVM, where pages are unmapped from the host as they are
> > > > faulted into the guest and can be shared back from the guest using pKVM
> > > > hypercalls. Protected guests are created using a new machine type
> > > > identifier and can be booted to a shell using the kvmtool patches
> > > > available at [2], which finally means that we are able to test the pVM
> > > > logic in pKVM. Since this is an incremental step towards full isolation
> > > > from the host (for example, the CPU register state and DMA accesses are
> > > > not yet isolated), creating a pVM requires a developer Kconfig option to
> > > > be enabled in addition to booting with 'kvm-arm.mode=protected' and
> > > > results in a kernel taint.
> > > >
> > >
> > > Good to see Protected VM support in upstream w/ pKVM.
> > >
> > > We (Qualcomm) have been trying to resume Gunyah upstreaming [1] efforts
> > > for some time but the path to re-use guest_memfd is not straight forward as
> > > guest_memfd is tightly coupled with KVM. While the efforts to use it for
> > > pKVM is pending and refactoring to make it use outside KVM is not
> > > happening anytime soon, we plan to send Gunyah series similar to how
> > > this series is dealt with pages lent/donated to the Guest. Please let us
> > > know if you have any suggestions/comments for us.
> >
> > The major problem I see with this is that the host/hyp interface for
> > handling stage-2 faults is internal to pKVM. The exception is injected
> > back into the host using a funky ESR encoding and the hypercall used
> > to forcefully reclaim the page is not ABI. I have no appetite for
> > standardising these mechanisms (the flexibility is one of pKVM's big
> > advantages) but I also do not want to complicate EL1 fault handling path
> > with hypervisor-specific crap that we have to maintain forever.
>
> Thanks Will for the feedback. Agree that we don't want to sprinkle Gunyah
> specific checks in fault handling code. Do we need to handle anything
> apart from
>
> (a) user space access a memory that is lent to the guest. Gunyah will
> inject Synchronous External Abort and the offending process will be killed.
>
> (b) For kernel access, we need to unmap the memory at S1 while lending
> it to the guest. Earlier, Elliot attempted this with [1]. I am thinking
> we can leverage from Direct map removal work done for guest_memfd w/o
> really using it :-) . I am hoping [2] can be made available for Gunyah
> module as well.
>
> For the (b) problem above, pKVM takes a different route in upstream i.e
> pkvm_force_reclaim_guest_page(). I believe this avoids kernel panic at
> the expense of memory corruption in the guest. correct?
sorry, not memory corruption but returning -EFAULT to VCPU_RUN ioctl
which probably make VMM to kill the VM.
Thanks,
Pavan
^ permalink raw reply
* Re: [PATCH 0/3] mm: split the file's i_mmap tree for NUMA
From: Huang Shijie @ 2026-04-21 3:06 UTC (permalink / raw)
To: Pedro Falcato
Cc: Mateusz Guzik, akpm, viro, brauner, linux-mm, linux-kernel,
linux-arm-kernel, linux-fsdevel, muchun.song, osalvador,
linux-trace-kernel, linux-perf-users, linux-parisc, nvdimm,
zhongyuan, fangbaoshun, yingzhiwei
In-Reply-To: <hshxzebq5y4gavo7mbrgn7qitz5j5wyun73wy7ooiiehzzpcui@hlknbp34sgja>
On Mon, Apr 20, 2026 at 02:48:49PM +0100, Pedro Falcato wrote:
> BTW you're missing _a lot_ of CC's here, including the whole of mm/rmap.c
> maintainership.
Thanks, my fault.
>
> On Mon, Apr 20, 2026 at 10:10:19AM +0800, Huang Shijie wrote:
> > On Mon, Apr 13, 2026 at 05:33:21PM +0200, Mateusz Guzik wrote:
> > > On Mon, Apr 13, 2026 at 02:20:39PM +0800, Huang Shijie wrote:
> > > > In NUMA, there are maybe many NUMA nodes and many CPUs.
> > > > For example, a Hygon's server has 12 NUMA nodes, and 384 CPUs.
> > > > In the UnixBench tests, there is a test "execl" which tests
> > > > the execve system call.
> > > >
> > > > When we test our server with "./Run -c 384 execl",
> > > > the test result is not good enough. The i_mmap locks contended heavily on
> > > > "libc.so" and "ld.so". For example, the i_mmap tree for "libc.so" can have
> > > > over 6000 VMAs, all the VMAs can be in different NUMA mode.
> > > > The insert/remove operations do not run quickly enough.
> > > >
> > > > patch 1 & patch 2 are try to hide the direct access of i_mmap.
> > > > patch 3 splits the i_mmap into sibling trees, and we can get better
> > > > performance with this patch set:
> > > > we can get 77% performance improvement(10 times average)
> > > >
> > >
> > > To my reading you kept the lock as-is and only distributed the protected
> > > state.
> > >
> > > While I don't doubt the improvement, I'm confident should you take a
> > > look at the profile you are going to find this still does not scale with
> > > rwsem being one of the problems (there are other global locks, some of
> > > which have experimental patches for).
> > >
> > > Apart from that this does nothing to help high core systems which are
> > > all one node, which imo puts another question mark on this specific
> > > proposal.
> > >
> > > Of course one may question whether a RB tree is the right choice here,
> > > it may be the lock-protected cost can go way down with merely a better
> > > data structure.
> > >
> > > Regardless of that, for actual scalability, there will be no way around
> > > decentralazing locking around this and partitioning per some core count
> > > (not just by numa awareness).
> > >
> > > Decentralizing locking is definitely possible, but I have not looked
> > > into specifics of how problematic it is. Best case scenario it will
> > > merely with separate locks. Worst case scenario something needs a fully
> > > stabilized state for traversal, in that case another rw lock can be
> > > slapped around this, creating locking order read lock -> per-subset
> > > write lock -- this will suffer scalability due to the read locking, but
> > > it will still scale drastically better as apart from that there will be
> > > no serialization. In this setting the problematic consumer will write
> > > lock the new thing to stabilize the state.
> > >
> > I thought over again.
> > I can change this patch set to support the non-NUMA case by:
> > 1.) Still use one rw lock.
>
> No. This doesn't help anything.
>
> > 2.) For NUMA, keep the patch set as it is.
>
> Please no. No NUMA vs non-NUMA case.
>
> > 3.) For non-NUMA case, split the i_mmap tree to several subtrees.
> > For example, if a machine has 192 CPUs, split the 32 CPUs as a tree.
>
> If lock contention is the problem, I don't see how splitting the tree helps,
> unless it helps reduce lock hold time in a way that randomly helps your workload.
> But that's entirely random.
We actually face two issues:
1.) the lock contention
2.) the lock hold time.
IMHO, if we can reduce the lock hold time, we can ease the lock contention too.
So this patch set is to reduce the lock hold time, which is much helpful in our
NUMA server in UnixBench test.
If we split the lock into small locks, we can also benefit from it.
If you or Mateusz create the patch in future, I can test it on our server.
I wonder if it can give us better performance then current patch set.
Thanks
Huang Shijie
^ permalink raw reply
* Re: [PATCH bpf-next 2/3] bpf, arm64: Add JIT support for stack arguments
From: Alexei Starovoitov @ 2026-04-21 2:58 UTC (permalink / raw)
To: Puranjay Mohan
Cc: bpf, Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko,
Martin KaFai Lau, Eduard Zingerman, Kumar Kartikeya Dwivedi,
Song Liu, Yonghong Song, Xu Kuohai, Catalin Marinas, Will Deacon,
linux-arm-kernel
In-Reply-To: <20260420153603.4097618-3-puranjay@kernel.org>
On Mon, Apr 20, 2026 at 8:36 AM Puranjay Mohan <puranjay@kernel.org> wrote:
>
nice and clean. I like how it maps to arm64 calling convention.
> + if (prog->aux->stack_arg_depth > prog->aux->incoming_stack_arg_depth) {
> + u16 outgoing = prog->aux->stack_arg_depth - prog->aux->incoming_stack_arg_depth;
> + int nr_on_stack = outgoing / sizeof(u64) - NR_STACK_ARG_REGS;
> +
> + if (nr_on_stack > 0)
> + ctx.stack_arg_size = round_up(nr_on_stack * sizeof(u64), 16);
> + }
I'm struggling to understand this part.
Why do this when this func calls more than what callee passed in?
Looks fishy. I'd like to see selftests with more than 6,7,8 args.
Because only then this logic will kick in?
^ permalink raw reply
* [PATCH 5.10.y] wifi: mac80211: always free skb on ieee80211_tx_prepare_skb() failure
From: Li hongliang @ 2026-04-21 2:44 UTC (permalink / raw)
To: gregkh, stable, nbd
Cc: patches, linux-kernel, toke, kvalo, johannes, matthias.bgg,
angelogioacchino.delregno, nbd, linux-wireless, linux-arm-kernel,
linux-mediatek, johannes.berg
From: Felix Fietkau <nbd@nbd.name>
[ Upstream commit d5ad6ab61cbd89afdb60881f6274f74328af3ee9 ]
ieee80211_tx_prepare_skb() has three error paths, but only two of them
free the skb. The first error path (ieee80211_tx_prepare() returning
TX_DROP) does not free it, while invoke_tx_handlers() failure and the
fragmentation check both do.
Add kfree_skb() to the first error path so all three are consistent,
and remove the now-redundant frees in callers (ath9k, mt76,
mac80211_hwsim) to avoid double-free.
Document the skb ownership guarantee in the function's kdoc.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Link: https://patch.msgid.link/20260314065455.2462900-1-nbd@nbd.name
Fixes: 06be6b149f7e ("mac80211: add ieee80211_tx_prepare_skb() helper function")
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
[ Exclude changes to drivers/net/wireless/mediatek/mt76/scan.c as this file is first
introduced by commit 31083e38548f("wifi: mt76: add code for emulating hardware scanning")
after linux-6.14.]
Signed-off-by: Li hongliang <1468888505@139.com>
---
drivers/net/wireless/ath/ath9k/channel.c | 6 ++----
drivers/net/wireless/mac80211_hwsim.c | 1 -
include/net/mac80211.h | 4 ++++
net/mac80211/tx.c | 4 +++-
4 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c
index 6cf087522157..31b7921bf34f 100644
--- a/drivers/net/wireless/ath/ath9k/channel.c
+++ b/drivers/net/wireless/ath/ath9k/channel.c
@@ -1011,7 +1011,7 @@ static void ath_scan_send_probe(struct ath_softc *sc,
skb_set_queue_mapping(skb, IEEE80211_AC_VO);
if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, NULL))
- goto error;
+ return;
txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO];
if (ath_tx_start(sc->hw, skb, &txctl))
@@ -1124,10 +1124,8 @@ ath_chanctx_send_vif_ps_frame(struct ath_softc *sc, struct ath_vif *avp,
skb->priority = 7;
skb_set_queue_mapping(skb, IEEE80211_AC_VO);
- if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, &sta)) {
- dev_kfree_skb_any(skb);
+ if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, &sta))
return false;
- }
break;
default:
return false;
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 037358606a51..865bbe029343 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -2275,7 +2275,6 @@ static void hw_scan_work(struct work_struct *work)
hwsim->tmp_chan->band,
NULL)) {
rcu_read_unlock();
- kfree_skb(probe);
continue;
}
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 8f91609f928c..70ee982f08d9 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -6337,6 +6337,10 @@ void ieee80211_report_wowlan_wakeup(struct ieee80211_vif *vif,
* @band: the band to transmit on
* @sta: optional pointer to get the station to send the frame to
*
+ * Return: %true if the skb was prepared, %false otherwise.
+ * On failure, the skb is freed by this function; callers must not
+ * free it again.
+ *
* Note: must be called under RCU lock
*/
bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw,
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 30ad46cfcad8..b923cd755a68 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1869,8 +1869,10 @@ bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw,
struct ieee80211_tx_data tx;
struct sk_buff *skb2;
- if (ieee80211_tx_prepare(sdata, &tx, NULL, skb) == TX_DROP)
+ if (ieee80211_tx_prepare(sdata, &tx, NULL, skb) == TX_DROP) {
+ kfree_skb(skb);
return false;
+ }
info->band = band;
info->control.vif = vif;
--
2.34.1
^ permalink raw reply related
* [PATCH 5.15.y] wifi: mac80211: always free skb on ieee80211_tx_prepare_skb() failure
From: Li hongliang @ 2026-04-21 2:44 UTC (permalink / raw)
To: gregkh, stable, nbd
Cc: patches, linux-kernel, toke, kvalo, johannes, matthias.bgg,
angelogioacchino.delregno, nbd, linux-wireless, linux-arm-kernel,
linux-mediatek, johannes.berg
From: Felix Fietkau <nbd@nbd.name>
[ Upstream commit d5ad6ab61cbd89afdb60881f6274f74328af3ee9 ]
ieee80211_tx_prepare_skb() has three error paths, but only two of them
free the skb. The first error path (ieee80211_tx_prepare() returning
TX_DROP) does not free it, while invoke_tx_handlers() failure and the
fragmentation check both do.
Add kfree_skb() to the first error path so all three are consistent,
and remove the now-redundant frees in callers (ath9k, mt76,
mac80211_hwsim) to avoid double-free.
Document the skb ownership guarantee in the function's kdoc.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Link: https://patch.msgid.link/20260314065455.2462900-1-nbd@nbd.name
Fixes: 06be6b149f7e ("mac80211: add ieee80211_tx_prepare_skb() helper function")
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
[ Exclude changes to drivers/net/wireless/mediatek/mt76/scan.c as this file is first
introduced by commit 31083e38548f("wifi: mt76: add code for emulating hardware scanning")
after linux-6.14.]
Signed-off-by: Li hongliang <1468888505@139.com>
---
drivers/net/wireless/ath/ath9k/channel.c | 6 ++----
drivers/net/wireless/mac80211_hwsim.c | 1 -
include/net/mac80211.h | 4 ++++
net/mac80211/tx.c | 4 +++-
4 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c
index 6cf087522157..31b7921bf34f 100644
--- a/drivers/net/wireless/ath/ath9k/channel.c
+++ b/drivers/net/wireless/ath/ath9k/channel.c
@@ -1011,7 +1011,7 @@ static void ath_scan_send_probe(struct ath_softc *sc,
skb_set_queue_mapping(skb, IEEE80211_AC_VO);
if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, NULL))
- goto error;
+ return;
txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO];
if (ath_tx_start(sc->hw, skb, &txctl))
@@ -1124,10 +1124,8 @@ ath_chanctx_send_vif_ps_frame(struct ath_softc *sc, struct ath_vif *avp,
skb->priority = 7;
skb_set_queue_mapping(skb, IEEE80211_AC_VO);
- if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, &sta)) {
- dev_kfree_skb_any(skb);
+ if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, &sta))
return false;
- }
break;
default:
return false;
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 7d7350258683..ed4d83775fe7 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -2347,7 +2347,6 @@ static void hw_scan_work(struct work_struct *work)
hwsim->tmp_chan->band,
NULL)) {
rcu_read_unlock();
- kfree_skb(probe);
continue;
}
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index f101ef4a1fd6..a4ef9f93a53c 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -6454,6 +6454,10 @@ void ieee80211_report_wowlan_wakeup(struct ieee80211_vif *vif,
* @band: the band to transmit on
* @sta: optional pointer to get the station to send the frame to
*
+ * Return: %true if the skb was prepared, %false otherwise.
+ * On failure, the skb is freed by this function; callers must not
+ * free it again.
+ *
* Note: must be called under RCU lock
*/
bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw,
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index a5be5fe5c6b4..054493161376 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1882,8 +1882,10 @@ bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw,
struct ieee80211_tx_data tx;
struct sk_buff *skb2;
- if (ieee80211_tx_prepare(sdata, &tx, NULL, skb) == TX_DROP)
+ if (ieee80211_tx_prepare(sdata, &tx, NULL, skb) == TX_DROP) {
+ kfree_skb(skb);
return false;
+ }
info->band = band;
info->control.vif = vif;
--
2.34.1
^ permalink raw reply related
* [PATCH 6.1.y] wifi: mac80211: always free skb on ieee80211_tx_prepare_skb() failure
From: Li hongliang @ 2026-04-21 2:43 UTC (permalink / raw)
To: gregkh, stable, nbd
Cc: patches, linux-kernel, toke, kvalo, johannes, matthias.bgg,
angelogioacchino.delregno, nbd, linux-wireless, linux-arm-kernel,
linux-mediatek, johannes.berg
From: Felix Fietkau <nbd@nbd.name>
[ Upstream commit d5ad6ab61cbd89afdb60881f6274f74328af3ee9 ]
ieee80211_tx_prepare_skb() has three error paths, but only two of them
free the skb. The first error path (ieee80211_tx_prepare() returning
TX_DROP) does not free it, while invoke_tx_handlers() failure and the
fragmentation check both do.
Add kfree_skb() to the first error path so all three are consistent,
and remove the now-redundant frees in callers (ath9k, mt76,
mac80211_hwsim) to avoid double-free.
Document the skb ownership guarantee in the function's kdoc.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Link: https://patch.msgid.link/20260314065455.2462900-1-nbd@nbd.name
Fixes: 06be6b149f7e ("mac80211: add ieee80211_tx_prepare_skb() helper function")
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
[ Exclude changes to drivers/net/wireless/mediatek/mt76/scan.c as this file is first
introduced by commit 31083e38548f("wifi: mt76: add code for emulating hardware scanning")
after linux-6.14.]
Signed-off-by: Li hongliang <1468888505@139.com>
---
drivers/net/wireless/ath/ath9k/channel.c | 6 ++----
drivers/net/wireless/mac80211_hwsim.c | 1 -
include/net/mac80211.h | 4 ++++
net/mac80211/tx.c | 4 +++-
4 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c
index 571062f2e82a..ba8ec5112afe 100644
--- a/drivers/net/wireless/ath/ath9k/channel.c
+++ b/drivers/net/wireless/ath/ath9k/channel.c
@@ -1011,7 +1011,7 @@ static void ath_scan_send_probe(struct ath_softc *sc,
skb_set_queue_mapping(skb, IEEE80211_AC_VO);
if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, NULL))
- goto error;
+ return;
txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO];
if (ath_tx_start(sc->hw, skb, &txctl))
@@ -1124,10 +1124,8 @@ ath_chanctx_send_vif_ps_frame(struct ath_softc *sc, struct ath_vif *avp,
skb->priority = 7;
skb_set_queue_mapping(skb, IEEE80211_AC_VO);
- if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, &sta)) {
- dev_kfree_skb_any(skb);
+ if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, &sta))
return false;
- }
break;
default:
return false;
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 80a2a668cfb9..316b5f56b6e5 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -2743,7 +2743,6 @@ static void hw_scan_work(struct work_struct *work)
hwsim->tmp_chan->band,
NULL)) {
rcu_read_unlock();
- kfree_skb(probe);
continue;
}
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 62e0847d3793..1769d03e6b1d 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -6874,6 +6874,10 @@ void ieee80211_report_wowlan_wakeup(struct ieee80211_vif *vif,
* @band: the band to transmit on
* @sta: optional pointer to get the station to send the frame to
*
+ * Return: %true if the skb was prepared, %false otherwise.
+ * On failure, the skb is freed by this function; callers must not
+ * free it again.
+ *
* Note: must be called under RCU lock
*/
bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw,
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 7333e43dfc35..2e99a1063e93 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1934,8 +1934,10 @@ bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw,
struct ieee80211_tx_data tx;
struct sk_buff *skb2;
- if (ieee80211_tx_prepare(sdata, &tx, NULL, skb) == TX_DROP)
+ if (ieee80211_tx_prepare(sdata, &tx, NULL, skb) == TX_DROP) {
+ kfree_skb(skb);
return false;
+ }
info->band = band;
info->control.vif = vif;
--
2.34.1
^ permalink raw reply related
* [PATCH 6.6.y] wifi: mac80211: always free skb on ieee80211_tx_prepare_skb() failure
From: Li hongliang @ 2026-04-21 2:43 UTC (permalink / raw)
To: gregkh, stable, nbd
Cc: patches, linux-kernel, toke, kvalo, johannes, matthias.bgg,
angelogioacchino.delregno, nbd, linux-wireless, linux-arm-kernel,
linux-mediatek, johannes.berg
From: Felix Fietkau <nbd@nbd.name>
[ Upstream commit d5ad6ab61cbd89afdb60881f6274f74328af3ee9 ]
ieee80211_tx_prepare_skb() has three error paths, but only two of them
free the skb. The first error path (ieee80211_tx_prepare() returning
TX_DROP) does not free it, while invoke_tx_handlers() failure and the
fragmentation check both do.
Add kfree_skb() to the first error path so all three are consistent,
and remove the now-redundant frees in callers (ath9k, mt76,
mac80211_hwsim) to avoid double-free.
Document the skb ownership guarantee in the function's kdoc.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Link: https://patch.msgid.link/20260314065455.2462900-1-nbd@nbd.name
Fixes: 06be6b149f7e ("mac80211: add ieee80211_tx_prepare_skb() helper function")
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
[ Exclude changes to drivers/net/wireless/mediatek/mt76/scan.c as this file is first
introduced by commit 31083e38548f("wifi: mt76: add code for emulating hardware scanning")
after linux-6.14.]
Signed-off-by: Li hongliang <1468888505@139.com>
---
drivers/net/wireless/ath/ath9k/channel.c | 6 ++----
drivers/net/wireless/virtual/mac80211_hwsim.c | 1 -
include/net/mac80211.h | 4 ++++
net/mac80211/tx.c | 4 +++-
4 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c
index 571062f2e82a..ba8ec5112afe 100644
--- a/drivers/net/wireless/ath/ath9k/channel.c
+++ b/drivers/net/wireless/ath/ath9k/channel.c
@@ -1011,7 +1011,7 @@ static void ath_scan_send_probe(struct ath_softc *sc,
skb_set_queue_mapping(skb, IEEE80211_AC_VO);
if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, NULL))
- goto error;
+ return;
txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO];
if (ath_tx_start(sc->hw, skb, &txctl))
@@ -1124,10 +1124,8 @@ ath_chanctx_send_vif_ps_frame(struct ath_softc *sc, struct ath_vif *avp,
skb->priority = 7;
skb_set_queue_mapping(skb, IEEE80211_AC_VO);
- if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, &sta)) {
- dev_kfree_skb_any(skb);
+ if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, &sta))
return false;
- }
break;
default:
return false;
diff --git a/drivers/net/wireless/virtual/mac80211_hwsim.c b/drivers/net/wireless/virtual/mac80211_hwsim.c
index 1214e7dcc812..bf12ff0ab06a 100644
--- a/drivers/net/wireless/virtual/mac80211_hwsim.c
+++ b/drivers/net/wireless/virtual/mac80211_hwsim.c
@@ -2892,7 +2892,6 @@ static void hw_scan_work(struct work_struct *work)
hwsim->tmp_chan->band,
NULL)) {
rcu_read_unlock();
- kfree_skb(probe);
continue;
}
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index adaa1b2323d2..85d785060e76 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -7032,6 +7032,10 @@ void ieee80211_report_wowlan_wakeup(struct ieee80211_vif *vif,
* @band: the band to transmit on
* @sta: optional pointer to get the station to send the frame to
*
+ * Return: %true if the skb was prepared, %false otherwise.
+ * On failure, the skb is freed by this function; callers must not
+ * free it again.
+ *
* Note: must be called under RCU lock
*/
bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw,
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 7eddcb6f9645..2a708132320c 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1911,8 +1911,10 @@ bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw,
struct ieee80211_tx_data tx;
struct sk_buff *skb2;
- if (ieee80211_tx_prepare(sdata, &tx, NULL, skb) == TX_DROP)
+ if (ieee80211_tx_prepare(sdata, &tx, NULL, skb) == TX_DROP) {
+ kfree_skb(skb);
return false;
+ }
info->band = band;
info->control.vif = vif;
--
2.34.1
^ permalink raw reply related
* [PATCH 6.12.y] wifi: mac80211: always free skb on ieee80211_tx_prepare_skb() failure
From: Li hongliang @ 2026-04-21 2:42 UTC (permalink / raw)
To: gregkh, stable, nbd
Cc: patches, linux-kernel, toke, kvalo, johannes, matthias.bgg,
angelogioacchino.delregno, nbd, linux-wireless, linux-arm-kernel,
linux-mediatek, johannes.berg
From: Felix Fietkau <nbd@nbd.name>
[ Upstream commit d5ad6ab61cbd89afdb60881f6274f74328af3ee9 ]
ieee80211_tx_prepare_skb() has three error paths, but only two of them
free the skb. The first error path (ieee80211_tx_prepare() returning
TX_DROP) does not free it, while invoke_tx_handlers() failure and the
fragmentation check both do.
Add kfree_skb() to the first error path so all three are consistent,
and remove the now-redundant frees in callers (ath9k, mt76,
mac80211_hwsim) to avoid double-free.
Document the skb ownership guarantee in the function's kdoc.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Link: https://patch.msgid.link/20260314065455.2462900-1-nbd@nbd.name
Fixes: 06be6b149f7e ("mac80211: add ieee80211_tx_prepare_skb() helper function")
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
[ Exclude changes to drivers/net/wireless/mediatek/mt76/scan.c as this file is first
introduced by commit 31083e38548f("wifi: mt76: add code for emulating hardware scanning")
after linux-6.14.]
Signed-off-by: Li hongliang <1468888505@139.com>
---
drivers/net/wireless/ath/ath9k/channel.c | 6 ++----
drivers/net/wireless/virtual/mac80211_hwsim.c | 1 -
include/net/mac80211.h | 4 +++-
net/mac80211/tx.c | 4 +++-
4 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c
index 571062f2e82a..ba8ec5112afe 100644
--- a/drivers/net/wireless/ath/ath9k/channel.c
+++ b/drivers/net/wireless/ath/ath9k/channel.c
@@ -1011,7 +1011,7 @@ static void ath_scan_send_probe(struct ath_softc *sc,
skb_set_queue_mapping(skb, IEEE80211_AC_VO);
if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, NULL))
- goto error;
+ return;
txctl.txq = sc->tx.txq_map[IEEE80211_AC_VO];
if (ath_tx_start(sc->hw, skb, &txctl))
@@ -1124,10 +1124,8 @@ ath_chanctx_send_vif_ps_frame(struct ath_softc *sc, struct ath_vif *avp,
skb->priority = 7;
skb_set_queue_mapping(skb, IEEE80211_AC_VO);
- if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, &sta)) {
- dev_kfree_skb_any(skb);
+ if (!ieee80211_tx_prepare_skb(sc->hw, vif, skb, band, &sta))
return false;
- }
break;
default:
return false;
diff --git a/drivers/net/wireless/virtual/mac80211_hwsim.c b/drivers/net/wireless/virtual/mac80211_hwsim.c
index 8b4fd5fd11b0..e992e59b5918 100644
--- a/drivers/net/wireless/virtual/mac80211_hwsim.c
+++ b/drivers/net/wireless/virtual/mac80211_hwsim.c
@@ -2977,7 +2977,6 @@ static void hw_scan_work(struct work_struct *work)
hwsim->tmp_chan->band,
NULL)) {
rcu_read_unlock();
- kfree_skb(probe);
continue;
}
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index 80259a37e724..7d71a4149cdf 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -7208,7 +7208,9 @@ void ieee80211_report_wowlan_wakeup(struct ieee80211_vif *vif,
* @band: the band to transmit on
* @sta: optional pointer to get the station to send the frame to
*
- * Return: %true if the skb was prepared, %false otherwise
+ * Return: %true if the skb was prepared, %false otherwise.
+ * On failure, the skb is freed by this function; callers must not
+ * free it again.
*
* Note: must be called under RCU lock
*/
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 9142d748a6a7..0458cbba232e 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1897,8 +1897,10 @@ bool ieee80211_tx_prepare_skb(struct ieee80211_hw *hw,
struct ieee80211_tx_data tx;
struct sk_buff *skb2;
- if (ieee80211_tx_prepare(sdata, &tx, NULL, skb) == TX_DROP)
+ if (ieee80211_tx_prepare(sdata, &tx, NULL, skb) == TX_DROP) {
+ kfree_skb(skb);
return false;
+ }
info->band = band;
info->control.vif = vif;
--
2.34.1
^ permalink raw reply related
* Re: [PATCH V3] dmaengine: imx-sdma: Fix SPBA bus detection on multi-SPBA platforms
From: Frank Li @ 2026-04-21 2:37 UTC (permalink / raw)
To: Shengjiu Wang
Cc: vkoul, Frank.Li, s.hauer, kernel, festevam, dmaengine, imx,
linux-arm-kernel, linux-kernel
In-Reply-To: <20260420100854.2095549-1-shengjiu.wang@nxp.com>
On Mon, Apr 20, 2026 at 06:08:54PM +0800, Shengjiu Wang wrote:
> i.MX8M platforms have multiple SPBA buses under different AIPS buses.
> The current code searches the entire device tree and returns the first
> SPBA bus found, which may not be under the same AIPS bus as the SDMA
> controller.
>
> This breaks SDMA P2P transfers because the SDMA script needs to know
> if peripherals are on SPBA or AIPS to configure watermark levels
> correctly. Using the wrong SPBA bus causes DMA timeouts and transfer
> failures.
>
> Fix by searching for the SPBA bus under the SDMA's parent node (AIPS)
> first, then falling back to a global search for backward compatibility.
>
> Example device tree showing the issue:
> aips1 {
> spba1 { sai@...; }; /* Correct SPBA for sdma1 */
> sdma1@...;
> };
> aips2 {
> spba2 { uart@...; }; /* Wrong SPBA - found first by old code */
> };
>
> Fixes: 8391ecf465ec ("dmaengine: imx-sdma: Add device to device support")
> Cc: stable@vger.kernel.org
> Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
> ---
Reviewed-by: Frank Li <Frank.Li@nxp.com>
> changs in v3:
> - add fallback to a global search for backward compatibility, which is
> to address comments from sashiko.dev
> - update commit subject and commit message
> - add comments in code.
> - add Cc stable tag
> - Don't add Frank's RB on v2 as there are several other changes.
>
> changes in v2:
> - add fixes tag
> - use __free(device_node) for auto release.
>
> drivers/dma/imx-sdma.c | 13 ++++++++++++-
> 1 file changed, 12 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
> index 3d527883776b..592705af2319 100644
> --- a/drivers/dma/imx-sdma.c
> +++ b/drivers/dma/imx-sdma.c
> @@ -2364,7 +2364,18 @@ static int sdma_probe(struct platform_device *pdev)
> return dev_err_probe(&pdev->dev, ret,
> "failed to register controller\n");
>
> - spba_bus = of_find_compatible_node(NULL, NULL, "fsl,spba-bus");
> + /*
> + * On i.MX8M platforms with multiple SPBA buses, we need to find
> + * the SPBA bus that's under the same AIPS bus as this SDMA controller.
> + * First check the SDMA's parent (AIPS bus) for a child SPBA bus.
> + * If not found, fall back to searching the entire device tree for
> + * backward compatibility with older platforms.
> + */
> + struct device_node *sdma_parent_np __free(device_node) = of_get_parent(np);
> +
> + spba_bus = of_get_compatible_child(sdma_parent_np, "fsl,spba-bus");
> + if (!spba_bus)
> + spba_bus = of_find_compatible_node(NULL, NULL, "fsl,spba-bus");
> ret = of_address_to_resource(spba_bus, 0, &spba_res);
> if (!ret) {
> sdma->spba_start_addr = spba_res.start;
> --
> 2.34.1
>
^ permalink raw reply
* Re: [PATCH] serial: fsl_lpuart: fix rx buffer and DMA map leaks in start_rx_dma
From: Frank Li @ 2026-04-21 2:33 UTC (permalink / raw)
To: Shitalkumar Gandhi
Cc: gregkh, jirislaby, bhuvanchandra.dv, peng.fan, sherry.sun,
linux-serial, imx, linux-arm-kernel, linux-kernel, stable,
Shitalkumar Gandhi
In-Reply-To: <20260420135903.2062024-1-shitalkumar.gandhi@cambiumnetworks.com>
On Mon, Apr 20, 2026 at 07:29:03PM +0530, Shitalkumar Gandhi wrote:
> lpuart_start_rx_dma() allocates sport->rx_ring.buf with kzalloc() and
> then maps a scatterlist via dma_map_sg(). On three subsequent error
> paths the function returns directly without releasing those resources:
>
> - when dma_map_sg() returns 0 (-EINVAL):
> ring->buf is leaked.
> - when dmaengine_slave_config() fails:
> ring->buf and the DMA mapping are leaked.
> - when dmaengine_prep_dma_cyclic() returns NULL:
> ring->buf and the DMA mapping are leaked.
>
> The sole cleanup path, lpuart_dma_rx_free(), is only reached when
> lpuart_dma_rx_use is set, and the caller lpuart_rx_dma_startup() clears
> that flag on failure of lpuart_start_rx_dma(). So these resources are
> permanently leaked on every failure in this function. Repeated port
> open/close or termios changes under error conditions will slowly consume
> memory and leave stale streaming DMA mappings behind.
>
> Fix it by introducing two error labels that unmap the scatterlist and
> free the ring buffer as appropriate. While here, replace the misleading
> -EFAULT (bad userspace pointer) returned when dmaengine_prep_dma_cyclic()
> fails with the more accurate -ENOMEM, matching how other dmaengine users
> in the tree treat this failure.
>
> No functional change on the success path.
>
> Fixes: 5887ad43ee02 ("tty: serial: fsl_lpuart: Use cyclic DMA for Rx")
> Cc: stable@vger.kernel.org
>
> Signed-off-by: Shitalkumar Gandhi <shitalkumar.gandhi@cambiumnetworks.com>
> ---
Reviewed-by: Frank Li <Frank.Li@nxp.com>
> drivers/tty/serial/fsl_lpuart.c | 15 ++++++++++++---
> 1 file changed, 12 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/tty/serial/fsl_lpuart.c b/drivers/tty/serial/fsl_lpuart.c
> index f36d50fe056f..296a096be351 100644
> --- a/drivers/tty/serial/fsl_lpuart.c
> +++ b/drivers/tty/serial/fsl_lpuart.c
> @@ -1376,7 +1376,8 @@ static inline int lpuart_start_rx_dma(struct lpuart_port *sport)
>
> if (!nent) {
> dev_err(sport->port.dev, "DMA Rx mapping error\n");
> - return -EINVAL;
> + ret = -EINVAL;
> + goto err_free_buf;
> }
>
> dma_rx_sconfig.src_addr = lpuart_dma_datareg_addr(sport);
> @@ -1388,7 +1389,7 @@ static inline int lpuart_start_rx_dma(struct lpuart_port *sport)
> if (ret < 0) {
> dev_err(sport->port.dev,
> "DMA Rx slave config failed, err = %d\n", ret);
> - return ret;
> + goto err_unmap_sg;
> }
>
> sport->dma_rx_desc = dmaengine_prep_dma_cyclic(chan,
> @@ -1399,7 +1400,8 @@ static inline int lpuart_start_rx_dma(struct lpuart_port *sport)
> DMA_PREP_INTERRUPT);
> if (!sport->dma_rx_desc) {
> dev_err(sport->port.dev, "Cannot prepare cyclic DMA\n");
> - return -EFAULT;
> + ret = -ENOMEM;
> + goto err_unmap_sg;
> }
>
> sport->dma_rx_desc->callback = lpuart_dma_rx_complete;
> @@ -1423,6 +1425,13 @@ static inline int lpuart_start_rx_dma(struct lpuart_port *sport)
> }
>
> return 0;
> +
> +err_unmap_sg:
> + dma_unmap_sg(chan->device->dev, &sport->rx_sgl, 1, DMA_FROM_DEVICE);
> +err_free_buf:
> + kfree(ring->buf);
> + ring->buf = NULL;
> + return ret;
> }
>
> static void lpuart_dma_rx_free(struct uart_port *port)
> --
> 2.25.1
>
^ permalink raw reply
* Re: [PATCH] arm64: KVM: Initialize vGIC before preempt-disabled section in kvm_reset_vcpu()
From: Deepanshu Kartikey @ 2026-04-21 1:48 UTC (permalink / raw)
To: Marc Zyngier
Cc: oupton, joey.gouly, suzuki.poulose, yuzenghui, catalin.marinas,
will, drjones, christoffer.dall, linux-arm-kernel, kvmarm,
linux-kernel, syzbot+12b178b7c756664d2518
In-Reply-To: <865x5r2dik.wl-maz@kernel.org>
On Thu, Apr 16, 2026 at 7:50 PM Marc Zyngier <maz@kernel.org> wrote:
>
> On Sun, 12 Apr 2026 09:04:37 +0100,
> Deepanshu Kartikey <kartikey406@gmail.com> wrote:
> >
> > kvm_reset_vcpu() calls kvm_timer_vcpu_reset() inside a preempt-disabled
> > section to avoid races with preempt notifiers that also call vcpu put/load.
> >
> > However, kvm_timer_vcpu_reset() eventually calls kvm_vgic_inject_irq()
> > which triggers vgic_lazy_init() if the vGIC has not been initialized yet.
> > vgic_lazy_init() acquires a mutex and calls vgic_init() which invokes
> > synchronize_srcu_expedited() -- both of which may sleep. Sleeping inside
> > a preempt-disabled section is illegal and causes:
> >
> > BUG: scheduling while atomic: syz.1.49/3699/0x00000002
> >
> > Fix this by calling vgic_lazy_init() before preempt_disable(). On the
> > second call inside kvm_vgic_inject_irq(), vgic_initialized() will return
> > true and vgic_lazy_init() will return immediately without sleeping.
> >
>
> I think this really goes in the wrong direction. Forcing the vgic (a
> global resource) to initialise when the vcpu's timer (a local
> resource) is reset feels at best bizarre. Now you are promoting it to
> be forced at vcpu reset. This makes things worse.
>
> You probably want to take a step back and look at *why* we end-up
> here. The core reason seems to be that the timer emulation caches the
> level in a per-timer structure, and tries hard not call into the vgic
> unless the level changes. Which means that unless the vgic is
> initialised and is able to latch that state, the initial pending state
> will not be propagated to the guest.
>
> But do we need this optimisation? I don't think so. Other emulated
> devices don't require it. We can let the vgic know the state of the
> timer at every vcpu entry, just like we do for other virtual
> interrupts that the kernel injects (PMU, vgic MI).
>
> Once you remove the this cache and the need for the vgic to buffer
> things outside of normal execution, you can also drop the magic init
> from the interrupt injection path, because the injection will happen
> on the run path, just like any other PPI.
>
> That'd be a much better approach IMO.
>
> Thanks,
>
> M.
>
> --
> Without deviation from the norm, progress is not possible.
Hi Marc,
Thank you for the detailed feedback! I apologize for the delayed
response — I was away on holiday.
I understand your point. My fix addresses the symptom rather than the
root cause. Forcing vGIC (a global resource) to initialize during
timer (a local resource) reset is not the right approach.
I will take your suggestion and work on:
I will send a v2 once I have something ready.
Thanks again for the guidance!
Best regards,
Deeanshu Kartikey
^ permalink raw reply
* RE: [RFC PATCH v5 1/9] media: v4l2-common: Add YUV24 format info
From: Nas Chung @ 2026-04-21 1:45 UTC (permalink / raw)
To: Nicolas Dufresne, mchehab@kernel.org, hverkuil@xs4all.nl,
robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org,
shawnguo@kernel.org, s.hauer@pengutronix.de
Cc: linux-media@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-imx@nxp.com,
linux-arm-kernel@lists.infradead.org, marek.vasut@mailbox.org,
ming.qian@oss.nxp.com
In-Reply-To: <90e206fad7bef6052fcf38314889e7ff525d3201.camel@collabora.com>
Hi, Nicolas.
>-----Original Message-----
>From: Nicolas Dufresne <nicolas.dufresne@collabora.com>
>Sent: Tuesday, April 21, 2026 12:40 AM
>To: Nas Chung <nas.chung@chipsnmedia.com>; mchehab@kernel.org;
>hverkuil@xs4all.nl; robh@kernel.org; krzk+dt@kernel.org;
>conor+dt@kernel.org; shawnguo@kernel.org; s.hauer@pengutronix.de
>Cc: linux-media@vger.kernel.org; devicetree@vger.kernel.org; linux-
>kernel@vger.kernel.org; linux-imx@nxp.com; linux-arm-
>kernel@lists.infradead.org; marek.vasut@mailbox.org; ming.qian@oss.nxp.com
>Subject: Re: [RFC PATCH v5 1/9] media: v4l2-common: Add YUV24 format info
>
>Le mercredi 15 avril 2026 à 18:25 +0900, Nas Chung a écrit :
>> The YUV24 format is missing an entry in the v4l2_format_info().
>> The YUV24 format is the packed YUV 4:4:4 formats with 8 bits
>> per component.
>>
>> Fixes: 0376a51fbe5e ("media: v4l: Add packed YUV444 24bpp pixel format")
>> Signed-off-by: Nas Chung <nas.chung@chipsnmedia.com>
>> Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
>
>Unless you disagree, I might cherry-pick this one. Would it be ok with you ?
Sure, that's fine with me.
Thanks.
Nas.
>
>Nicolas
>
>> ---
>> drivers/media/v4l2-core/v4l2-common.c | 1 +
>> 1 file changed, 1 insertion(+)
>>
>> diff --git a/drivers/media/v4l2-core/v4l2-common.c b/drivers/media/v4l2-
>core/v4l2-common.c
>> index 554c591e1113..55bcd5975d9f 100644
>> --- a/drivers/media/v4l2-core/v4l2-common.c
>> +++ b/drivers/media/v4l2-core/v4l2-common.c
>> @@ -281,6 +281,7 @@ const struct v4l2_format_info *v4l2_format_info(u32
>format)
>> { .format = V4L2_PIX_FMT_Y212, .pixel_enc =
>V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0,
>0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 1 },
>> { .format = V4L2_PIX_FMT_Y216, .pixel_enc =
>V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 4, 0, 0,
>0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 2, .vdiv = 1 },
>> { .format = V4L2_PIX_FMT_YUV48_12, .pixel_enc =
>V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 6, 0, 0,
>0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
>> + { .format = V4L2_PIX_FMT_YUV24, .pixel_enc =
>V4L2_PIXEL_ENC_YUV, .mem_planes = 1, .comp_planes = 1, .bpp = { 3, 0, 0,
>0 }, .bpp_div = { 1, 1, 1, 1 }, .hdiv = 1, .vdiv = 1 },
>> { .format = V4L2_PIX_FMT_MT2110T, .pixel_enc =
>V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 5, 10, 0,
>0 }, .bpp_div = { 4, 4, 1, 1 }, .hdiv = 2, .vdiv = 2,
>> .block_w = { 16, 8, 0, 0 }, .block_h = { 32, 16, 0, 0 }},
>> { .format = V4L2_PIX_FMT_MT2110R, .pixel_enc =
>V4L2_PIXEL_ENC_YUV, .mem_planes = 2, .comp_planes = 2, .bpp = { 5, 10, 0,
>0 }, .bpp_div = { 4, 4, 1, 1 }, .hdiv = 2, .vdiv = 2,
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox