[2/3] maple_tree: use preallocations in mas_store_gfp()

Message ID 20231009201639.920512-3-sidhartha.kumar@oracle.com
State New
Headers
Series align maple tree write paths |

Commit Message

Sidhartha Kumar Oct. 9, 2023, 8:16 p.m. UTC
  Preallocate maple nodes before call to mas_wr_store_entry(). If a new
node is not needed, go directly to mas_wr_store_entry(), otherwise
allocate the needed nodes and set the MA_STATE_PREALLOC flag.

Signed-off-by: Sidhartha Kumar <sidhartha.kumar@oracle.com>
---
 lib/maple_tree.c | 22 +++++++++++++++++++---
 1 file changed, 19 insertions(+), 3 deletions(-)
  

Comments

Peng Zhang Oct. 10, 2023, 3:03 a.m. UTC | #1
Hi,

在 2023/10/10 04:16, Sidhartha Kumar 写道:
> Preallocate maple nodes before call to mas_wr_store_entry(). If a new
> node is not needed, go directly to mas_wr_store_entry(), otherwise
> allocate the needed nodes and set the MA_STATE_PREALLOC flag.
> 
> Signed-off-by: Sidhartha Kumar <sidhartha.kumar@oracle.com>
> ---
>   lib/maple_tree.c | 22 +++++++++++++++++++---
>   1 file changed, 19 insertions(+), 3 deletions(-)
> 
> diff --git a/lib/maple_tree.c b/lib/maple_tree.c
> index e239197a57fc..25ae66e585f4 100644
> --- a/lib/maple_tree.c
> +++ b/lib/maple_tree.c
> @@ -5478,17 +5478,33 @@ int mas_prealloc_calc(struct ma_wr_state *wr_mas)
>   int mas_store_gfp(struct ma_state *mas, void *entry, gfp_t gfp)
>   {
>   	MA_WR_STATE(wr_mas, mas, entry);
> +	int request;
>   
>   	mas_wr_store_setup(&wr_mas);
> -	trace_ma_write(__func__, mas, 0, entry);
> -retry:
> +	wr_mas.content = mas_start(mas);
> +
> +	request = mas_prealloc_calc(&wr_mas);
mas_wr_store_entry() does something similar to mas_prealloc_calc().
Now, making it do it twice would incur additional overhead.
We encountered this issue while optimizing preallocation, but it
hasn't been resolved yet. Previously, this problem only occurred
when using mas_preallocate(). Now, this change would bring this
impact to all write operations on maple tree. What do you think
about it?

Thanks,
Peng
> +	if (!request)
> +		goto store_entry;
> +
> +	mas_node_count_gfp(mas, request, gfp);
> +	if (unlikely(mas_is_err(mas))) {
> +		mas_set_alloc_req(mas, 0);
> +		mas_destroy(mas);
> +		mas_reset(mas);
> +		return xa_err(mas->node);
> +	}
> +	mas->mas_flags |= MA_STATE_PREALLOC;
> +
> +store_entry:
>   	mas_wr_store_entry(&wr_mas);
>   	if (unlikely(mas_nomem(mas, gfp)))
> -		goto retry;
> +		goto store_entry;
>   
>   	if (unlikely(mas_is_err(mas)))
>   		return xa_err(mas->node);
>   
> +	trace_ma_write(__func__, mas, 0, entry);
>   	return 0;
>   }
>   EXPORT_SYMBOL_GPL(mas_store_gfp);
  
Liam R. Howlett Oct. 10, 2023, 6:15 p.m. UTC | #2
* Sidhartha Kumar <sidhartha.kumar@oracle.com> [231009 16:16]:
> Preallocate maple nodes before call to mas_wr_store_entry(). If a new
> node is not needed, go directly to mas_wr_store_entry(), otherwise
> allocate the needed nodes and set the MA_STATE_PREALLOC flag.


The way I'd like to see this working is to preallocate nodes prior to
writing, but also to end in a state where we can call the store
operation to continue the operation.  Both of these parts need to be
together in a patch set if they cannot be in the same patch.

Thanks,
Liam

