On 17/12/2025 15:42, Charles Keepax wrote:
> On Wed, Dec 17, 2025 at 03:13:45PM +0200, Péter Ujfalusi wrote:
>> On 17/12/2025 14:47, Charles Keepax wrote:
>>> On Wed, Dec 17, 2025 at 02:06:23PM +0200, Peter Ujfalusi wrote:
>>>> sound/soc/soc-ops.c | 2 +-
>>>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>>>
>>>> diff --git a/sound/soc/soc-ops.c b/sound/soc/soc-ops.c
>>>> index ce86978c158d..6a18c56a9746 100644
>>>> --- a/sound/soc/soc-ops.c
>>>> +++ b/sound/soc/soc-ops.c
>>>> @@ -148,7 +148,7 @@ static int soc_mixer_reg_to_ctl(struct soc_mixer_control *mc, unsigned int reg_v
>>>> if (mc->sign_bit)
>>>> val = sign_extend32(val, mc->sign_bit);
>>>>
>>>> - val = clamp(val, mc->min, mc->max);
>>>> + val = clamp(val, mc->min, mc->min + max);
>>>
>>> This won't work, for an SX control it is perfectly valid for
>>> the value read from the register to be smaller than the minimum
>>> value specified in the control.
>>
>> Hrm, so an SX control returns sort of rand() and the value have no
>> correlation to min or max?
>
> lol, yes exactly :-) arn't they great
>
>> The value can wrap at any random value to 0 and continue from 0 up to
>> some value, which is the max?
>
> Mostly correct, not any random value it wraps at the mask.
>
>> How this is in practice for the cs42l43' Headphone Digital Volume?
>> SOC_DOUBLE_SX_TLV("Headphone Digital Volume", CS42L43_HPPATHVOL,
>> CS42L43_AMP3_PATH_VOL_SHIFT, CS42L43_AMP4_PATH_VOL_SHIFT,
>> 0x11B, 229, cs42l43_headphone_tlv),
>>
>> min=283
>> max=229
>> shifts: 0 and 16
>> masks are 0x1ff
>>
>> if you step 229 from 283 then you reach 0x1ff, this is the max the mask
>> can cover.
>
> Not quite your maths is off by one, 229 + 283 = 512 = 0x200,
> which is then &ed with the mask to get 0x0. Which on the cs42l43
> headphones a value of 0x0->0dB. Stepping 1 back from that would
> give you 0x1FF->-0.5dB.
>
>>> I often think of it in terms of a 2's compliement number
>>> with an implicit sign bit.
>>
>> I see, but why???
>
> Mostly because hardware people love to wind me up, I assume. But
> more seriously, imagine an 4-bit signed number volume control
> with 5 values:
>
> 0xE -> -2 -> -2dB
> 0xF -> -1 -> -1dB
> 0x0 -> 0 -> 0dB
> 0x1 -> 1 -> 1dB
> 0x2 -> 2 -> 2dB
>
> Super, a very sensible control, but wait being a good hardware
> engineer you realise you don't need 4 bits to represent 5 values
> you can get away with 3 bits for that and save like 2 gates
> resulting in an ice cream and a plaque from your manager. So
> you drop the sign bit giving you:
>
> 0x6 -> -2dB
> 0x7 -> -1dB
> 0x0 -> 0dB
> 0x1 -> 1dB
> 0x2 -> 2dB
I must say, wow.
Being a SW guy I would probably done this differently:
0x0 -> -2dB
0x1 -> -1dB
0x2 -> 0dB
0x3 -> 1dB
0x4 -> 2dB
> This then results in an SX control with a minimum of 0x6 and a
> mask of 0x7.
then the comment at info() is hard to match still.
static const DECLARE_TLV_DB_RANGE(sx_thing,
6, 7, TLV_DB_SCALE_ITEM(-2000, -1000, 0),
0, 2, TLV_DB_SCALE_ITEM(0, 1000, 0)
};
is sort of the same, no?
Thanks for the explanation, fascinating!
--
Péter
On Wed, Dec 17, 2025 at 04:19:31PM +0200, Péter Ujfalusi wrote:
> On 17/12/2025 16:00, Mark Brown wrote:
> > What did you actually run there? Did you somehow have an existing
> > .config that it was picking up with everything turned off?
> git clean -xdf
> make mrproper
> ./tools/testing/kunit/kunit.py run --alltests
Interesting, that works happily for me. You might try running in qemu
by specifying --arch I guess, but generally I'd report that to the kunit
people.
On Wed, Dec 17, 2025 at 03:59:02PM +0200, Péter Ujfalusi wrote:
> On 17/12/2025 15:56, Mark Brown wrote:
> > What do you mean by "kunit test setup" - that's just a self contained
> > Python script that drives everything, it has minimal Python
> > requirements.
> I'm holding it wrong I'm sure:
> [15:35:21] Configuring KUnit Kernel ...
> [15:35:21] Building KUnit Kernel ...
> Populating config with:
> $ make ARCH=um O=.kunit olddefconfig
What did you actually run there? Did you somehow have an existing
.config that it was picking up with everything turned off?
> On 17 Dec 2025, at 10:10, Alice Ryhl <aliceryhl(a)google.com> wrote:
>
> When running the Rust maple tree kunit tests with lockdep, you may
> trigger a warning that looks like this:
>
> lib/maple_tree.c:780 suspicious rcu_dereference_check() usage!
>
> other info that might help us debug this:
>
> rcu_scheduler_active = 2, debug_locks = 1
> no locks held by kunit_try_catch/344.
>
> stack backtrace:
> CPU: 3 UID: 0 PID: 344 Comm: kunit_try_catch Tainted: G N 6.19.0-rc1+ #2 NONE
> Tainted: [N]=TEST
> Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS rel-1.17.0-0-gb52ca86e094d-prebuilt.qemu.org 04/01/2014
> Call Trace:
> <TASK>
> dump_stack_lvl+0x71/0x90
> lockdep_rcu_suspicious+0x150/0x190
> mas_start+0x104/0x150
> mas_find+0x179/0x240
> _RINvNtCs5QSdWC790r4_4core3ptr13drop_in_placeINtNtCs1cdwasc6FUb_6kernel10maple_tree9MapleTreeINtNtNtBL_5alloc4kbox3BoxlNtNtB1x_9allocator7KmallocEEECsgxAQYCfdR72_25doctests_kernel_generated+0xaf/0x130
> rust_doctest_kernel_maple_tree_rs_0+0x600/0x6b0
> ? lock_release+0xeb/0x2a0
> ? kunit_try_catch_run+0x210/0x210
> kunit_try_run_case+0x74/0x160
> ? kunit_try_catch_run+0x210/0x210
> kunit_generic_run_threadfn_adapter+0x12/0x30
> kthread+0x21c/0x230
> ? __do_trace_sched_kthread_stop_ret+0x40/0x40
> ret_from_fork+0x16c/0x270
> ? __do_trace_sched_kthread_stop_ret+0x40/0x40
> ret_from_fork_asm+0x11/0x20
> </TASK>
>
> This is because the destructor of maple tree calls mas_find() without
> taking rcu_read_lock() or the spinlock. Doing that is actually ok in
> this case since the destructor has exclusive access to the entire maple
> tree, but it triggers a lockdep warning. To fix that, take the rcu read
> lock.
>
> In the future, it's possible that memory reclaim could gain a feature
> where it reallocates entries in maple trees even if no user-code is
> touching it. If that feature is added, then this use of rcu read lock
> would become load-bearing, so I did not make it conditional on lockdep.
>
> We have to repeatedly take and release rcu because the destructor of T
> might perform operations that sleep.
>
> Reported-by: Andreas Hindborg <a.hindborg(a)kernel.org>
> Closes: https://rust-for-linux.zulipchat.com/#narrow/channel/x/topic/x/near/5642151…
> Fixes: da939ef4c494 ("rust: maple_tree: add MapleTree")
> Cc: stable(a)vger.kernel.org
> Signed-off-by: Alice Ryhl <aliceryhl(a)google.com>
> ---
> Intended for the same tree as any other maple tree patch. (I believe
> that's Andrew Morton's tree.)
> ---
> rust/kernel/maple_tree.rs | 11 ++++++++++-
> 1 file changed, 10 insertions(+), 1 deletion(-)
>
> diff --git a/rust/kernel/maple_tree.rs b/rust/kernel/maple_tree.rs
> index e72eec56bf5772ada09239f47748cd649212d8b0..265d6396a78a17886c8b5a3ebe7ba39ccc354add 100644
> --- a/rust/kernel/maple_tree.rs
> +++ b/rust/kernel/maple_tree.rs
> @@ -265,7 +265,16 @@ unsafe fn free_all_entries(self: Pin<&mut Self>) {
> loop {
> // This uses the raw accessor because we're destroying pointers without removing them
> // from the maple tree, which is only valid because this is the destructor.
> - let ptr = ma_state.mas_find_raw(usize::MAX);
> + //
> + // Take the rcu lock because mas_find_raw() requires that you hold either the spinlock
> + // or the rcu read lock. This is only really required if memory reclaim might
> + // reallocate entries in the tree, as we otherwise have exclusive access. That feature
> + // doesn't exist yet, so for now, taking the rcu lock only serves the purpose of
> + // silencing lockdep.
> + let ptr = {
> + let _rcu = kernel::sync::rcu::Guard::new();
> + ma_state.mas_find_raw(usize::MAX)
> + };
> if ptr.is_null() {
> break;
> }
>
> ---
> base-commit: 8f0b4cce4481fb22653697cced8d0d04027cb1e8
> change-id: 20251217-maple-drop-rcu-dfe72fb5f49e
>
> Best regards,
> --
> Alice Ryhl <aliceryhl(a)google.com>
>
>
Reviewed-by: Daniel Almeida <daniel.almeida(a)collabora.com>
From: Li Nan <linan122(a)huawei.com>
commit 9c47127a807da3e36ce80f7c83a1134a291fc021 upstream.
Raid checks if pad3 is zero when loading superblock from disk. Arrays
created with new features may fail to assemble on old kernels as pad3
is used.
Add module parameter check_new_feature to bypass this check.
Link: https://lore.kernel.org/linux-raid/20251103125757.1405796-5-linan666@huawei…
Signed-off-by: Li Nan <linan122(a)huawei.com>
Reviewed-by: Xiao Ni <xni(a)redhat.com>
Signed-off-by: Yu Kuai <yukuai(a)fnnas.com>
---
drivers/md/md.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 4e033c26fdd4..9d9cb7e1e6e8 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -340,6 +340,7 @@ static int start_readonly;
*/
static bool create_on_open = true;
static bool legacy_async_del_gendisk = true;
+static bool check_new_feature = true;
/*
* We have a system wide 'event count' that is incremented
@@ -1752,9 +1753,13 @@ static int super_1_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor_
}
if (sb->pad0 ||
sb->pad3[0] ||
- memcmp(sb->pad3, sb->pad3+1, sizeof(sb->pad3) - sizeof(sb->pad3[1])))
- /* Some padding is non-zero, might be a new feature */
- return -EINVAL;
+ memcmp(sb->pad3, sb->pad3+1, sizeof(sb->pad3) - sizeof(sb->pad3[1]))) {
+ pr_warn("Some padding is non-zero on %pg, might be a new feature\n",
+ rdev->bdev);
+ if (check_new_feature)
+ return -EINVAL;
+ pr_warn("check_new_feature is disabled, data corruption possible\n");
+ }
rdev->preferred_minor = 0xffff;
rdev->data_offset = le64_to_cpu(sb->data_offset);
@@ -10459,6 +10464,7 @@ module_param(start_dirty_degraded, int, S_IRUGO|S_IWUSR);
module_param_call(new_array, add_named_array, NULL, NULL, S_IWUSR);
module_param(create_on_open, bool, S_IRUSR|S_IWUSR);
module_param(legacy_async_del_gendisk, bool, 0600);
+module_param(check_new_feature, bool, 0600);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("MD RAID framework");
--
2.39.2
On 17/12/2025 15:56, Mark Brown wrote:
> On Wed, Dec 17, 2025 at 03:54:43PM +0200, Péter Ujfalusi wrote:
>
>>> rf@debianbox:~/work/kernel/linux$ time ./tools/testing/kunit/kunit.py
>>> run --alltests
>
>> well, I don't have kunit test setup, so it fails, but I can build the
>
> What do you mean by "kunit test setup" - that's just a self contained
> Python script that drives everything, it has minimal Python
> requirements.
I'm holding it wrong I'm sure:
[15:35:21] Configuring KUnit Kernel ...
[15:35:21] Building KUnit Kernel ...
Populating config with:
$ make ARCH=um O=.kunit olddefconfig
Building with:
$ make all compile_commands.json scripts_gdb ARCH=um O=.kunit --jobs=14
[15:35:30] Starting KUnit Kernel (1/1)...
[15:35:30] ============================================================
Running tests with:
$ .kunit/linux kunit.enable=1 mem=1G console=tty kunit_shutdown=halt
[15:35:30] [ERROR] Test: <missing>: Could not find any KTAP output. Did any KUnit tests run?
[15:35:30] ============================================================
[15:35:30] Testing complete. Ran 0 tests: errors: 1
[15:35:30] Elapsed time: 9.328s total, 0.001s configuring, 9.321s building, 0.006s running
--
Péter