[rh7] sched: Fallback to 0-order allocations in sched_create_group()

Submitted by Andrey Ryabinin on Dec. 29, 2017, 11:44 a.m.

Details

Message ID 20171229114423.18486-1-aryabinin@virtuozzo.com
State New
Series "sched: Fallback to 0-order allocations in sched_create_group()"
Headers show

Commit Message

Andrey Ryabinin Dec. 29, 2017, 11:44 a.m.
On large machines ->cpustat_last/->vcpustat arrays are large
causing possibly failing high-order allocation:

       fio: page allocation failure: order:4, mode:0xc0d0

       Call Trace:
         dump_stack+0x19/0x1b
         warn_alloc_failed+0x110/0x180
          __alloc_pages_nodemask+0x7bf/0xc60
         alloc_pages_current+0x98/0x110
         kmalloc_order+0x18/0x40
         kmalloc_order_trace+0x26/0xa0
         __kmalloc+0x279/0x290
         sched_create_group+0xba/0x150
         sched_autogroup_create_attach+0x3f/0x1a0
         sys_setsid+0x73/0xc0
         system_call_fastpath+0x16/0x1b

Use kvzalloc to fallback to vmalloc() and avoid failure if
high order page is not available.

https://jira.sw.ru/browse/PSBM-79891
Fixes: 85fd6b2ff490 ("sched: Port cpustat related patches")
Signed-off-by: Andrey Ryabinin <aryabinin@virtuozzo.com>
---
 kernel/sched/core.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

Patch hide | download patch | download mbox

diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 75ef029b1595..6979f7d8ead7 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -8761,8 +8761,8 @@  static void free_sched_group(struct task_group *tg)
 	free_rt_sched_group(tg);
 	autogroup_free(tg);
 	free_percpu(tg->taskstats);
-	kfree(tg->cpustat_last);
-	kfree(tg->vcpustat);
+	kvfree(tg->cpustat_last);
+	kvfree(tg->vcpustat);
 	kfree(tg);
 }
 
@@ -8785,12 +8785,12 @@  struct task_group *sched_create_group(struct task_group *parent)
 	if (!tg->taskstats)
 		goto err;
 
-	tg->cpustat_last = kcalloc(nr_cpu_ids, sizeof(struct kernel_cpustat),
+	tg->cpustat_last = kvzalloc(nr_cpu_ids * sizeof(struct kernel_cpustat),
 				   GFP_KERNEL);
 	if (!tg->cpustat_last)
 		goto err;
 
-	tg->vcpustat = kcalloc(nr_cpu_ids, sizeof(struct kernel_cpustat),
+	tg->vcpustat = kvzalloc(nr_cpu_ids * sizeof(struct kernel_cpustat),
 			       GFP_KERNEL);
 	if (!tg->vcpustat)
 		goto err;

Comments

Kirill Tkhai Dec. 29, 2017, 12:06 p.m.
On 29.12.2017 14:44, Andrey Ryabinin wrote:
> On large machines ->cpustat_last/->vcpustat arrays are large
> causing possibly failing high-order allocation:
> 
>        fio: page allocation failure: order:4, mode:0xc0d0
> 
>        Call Trace:
>          dump_stack+0x19/0x1b
>          warn_alloc_failed+0x110/0x180
>           __alloc_pages_nodemask+0x7bf/0xc60
>          alloc_pages_current+0x98/0x110
>          kmalloc_order+0x18/0x40
>          kmalloc_order_trace+0x26/0xa0
>          __kmalloc+0x279/0x290
>          sched_create_group+0xba/0x150
>          sched_autogroup_create_attach+0x3f/0x1a0
>          sys_setsid+0x73/0xc0
>          system_call_fastpath+0x16/0x1b
> 
> Use kvzalloc to fallback to vmalloc() and avoid failure if
> high order page is not available.
> 
> https://jira.sw.ru/browse/PSBM-79891
> Fixes: 85fd6b2ff490 ("sched: Port cpustat related patches")
> Signed-off-by: Andrey Ryabinin <aryabinin@virtuozzo.com>

Acked-by: Kirill Tkhai <ktkhai@virtuozzo.com>

> ---
>  kernel/sched/core.c | 8 ++++----
>  1 file changed, 4 insertions(+), 4 deletions(-)
> 
> diff --git a/kernel/sched/core.c b/kernel/sched/core.c
> index 75ef029b1595..6979f7d8ead7 100644
> --- a/kernel/sched/core.c
> +++ b/kernel/sched/core.c
> @@ -8761,8 +8761,8 @@ static void free_sched_group(struct task_group *tg)
>  	free_rt_sched_group(tg);
>  	autogroup_free(tg);
>  	free_percpu(tg->taskstats);
> -	kfree(tg->cpustat_last);
> -	kfree(tg->vcpustat);
> +	kvfree(tg->cpustat_last);
> +	kvfree(tg->vcpustat);
>  	kfree(tg);
>  }
>  
> @@ -8785,12 +8785,12 @@ struct task_group *sched_create_group(struct task_group *parent)
>  	if (!tg->taskstats)
>  		goto err;
>  
> -	tg->cpustat_last = kcalloc(nr_cpu_ids, sizeof(struct kernel_cpustat),
> +	tg->cpustat_last = kvzalloc(nr_cpu_ids * sizeof(struct kernel_cpustat),
>  				   GFP_KERNEL);
>  	if (!tg->cpustat_last)
>  		goto err;
>  
> -	tg->vcpustat = kcalloc(nr_cpu_ids, sizeof(struct kernel_cpustat),
> +	tg->vcpustat = kvzalloc(nr_cpu_ids * sizeof(struct kernel_cpustat),
>  			       GFP_KERNEL);
>  	if (!tg->vcpustat)
>  		goto err;
>