> 
> Signed-off-by: Sidhartha Kumar <sidhartha.kumar@oracle.com>
> ---
>  lib/maple_tree.c | 22 +++++++++++++++++++---
>  1 file changed, 19 insertions(+), 3 deletions(-)
> 
> diff --git a/lib/maple_tree.c b/lib/maple_tree.c
> index e239197a57fc..25ae66e585f4 100644
> --- a/lib/maple_tree.c
> +++ b/lib/maple_tree.c
> @@ -5478,17 +5478,33 @@ int mas_prealloc_calc(struct ma_wr_state *wr_mas)
>  int mas_store_gfp(struct ma_state *mas, void *entry, gfp_t gfp)
>  {
>  	MA_WR_STATE(wr_mas, mas, entry);
> +	int request;
>  
>  	mas_wr_store_setup(&wr_mas);
> -	trace_ma_write(__func__, mas, 0, entry);
> -retry:
> +	wr_mas.content = mas_start(mas);
> +
> +	request = mas_prealloc_calc(&wr_mas);
> +	if (!request)
> +		goto store_entry;
> +
> +	mas_node_count_gfp(mas, request, gfp);
> +	if (unlikely(mas_is_err(mas))) {
> +		mas_set_alloc_req(mas, 0);
> +		mas_destroy(mas);
> +		mas_reset(mas);
> +		return xa_err(mas->node);
> +	}
> +	mas->mas_flags |= MA_STATE_PREALLOC;
> +
> +store_entry:
>  	mas_wr_store_entry(&wr_mas);
>  	if (unlikely(mas_nomem(mas, gfp)))
> -		goto retry;
> +		goto store_entry;
>  
>  	if (unlikely(mas_is_err(mas)))
>  		return xa_err(mas->node);
>  
> +	trace_ma_write(__func__, mas, 0, entry);
>  	return 0;
>  }
>  EXPORT_SYMBOL_GPL(mas_store_gfp);
> -- 
> 2.41.0
>
  
Sidhartha Kumar Oct. 11, 2023, 12:17 a.m. UTC | #3
On 10/9/23 8:03 PM, Peng Zhang wrote:
> Hi,
> 
> 在 2023/10/10 04:16, Sidhartha Kumar 写道:
>> Preallocate maple nodes before call to mas_wr_store_entry(). If a new
>> node is not needed, go directly to mas_wr_store_entry(), otherwise
>> allocate the needed nodes and set the MA_STATE_PREALLOC flag.
>>
>> Signed-off-by: Sidhartha Kumar <sidhartha.kumar@oracle.com>
>> ---
>>   lib/maple_tree.c | 22 +++++++++++++++++++---
>>   1 file changed, 19 insertions(+), 3 deletions(-)
>>
>> diff --git a/lib/maple_tree.c b/lib/maple_tree.c
>> index e239197a57fc..25ae66e585f4 100644
>> --- a/lib/maple_tree.c
>> +++ b/lib/maple_tree.c
>> @@ -5478,17 +5478,33 @@ int mas_prealloc_calc(struct ma_wr_state *wr_mas)
>>   int mas_store_gfp(struct ma_state *mas, void *entry, gfp_t gfp)
>>   {
>>       MA_WR_STATE(wr_mas, mas, entry);
>> +    int request;
>>       mas_wr_store_setup(&wr_mas);
>> -    trace_ma_write(__func__, mas, 0, entry);
>> -retry:
>> +    wr_mas.content = mas_start(mas);
>> +
>> +    request = mas_prealloc_calc(&wr_mas);
> mas_wr_store_entry() does something similar to mas_prealloc_calc().
> Now, making it do it twice would incur additional overhead.
> We encountered this issue while optimizing preallocation, but it
> hasn't been resolved yet. Previously, this problem only occurred
> when using mas_preallocate(). Now, this change would bring this
> impact to all write operations on maple tree. What do you think
> about it?
> 

After talking to Liam, I will have to implement the store type enum 
feature on the Maple Tree Work list so that mas_prealloc_calc() can 
start a partial walk and write that information to the enum. 
mas_wr_store_entry() can then read that enum to continue the walk that 
was already started rather than having to redo the whole walk. This 
could also be used in mas_preallocate(). Do you have any suggestions for 
the implementation of this enum?

Thanks,
Sid

> Thanks,
> Peng
>> +    if (!request)
>> +        goto store_entry;
>> +
>> +    mas_node_count_gfp(mas, request, gfp);
>> +    if (unlikely(mas_is_err(mas))) {
>> +        mas_set_alloc_req(mas, 0);
>> +        mas_destroy(mas);
>> +        mas_reset(mas);
>> +        return xa_err(mas->node);
>> +    }
>> +    mas->mas_flags |= MA_STATE_PREALLOC;
>> +
>> +store_entry:
>>       mas_wr_store_entry(&wr_mas);
>>       if (unlikely(mas_nomem(mas, gfp)))
>> -        goto retry;
>> +        goto store_entry;
>>       if (unlikely(mas_is_err(mas)))
>>           return xa_err(mas->node);
>> +    trace_ma_write(__func__, mas, 0, entry);
>>       return 0;
>>   }
>>   EXPORT_SYMBOL_GPL(mas_store_gfp);
>
  
