diff options
author | Eric Wong <normalperson@yhbt.net> | 2013-04-30 18:27:38 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-04-30 20:04:04 -0400 |
commit | 39732ca5af4b09f4db561149041ddad7211019a5 (patch) | |
tree | 654d9dc83e3884358e02dd7d765a22423334840d | |
parent | 4a22f16636259f503847b0805e04824171b270fc (diff) |
epoll: trim epitem by one cache line
It is common for epoll users to have thousands of epitems, so saving a
cache line on every allocation leads to large memory savings.
Since epitem allocations are cache-aligned, reducing sizeof(struct
epitem) from 136 bytes to 128 bytes will allow it to squeeze under a
cache line boundary on x86_64.
Via /sys/kernel/slab/eventpoll_epi, I see the following changes on my
x86_64 Core2 Duo (which has 64-byte cache alignment):
object_size : 192 => 128
objs_per_slab: 21 => 32
Also, add a BUILD_BUG_ON() to check for future accidental breakage.
[akpm@linux-foundation.org: use __packed, for all architectures]
Signed-off-by: Eric Wong <normalperson@yhbt.net>
Cc: Davide Libenzi <davidel@xmailserver.org>
Cc: Al Viro <viro@ZenIV.linux.org.uk>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | fs/eventpoll.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/fs/eventpoll.c b/fs/eventpoll.c index 9fec1836057a..0e5eda068520 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c | |||
@@ -104,7 +104,7 @@ | |||
104 | struct epoll_filefd { | 104 | struct epoll_filefd { |
105 | struct file *file; | 105 | struct file *file; |
106 | int fd; | 106 | int fd; |
107 | }; | 107 | } __packed; |
108 | 108 | ||
109 | /* | 109 | /* |
110 | * Structure used to track possible nested calls, for too deep recursions | 110 | * Structure used to track possible nested calls, for too deep recursions |
@@ -128,6 +128,8 @@ struct nested_calls { | |||
128 | /* | 128 | /* |
129 | * Each file descriptor added to the eventpoll interface will | 129 | * Each file descriptor added to the eventpoll interface will |
130 | * have an entry of this type linked to the "rbr" RB tree. | 130 | * have an entry of this type linked to the "rbr" RB tree. |
131 | * Avoid increasing the size of this struct, there can be many thousands | ||
132 | * of these on a server and we do not want this to take another cache line. | ||
131 | */ | 133 | */ |
132 | struct epitem { | 134 | struct epitem { |
133 | /* RB tree node used to link this structure to the eventpoll RB tree */ | 135 | /* RB tree node used to link this structure to the eventpoll RB tree */ |
@@ -1964,6 +1966,12 @@ static int __init eventpoll_init(void) | |||
1964 | /* Initialize the structure used to perform file's f_op->poll() calls */ | 1966 | /* Initialize the structure used to perform file's f_op->poll() calls */ |
1965 | ep_nested_calls_init(&poll_readywalk_ncalls); | 1967 | ep_nested_calls_init(&poll_readywalk_ncalls); |
1966 | 1968 | ||
1969 | /* | ||
1970 | * We can have many thousands of epitems, so prevent this from | ||
1971 | * using an extra cache line on 64-bit (and smaller) CPUs | ||
1972 | */ | ||
1973 | BUILD_BUG_ON(sizeof(void *) <= 8 && sizeof(struct epitem) > 128); | ||
1974 | |||
1967 | /* Allocates slab cache used to allocate "struct epitem" items */ | 1975 | /* Allocates slab cache used to allocate "struct epitem" items */ |
1968 | epi_cache = kmem_cache_create("eventpoll_epi", sizeof(struct epitem), | 1976 | epi_cache = kmem_cache_create("eventpoll_epi", sizeof(struct epitem), |
1969 | 0, SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL); | 1977 | 0, SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL); |