Skip to content

Commit 917d929

Browse files
pdxChentorvalds
authored andcommitted
mm: tune vm_committed_as percpu_counter batching size
Currently the per cpu counter's batch size for memory accounting is configured as twice the number of cpus in the system. However, for system with very large memory, it is more appropriate to make it proportional to the memory size per cpu in the system. For example, for a x86_64 system with 64 cpus and 128 GB of memory, the batch size is only 2*64 pages (0.5 MB). So any memory accounting changes of more than 0.5MB will overflow the per cpu counter into the global counter. Instead, for the new scheme, the batch size is configured to be 0.4% of the memory/cpu = 8MB (128 GB/64 /256), which is more inline with the memory size. I've done a repeated brk test of 800KB (from will-it-scale test suite) with 80 concurrent processes on a 4 socket Westmere machine with a total of 40 cores. Without the patch, about 80% of cpu is spent on spin-lock contention within the vm_committed_as counter. With the patch, there's a 73x speedup on the benchmark and the lock contention drops off almost entirely. [[email protected]: fix section mismatch] Signed-off-by: Tim Chen <[email protected]> Cc: Tejun Heo <[email protected]> Cc: Eric Dumazet <[email protected]> Cc: Dave Hansen <[email protected]> Cc: Andi Kleen <[email protected]> Cc: Wu Fengguang <[email protected]> Signed-off-by: Andrew Morton <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent 2415cf1 commit 917d929

File tree

2 files changed

+54
-1
lines changed

2 files changed

+54
-1
lines changed

include/linux/mman.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,17 @@ extern int sysctl_overcommit_memory;
1111
extern int sysctl_overcommit_ratio;
1212
extern struct percpu_counter vm_committed_as;
1313

14+
#ifdef CONFIG_SMP
15+
extern s32 vm_committed_as_batch;
16+
#else
17+
#define vm_committed_as_batch 0
18+
#endif
19+
1420
unsigned long vm_memory_committed(void);
1521

1622
static inline void vm_acct_memory(long pages)
1723
{
18-
percpu_counter_add(&vm_committed_as, pages);
24+
__percpu_counter_add(&vm_committed_as, pages, vm_committed_as_batch);
1925
}
2026

2127
static inline void vm_unacct_memory(long pages)

mm/mm_init.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
#include <linux/init.h>
1010
#include <linux/kobject.h>
1111
#include <linux/export.h>
12+
#include <linux/memory.h>
13+
#include <linux/notifier.h>
1214
#include "internal.h"
1315

1416
#ifdef CONFIG_DEBUG_MEMORY_INIT
@@ -147,6 +149,51 @@ early_param("mminit_loglevel", set_mminit_loglevel);
147149
struct kobject *mm_kobj;
148150
EXPORT_SYMBOL_GPL(mm_kobj);
149151

152+
#ifdef CONFIG_SMP
153+
s32 vm_committed_as_batch = 32;
154+
155+
static void __meminit mm_compute_batch(void)
156+
{
157+
u64 memsized_batch;
158+
s32 nr = num_present_cpus();
159+
s32 batch = max_t(s32, nr*2, 32);
160+
161+
/* batch size set to 0.4% of (total memory/#cpus), or max int32 */
162+
memsized_batch = min_t(u64, (totalram_pages/nr)/256, 0x7fffffff);
163+
164+
vm_committed_as_batch = max_t(s32, memsized_batch, batch);
165+
}
166+
167+
static int __meminit mm_compute_batch_notifier(struct notifier_block *self,
168+
unsigned long action, void *arg)
169+
{
170+
switch (action) {
171+
case MEM_ONLINE:
172+
case MEM_OFFLINE:
173+
mm_compute_batch();
174+
default:
175+
break;
176+
}
177+
return NOTIFY_OK;
178+
}
179+
180+
static struct notifier_block compute_batch_nb __meminitdata = {
181+
.notifier_call = mm_compute_batch_notifier,
182+
.priority = IPC_CALLBACK_PRI, /* use lowest priority */
183+
};
184+
185+
static int __init mm_compute_batch_init(void)
186+
{
187+
mm_compute_batch();
188+
register_hotmemory_notifier(&compute_batch_nb);
189+
190+
return 0;
191+
}
192+
193+
__initcall(mm_compute_batch_init);
194+
195+
#endif
196+
150197
static int __init mm_sysfs_init(void)
151198
{
152199
mm_kobj = kobject_create_and_add("mm", kernel_kobj);

0 commit comments

Comments
 (0)