Peng Zhang Oct. 11, 2023, 7:40 a.m. UTC | #4
在 2023/10/11 08:17, Sidhartha Kumar 写道:
> On 10/9/23 8:03 PM, Peng Zhang wrote:
>> Hi,
>>
>> 在 2023/10/10 04:16, Sidhartha Kumar 写道:
>>> Preallocate maple nodes before call to mas_wr_store_entry(). If a new
>>> node is not needed, go directly to mas_wr_store_entry(), otherwise
>>> allocate the needed nodes and set the MA_STATE_PREALLOC flag.
>>>
>>> Signed-off-by: Sidhartha Kumar <sidhartha.kumar@oracle.com>
>>> ---
>>>   lib/maple_tree.c | 22 +++++++++++++++++++---
>>>   1 file changed, 19 insertions(+), 3 deletions(-)
>>>
>>> diff --git a/lib/maple_tree.c b/lib/maple_tree.c
>>> index e239197a57fc..25ae66e585f4 100644
>>> --- a/lib/maple_tree.c
>>> +++ b/lib/maple_tree.c
>>> @@ -5478,17 +5478,33 @@ int mas_prealloc_calc(struct ma_wr_state *wr_mas)
>>>   int mas_store_gfp(struct ma_state *mas, void *entry, gfp_t gfp)
>>>   {
>>>       MA_WR_STATE(wr_mas, mas, entry);
>>> +    int request;
>>>       mas_wr_store_setup(&wr_mas);
>>> -    trace_ma_write(__func__, mas, 0, entry);
>>> -retry:
>>> +    wr_mas.content = mas_start(mas);
>>> +
>>> +    request = mas_prealloc_calc(&wr_mas);
>> mas_wr_store_entry() does something similar to mas_prealloc_calc().
>> Now, making it do it twice would incur additional overhead.
>> We encountered this issue while optimizing preallocation, but it
>> hasn't been resolved yet. Previously, this problem only occurred
>> when using mas_preallocate(). Now, this change would bring this
>> impact to all write operations on maple tree. What do you think
>> about it?
>>
> 
> After talking to Liam, I will have to implement the store type enum feature on the Maple Tree Work list so that mas_prealloc_calc() can start a partial walk and write that information to the enum. mas_wr_store_entry() can then read that enum to continue the walk that was already started rather than having to redo the whole walk. This could also be used in mas_preallocate(). Do you have any suggestions for the implementation of this enum?
There is another scenario where this enum can be useful,
as seen in the implementation of mas_replace_entry() in [1].
It is a faster alternative to mas_store(), but it is not safe.
If we can determine through the enum while writing the maple
tree that a faster write operation can be performed, it would
be beneficial. Some performance improvements can also be
observed in [1].

[1] https://lore.kernel.org/lkml/49f0181a-55a4-41aa-8596-877560c8b802@bytedance.com/
> 
> Thanks,
> Sid
> 
>> Thanks,
>> Peng
>>> +    if (!request)
>>> +        goto store_entry;
>>> +
>>> +    mas_node_count_gfp(mas, request, gfp);
>>> +    if (unlikely(mas_is_err(mas))) {
>>> +        mas_set_alloc_req(mas, 0);
>>> +        mas_destroy(mas);
>>> +        mas_reset(mas);
>>> +        return xa_err(mas->node);
>>> +    }
>>> +    mas->mas_flags |= MA_STATE_PREALLOC;
>>> +
>>> +store_entry:
>>>       mas_wr_store_entry(&wr_mas);
>>>       if (unlikely(mas_nomem(mas, gfp)))
>>> -        goto retry;
>>> +        goto store_entry;
>>>       if (unlikely(mas_is_err(mas)))
>>>           return xa_err(mas->node);
>>> +    trace_ma_write(__func__, mas, 0, entry);
>>>       return 0;
>>>   }
>>>   EXPORT_SYMBOL_GPL(mas_store_gfp);
>>
> 
>
  
