.../admin-guide/gpio/gpio-aggregator.rst | 107 ++ drivers/gpio/Kconfig | 2 + drivers/gpio/gpio-aggregator.c | 1129 ++++++++++++++--- 3 files changed, 1050 insertions(+), 188 deletions(-)
This patch series introduces a configfs-based interface to gpio-aggregator
to address limitations in the existing 'new_device' interface.
The existing 'new_device' interface has several limitations:
Issue#1. No way to determine when GPIO aggregator creation is complete.
Issue#2. No way to retrieve errors when creating a GPIO aggregator.
Issue#3. No way to trace a GPIO line of an aggregator back to its
corresponding physical device.
Issue#4. The 'new_device' echo does not indicate which virtual
gpiochip<N> was created.
Issue#5. No way to assign names to GPIO lines exported through an
aggregator.
Although Issue#1 to #3 could technically be resolved easily without
configfs, using configfs offers a streamlined, modern, and extensible
approach, especially since gpio-sim and gpio-virtuser already utilize
configfs.
This v5 patch series includes 9 patches:
Patch#1: Fix an issue that was spotted during v3 preparation.
Patch#2: Reorder functions to prepare for configfs introduction.
Patch#3: Add aggr_alloc() to reduce code duplication.
Patch#4: Introduce basic configfs interface. Address Issue#1 to #4.
Patch#5: Address Issue#5.
Patch#6: Prepare for Patch#7.
Patch#7: Expose devices created with sysfs to configfs.
Patch#8: Suppress deferred probe for purely configfs-based aggregators.
Patch#9: Documentation for the new configfs interface.
N.B. This v5 is based on the latest gpio/for-next commit as of writing this:
* 45af02f06f69 ("gpio: virtuser: convert to use dev-sync-probe utilities")
v4->v5 changes:
- Rebased off of the latest gpio/for-next, that includes the patch series:
"Add synchronous fake device creation utility for GPIO drivers"
(https://lore.kernel.org/all/20250221133501.2203897-1-koichiro.den@canonical.com/)
v3->v4 changes:
- Splitted off the introduction of gpio-pseudo.[ch] and conversions.
- Reordered commits to place a fix commit first.
- Squashed the trivial update for gpio-aggregator's conversion to gpio-pseudo
into the primary commit "gpio: aggregator: introduce basic configfs interface"
as it is only meaningful when combined.
v2->v3 changes:
- Addressed feedback from Bartosz:
* Factored out the common mechanism for synchronizing platform device
probe by adding gpio-pseudo.[ch].
* Renamed "_auto." prefix to "_sysfs." for auto-generated
configfs entries corresponding to sysfs-created devices.
* Squashed v2 Patch#3 into its predecessor.
- Addressed feedback from Geert:
* Factored out duplicate code in struct gpio_aggregator initialization
by adding gpio_alloc()/gpio_free() functions. Note that v2 Patch#7
was dropped for other reasons as mentioned below, so aggr_free() in
v3 is unrelated to the same-named function in v2.
* Removed redundant parsing of gpio-line-names and unnecessary
chip->names assignments; squashed v2 Patch#4 + v2 Patch#5 into v3
Patch#9.
* Updated to use sysfs_emit().
* Updated Kconfig (select CONFIGFS_FS).
* Fixed typos, coding style issues, missing const qualifiers, and other
minor issues.
- Resolved an issue that was spotted during v3 preparation. See Patch#2.
- Reordered resource initialization order in gpio_aggregator_init() to
both eliminate a potential race condition (as noted in the source code
comment) and simplify the code. See Patch#8. This enabled:
* Removal of v2 Patch#7.
* Merging of aggr_unregister_lines() and aggr_free_lines() into a
unified function.
- Disabled 'delete_device' functionality for devices created via configfs
for simplicity. It was mistakenly allowed in v2 and proved buggy. See
Patch #8.
RFC->v2 changes:
- Addressed feedback from Bartosz:
* Expose devices created with sysfs to configfs.
* Drop 'num_lines' attribute.
* Fix bugs and crashes.
* Organize internal symbol prefixes more cleanly.
- Split diffs for improved reviewability.
- Update kernel doc to reflect the changes.
v4: https://lore.kernel.org/all/20250217143531.541185-1-koichiro.den@canonical.com/
v3: https://lore.kernel.org/all/20250216125816.14430-1-koichiro.den@canonical.com/
v2: https://lore.kernel.org/all/20250203031213.399914-1-koichiro.den@canonical.com/
RFC (v1): https://lore.kernel.org/linux-gpio/20250129155525.663780-1-koichiro.den@canonical.com/T/#u
*** BLURB HERE ***
Koichiro Den (9):
gpio: aggregator: protect driver attr handlers against module unload
gpio: aggregator: reorder functions to prepare for configfs
introduction
gpio: aggregator: add aggr_alloc()/aggr_free()
gpio: aggregator: introduce basic configfs interface
gpio: aggregator: add 'name' attribute for custom GPIO line names
gpio: aggregator: rename 'name' to 'key' in aggr_parse()
gpio: aggregator: expose aggregator created via legacy sysfs to
configfs
gpio: aggregator: cancel deferred probe for devices created via
configfs
Documentation: gpio: document configfs interface for gpio-aggregator
.../admin-guide/gpio/gpio-aggregator.rst | 107 ++
drivers/gpio/Kconfig | 2 +
drivers/gpio/gpio-aggregator.c | 1129 ++++++++++++++---
3 files changed, 1050 insertions(+), 188 deletions(-)
--
2.45.2
On Mon, Feb 24, 2025 at 3:31 PM Koichiro Den <koichiro.den@canonical.com> wrote:
>
> This patch series introduces a configfs-based interface to gpio-aggregator
> to address limitations in the existing 'new_device' interface.
>
> The existing 'new_device' interface has several limitations:
>
> Issue#1. No way to determine when GPIO aggregator creation is complete.
> Issue#2. No way to retrieve errors when creating a GPIO aggregator.
> Issue#3. No way to trace a GPIO line of an aggregator back to its
> corresponding physical device.
> Issue#4. The 'new_device' echo does not indicate which virtual
> gpiochip<N> was created.
> Issue#5. No way to assign names to GPIO lines exported through an
> aggregator.
>
> Although Issue#1 to #3 could technically be resolved easily without
> configfs, using configfs offers a streamlined, modern, and extensible
> approach, especially since gpio-sim and gpio-virtuser already utilize
> configfs.
>
> This v5 patch series includes 9 patches:
>
> Patch#1: Fix an issue that was spotted during v3 preparation.
> Patch#2: Reorder functions to prepare for configfs introduction.
> Patch#3: Add aggr_alloc() to reduce code duplication.
> Patch#4: Introduce basic configfs interface. Address Issue#1 to #4.
> Patch#5: Address Issue#5.
> Patch#6: Prepare for Patch#7.
> Patch#7: Expose devices created with sysfs to configfs.
> Patch#8: Suppress deferred probe for purely configfs-based aggregators.
> Patch#9: Documentation for the new configfs interface.
>
> N.B. This v5 is based on the latest gpio/for-next commit as of writing this:
> * 45af02f06f69 ("gpio: virtuser: convert to use dev-sync-probe utilities")
>
>
> v4->v5 changes:
> - Rebased off of the latest gpio/for-next, that includes the patch series:
> "Add synchronous fake device creation utility for GPIO drivers"
> (https://lore.kernel.org/all/20250221133501.2203897-1-koichiro.den@canonical.com/)
>
> v3->v4 changes:
> - Splitted off the introduction of gpio-pseudo.[ch] and conversions.
> - Reordered commits to place a fix commit first.
> - Squashed the trivial update for gpio-aggregator's conversion to gpio-pseudo
> into the primary commit "gpio: aggregator: introduce basic configfs interface"
> as it is only meaningful when combined.
>
> v2->v3 changes:
> - Addressed feedback from Bartosz:
> * Factored out the common mechanism for synchronizing platform device
> probe by adding gpio-pseudo.[ch].
> * Renamed "_auto." prefix to "_sysfs." for auto-generated
> configfs entries corresponding to sysfs-created devices.
> * Squashed v2 Patch#3 into its predecessor.
> - Addressed feedback from Geert:
> * Factored out duplicate code in struct gpio_aggregator initialization
> by adding gpio_alloc()/gpio_free() functions. Note that v2 Patch#7
> was dropped for other reasons as mentioned below, so aggr_free() in
> v3 is unrelated to the same-named function in v2.
> * Removed redundant parsing of gpio-line-names and unnecessary
> chip->names assignments; squashed v2 Patch#4 + v2 Patch#5 into v3
> Patch#9.
> * Updated to use sysfs_emit().
> * Updated Kconfig (select CONFIGFS_FS).
> * Fixed typos, coding style issues, missing const qualifiers, and other
> minor issues.
> - Resolved an issue that was spotted during v3 preparation. See Patch#2.
> - Reordered resource initialization order in gpio_aggregator_init() to
> both eliminate a potential race condition (as noted in the source code
> comment) and simplify the code. See Patch#8. This enabled:
> * Removal of v2 Patch#7.
> * Merging of aggr_unregister_lines() and aggr_free_lines() into a
> unified function.
> - Disabled 'delete_device' functionality for devices created via configfs
> for simplicity. It was mistakenly allowed in v2 and proved buggy. See
> Patch #8.
>
> RFC->v2 changes:
> - Addressed feedback from Bartosz:
> * Expose devices created with sysfs to configfs.
> * Drop 'num_lines' attribute.
> * Fix bugs and crashes.
> * Organize internal symbol prefixes more cleanly.
> - Split diffs for improved reviewability.
> - Update kernel doc to reflect the changes.
>
> v4: https://lore.kernel.org/all/20250217143531.541185-1-koichiro.den@canonical.com/
> v3: https://lore.kernel.org/all/20250216125816.14430-1-koichiro.den@canonical.com/
> v2: https://lore.kernel.org/all/20250203031213.399914-1-koichiro.den@canonical.com/
> RFC (v1): https://lore.kernel.org/linux-gpio/20250129155525.663780-1-koichiro.den@canonical.com/T/#u
>
>
> *** BLURB HERE ***
>
> Koichiro Den (9):
> gpio: aggregator: protect driver attr handlers against module unload
> gpio: aggregator: reorder functions to prepare for configfs
> introduction
> gpio: aggregator: add aggr_alloc()/aggr_free()
> gpio: aggregator: introduce basic configfs interface
> gpio: aggregator: add 'name' attribute for custom GPIO line names
> gpio: aggregator: rename 'name' to 'key' in aggr_parse()
> gpio: aggregator: expose aggregator created via legacy sysfs to
> configfs
> gpio: aggregator: cancel deferred probe for devices created via
> configfs
> Documentation: gpio: document configfs interface for gpio-aggregator
>
> .../admin-guide/gpio/gpio-aggregator.rst | 107 ++
> drivers/gpio/Kconfig | 2 +
> drivers/gpio/gpio-aggregator.c | 1129 ++++++++++++++---
> 3 files changed, 1050 insertions(+), 188 deletions(-)
>
> --
> 2.45.2
>
I did some more testing as I want to pick it up for v6.15 but I now
noticed that we're hitting the lockdep_assert_held(&aggr->lock) splat
in aggr_line_add(). Could you please look into it?
Bartosz
On Mon, Mar 10, 2025 at 11:19:40AM GMT, Bartosz Golaszewski wrote:
> On Mon, Feb 24, 2025 at 3:31 PM Koichiro Den <koichiro.den@canonical.com> wrote:
> >
> > This patch series introduces a configfs-based interface to gpio-aggregator
> > to address limitations in the existing 'new_device' interface.
> >
> > The existing 'new_device' interface has several limitations:
> >
> > Issue#1. No way to determine when GPIO aggregator creation is complete.
> > Issue#2. No way to retrieve errors when creating a GPIO aggregator.
> > Issue#3. No way to trace a GPIO line of an aggregator back to its
> > corresponding physical device.
> > Issue#4. The 'new_device' echo does not indicate which virtual
> > gpiochip<N> was created.
> > Issue#5. No way to assign names to GPIO lines exported through an
> > aggregator.
> >
> > Although Issue#1 to #3 could technically be resolved easily without
> > configfs, using configfs offers a streamlined, modern, and extensible
> > approach, especially since gpio-sim and gpio-virtuser already utilize
> > configfs.
> >
> > This v5 patch series includes 9 patches:
> >
> > Patch#1: Fix an issue that was spotted during v3 preparation.
> > Patch#2: Reorder functions to prepare for configfs introduction.
> > Patch#3: Add aggr_alloc() to reduce code duplication.
> > Patch#4: Introduce basic configfs interface. Address Issue#1 to #4.
> > Patch#5: Address Issue#5.
> > Patch#6: Prepare for Patch#7.
> > Patch#7: Expose devices created with sysfs to configfs.
> > Patch#8: Suppress deferred probe for purely configfs-based aggregators.
> > Patch#9: Documentation for the new configfs interface.
> >
> > N.B. This v5 is based on the latest gpio/for-next commit as of writing this:
> > * 45af02f06f69 ("gpio: virtuser: convert to use dev-sync-probe utilities")
> >
> >
> > v4->v5 changes:
> > - Rebased off of the latest gpio/for-next, that includes the patch series:
> > "Add synchronous fake device creation utility for GPIO drivers"
> > (https://lore.kernel.org/all/20250221133501.2203897-1-koichiro.den@canonical.com/)
> >
> > v3->v4 changes:
> > - Splitted off the introduction of gpio-pseudo.[ch] and conversions.
> > - Reordered commits to place a fix commit first.
> > - Squashed the trivial update for gpio-aggregator's conversion to gpio-pseudo
> > into the primary commit "gpio: aggregator: introduce basic configfs interface"
> > as it is only meaningful when combined.
> >
> > v2->v3 changes:
> > - Addressed feedback from Bartosz:
> > * Factored out the common mechanism for synchronizing platform device
> > probe by adding gpio-pseudo.[ch].
> > * Renamed "_auto." prefix to "_sysfs." for auto-generated
> > configfs entries corresponding to sysfs-created devices.
> > * Squashed v2 Patch#3 into its predecessor.
> > - Addressed feedback from Geert:
> > * Factored out duplicate code in struct gpio_aggregator initialization
> > by adding gpio_alloc()/gpio_free() functions. Note that v2 Patch#7
> > was dropped for other reasons as mentioned below, so aggr_free() in
> > v3 is unrelated to the same-named function in v2.
> > * Removed redundant parsing of gpio-line-names and unnecessary
> > chip->names assignments; squashed v2 Patch#4 + v2 Patch#5 into v3
> > Patch#9.
> > * Updated to use sysfs_emit().
> > * Updated Kconfig (select CONFIGFS_FS).
> > * Fixed typos, coding style issues, missing const qualifiers, and other
> > minor issues.
> > - Resolved an issue that was spotted during v3 preparation. See Patch#2.
> > - Reordered resource initialization order in gpio_aggregator_init() to
> > both eliminate a potential race condition (as noted in the source code
> > comment) and simplify the code. See Patch#8. This enabled:
> > * Removal of v2 Patch#7.
> > * Merging of aggr_unregister_lines() and aggr_free_lines() into a
> > unified function.
> > - Disabled 'delete_device' functionality for devices created via configfs
> > for simplicity. It was mistakenly allowed in v2 and proved buggy. See
> > Patch #8.
> >
> > RFC->v2 changes:
> > - Addressed feedback from Bartosz:
> > * Expose devices created with sysfs to configfs.
> > * Drop 'num_lines' attribute.
> > * Fix bugs and crashes.
> > * Organize internal symbol prefixes more cleanly.
> > - Split diffs for improved reviewability.
> > - Update kernel doc to reflect the changes.
> >
> > v4: https://lore.kernel.org/all/20250217143531.541185-1-koichiro.den@canonical.com/
> > v3: https://lore.kernel.org/all/20250216125816.14430-1-koichiro.den@canonical.com/
> > v2: https://lore.kernel.org/all/20250203031213.399914-1-koichiro.den@canonical.com/
> > RFC (v1): https://lore.kernel.org/linux-gpio/20250129155525.663780-1-koichiro.den@canonical.com/T/#u
> >
> >
> > *** BLURB HERE ***
> >
> > Koichiro Den (9):
> > gpio: aggregator: protect driver attr handlers against module unload
> > gpio: aggregator: reorder functions to prepare for configfs
> > introduction
> > gpio: aggregator: add aggr_alloc()/aggr_free()
> > gpio: aggregator: introduce basic configfs interface
> > gpio: aggregator: add 'name' attribute for custom GPIO line names
> > gpio: aggregator: rename 'name' to 'key' in aggr_parse()
> > gpio: aggregator: expose aggregator created via legacy sysfs to
> > configfs
> > gpio: aggregator: cancel deferred probe for devices created via
> > configfs
> > Documentation: gpio: document configfs interface for gpio-aggregator
> >
> > .../admin-guide/gpio/gpio-aggregator.rst | 107 ++
> > drivers/gpio/Kconfig | 2 +
> > drivers/gpio/gpio-aggregator.c | 1129 ++++++++++++++---
> > 3 files changed, 1050 insertions(+), 188 deletions(-)
> >
> > --
> > 2.45.2
> >
>
> I did some more testing as I want to pick it up for v6.15 but I now
> noticed that we're hitting the lockdep_assert_held(&aggr->lock) splat
> in aggr_line_add(). Could you please look into it?
Thanks. Could you share with me a sample splat?
Koichiro
>
> Bartosz
On Mon, 10 Mar 2025 14:32:12 +0100, Koichiro Den
<koichiro.den@canonical.com> said:
>>
>> I did some more testing as I want to pick it up for v6.15 but I now
>> noticed that we're hitting the lockdep_assert_held(&aggr->lock) splat
>> in aggr_line_add(). Could you please look into it?
>
> Thanks. Could you share with me a sample splat?
>
Just a simple aggregator instantiation using the new_device attribute like:
echo "gpio-sim.0:node0 3 gpio-sim.1:node0 5" > new_device
is giving me this:
[ 11.125700] ------------[ cut here ]------------
[ 11.125754] WARNING: CPU: 11 PID: 349 at
drivers/gpio/gpio-aggregator.c:185 aggr_line_add+0x2a5/0x370
[gpio_aggregator]
[ 11.125799] Modules linked in: gpio_sim gpio_aggregator
dev_sync_probe cfg80211 parport_pc parport nfsd sch_fq_codel fuse
configfs
[ 11.125933] CPU: 11 UID: 0 PID: 349 Comm: sh Not tainted
6.14.0-rc6-yocto-standard+ #80
[ 11.125959] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009),
BIOS rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/2014
[ 11.125977] RIP: 0010:aggr_line_add+0x2a5/0x370 [gpio_aggregator]
[ 11.126005] Code: c4 10 5b 41 5c 41 5d 41 5e 41 5f 5d c3 cc cc cc
cc 49 8d be 80 01 00 00 be ff ff ff ff e8 43 f8 eb d7 85 c0 0f 85 b3
fd ff ff <0f> 0b e9 ac fd ff ff 48 c7 c7 fc aa f1 99 e8 78 c1 50 d5 e9
8d fd
[ 11.126027] RSP: 0018:ffffc90002bd79e0 EFLAGS: 00010246
[ 11.126057] RAX: 0000000000000000 RBX: ffff888108bb1000 RCX: 0000000000000001
[ 11.126076] RDX: 0000000000000001 RSI: ffff888108bb1180 RDI: ffff88810cbf2400
[ 11.126093] RBP: ffffc90002bd7a18 R08: 0000000000000001 R09: ffffed102208fc00
[ 11.126110] R10: ffff88811047e003 R11: 0000000000000000 R12: 0000000000000003
[ 11.126125] R13: ffff88811047e100 R14: ffff888108bb1000 R15: ffffc90002bd7ac8
[ 11.126143] FS: 00007f9b3b293740(0000) GS:ffff888155180000(0000)
knlGS:0000000000000000
[ 11.126171] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 11.126261] CR2: 0000561597676ec0 CR3: 000000010f110000 CR4: 00000000001506f0
[ 11.126282] Call Trace:
[ 11.126294] <TASK>
[ 11.126308] ? show_regs.cold+0x19/0x1e
[ 11.126356] ? __warn.cold+0x60/0x245
[ 11.126375] ? aggr_line_add+0x2a5/0x370 [gpio_aggregator]
[ 11.126402] ? report_bug+0x20b/0x2d0
[ 11.126439] ? handle_bug+0x5b/0x90
[ 11.126462] ? exc_invalid_op+0x1c/0x50
[ 11.126485] ? asm_exc_invalid_op+0x1f/0x30
[ 11.126528] ? aggr_line_add+0x2a5/0x370 [gpio_aggregator]
[ 11.126553] ? configfs_register_group+0x239/0x390 [configfs]
[ 11.126606] new_device_store+0x88a/0xae0 [gpio_aggregator]
[ 11.126649] ? __pfx_new_device_store+0x10/0x10 [gpio_aggregator]
[ 11.126694] ? kernfs_fop_write_iter+0x258/0x5a0
[ 11.126742] ? __pfx_lock_acquire+0x10/0x10
[ 11.126774] ? __pfx_new_device_store+0x10/0x10 [gpio_aggregator]
[ 11.126795] ? __pfx_drv_attr_store+0x10/0x10
[ 11.126819] drv_attr_store+0x71/0xb0
[ 11.126838] ? sysfs_file_ops+0x129/0x180
[ 11.126863] sysfs_kf_write+0x10d/0x160
[ 11.126888] ? __pfx_sysfs_kf_write+0x10/0x10
[ 11.126908] kernfs_fop_write_iter+0x398/0x5a0
[ 11.126939] vfs_write+0x612/0x10a0
[ 11.126963] ? vfs_getattr_nosec+0x22a/0x310
[ 11.126989] ? __pfx_vfs_write+0x10/0x10
[ 11.127020] ? __do_sys_newfstat+0xed/0x100
[ 11.127070] ksys_write+0x112/0x200
[ 11.127096] ? __pfx_ksys_write+0x10/0x10
[ 11.127119] ? do_raw_spin_unlock+0x5d/0x220
[ 11.127154] __x64_sys_write+0x76/0xb0
[ 11.127175] ? trace_hardirqs_on+0x26/0x140
[ 11.127232] x64_sys_call+0x293/0x1d70
[ 11.127252] do_syscall_64+0x71/0x140
[ 11.127277] entry_SYSCALL_64_after_hwframe+0x76/0x7e
[ 11.127294] RIP: 0033:0x7f9b3b392424
[ 11.127312] Code: c7 00 16 00 00 00 b8 ff ff ff ff c3 66 2e 0f 1f
84 00 00 00 00 00 f3 0f 1e fa 80 3d 45 7c 0e 00 00 74 13 b8 01 00 00
00 0f 05 <48> 3d 00 f0 ff ff 77 54 c3 0f 1f 00 48 83 ec 28 48 89 54 24
18 48
[ 11.127327] RSP: 002b:00007fff16e6fb78 EFLAGS: 00000202 ORIG_RAX:
0000000000000001
[ 11.127351] RAX: ffffffffffffffda RBX: 0000000000000026 RCX: 00007f9b3b392424
[ 11.127365] RDX: 0000000000000026 RSI: 00005615976c3590 RDI: 0000000000000001
[ 11.127378] RBP: 00007f9b3b4735c0 R08: 0000000000000000 R09: 0000000000000001
[ 11.127390] R10: 0000000000000004 R11: 0000000000000202 R12: 0000000000000026
[ 11.127403] R13: 00005615976c3590 R14: 00007f9b3b470ec0 R15: 0000000000000000
[ 11.127457] </TASK>
[ 11.127469] irq event stamp: 54943
[ 11.127481] hardirqs last enabled at (54949): [<ffffffff958284fc>]
__up_console_sem+0x5c/0x70
[ 11.127503] hardirqs last disabled at (54954): [<ffffffff958284e1>]
__up_console_sem+0x41/0x70
[ 11.127522] softirqs last enabled at (54242): [<ffffffff956b645a>]
irq_exit_rcu+0x11a/0x1b0
[ 11.127541] softirqs last disabled at (54237): [<ffffffff956b645a>]
irq_exit_rcu+0x11a/0x1b0
[ 11.127576] ---[ end trace 0000000000000000 ]---
[ 11.127886] ------------[ cut here ]------------
[ 11.127902] WARNING: CPU: 11 PID: 349 at
drivers/gpio/gpio-aggregator.c:185 aggr_line_add+0x2a5/0x370
[gpio_aggregator]
[ 11.127932] Modules linked in: gpio_sim gpio_aggregator
dev_sync_probe cfg80211 parport_pc parport nfsd sch_fq_codel fuse
configfs
[ 11.128059] CPU: 11 UID: 0 PID: 349 Comm: sh Tainted: G W
6.14.0-rc6-yocto-standard+ #80
[ 11.128086] Tainted: [W]=WARN
[ 11.128102] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009),
BIOS rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/2014
[ 11.128118] RIP: 0010:aggr_line_add+0x2a5/0x370 [gpio_aggregator]
[ 11.128143] Code: c4 10 5b 41 5c 41 5d 41 5e 41 5f 5d c3 cc cc cc
cc 49 8d be 80 01 00 00 be ff ff ff ff e8 43 f8 eb d7 85 c0 0f 85 b3
fd ff ff <0f> 0b e9 ac fd ff ff 48 c7 c7 fc aa f1 99 e8 78 c1 50 d5 e9
8d fd
[ 11.128162] RSP: 0018:ffffc90002bd79e0 EFLAGS: 00010246
[ 11.128188] RAX: 0000000000000000 RBX: ffff888108bb1000 RCX: 0000000000000001
[ 11.128254] RDX: 0000000000000001 RSI: ffff888108bb1180 RDI: ffff88810cbf2400
[ 11.128270] RBP: ffffc90002bd7a18 R08: 0000000000000001 R09: ffffed1020a1cfa0
[ 11.128287] R10: ffff8881050e7d03 R11: 0000000000000000 R12: 0000000000000005
[ 11.128302] R13: ffff8881050e7a00 R14: ffff888108bb1000 R15: ffffc90002bd7ac8
[ 11.128319] FS: 00007f9b3b293740(0000) GS:ffff888155180000(0000)
knlGS:0000000000000000
[ 11.128344] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 11.128362] CR2: 0000561597676ec0 CR3: 000000010f110000 CR4: 00000000001506f0
[ 11.128379] Call Trace:
[ 11.128393] <TASK>
[ 11.128410] ? show_regs.cold+0x19/0x1e
[ 11.128435] ? __warn.cold+0x60/0x245
[ 11.128454] ? aggr_line_add+0x2a5/0x370 [gpio_aggregator]
[ 11.128482] ? report_bug+0x20b/0x2d0
[ 11.128517] ? handle_bug+0x5b/0x90
[ 11.128538] ? exc_invalid_op+0x1c/0x50
[ 11.128574] ? asm_exc_invalid_op+0x1f/0x30
[ 11.128617] ? aggr_line_add+0x2a5/0x370 [gpio_aggregator]
[ 11.128643] ? configfs_register_group+0x239/0x390 [configfs]
[ 11.128678] new_device_store+0x88a/0xae0 [gpio_aggregator]
[ 11.128721] ? __pfx_new_device_store+0x10/0x10 [gpio_aggregator]
[ 11.128766] ? kernfs_fop_write_iter+0x258/0x5a0
[ 11.128814] ? __pfx_lock_acquire+0x10/0x10
[ 11.128845] ? __pfx_new_device_store+0x10/0x10 [gpio_aggregator]
[ 11.128865] ? __pfx_drv_attr_store+0x10/0x10
[ 11.128888] drv_attr_store+0x71/0xb0
[ 11.128908] ? sysfs_file_ops+0x129/0x180
[ 11.128933] sysfs_kf_write+0x10d/0x160
[ 11.128957] ? __pfx_sysfs_kf_write+0x10/0x10
[ 11.128977] kernfs_fop_write_iter+0x398/0x5a0
[ 11.129009] vfs_write+0x612/0x10a0
[ 11.129031] ? vfs_getattr_nosec+0x22a/0x310
[ 11.129056] ? __pfx_vfs_write+0x10/0x10
[ 11.129088] ? __do_sys_newfstat+0xed/0x100
[ 11.129138] ksys_write+0x112/0x200
[ 11.129163] ? __pfx_ksys_write+0x10/0x10
[ 11.129187] ? do_raw_spin_unlock+0x5d/0x220
[ 11.129250] __x64_sys_write+0x76/0xb0
[ 11.129271] ? trace_hardirqs_on+0x26/0x140
[ 11.129292] x64_sys_call+0x293/0x1d70
[ 11.129312] do_syscall_64+0x71/0x140
[ 11.129337] entry_SYSCALL_64_after_hwframe+0x76/0x7e
[ 11.129354] RIP: 0033:0x7f9b3b392424
[ 11.129369] Code: c7 00 16 00 00 00 b8 ff ff ff ff c3 66 2e 0f 1f
84 00 00 00 00 00 f3 0f 1e fa 80 3d 45 7c 0e 00 00 74 13 b8 01 00 00
00 0f 05 <48> 3d 00 f0 ff ff 77 54 c3 0f 1f 00 48 83 ec 28 48 89 54 24
18 48
[ 11.129384] RSP: 002b:00007fff16e6fb78 EFLAGS: 00000202 ORIG_RAX:
0000000000000001
[ 11.129405] RAX: ffffffffffffffda RBX: 0000000000000026 RCX: 00007f9b3b392424
[ 11.129418] RDX: 0000000000000026 RSI: 00005615976c3590 RDI: 0000000000000001
[ 11.129432] RBP: 00007f9b3b4735c0 R08: 0000000000000000 R09: 0000000000000001
[ 11.129444] R10: 0000000000000004 R11: 0000000000000202 R12: 0000000000000026
[ 11.129457] R13: 00005615976c3590 R14: 00007f9b3b470ec0 R15: 0000000000000000
[ 11.129502] </TASK>
[ 11.129513] irq event stamp: 55455
[ 11.129524] hardirqs last enabled at (55461): [<ffffffff958284fc>]
__up_console_sem+0x5c/0x70
[ 11.129544] hardirqs last disabled at (55466): [<ffffffff958284e1>]
__up_console_sem+0x41/0x70
[ 11.129574] softirqs last enabled at (55142): [<ffffffff956b645a>]
irq_exit_rcu+0x11a/0x1b0
[ 11.129592] softirqs last disabled at (55137): [<ffffffff956b645a>]
irq_exit_rcu+0x11a/0x1b0
[ 11.129609] ---[ end trace 0000000000000000 ]---
While at it I now noticed that removing a top-level attribute from
/sys/kernel/config/gpio-aggregator results in the following lockdep AND KASAN
splats:
[ 18.245874] ------------[ cut here ]------------
[ 18.246196] DEBUG_LOCKS_WARN_ON(mutex_is_locked(lock))
[ 18.246205] WARNING: CPU: 11 PID: 394 at
kernel/locking/mutex-debug.c:114 mutex_destroy+0xd1/0x110
[ 18.247143] Modules linked in: gpio_aggregator dev_sync_probe
cfg80211 parport_pc parport nfsd sch_fq_codel fuse configfs
[ 18.247888] CPU: 11 UID: 0 PID: 394 Comm: rmdir Not tainted
6.14.0-rc6-yocto-standard+ #80
[ 18.248413] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009),
BIOS rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/2014
[ 18.249124] RIP: 0010:mutex_destroy+0xd1/0x110
[ 18.249414] Code: 03 0f b6 14 11 38 d0 7c 04 84 d2 75 3f 8b 05 9e
b3 71 04 85 c0 75 86 48 c7 c6 c0 f8 e7 b0 48 c7 c7 00 f9 e7 b0 e8 4f
b6 e9 ff <0f> 0b e9 6c ff ff ff 48 c7 c7 80 7d 4d b3 e8 0c 5f 6d 00 e9
51 ff
[ 18.250594] RSP: 0018:ffffc900028b7c60 EFLAGS: 00010286
[ 18.250962] RAX: 0000000000000000 RBX: ffff88810fc71118 RCX: 0000000000000027
[ 18.251415] RDX: 0000000000000000 RSI: 0000000000000004 RDI: ffff88815b1a8a48
[ 18.251920] RBP: ffffc900028b7c68 R08: 0000000000000001 R09: ffffed102b635149
[ 18.252401] R10: ffff88815b1a8a4b R11: 0000000000000001 R12: ffff88810fc71118
[ 18.252887] R13: ffff88810fc71000 R14: ffffffffc0a96660 R15: 0000000000000000
[ 18.253367] FS: 00007faabbf07740(0000) GS:ffff88815b180000(0000)
knlGS:0000000000000000
[ 18.253920] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 18.254283] CR2: 00007faabc0e8000 CR3: 000000010331c000 CR4: 00000000001506f0
[ 18.254765] Call Trace:
[ 18.254942] <TASK>
[ 18.255093] ? show_regs.cold+0x19/0x1e
[ 18.255359] ? __warn.cold+0x60/0x245
[ 18.255610] ? mutex_destroy+0xd1/0x110
[ 18.255882] ? report_bug+0x20b/0x2d0
[ 18.256140] ? handle_bug+0x5b/0x90
[ 18.256382] ? exc_invalid_op+0x1c/0x50
[ 18.256644] ? asm_exc_invalid_op+0x1f/0x30
[ 18.256943] ? mutex_destroy+0xd1/0x110
[ 18.257206] gpio_aggr_device_release+0x86/0xb0 [gpio_aggregator]
[ 18.257617] config_item_cleanup+0x122/0x220 [configfs]
[ 18.257981] config_item_put+0x52/0x6a [configfs]
[ 18.258302] configfs_rmdir+0x6f9/0xe20 [configfs]
[ 18.258629] ? __pfx_configfs_rmdir+0x10/0x10 [configfs]
[ 18.258999] ? __kasan_check_read+0x15/0x20
[ 18.259284] ? do_raw_spin_unlock+0x5d/0x220
[ 18.259577] vfs_rmdir+0x1b0/0x5d0
[ 18.259821] ? hook_path_rmdir+0x17/0x20
[ 18.260092] do_rmdir+0x31c/0x380
[ 18.260322] ? __pfx_do_rmdir+0x10/0x10
[ 18.260585] ? __kasan_check_write+0x18/0x20
[ 18.260885] ? __kasan_check_write+0x18/0x20
[ 18.261179] ? getname_flags+0xb5/0x400
[ 18.261442] __x64_sys_rmdir+0x44/0x60
[ 18.261698] x64_sys_call+0x114f/0x1d70
[ 18.261973] do_syscall_64+0x71/0x140
[ 18.262225] entry_SYSCALL_64_after_hwframe+0x76/0x7e
[ 18.262565] RIP: 0033:0x7faabc005d7b
[ 18.262821] Code: f0 ff ff 73 01 c3 48 8b 0d a2 00 0e 00 f7 d8 64
89 01 48 83 c8 ff c3 0f 1f 84 00 00 00 00 00 f3 0f 1e fa b8 54 00 00
00 0f 05 <48> 3d 00 f0 ff ff 77 05 c3 0f 1f 40 00 48 8b 15 71 00 0e 00
f7 d8
[ 18.264054] RSP: 002b:00007ffea3b3d9b8 EFLAGS: 00000246 ORIG_RAX:
0000000000000054
[ 18.264559] RAX: ffffffffffffffda RBX: 00007ffea3b3dba8 RCX: 00007faabc005d7b
[ 18.265047] RDX: 0000000000000000 RSI: 00007ffea3b3dee2 RDI: 00007ffea3b3dee2
[ 18.265520] RBP: 0000000000000002 R08: 0000000000000000 R09: 0000000000000000
[ 18.266004] R10: fffffffffffff199 R11: 0000000000000246 R12: 00007ffea3b3dee2
[ 18.266478] R13: 0000000000000001 R14: 00007faabc135000 R15: 0000559416916a78
[ 18.266965] </TASK>
[ 18.267122] irq event stamp: 3193
[ 18.267351] hardirqs last enabled at (3193): [<ffffffffadca3bf7>]
__call_rcu_common.constprop.0+0x597/0xdf0
[ 18.268009] hardirqs last disabled at (3192): [<ffffffffadca3c1a>]
__call_rcu_common.constprop.0+0x5ba/0xdf0
[ 18.268656] softirqs last enabled at (2320): [<ffffffffb0095be7>]
release_sock+0x147/0x190
[ 18.269216] softirqs last disabled at (2318): [<ffffffffb0095ac4>]
release_sock+0x24/0x190
[ 18.269760] ---[ end trace 0000000000000000 ]---
[ 18.270091] ==================================================================
[ 18.270573] BUG: KASAN: slab-use-after-free in
__mutex_unlock_slowpath+0xb1/0x6d0
[ 18.271078] Read of size 8 at addr ffff88810fc71118 by task rmdir/394
[ 18.271508]
[ 18.271623] CPU: 11 UID: 0 PID: 394 Comm: rmdir Tainted: G W
6.14.0-rc6-yocto-standard+ #80
[ 18.271627] Tainted: [W]=WARN
[ 18.271629] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009),
BIOS rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/2014
[ 18.271630] Call Trace:
[ 18.271632] <TASK>
[ 18.271633] dump_stack_lvl+0x63/0x90
[ 18.271637] print_report+0x159/0x53a
[ 18.271640] ? __virt_addr_valid+0x201/0x420
[ 18.271644] ? kasan_complete_mode_report_info+0x64/0x200
[ 18.271648] kasan_report+0xec/0x130
[ 18.271652] ? __mutex_unlock_slowpath+0xb1/0x6d0
[ 18.271656] ? __mutex_unlock_slowpath+0xb1/0x6d0
[ 18.271661] kasan_check_range+0x122/0x1f0
[ 18.271664] __kasan_check_read+0x15/0x20
[ 18.271667] __mutex_unlock_slowpath+0xb1/0x6d0
[ 18.271670] ? __kasan_slab_free+0x61/0x70
[ 18.271674] ? __kasan_slab_free+0x61/0x70
[ 18.271677] ? trace_hardirqs_on+0x26/0x140
[ 18.271681] ? __pfx___mutex_unlock_slowpath+0x10/0x10
[ 18.271685] ? __kasan_slab_free+0x61/0x70
[ 18.271689] ? kfree+0x154/0x420
[ 18.271693] mutex_unlock+0x16/0x20
[ 18.271696] gpio_aggr_device_release+0x9b/0xb0 [gpio_aggregator]
[ 18.271701] config_item_cleanup+0x122/0x220 [configfs]
[ 18.271707] config_item_put+0x52/0x6a [configfs]
[ 18.271713] configfs_rmdir+0x6f9/0xe20 [configfs]
[ 18.271721] ? __pfx_configfs_rmdir+0x10/0x10 [configfs]
[ 18.271727] ? __kasan_check_read+0x15/0x20
[ 18.271730] ? do_raw_spin_unlock+0x5d/0x220
[ 18.271735] vfs_rmdir+0x1b0/0x5d0
[ 18.271738] ? hook_path_rmdir+0x17/0x20
[ 18.271742] do_rmdir+0x31c/0x380
[ 18.271746] ? __pfx_do_rmdir+0x10/0x10
[ 18.271750] ? __kasan_check_write+0x18/0x20
[ 18.271754] ? __kasan_check_write+0x18/0x20
[ 18.271757] ? getname_flags+0xb5/0x400
[ 18.271761] __x64_sys_rmdir+0x44/0x60
[ 18.271765] x64_sys_call+0x114f/0x1d70
[ 18.271768] do_syscall_64+0x71/0x140
[ 18.271772] entry_SYSCALL_64_after_hwframe+0x76/0x7e
[ 18.271775] RIP: 0033:0x7faabc005d7b
[ 18.271777] Code: f0 ff ff 73 01 c3 48 8b 0d a2 00 0e 00 f7 d8 64
89 01 48 83 c8 ff c3 0f 1f 84 00 00 00 00 00 f3 0f 1e fa b8 54 00 00
00 0f 05 <48> 3d 00 f0 ff ff 77 05 c3 0f 1f 40 00 48 8b 15 71 00 0e 00
f7 d8
[ 18.271779] RSP: 002b:00007ffea3b3d9b8 EFLAGS: 00000246 ORIG_RAX:
0000000000000054
[ 18.271782] RAX: ffffffffffffffda RBX: 00007ffea3b3dba8 RCX: 00007faabc005d7b
[ 18.271784] RDX: 0000000000000000 RSI: 00007ffea3b3dee2 RDI: 00007ffea3b3dee2
[ 18.271786] RBP: 0000000000000002 R08: 0000000000000000 R09: 0000000000000000
[ 18.271787] R10: fffffffffffff199 R11: 0000000000000246 R12: 00007ffea3b3dee2
[ 18.271789] R13: 0000000000000001 R14: 00007faabc135000 R15: 0000559416916a78
[ 18.271795] </TASK>
[ 18.271796]
[ 18.288331] Allocated by task 392:
[ 18.288566] kasan_save_stack+0x3d/0x60
[ 18.288830] kasan_save_track+0x18/0x40
[ 18.289118] kasan_save_alloc_info+0x3b/0x50
[ 18.289410] __kasan_kmalloc+0xb7/0xc0
[ 18.289667] __kmalloc_noprof+0x1c8/0x4e0
[ 18.289945] aggr_alloc+0x22/0x190 [gpio_aggregator]
[ 18.290281] gpio_aggr_make_group+0xc1/0x100 [gpio_aggregator]
[ 18.290673] configfs_mkdir+0x3f9/0xd40 [configfs]
[ 18.291003] vfs_mkdir+0x3ca/0x610
[ 18.291239] do_mkdirat+0x27b/0x320
[ 18.291481] __x64_sys_mkdir+0x69/0x90
[ 18.291739] x64_sys_call+0x15d6/0x1d70
[ 18.292004] do_syscall_64+0x71/0x140
[ 18.292259] entry_SYSCALL_64_after_hwframe+0x76/0x7e
[ 18.292602]
[ 18.292717] Freed by task 394:
[ 18.292933] kasan_save_stack+0x3d/0x60
[ 18.293198] kasan_save_track+0x18/0x40
[ 18.293462] kasan_save_free_info+0x3f/0x70
[ 18.293748] __kasan_slab_free+0x56/0x70
[ 18.294022] kfree+0x154/0x420
[ 18.294237] gpio_aggr_device_release+0x8e/0xb0 [gpio_aggregator]
[ 18.294649] config_item_cleanup+0x122/0x220 [configfs]
[ 18.295008] config_item_put+0x52/0x6a [configfs]
[ 18.295331] configfs_rmdir+0x6f9/0xe20 [configfs]
[ 18.295659] vfs_rmdir+0x1b0/0x5d0
[ 18.295896] do_rmdir+0x31c/0x380
[ 18.296131] __x64_sys_rmdir+0x44/0x60
[ 18.296390] x64_sys_call+0x114f/0x1d70
[ 18.296654] do_syscall_64+0x71/0x140
[ 18.296909] entry_SYSCALL_64_after_hwframe+0x76/0x7e
[ 18.297251]
[ 18.297365] The buggy address belongs to the object at ffff88810fc71000
[ 18.297365] which belongs to the cache kmalloc-512 of size 512
[ 18.298186] The buggy address is located 280 bytes inside of
[ 18.298186] freed 512-byte region [ffff88810fc71000, ffff88810fc71200)
[ 18.298992]
[ 18.299106] The buggy address belongs to the physical page:
[ 18.299481] page: refcount:0 mapcount:0 mapping:0000000000000000
index:0x0 pfn:0x10fc70
[ 18.300018] head: order:3 mapcount:0 entire_mapcount:0
nr_pages_mapped:0 pincount:0
[ 18.300526] flags: 0x8000000000000040(head|zone=2)
[ 18.300852] page_type: f5(slab)
[ 18.301076] raw: 8000000000000040 ffff888100042c80 dead000000000100
dead000000000122
[ 18.301591] raw: 0000000000000000 0000000080200020 00000000f5000000
0000000000000000
[ 18.302109] head: 8000000000000040 ffff888100042c80
dead000000000100 dead000000000122
[ 18.302629] head: 0000000000000000 0000000080200020
00000000f5000000 0000000000000000
[ 18.303152] head: 8000000000000003 ffffea00043f1c01
ffffffffffffffff 0000000000000000
[ 18.303671] head: 0000000000000008 0000000000000000
00000000ffffffff 0000000000000000
[ 18.304194] page dumped because: kasan: bad access detected
[ 18.304568]
[ 18.304682] Memory state around the buggy address:
[ 18.305008] ffff88810fc71000: fa fb fb fb fb fb fb fb fb fb fb fb
fb fb fb fb
[ 18.305491] ffff88810fc71080: fb fb fb fb fb fb fb fb fb fb fb fb
fb fb fb fb
[ 18.305975] >ffff88810fc71100: fb fb fb fb fb fb fb fb fb fb fb fb
fb fb fb fb
[ 18.306456] ^
[ 18.306731] ffff88810fc71180: fb fb fb fb fb fb fb fb fb fb fb fb
fb fb fb fb
[ 18.307215] ffff88810fc71200: fc fc fc fc fc fc fc fc fc fc fc fc
fc fc fc fc
[ 18.307696] ==================================================================
Bart
On Mon, Mar 10, 2025 at 10:17:44AM GMT, Bartosz Golaszewski wrote:
> On Mon, 10 Mar 2025 14:32:12 +0100, Koichiro Den
> <koichiro.den@canonical.com> said:
> >>
> >> I did some more testing as I want to pick it up for v6.15 but I now
> >> noticed that we're hitting the lockdep_assert_held(&aggr->lock) splat
> >> in aggr_line_add(). Could you please look into it?
> >
> > Thanks. Could you share with me a sample splat?
> >
>
> Just a simple aggregator instantiation using the new_device attribute like:
>
> echo "gpio-sim.0:node0 3 gpio-sim.1:node0 5" > new_device
>
> is giving me this:
>
> [ 11.125700] ------------[ cut here ]------------
> [ 11.125754] WARNING: CPU: 11 PID: 349 at
> drivers/gpio/gpio-aggregator.c:185 aggr_line_add+0x2a5/0x370
> [gpio_aggregator]
> [ 11.125799] Modules linked in: gpio_sim gpio_aggregator
> dev_sync_probe cfg80211 parport_pc parport nfsd sch_fq_codel fuse
> configfs
> [ 11.125933] CPU: 11 UID: 0 PID: 349 Comm: sh Not tainted
> 6.14.0-rc6-yocto-standard+ #80
> [ 11.125959] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009),
> BIOS rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/2014
> [ 11.125977] RIP: 0010:aggr_line_add+0x2a5/0x370 [gpio_aggregator]
> [ 11.126005] Code: c4 10 5b 41 5c 41 5d 41 5e 41 5f 5d c3 cc cc cc
> cc 49 8d be 80 01 00 00 be ff ff ff ff e8 43 f8 eb d7 85 c0 0f 85 b3
> fd ff ff <0f> 0b e9 ac fd ff ff 48 c7 c7 fc aa f1 99 e8 78 c1 50 d5 e9
> 8d fd
> [ 11.126027] RSP: 0018:ffffc90002bd79e0 EFLAGS: 00010246
> [ 11.126057] RAX: 0000000000000000 RBX: ffff888108bb1000 RCX: 0000000000000001
> [ 11.126076] RDX: 0000000000000001 RSI: ffff888108bb1180 RDI: ffff88810cbf2400
> [ 11.126093] RBP: ffffc90002bd7a18 R08: 0000000000000001 R09: ffffed102208fc00
> [ 11.126110] R10: ffff88811047e003 R11: 0000000000000000 R12: 0000000000000003
> [ 11.126125] R13: ffff88811047e100 R14: ffff888108bb1000 R15: ffffc90002bd7ac8
> [ 11.126143] FS: 00007f9b3b293740(0000) GS:ffff888155180000(0000)
> knlGS:0000000000000000
> [ 11.126171] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [ 11.126261] CR2: 0000561597676ec0 CR3: 000000010f110000 CR4: 00000000001506f0
> [ 11.126282] Call Trace:
> [ 11.126294] <TASK>
> [ 11.126308] ? show_regs.cold+0x19/0x1e
> [ 11.126356] ? __warn.cold+0x60/0x245
> [ 11.126375] ? aggr_line_add+0x2a5/0x370 [gpio_aggregator]
> [ 11.126402] ? report_bug+0x20b/0x2d0
> [ 11.126439] ? handle_bug+0x5b/0x90
> [ 11.126462] ? exc_invalid_op+0x1c/0x50
> [ 11.126485] ? asm_exc_invalid_op+0x1f/0x30
> [ 11.126528] ? aggr_line_add+0x2a5/0x370 [gpio_aggregator]
> [ 11.126553] ? configfs_register_group+0x239/0x390 [configfs]
> [ 11.126606] new_device_store+0x88a/0xae0 [gpio_aggregator]
> [ 11.126649] ? __pfx_new_device_store+0x10/0x10 [gpio_aggregator]
> [ 11.126694] ? kernfs_fop_write_iter+0x258/0x5a0
> [ 11.126742] ? __pfx_lock_acquire+0x10/0x10
> [ 11.126774] ? __pfx_new_device_store+0x10/0x10 [gpio_aggregator]
> [ 11.126795] ? __pfx_drv_attr_store+0x10/0x10
> [ 11.126819] drv_attr_store+0x71/0xb0
> [ 11.126838] ? sysfs_file_ops+0x129/0x180
> [ 11.126863] sysfs_kf_write+0x10d/0x160
> [ 11.126888] ? __pfx_sysfs_kf_write+0x10/0x10
> [ 11.126908] kernfs_fop_write_iter+0x398/0x5a0
> [ 11.126939] vfs_write+0x612/0x10a0
> [ 11.126963] ? vfs_getattr_nosec+0x22a/0x310
> [ 11.126989] ? __pfx_vfs_write+0x10/0x10
> [ 11.127020] ? __do_sys_newfstat+0xed/0x100
> [ 11.127070] ksys_write+0x112/0x200
> [ 11.127096] ? __pfx_ksys_write+0x10/0x10
> [ 11.127119] ? do_raw_spin_unlock+0x5d/0x220
> [ 11.127154] __x64_sys_write+0x76/0xb0
> [ 11.127175] ? trace_hardirqs_on+0x26/0x140
> [ 11.127232] x64_sys_call+0x293/0x1d70
> [ 11.127252] do_syscall_64+0x71/0x140
> [ 11.127277] entry_SYSCALL_64_after_hwframe+0x76/0x7e
> [ 11.127294] RIP: 0033:0x7f9b3b392424
> [ 11.127312] Code: c7 00 16 00 00 00 b8 ff ff ff ff c3 66 2e 0f 1f
> 84 00 00 00 00 00 f3 0f 1e fa 80 3d 45 7c 0e 00 00 74 13 b8 01 00 00
> 00 0f 05 <48> 3d 00 f0 ff ff 77 54 c3 0f 1f 00 48 83 ec 28 48 89 54 24
> 18 48
> [ 11.127327] RSP: 002b:00007fff16e6fb78 EFLAGS: 00000202 ORIG_RAX:
> 0000000000000001
> [ 11.127351] RAX: ffffffffffffffda RBX: 0000000000000026 RCX: 00007f9b3b392424
> [ 11.127365] RDX: 0000000000000026 RSI: 00005615976c3590 RDI: 0000000000000001
> [ 11.127378] RBP: 00007f9b3b4735c0 R08: 0000000000000000 R09: 0000000000000001
> [ 11.127390] R10: 0000000000000004 R11: 0000000000000202 R12: 0000000000000026
> [ 11.127403] R13: 00005615976c3590 R14: 00007f9b3b470ec0 R15: 0000000000000000
> [ 11.127457] </TASK>
> [ 11.127469] irq event stamp: 54943
> [ 11.127481] hardirqs last enabled at (54949): [<ffffffff958284fc>]
> __up_console_sem+0x5c/0x70
> [ 11.127503] hardirqs last disabled at (54954): [<ffffffff958284e1>]
> __up_console_sem+0x41/0x70
> [ 11.127522] softirqs last enabled at (54242): [<ffffffff956b645a>]
> irq_exit_rcu+0x11a/0x1b0
> [ 11.127541] softirqs last disabled at (54237): [<ffffffff956b645a>]
> irq_exit_rcu+0x11a/0x1b0
> [ 11.127576] ---[ end trace 0000000000000000 ]---
> [ 11.127886] ------------[ cut here ]------------
> [ 11.127902] WARNING: CPU: 11 PID: 349 at
> drivers/gpio/gpio-aggregator.c:185 aggr_line_add+0x2a5/0x370
> [gpio_aggregator]
> [ 11.127932] Modules linked in: gpio_sim gpio_aggregator
> dev_sync_probe cfg80211 parport_pc parport nfsd sch_fq_codel fuse
> configfs
> [ 11.128059] CPU: 11 UID: 0 PID: 349 Comm: sh Tainted: G W
> 6.14.0-rc6-yocto-standard+ #80
> [ 11.128086] Tainted: [W]=WARN
> [ 11.128102] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009),
> BIOS rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/2014
> [ 11.128118] RIP: 0010:aggr_line_add+0x2a5/0x370 [gpio_aggregator]
> [ 11.128143] Code: c4 10 5b 41 5c 41 5d 41 5e 41 5f 5d c3 cc cc cc
> cc 49 8d be 80 01 00 00 be ff ff ff ff e8 43 f8 eb d7 85 c0 0f 85 b3
> fd ff ff <0f> 0b e9 ac fd ff ff 48 c7 c7 fc aa f1 99 e8 78 c1 50 d5 e9
> 8d fd
> [ 11.128162] RSP: 0018:ffffc90002bd79e0 EFLAGS: 00010246
> [ 11.128188] RAX: 0000000000000000 RBX: ffff888108bb1000 RCX: 0000000000000001
> [ 11.128254] RDX: 0000000000000001 RSI: ffff888108bb1180 RDI: ffff88810cbf2400
> [ 11.128270] RBP: ffffc90002bd7a18 R08: 0000000000000001 R09: ffffed1020a1cfa0
> [ 11.128287] R10: ffff8881050e7d03 R11: 0000000000000000 R12: 0000000000000005
> [ 11.128302] R13: ffff8881050e7a00 R14: ffff888108bb1000 R15: ffffc90002bd7ac8
> [ 11.128319] FS: 00007f9b3b293740(0000) GS:ffff888155180000(0000)
> knlGS:0000000000000000
> [ 11.128344] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [ 11.128362] CR2: 0000561597676ec0 CR3: 000000010f110000 CR4: 00000000001506f0
> [ 11.128379] Call Trace:
> [ 11.128393] <TASK>
> [ 11.128410] ? show_regs.cold+0x19/0x1e
> [ 11.128435] ? __warn.cold+0x60/0x245
> [ 11.128454] ? aggr_line_add+0x2a5/0x370 [gpio_aggregator]
> [ 11.128482] ? report_bug+0x20b/0x2d0
> [ 11.128517] ? handle_bug+0x5b/0x90
> [ 11.128538] ? exc_invalid_op+0x1c/0x50
> [ 11.128574] ? asm_exc_invalid_op+0x1f/0x30
> [ 11.128617] ? aggr_line_add+0x2a5/0x370 [gpio_aggregator]
> [ 11.128643] ? configfs_register_group+0x239/0x390 [configfs]
> [ 11.128678] new_device_store+0x88a/0xae0 [gpio_aggregator]
> [ 11.128721] ? __pfx_new_device_store+0x10/0x10 [gpio_aggregator]
> [ 11.128766] ? kernfs_fop_write_iter+0x258/0x5a0
> [ 11.128814] ? __pfx_lock_acquire+0x10/0x10
> [ 11.128845] ? __pfx_new_device_store+0x10/0x10 [gpio_aggregator]
> [ 11.128865] ? __pfx_drv_attr_store+0x10/0x10
> [ 11.128888] drv_attr_store+0x71/0xb0
> [ 11.128908] ? sysfs_file_ops+0x129/0x180
> [ 11.128933] sysfs_kf_write+0x10d/0x160
> [ 11.128957] ? __pfx_sysfs_kf_write+0x10/0x10
> [ 11.128977] kernfs_fop_write_iter+0x398/0x5a0
> [ 11.129009] vfs_write+0x612/0x10a0
> [ 11.129031] ? vfs_getattr_nosec+0x22a/0x310
> [ 11.129056] ? __pfx_vfs_write+0x10/0x10
> [ 11.129088] ? __do_sys_newfstat+0xed/0x100
> [ 11.129138] ksys_write+0x112/0x200
> [ 11.129163] ? __pfx_ksys_write+0x10/0x10
> [ 11.129187] ? do_raw_spin_unlock+0x5d/0x220
> [ 11.129250] __x64_sys_write+0x76/0xb0
> [ 11.129271] ? trace_hardirqs_on+0x26/0x140
> [ 11.129292] x64_sys_call+0x293/0x1d70
> [ 11.129312] do_syscall_64+0x71/0x140
> [ 11.129337] entry_SYSCALL_64_after_hwframe+0x76/0x7e
> [ 11.129354] RIP: 0033:0x7f9b3b392424
> [ 11.129369] Code: c7 00 16 00 00 00 b8 ff ff ff ff c3 66 2e 0f 1f
> 84 00 00 00 00 00 f3 0f 1e fa 80 3d 45 7c 0e 00 00 74 13 b8 01 00 00
> 00 0f 05 <48> 3d 00 f0 ff ff 77 54 c3 0f 1f 00 48 83 ec 28 48 89 54 24
> 18 48
> [ 11.129384] RSP: 002b:00007fff16e6fb78 EFLAGS: 00000202 ORIG_RAX:
> 0000000000000001
> [ 11.129405] RAX: ffffffffffffffda RBX: 0000000000000026 RCX: 00007f9b3b392424
> [ 11.129418] RDX: 0000000000000026 RSI: 00005615976c3590 RDI: 0000000000000001
> [ 11.129432] RBP: 00007f9b3b4735c0 R08: 0000000000000000 R09: 0000000000000001
> [ 11.129444] R10: 0000000000000004 R11: 0000000000000202 R12: 0000000000000026
> [ 11.129457] R13: 00005615976c3590 R14: 00007f9b3b470ec0 R15: 0000000000000000
> [ 11.129502] </TASK>
> [ 11.129513] irq event stamp: 55455
> [ 11.129524] hardirqs last enabled at (55461): [<ffffffff958284fc>]
> __up_console_sem+0x5c/0x70
> [ 11.129544] hardirqs last disabled at (55466): [<ffffffff958284e1>]
> __up_console_sem+0x41/0x70
> [ 11.129574] softirqs last enabled at (55142): [<ffffffff956b645a>]
> irq_exit_rcu+0x11a/0x1b0
> [ 11.129592] softirqs last disabled at (55137): [<ffffffff956b645a>]
> irq_exit_rcu+0x11a/0x1b0
> [ 11.129609] ---[ end trace 0000000000000000 ]---
>
> While at it I now noticed that removing a top-level attribute from
> /sys/kernel/config/gpio-aggregator results in the following lockdep AND KASAN
> splats:
>
> [ 18.245874] ------------[ cut here ]------------
> [ 18.246196] DEBUG_LOCKS_WARN_ON(mutex_is_locked(lock))
> [ 18.246205] WARNING: CPU: 11 PID: 394 at
> kernel/locking/mutex-debug.c:114 mutex_destroy+0xd1/0x110
> [ 18.247143] Modules linked in: gpio_aggregator dev_sync_probe
> cfg80211 parport_pc parport nfsd sch_fq_codel fuse configfs
> [ 18.247888] CPU: 11 UID: 0 PID: 394 Comm: rmdir Not tainted
> 6.14.0-rc6-yocto-standard+ #80
> [ 18.248413] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009),
> BIOS rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/2014
> [ 18.249124] RIP: 0010:mutex_destroy+0xd1/0x110
> [ 18.249414] Code: 03 0f b6 14 11 38 d0 7c 04 84 d2 75 3f 8b 05 9e
> b3 71 04 85 c0 75 86 48 c7 c6 c0 f8 e7 b0 48 c7 c7 00 f9 e7 b0 e8 4f
> b6 e9 ff <0f> 0b e9 6c ff ff ff 48 c7 c7 80 7d 4d b3 e8 0c 5f 6d 00 e9
> 51 ff
> [ 18.250594] RSP: 0018:ffffc900028b7c60 EFLAGS: 00010286
> [ 18.250962] RAX: 0000000000000000 RBX: ffff88810fc71118 RCX: 0000000000000027
> [ 18.251415] RDX: 0000000000000000 RSI: 0000000000000004 RDI: ffff88815b1a8a48
> [ 18.251920] RBP: ffffc900028b7c68 R08: 0000000000000001 R09: ffffed102b635149
> [ 18.252401] R10: ffff88815b1a8a4b R11: 0000000000000001 R12: ffff88810fc71118
> [ 18.252887] R13: ffff88810fc71000 R14: ffffffffc0a96660 R15: 0000000000000000
> [ 18.253367] FS: 00007faabbf07740(0000) GS:ffff88815b180000(0000)
> knlGS:0000000000000000
> [ 18.253920] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [ 18.254283] CR2: 00007faabc0e8000 CR3: 000000010331c000 CR4: 00000000001506f0
> [ 18.254765] Call Trace:
> [ 18.254942] <TASK>
> [ 18.255093] ? show_regs.cold+0x19/0x1e
> [ 18.255359] ? __warn.cold+0x60/0x245
> [ 18.255610] ? mutex_destroy+0xd1/0x110
> [ 18.255882] ? report_bug+0x20b/0x2d0
> [ 18.256140] ? handle_bug+0x5b/0x90
> [ 18.256382] ? exc_invalid_op+0x1c/0x50
> [ 18.256644] ? asm_exc_invalid_op+0x1f/0x30
> [ 18.256943] ? mutex_destroy+0xd1/0x110
> [ 18.257206] gpio_aggr_device_release+0x86/0xb0 [gpio_aggregator]
> [ 18.257617] config_item_cleanup+0x122/0x220 [configfs]
> [ 18.257981] config_item_put+0x52/0x6a [configfs]
> [ 18.258302] configfs_rmdir+0x6f9/0xe20 [configfs]
> [ 18.258629] ? __pfx_configfs_rmdir+0x10/0x10 [configfs]
> [ 18.258999] ? __kasan_check_read+0x15/0x20
> [ 18.259284] ? do_raw_spin_unlock+0x5d/0x220
> [ 18.259577] vfs_rmdir+0x1b0/0x5d0
> [ 18.259821] ? hook_path_rmdir+0x17/0x20
> [ 18.260092] do_rmdir+0x31c/0x380
> [ 18.260322] ? __pfx_do_rmdir+0x10/0x10
> [ 18.260585] ? __kasan_check_write+0x18/0x20
> [ 18.260885] ? __kasan_check_write+0x18/0x20
> [ 18.261179] ? getname_flags+0xb5/0x400
> [ 18.261442] __x64_sys_rmdir+0x44/0x60
> [ 18.261698] x64_sys_call+0x114f/0x1d70
> [ 18.261973] do_syscall_64+0x71/0x140
> [ 18.262225] entry_SYSCALL_64_after_hwframe+0x76/0x7e
> [ 18.262565] RIP: 0033:0x7faabc005d7b
> [ 18.262821] Code: f0 ff ff 73 01 c3 48 8b 0d a2 00 0e 00 f7 d8 64
> 89 01 48 83 c8 ff c3 0f 1f 84 00 00 00 00 00 f3 0f 1e fa b8 54 00 00
> 00 0f 05 <48> 3d 00 f0 ff ff 77 05 c3 0f 1f 40 00 48 8b 15 71 00 0e 00
> f7 d8
> [ 18.264054] RSP: 002b:00007ffea3b3d9b8 EFLAGS: 00000246 ORIG_RAX:
> 0000000000000054
> [ 18.264559] RAX: ffffffffffffffda RBX: 00007ffea3b3dba8 RCX: 00007faabc005d7b
> [ 18.265047] RDX: 0000000000000000 RSI: 00007ffea3b3dee2 RDI: 00007ffea3b3dee2
> [ 18.265520] RBP: 0000000000000002 R08: 0000000000000000 R09: 0000000000000000
> [ 18.266004] R10: fffffffffffff199 R11: 0000000000000246 R12: 00007ffea3b3dee2
> [ 18.266478] R13: 0000000000000001 R14: 00007faabc135000 R15: 0000559416916a78
> [ 18.266965] </TASK>
> [ 18.267122] irq event stamp: 3193
> [ 18.267351] hardirqs last enabled at (3193): [<ffffffffadca3bf7>]
> __call_rcu_common.constprop.0+0x597/0xdf0
> [ 18.268009] hardirqs last disabled at (3192): [<ffffffffadca3c1a>]
> __call_rcu_common.constprop.0+0x5ba/0xdf0
> [ 18.268656] softirqs last enabled at (2320): [<ffffffffb0095be7>]
> release_sock+0x147/0x190
> [ 18.269216] softirqs last disabled at (2318): [<ffffffffb0095ac4>]
> release_sock+0x24/0x190
> [ 18.269760] ---[ end trace 0000000000000000 ]---
> [ 18.270091] ==================================================================
> [ 18.270573] BUG: KASAN: slab-use-after-free in
> __mutex_unlock_slowpath+0xb1/0x6d0
> [ 18.271078] Read of size 8 at addr ffff88810fc71118 by task rmdir/394
> [ 18.271508]
> [ 18.271623] CPU: 11 UID: 0 PID: 394 Comm: rmdir Tainted: G W
> 6.14.0-rc6-yocto-standard+ #80
> [ 18.271627] Tainted: [W]=WARN
> [ 18.271629] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009),
> BIOS rel-1.16.3-0-ga6ed6b701f0a-prebuilt.qemu.org 04/01/2014
> [ 18.271630] Call Trace:
> [ 18.271632] <TASK>
> [ 18.271633] dump_stack_lvl+0x63/0x90
> [ 18.271637] print_report+0x159/0x53a
> [ 18.271640] ? __virt_addr_valid+0x201/0x420
> [ 18.271644] ? kasan_complete_mode_report_info+0x64/0x200
> [ 18.271648] kasan_report+0xec/0x130
> [ 18.271652] ? __mutex_unlock_slowpath+0xb1/0x6d0
> [ 18.271656] ? __mutex_unlock_slowpath+0xb1/0x6d0
> [ 18.271661] kasan_check_range+0x122/0x1f0
> [ 18.271664] __kasan_check_read+0x15/0x20
> [ 18.271667] __mutex_unlock_slowpath+0xb1/0x6d0
> [ 18.271670] ? __kasan_slab_free+0x61/0x70
> [ 18.271674] ? __kasan_slab_free+0x61/0x70
> [ 18.271677] ? trace_hardirqs_on+0x26/0x140
> [ 18.271681] ? __pfx___mutex_unlock_slowpath+0x10/0x10
> [ 18.271685] ? __kasan_slab_free+0x61/0x70
> [ 18.271689] ? kfree+0x154/0x420
> [ 18.271693] mutex_unlock+0x16/0x20
> [ 18.271696] gpio_aggr_device_release+0x9b/0xb0 [gpio_aggregator]
> [ 18.271701] config_item_cleanup+0x122/0x220 [configfs]
> [ 18.271707] config_item_put+0x52/0x6a [configfs]
> [ 18.271713] configfs_rmdir+0x6f9/0xe20 [configfs]
> [ 18.271721] ? __pfx_configfs_rmdir+0x10/0x10 [configfs]
> [ 18.271727] ? __kasan_check_read+0x15/0x20
> [ 18.271730] ? do_raw_spin_unlock+0x5d/0x220
> [ 18.271735] vfs_rmdir+0x1b0/0x5d0
> [ 18.271738] ? hook_path_rmdir+0x17/0x20
> [ 18.271742] do_rmdir+0x31c/0x380
> [ 18.271746] ? __pfx_do_rmdir+0x10/0x10
> [ 18.271750] ? __kasan_check_write+0x18/0x20
> [ 18.271754] ? __kasan_check_write+0x18/0x20
> [ 18.271757] ? getname_flags+0xb5/0x400
> [ 18.271761] __x64_sys_rmdir+0x44/0x60
> [ 18.271765] x64_sys_call+0x114f/0x1d70
> [ 18.271768] do_syscall_64+0x71/0x140
> [ 18.271772] entry_SYSCALL_64_after_hwframe+0x76/0x7e
> [ 18.271775] RIP: 0033:0x7faabc005d7b
> [ 18.271777] Code: f0 ff ff 73 01 c3 48 8b 0d a2 00 0e 00 f7 d8 64
> 89 01 48 83 c8 ff c3 0f 1f 84 00 00 00 00 00 f3 0f 1e fa b8 54 00 00
> 00 0f 05 <48> 3d 00 f0 ff ff 77 05 c3 0f 1f 40 00 48 8b 15 71 00 0e 00
> f7 d8
> [ 18.271779] RSP: 002b:00007ffea3b3d9b8 EFLAGS: 00000246 ORIG_RAX:
> 0000000000000054
> [ 18.271782] RAX: ffffffffffffffda RBX: 00007ffea3b3dba8 RCX: 00007faabc005d7b
> [ 18.271784] RDX: 0000000000000000 RSI: 00007ffea3b3dee2 RDI: 00007ffea3b3dee2
> [ 18.271786] RBP: 0000000000000002 R08: 0000000000000000 R09: 0000000000000000
> [ 18.271787] R10: fffffffffffff199 R11: 0000000000000246 R12: 00007ffea3b3dee2
> [ 18.271789] R13: 0000000000000001 R14: 00007faabc135000 R15: 0000559416916a78
> [ 18.271795] </TASK>
> [ 18.271796]
> [ 18.288331] Allocated by task 392:
> [ 18.288566] kasan_save_stack+0x3d/0x60
> [ 18.288830] kasan_save_track+0x18/0x40
> [ 18.289118] kasan_save_alloc_info+0x3b/0x50
> [ 18.289410] __kasan_kmalloc+0xb7/0xc0
> [ 18.289667] __kmalloc_noprof+0x1c8/0x4e0
> [ 18.289945] aggr_alloc+0x22/0x190 [gpio_aggregator]
> [ 18.290281] gpio_aggr_make_group+0xc1/0x100 [gpio_aggregator]
> [ 18.290673] configfs_mkdir+0x3f9/0xd40 [configfs]
> [ 18.291003] vfs_mkdir+0x3ca/0x610
> [ 18.291239] do_mkdirat+0x27b/0x320
> [ 18.291481] __x64_sys_mkdir+0x69/0x90
> [ 18.291739] x64_sys_call+0x15d6/0x1d70
> [ 18.292004] do_syscall_64+0x71/0x140
> [ 18.292259] entry_SYSCALL_64_after_hwframe+0x76/0x7e
> [ 18.292602]
> [ 18.292717] Freed by task 394:
> [ 18.292933] kasan_save_stack+0x3d/0x60
> [ 18.293198] kasan_save_track+0x18/0x40
> [ 18.293462] kasan_save_free_info+0x3f/0x70
> [ 18.293748] __kasan_slab_free+0x56/0x70
> [ 18.294022] kfree+0x154/0x420
> [ 18.294237] gpio_aggr_device_release+0x8e/0xb0 [gpio_aggregator]
> [ 18.294649] config_item_cleanup+0x122/0x220 [configfs]
> [ 18.295008] config_item_put+0x52/0x6a [configfs]
> [ 18.295331] configfs_rmdir+0x6f9/0xe20 [configfs]
> [ 18.295659] vfs_rmdir+0x1b0/0x5d0
> [ 18.295896] do_rmdir+0x31c/0x380
> [ 18.296131] __x64_sys_rmdir+0x44/0x60
> [ 18.296390] x64_sys_call+0x114f/0x1d70
> [ 18.296654] do_syscall_64+0x71/0x140
> [ 18.296909] entry_SYSCALL_64_after_hwframe+0x76/0x7e
> [ 18.297251]
> [ 18.297365] The buggy address belongs to the object at ffff88810fc71000
> [ 18.297365] which belongs to the cache kmalloc-512 of size 512
> [ 18.298186] The buggy address is located 280 bytes inside of
> [ 18.298186] freed 512-byte region [ffff88810fc71000, ffff88810fc71200)
> [ 18.298992]
> [ 18.299106] The buggy address belongs to the physical page:
> [ 18.299481] page: refcount:0 mapcount:0 mapping:0000000000000000
> index:0x0 pfn:0x10fc70
> [ 18.300018] head: order:3 mapcount:0 entire_mapcount:0
> nr_pages_mapped:0 pincount:0
> [ 18.300526] flags: 0x8000000000000040(head|zone=2)
> [ 18.300852] page_type: f5(slab)
> [ 18.301076] raw: 8000000000000040 ffff888100042c80 dead000000000100
> dead000000000122
> [ 18.301591] raw: 0000000000000000 0000000080200020 00000000f5000000
> 0000000000000000
> [ 18.302109] head: 8000000000000040 ffff888100042c80
> dead000000000100 dead000000000122
> [ 18.302629] head: 0000000000000000 0000000080200020
> 00000000f5000000 0000000000000000
> [ 18.303152] head: 8000000000000003 ffffea00043f1c01
> ffffffffffffffff 0000000000000000
> [ 18.303671] head: 0000000000000008 0000000000000000
> 00000000ffffffff 0000000000000000
> [ 18.304194] page dumped because: kasan: bad access detected
> [ 18.304568]
> [ 18.304682] Memory state around the buggy address:
> [ 18.305008] ffff88810fc71000: fa fb fb fb fb fb fb fb fb fb fb fb
> fb fb fb fb
> [ 18.305491] ffff88810fc71080: fb fb fb fb fb fb fb fb fb fb fb fb
> fb fb fb fb
> [ 18.305975] >ffff88810fc71100: fb fb fb fb fb fb fb fb fb fb fb fb
> fb fb fb fb
> [ 18.306456] ^
> [ 18.306731] ffff88810fc71180: fb fb fb fb fb fb fb fb fb fb fb fb
> fb fb fb fb
> [ 18.307215] ffff88810fc71200: fc fc fc fc fc fc fc fc fc fc fc fc
> fc fc fc fc
> [ 18.307696] ==================================================================
Thanks, I've confirmed it. It seems I overlooked it because somehow
lockdep and kasan were not enabled for a while.
Assuming the v5 patch series rebased onto the latest gpio/for-next
21c853ad9309 ("gpio: adnp: use new line value setter callbacks"),
the following follow-up patch should suffice.
------------8<--------------8<---------------
diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c
index df34d8fcb79a..56f0fde8c843 100644
--- a/drivers/gpio/gpio-aggregator.c
+++ b/drivers/gpio/gpio-aggregator.c
@@ -207,7 +207,18 @@ static void aggr_free_lines(struct gpio_aggregator *aggr)
list_for_each_entry_safe(line, tmp, &aggr->list_head, entry) {
configfs_unregister_group(&line->group);
- aggr_line_del(aggr, line);
+ /*
+ * Normally, we acquire aggr->lock within the configfs
+ * callback. However, in the legacy sysfs interface case,
+ * calling configfs_(un)register_group while holding
+ * aggr->lock could cause a deadlock. Fortunately, this is
+ * unnecessary because the new_device/delete_device path
+ * and the module unload path are mutually exclusive,
+ * thanks to an explicit try_module_get. That's why this
+ * minimal scoped_guard suffices here.
+ */
+ scoped_guard(mutex, &aggr->lock)
+ aggr_line_del(aggr, line);
kfree(line->key);
kfree(line);
}
@@ -926,8 +937,6 @@ static void gpio_aggr_device_release(struct config_item *item)
{
struct gpio_aggregator *aggr = to_gpio_aggregator(item);
- guard(mutex)(&aggr->lock);
-
/*
* At this point, aggr is neither active nor activating,
* so calling aggr_deactivate() is always unnecessary.
@@ -1072,7 +1081,8 @@ static int aggr_parse(struct gpio_aggregator *aggr)
&line->group);
if (error)
goto err;
- aggr_line_add(aggr, line);
+ scoped_guard(mutex, &aggr->lock)
+ aggr_line_add(aggr, line);
error = aggr_add_gpio(aggr, key, U16_MAX, &n);
if (error)
@@ -1101,7 +1111,8 @@ static int aggr_parse(struct gpio_aggregator *aggr)
&line->group);
if (error)
goto err;
- aggr_line_add(aggr, line);
+ scoped_guard(mutex, &aggr->lock)
+ aggr_line_add(aggr, line);
error = aggr_add_gpio(aggr, key, i, &n);
if (error)
@@ -1205,8 +1216,10 @@ static DRIVER_ATTR_WO(new_device);
static void gpio_aggregator_free(struct gpio_aggregator *aggr)
{
- if (aggr_is_activating(aggr) || aggr_is_active(aggr))
- aggr_deactivate(aggr);
+ scoped_guard(mutex, &aggr->lock) {
+ if (aggr_is_activating(aggr) || aggr_is_active(aggr))
+ aggr_deactivate(aggr);
+ }
aggr_free_lines(aggr);
configfs_unregister_group(&aggr->group);
kfree(aggr);
------------8<--------------8<---------------
* The second hunk should be squashed into
[PATCH v5 4/9] gpio: aggregator: introduce basic configfs interface
* The rest of the hunks should be squashed into
[PATCH v5 8/9] gpio: aggregator: expose aggregator created via legacy sysfs to configfs
If you agree with the above approach, I'll send out v6,
while also addressing your feedback here:
https://lore.kernel.org/all/CAMRc=MdoMKdqyzGMFDa3aMz3h=vfZ0OtwARxY7FdsPKcBu9HQA@mail.gmail.com/
Koichiro
>
> Bart
On Mon, Mar 10, 2025 at 5:28 PM Koichiro Den <koichiro.den@canonical.com> wrote:
>
[snip!]
Please remove unnecessary context from responses. You attached
hundreds of lines of stack traces here. :(
>
> Thanks, I've confirmed it. It seems I overlooked it because somehow
> lockdep and kasan were not enabled for a while.
>
> Assuming the v5 patch series rebased onto the latest gpio/for-next
> 21c853ad9309 ("gpio: adnp: use new line value setter callbacks"),
> the following follow-up patch should suffice.
>
> ------------8<--------------8<---------------
> diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c
> index df34d8fcb79a..56f0fde8c843 100644
> --- a/drivers/gpio/gpio-aggregator.c
> +++ b/drivers/gpio/gpio-aggregator.c
> @@ -207,7 +207,18 @@ static void aggr_free_lines(struct gpio_aggregator *aggr)
>
> list_for_each_entry_safe(line, tmp, &aggr->list_head, entry) {
> configfs_unregister_group(&line->group);
> - aggr_line_del(aggr, line);
> + /*
> + * Normally, we acquire aggr->lock within the configfs
> + * callback. However, in the legacy sysfs interface case,
> + * calling configfs_(un)register_group while holding
> + * aggr->lock could cause a deadlock. Fortunately, this is
> + * unnecessary because the new_device/delete_device path
> + * and the module unload path are mutually exclusive,
> + * thanks to an explicit try_module_get. That's why this
> + * minimal scoped_guard suffices here.
> + */
> + scoped_guard(mutex, &aggr->lock)
> + aggr_line_del(aggr, line);
> kfree(line->key);
> kfree(line);
> }
> @@ -926,8 +937,6 @@ static void gpio_aggr_device_release(struct config_item *item)
> {
> struct gpio_aggregator *aggr = to_gpio_aggregator(item);
>
> - guard(mutex)(&aggr->lock);
> -
> /*
> * At this point, aggr is neither active nor activating,
> * so calling aggr_deactivate() is always unnecessary.
> @@ -1072,7 +1081,8 @@ static int aggr_parse(struct gpio_aggregator *aggr)
> &line->group);
> if (error)
> goto err;
> - aggr_line_add(aggr, line);
> + scoped_guard(mutex, &aggr->lock)
> + aggr_line_add(aggr, line);
>
> error = aggr_add_gpio(aggr, key, U16_MAX, &n);
> if (error)
> @@ -1101,7 +1111,8 @@ static int aggr_parse(struct gpio_aggregator *aggr)
> &line->group);
> if (error)
> goto err;
> - aggr_line_add(aggr, line);
> + scoped_guard(mutex, &aggr->lock)
> + aggr_line_add(aggr, line);
>
> error = aggr_add_gpio(aggr, key, i, &n);
> if (error)
> @@ -1205,8 +1216,10 @@ static DRIVER_ATTR_WO(new_device);
>
> static void gpio_aggregator_free(struct gpio_aggregator *aggr)
> {
> - if (aggr_is_activating(aggr) || aggr_is_active(aggr))
> - aggr_deactivate(aggr);
> + scoped_guard(mutex, &aggr->lock) {
> + if (aggr_is_activating(aggr) || aggr_is_active(aggr))
> + aggr_deactivate(aggr);
> + }
> aggr_free_lines(aggr);
> configfs_unregister_group(&aggr->group);
> kfree(aggr);
> ------------8<--------------8<---------------
>
>
> * The second hunk should be squashed into
> [PATCH v5 4/9] gpio: aggregator: introduce basic configfs interface
>
> * The rest of the hunks should be squashed into
> [PATCH v5 8/9] gpio: aggregator: expose aggregator created via legacy sysfs to configfs
>
> If you agree with the above approach, I'll send out v6,
> while also addressing your feedback here:
> https://lore.kernel.org/all/CAMRc=MdoMKdqyzGMFDa3aMz3h=vfZ0OtwARxY7FdsPKcBu9HQA@mail.gmail.com/
>
> Koichiro
>
I won't be testing in-line diff chunks. Please, just fix these issues
and send a v6. Also: please do write some sort of a script to automate
the testing of this driver if possible. Ideally: add test script to
selftests.
Bart
On Mon, Mar 10, 2025 at 06:46:25PM GMT, Bartosz Golaszewski wrote:
> On Mon, Mar 10, 2025 at 5:28 PM Koichiro Den <koichiro.den@canonical.com> wrote:
> >
>
> [snip!]
>
> Please remove unnecessary context from responses. You attached
> hundreds of lines of stack traces here. :(
Right, this will never happen. Sorry for inconvenience.
>
> >
> > Thanks, I've confirmed it. It seems I overlooked it because somehow
> > lockdep and kasan were not enabled for a while.
> >
> > Assuming the v5 patch series rebased onto the latest gpio/for-next
> > 21c853ad9309 ("gpio: adnp: use new line value setter callbacks"),
> > the following follow-up patch should suffice.
> >
> > ------------8<--------------8<---------------
> > diff --git a/drivers/gpio/gpio-aggregator.c b/drivers/gpio/gpio-aggregator.c
> > index df34d8fcb79a..56f0fde8c843 100644
> > --- a/drivers/gpio/gpio-aggregator.c
> > +++ b/drivers/gpio/gpio-aggregator.c
> > @@ -207,7 +207,18 @@ static void aggr_free_lines(struct gpio_aggregator *aggr)
> >
> > list_for_each_entry_safe(line, tmp, &aggr->list_head, entry) {
> > configfs_unregister_group(&line->group);
> > - aggr_line_del(aggr, line);
> > + /*
> > + * Normally, we acquire aggr->lock within the configfs
> > + * callback. However, in the legacy sysfs interface case,
> > + * calling configfs_(un)register_group while holding
> > + * aggr->lock could cause a deadlock. Fortunately, this is
> > + * unnecessary because the new_device/delete_device path
> > + * and the module unload path are mutually exclusive,
> > + * thanks to an explicit try_module_get. That's why this
> > + * minimal scoped_guard suffices here.
> > + */
> > + scoped_guard(mutex, &aggr->lock)
> > + aggr_line_del(aggr, line);
> > kfree(line->key);
> > kfree(line);
> > }
> > @@ -926,8 +937,6 @@ static void gpio_aggr_device_release(struct config_item *item)
> > {
> > struct gpio_aggregator *aggr = to_gpio_aggregator(item);
> >
> > - guard(mutex)(&aggr->lock);
> > -
> > /*
> > * At this point, aggr is neither active nor activating,
> > * so calling aggr_deactivate() is always unnecessary.
> > @@ -1072,7 +1081,8 @@ static int aggr_parse(struct gpio_aggregator *aggr)
> > &line->group);
> > if (error)
> > goto err;
> > - aggr_line_add(aggr, line);
> > + scoped_guard(mutex, &aggr->lock)
> > + aggr_line_add(aggr, line);
> >
> > error = aggr_add_gpio(aggr, key, U16_MAX, &n);
> > if (error)
> > @@ -1101,7 +1111,8 @@ static int aggr_parse(struct gpio_aggregator *aggr)
> > &line->group);
> > if (error)
> > goto err;
> > - aggr_line_add(aggr, line);
> > + scoped_guard(mutex, &aggr->lock)
> > + aggr_line_add(aggr, line);
> >
> > error = aggr_add_gpio(aggr, key, i, &n);
> > if (error)
> > @@ -1205,8 +1216,10 @@ static DRIVER_ATTR_WO(new_device);
> >
> > static void gpio_aggregator_free(struct gpio_aggregator *aggr)
> > {
> > - if (aggr_is_activating(aggr) || aggr_is_active(aggr))
> > - aggr_deactivate(aggr);
> > + scoped_guard(mutex, &aggr->lock) {
> > + if (aggr_is_activating(aggr) || aggr_is_active(aggr))
> > + aggr_deactivate(aggr);
> > + }
> > aggr_free_lines(aggr);
> > configfs_unregister_group(&aggr->group);
> > kfree(aggr);
> > ------------8<--------------8<---------------
> >
> >
> > * The second hunk should be squashed into
> > [PATCH v5 4/9] gpio: aggregator: introduce basic configfs interface
> >
> > * The rest of the hunks should be squashed into
> > [PATCH v5 8/9] gpio: aggregator: expose aggregator created via legacy sysfs to configfs
> >
> > If you agree with the above approach, I'll send out v6,
> > while also addressing your feedback here:
> > https://lore.kernel.org/all/CAMRc=MdoMKdqyzGMFDa3aMz3h=vfZ0OtwARxY7FdsPKcBu9HQA@mail.gmail.com/
> >
> > Koichiro
> >
>
> I won't be testing in-line diff chunks. Please, just fix these issues
> and send a v6. Also: please do write some sort of a script to automate
> the testing of this driver if possible. Ideally: add test script to
> selftests.
Sorry for the delayed response, I've been so tied up with other tasks this
week. Ok, I'll introduce a kselftest for gpio-aggregator. Actually I've
wanted that from the beginning.. I believe it should rely on gpio-sim for
convenience, but please let me know if you don't think so.
Thanks.
>
> Bart
From: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
On Mon, 24 Feb 2025 23:31:25 +0900, Koichiro Den wrote:
> This patch series introduces a configfs-based interface to gpio-aggregator
> to address limitations in the existing 'new_device' interface.
>
> The existing 'new_device' interface has several limitations:
>
> Issue#1. No way to determine when GPIO aggregator creation is complete.
> Issue#2. No way to retrieve errors when creating a GPIO aggregator.
> Issue#3. No way to trace a GPIO line of an aggregator back to its
> corresponding physical device.
> Issue#4. The 'new_device' echo does not indicate which virtual
> gpiochip<N> was created.
> Issue#5. No way to assign names to GPIO lines exported through an
> aggregator.
>
> [...]
I don't see anything wrong with this patch so I queued it for fixes. I
will pull it back into my gpio/for-next branch once it's upstream and
apply the rest of the aggregator changes for v6.15.
[1/9] gpio: aggregator: protect driver attr handlers against module unload
commit: 12f65d1203507f7db3ba59930fe29a3b8eee9945
Best regards,
--
Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
© 2016 - 2025 Red Hat, Inc.