kernel test robot Oct. 25, 2023, 9:52 a.m. UTC | #5
Hello,

kernel test robot noticed "BUG:sleeping_function_called_from_invalid_context_at_include/linux/sched/mm.h" on:

commit: 9116baa49536116f013d691d2178c520959f46c2 ("[PATCH 2/3] maple_tree: use preallocations in mas_store_gfp()")
url: https://github.com/intel-lab-lkp/linux/commits/Sidhartha-Kumar/maple_tree-introduce-mas_prealloc_calc/20231010-041859
base: https://git.kernel.org/cgit/linux/kernel/git/akpm/mm.git mm-everything
patch link: https://lore.kernel.org/all/20231009201639.920512-3-sidhartha.kumar@oracle.com/
patch subject: [PATCH 2/3] maple_tree: use preallocations in mas_store_gfp()

in testcase: boot

compiler: gcc-11
test machine: qemu-system-x86_64 -enable-kvm -cpu SandyBridge -smp 2 -m 16G

(please refer to attached dmesg/kmsg for entire log/backtrace)


+------------------------------------------------------------------------------------+------------+------------+
|                                                                                    | 9cbebad6db | 9116baa495 |
+------------------------------------------------------------------------------------+------------+------------+
| BUG:sleeping_function_called_from_invalid_context_at_include/linux/sched/mm.h      | 0          | 7          |
| WARNING:suspicious_RCU_usage                                                       | 0          | 7          |
| include/linux/rcupdate.h:#Illegal_context_switch_in_RCU_read-side_critical_section | 0          | 7          |
+------------------------------------------------------------------------------------+------------+------------+


If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <oliver.sang@intel.com>
| Closes: https://lore.kernel.org/oe-lkp/202310251706.6e6f6c4a-oliver.sang@intel.com


[   12.322393][    T1] BUG: sleeping function called from invalid context at include/linux/sched/mm.h:306
[   12.324008][    T1] in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 1, name: swapper
[   12.325486][    T1] preempt_count: 1, expected: 0
[   12.326345][    T1] 1 lock held by swapper/1:
[ 12.327164][ T1] #0: c2b52570 (&mt->ma_lock){+.+.}-{2:2}, at: check_root_expand+0x46/0xac0 
[   12.328850][    T1] CPU: 0 PID: 1 Comm: swapper Tainted: G                T  6.6.0-rc4-00400-g9116baa49536 #1
[   12.329034][    T1] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.2-debian-1.16.2-1 04/01/2014
[   12.329034][    T1] Call Trace:
[ 12.329034][ T1] dump_stack_lvl (lib/dump_stack.c:107 (discriminator 1)) 
[ 12.329034][ T1] dump_stack (lib/dump_stack.c:114) 
[ 12.329034][ T1] __might_resched (kernel/sched/core.c:10188) 
[ 12.329034][ T1] __might_sleep (kernel/sched/core.c:10117 (discriminator 17)) 
[ 12.329034][ T1] kmem_cache_alloc (include/linux/sched/mm.h:306 mm/slab.h:705 mm/slub.c:3460 mm/slub.c:3486 mm/slub.c:3493 mm/slub.c:3502) 
[ 12.329034][ T1] ? mas_alloc_nodes (lib/maple_tree.c:160 lib/maple_tree.c:1265) 
[ 12.329034][ T1] mas_alloc_nodes (lib/maple_tree.c:160 lib/maple_tree.c:1265) 
[ 12.329034][ T1] mas_node_count_gfp (lib/maple_tree.c:1347) 
[ 12.329034][ T1] mas_store_gfp (lib/maple_tree.c:256 lib/maple_tree.c:5491) 
[ 12.329034][ T1] ? check_empty_area_fill+0x3d0/0x3d0 
[ 12.329034][ T1] check_root_expand+0x162/0xac0 
[ 12.329034][ T1] maple_tree_seed (lib/test_maple_tree.c:3577) 
[ 12.329034][ T1] ? check_gap_combining+0xdf8/0xdf8 
[ 12.329034][ T1] do_one_initcall (init/main.c:1232) 
[ 12.329034][ T1] do_initcalls (init/main.c:1293 init/main.c:1310) 
[ 12.329034][ T1] kernel_init_freeable (init/main.c:1551) 
[ 12.329034][ T1] ? rest_init (init/main.c:1429) 
[ 12.329034][ T1] kernel_init (init/main.c:1439) 
[ 12.329034][ T1] ret_from_fork (arch/x86/kernel/process.c:153) 
[ 12.329034][ T1] ? rest_init (init/main.c:1429) 
[ 12.329034][ T1] ret_from_fork_asm (arch/x86/entry/entry_32.S:741) 
[ 12.329034][ T1] entry_INT80_32 (arch/x86/entry/entry_32.S:944) 
[   12.353802][    T1]
[   12.354345][    T1] =============================
[   12.355188][    T1] WARNING: suspicious RCU usage
[   12.356056][    T1] 6.6.0-rc4-00400-g9116baa49536 #1 Tainted: G        W       T
[   12.357413][    T1] -----------------------------
[   12.358272][    T1] include/linux/rcupdate.h:375 Illegal context switch in RCU read-side critical section!
[   12.359905][    T1]
[   12.359905][    T1] other info that might help us debug this:
[   12.359905][    T1]
[   12.361711][    T1]
[   12.361711][    T1] rcu_scheduler_active = 2, debug_locks = 1
[   12.363058][    T1] 2 locks held by swapper/1:
[ 12.363877][ T1] #0: c2ad5938 (rcu_read_lock){....}-{1:2}, at: check_mas_store_gfp+0xa9/0x1b0 
[ 12.365646][ T1] #1: c3965e84 (&mt->ma_lock){+.+.}-{2:2}, at: check_mas_store_gfp+0x104/0x1b0 
[   12.367338][    T1]
[   12.367338][    T1] stack backtrace:
[   12.368430][    T1] CPU: 0 PID: 1 Comm: swapper Tainted: G        W       T  6.6.0-rc4-00400-g9116baa49536 #1
[   12.369129][    T1] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.2-debian-1.16.2-1 04/01/2014
[   12.369129][    T1] Call Trace:
[ 12.369129][ T1] dump_stack_lvl (lib/dump_stack.c:107 (discriminator 1)) 
[ 12.369129][ T1] dump_stack (lib/dump_stack.c:114) 
[ 12.369129][ T1] lockdep_rcu_suspicious (kernel/locking/lockdep.c:6713) 
[ 12.369129][ T1] __might_resched (include/linux/rcupdate.h:375 kernel/sched/core.c:10149) 
[ 12.369129][ T1] __might_sleep (kernel/sched/core.c:10117 (discriminator 17)) 
[ 12.369129][ T1] kmem_cache_alloc (include/linux/sched/mm.h:306 mm/slab.h:705 mm/slub.c:3460 mm/slub.c:3486 mm/slub.c:3493 mm/slub.c:3502) 
[ 12.369129][ T1] ? mas_alloc_nodes (lib/maple_tree.c:160 lib/maple_tree.c:1265) 
[ 12.369129][ T1] mas_alloc_nodes (lib/maple_tree.c:160 lib/maple_tree.c:1265) 
[ 12.369129][ T1] mas_node_count_gfp (lib/maple_tree.c:1347) 
[ 12.369129][ T1] mas_store_gfp (lib/maple_tree.c:256 lib/maple_tree.c:5491) 
[ 12.369129][ T1] check_mas_store_gfp+0x14b/0x1b0 
[ 12.369129][ T1] maple_tree_seed (lib/test_maple_tree.c:3646) 
[ 12.369129][ T1] ? check_gap_combining+0xdf8/0xdf8 
[ 12.369129][ T1] do_one_initcall (init/main.c:1232) 
[ 12.369129][ T1] do_initcalls (init/main.c:1293 init/main.c:1310) 
[ 12.369129][ T1] kernel_init_freeable (init/main.c:1551) 
[ 12.369129][ T1] ? rest_init (init/main.c:1429) 
[ 12.369129][ T1] kernel_init (init/main.c:1439) 
[ 12.369129][ T1] ret_from_fork (arch/x86/kernel/process.c:153) 
[ 12.369129][ T1] ? rest_init (init/main.c:1429) 
[ 12.369129][ T1] ret_from_fork_asm (arch/x86/entry/entry_32.S:741) 
[ 12.369129][ T1] entry_INT80_32 (arch/x86/entry/entry_32.S:944) 
[   15.220029][   T34] torture_spin_lock_write_delay: delay = 25 jiffies.
[   16.033920][   T35] torture_spin_lock_write_delay: delay = 25 jiffies.
[   17.655206][   T35] torture_spin_lock_write_delay: delay = 25 jiffies.
[   19.245918][   T35] torture_spin_lock_write_delay: delay = 25 jiffies.
[   36.522020][   T34] torture_spin_lock_write_delay: delay = 25 jiffies.
[   37.994914][   T34] torture_spin_lock_write_delay: delay = 25 jiffies.
[   38.766533][   T35] torture_spin_lock_write_delay: delay = 25 jiffies.
[   41.775652][   T34] torture_spin_lock_write_delay: delay = 25 jiffies.
[   43.236341][   T35] torture_spin_lock_write_delay: delay = 24 jiffies.
[   44.106914][   T34] torture_spin_lock_write_delay: delay = 25 jiffies.
[   46.776934][   T34] torture_spin_lock_write_delay: delay = 25 jiffies.
[   47.165604][   T35] torture_spin_lock_write_delay: delay = 25 jiffies.
[   49.209209][   T34] torture_spin_lock_write_delay: delay = 25 jiffies.
[   50.316931][   T35] torture_spin_lock_write_delay: delay = 25 jiffies.
[   51.511048][   T34] torture_spin_lock_write_delay: delay = 25 jiffies.
[   54.564928][   T35] torture_spin_lock_write_delay: delay = 25 jiffies.
[   59.372367][    T1] BUG: sleeping function called from invalid context at include/linux/sched/mm.h:306
[   59.374045][    T1] in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 1, name: swapper
[   59.375483][    T1] preempt_count: 1, expected: 0
[   59.376310][    T1] 1 lock held by swapper/1:
[ 59.377090][ T1] #0: c2b52570 (&mt->ma_lock){+.+.}-{2:2}, at: check_empty_area_fill+0xe5/0x3d0 
[   59.378744][    T1] CPU: 0 PID: 1 Comm: swapper Tainted: G        W       T  6.6.0-rc4-00400-g9116baa49536 #1
[   59.380409][    T1] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.2-debian-1.16.2-1 04/01/2014
[   59.381080][    T1] Call Trace:
[ 59.381080][ T1] dump_stack_lvl (lib/dump_stack.c:107 (discriminator 1)) 
[ 59.381080][ T1] dump_stack (lib/dump_stack.c:114) 
[ 59.381080][ T1] __might_resched (kernel/sched/core.c:10188) 
[ 59.381080][ T1] __might_sleep (kernel/sched/core.c:10117 (discriminator 17)) 
[ 59.381080][ T1] kmem_cache_alloc (include/linux/sched/mm.h:306 mm/slab.h:705 mm/slub.c:3460 mm/slub.c:3486 mm/slub.c:3493 mm/slub.c:3502) 
[ 59.381080][ T1] ? mas_alloc_nodes (lib/maple_tree.c:160 lib/maple_tree.c:1265) 
[ 59.381080][ T1] mas_alloc_nodes (lib/maple_tree.c:160 lib/maple_tree.c:1265) 
[ 59.381080][ T1] mas_node_count_gfp (lib/maple_tree.c:1347) 
[ 59.381080][ T1] mas_store_gfp (lib/maple_tree.c:256 lib/maple_tree.c:5491) 
[ 59.381080][ T1] check_empty_area_fill+0xab/0x3d0 
[ 59.381080][ T1] maple_tree_seed (lib/test_maple_tree.c:3837) 
[ 59.381080][ T1] ? check_gap_combining+0xdf8/0xdf8 
[ 59.381080][ T1] do_one_initcall (init/main.c:1232) 
[ 59.381080][ T1] do_initcalls (init/main.c:1293 init/main.c:1310) 
[ 59.381080][ T1] kernel_init_freeable (init/main.c:1551) 
[ 59.381080][ T1] ? rest_init (init/main.c:1429) 
[ 59.381080][ T1] kernel_init (init/main.c:1439) 
[ 59.381080][ T1] ret_from_fork (arch/x86/kernel/process.c:153) 
[ 59.381080][ T1] ? rest_init (init/main.c:1429) 
[ 59.381080][ T1] ret_from_fork_asm (arch/x86/entry/entry_32.S:741) 
[ 59.381080][ T1] entry_INT80_32 (arch/x86/entry/entry_32.S:944) 
[   59.571154][    T1] maple_tree: 3807933 of 3807933 tests passed
[   59.572831][    T1] test_memcat_p: test passed
[   59.590510][    T1] test_meminit: all 11 tests in test_pages passed
[   59.621976][    T1] test_meminit: all 40 tests in test_kvmalloc passed
[   60.207905][    T1] test_meminit: all 70 tests in test_kmemcache passed
[   60.217750][    T1] test_meminit: all 10 tests in test_rcu_persistent passed
[   60.219088][    T1] test_meminit: all 131 tests passed!
[   60.220126][    T1] ref_tracker: reference already released.
[   60.220912][    T1] ref_tracker: allocated in:



The kernel config and materials to reproduce are available at:
https://download.01.org/0day-ci/archive/20231025/202310251706.6e6f6c4a-oliver.sang@intel.com
  
Liam R. Howlett Oct. 26, 2023, 5:16 p.m. UTC | #6
... Dropping direct Cc's in attempt to avoid even more noise.

* kernel test robot <oliver.sang@intel.com> [231025 05:52]:
> 
> 
> Hello,
> 
> kernel test robot noticed "BUG:sleeping_function_called_from_invalid_context_at_include/linux/sched/mm.h" on:
...

This patch set is being revised and discussed on how to make it a more
complete solution.

In the mean time, is there any way to stop the bot from emailing
everyone and burning more power?

Thank you,
Liam
  

Patch

diff --git a/lib/maple_tree.c b/lib/maple_tree.c
index e239197a57fc..25ae66e585f4 100644
--- a/lib/maple_tree.c
+++ b/lib/maple_tree.c
@@ -5478,17 +5478,33 @@  int mas_prealloc_calc(struct ma_wr_state *wr_mas)
 int mas_store_gfp(struct ma_state *mas, void *entry, gfp_t gfp)
 {
 	MA_WR_STATE(wr_mas, mas, entry);
+	int request;
 
 	mas_wr_store_setup(&wr_mas);
-	trace_ma_write(__func__, mas, 0, entry);
-retry:
+	wr_mas.content = mas_start(mas);
+
+	request = mas_prealloc_calc(&wr_mas);
+	if (!request)
+		goto store_entry;
+
+	mas_node_count_gfp(mas, request, gfp);
+	if (unlikely(mas_is_err(mas))) {
+		mas_set_alloc_req(mas, 0);
+		mas_destroy(mas);
+		mas_reset(mas);
+		return xa_err(mas->node);
+	}
+	mas->mas_flags |= MA_STATE_PREALLOC;
+
+store_entry:
 	mas_wr_store_entry(&wr_mas);
 	if (unlikely(mas_nomem(mas, gfp)))
-		goto retry;
+		goto store_entry;
 
 	if (unlikely(mas_is_err(mas)))
 		return xa_err(mas->node);
 
+	trace_ma_write(__func__, mas, 0, entry);
 	return 0;
 }
 EXPORT_SYMBOL_GPL(mas_store_gfp);