aboutsummaryrefslogtreecommitdiffstats
path: root/mm
diff options
context:
space:
mode:
Diffstat (limited to 'mm')
-rw-r--r--mm/slub.c39
1 files changed, 28 insertions, 11 deletions
diff --git a/mm/slub.c b/mm/slub.c
index c8514e93ffdf..35c22d940ba7 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -1113,28 +1113,43 @@ static inline void dec_slabs_node(struct kmem_cache *s, int node,
1113/* 1113/*
1114 * Slab allocation and freeing 1114 * Slab allocation and freeing
1115 */ 1115 */
1116static inline struct page *alloc_slab_page(gfp_t flags, int node,
1117 struct kmem_cache_order_objects oo)
1118{
1119 int order = oo_order(oo);
1120
1121 if (node == -1)
1122 return alloc_pages(flags, order);
1123 else
1124 return alloc_pages_node(node, flags, order);
1125}
1126
1116static struct page *allocate_slab(struct kmem_cache *s, gfp_t flags, int node) 1127static struct page *allocate_slab(struct kmem_cache *s, gfp_t flags, int node)
1117{ 1128{
1118 struct page *page; 1129 struct page *page;
1119 struct kmem_cache_order_objects oo = s->oo; 1130 struct kmem_cache_order_objects oo = s->oo;
1120 int order = oo_order(oo);
1121 int pages = 1 << order;
1122 1131
1123 flags |= s->allocflags; 1132 flags |= s->allocflags;
1124 1133
1125 if (node == -1) 1134 page = alloc_slab_page(flags | __GFP_NOWARN | __GFP_NORETRY, node,
1126 page = alloc_pages(flags, order); 1135 oo);
1127 else 1136 if (unlikely(!page)) {
1128 page = alloc_pages_node(node, flags, order); 1137 oo = s->min;
1129 1138 /*
1130 if (!page) 1139 * Allocation may have failed due to fragmentation.
1131 return NULL; 1140 * Try a lower order alloc if possible
1141 */
1142 page = alloc_slab_page(flags, node, oo);
1143 if (!page)
1144 return NULL;
1132 1145
1146 stat(get_cpu_slab(s, raw_smp_processor_id()), ORDER_FALLBACK);
1147 }
1133 page->objects = oo_objects(oo); 1148 page->objects = oo_objects(oo);
1134 mod_zone_page_state(page_zone(page), 1149 mod_zone_page_state(page_zone(page),
1135 (s->flags & SLAB_RECLAIM_ACCOUNT) ? 1150 (s->flags & SLAB_RECLAIM_ACCOUNT) ?
1136 NR_SLAB_RECLAIMABLE : NR_SLAB_UNRECLAIMABLE, 1151 NR_SLAB_RECLAIMABLE : NR_SLAB_UNRECLAIMABLE,
1137 pages); 1152 1 << oo_order(oo));
1138 1153
1139 return page; 1154 return page;
1140} 1155}
@@ -2347,6 +2362,7 @@ static int calculate_sizes(struct kmem_cache *s)
2347 * Determine the number of objects per slab 2362 * Determine the number of objects per slab
2348 */ 2363 */
2349 s->oo = oo_make(order, size); 2364 s->oo = oo_make(order, size);
2365 s->min = oo_make(get_order(size), size);
2350 if (oo_objects(s->oo) > oo_objects(s->max)) 2366 if (oo_objects(s->oo) > oo_objects(s->max))
2351 s->max = s->oo; 2367 s->max = s->oo;
2352 2368
@@ -4163,7 +4179,7 @@ STAT_ATTR(DEACTIVATE_EMPTY, deactivate_empty);
4163STAT_ATTR(DEACTIVATE_TO_HEAD, deactivate_to_head); 4179STAT_ATTR(DEACTIVATE_TO_HEAD, deactivate_to_head);
4164STAT_ATTR(DEACTIVATE_TO_TAIL, deactivate_to_tail); 4180STAT_ATTR(DEACTIVATE_TO_TAIL, deactivate_to_tail);
4165STAT_ATTR(DEACTIVATE_REMOTE_FREES, deactivate_remote_frees); 4181STAT_ATTR(DEACTIVATE_REMOTE_FREES, deactivate_remote_frees);
4166 4182STAT_ATTR(ORDER_FALLBACK, order_fallback);
4167#endif 4183#endif
4168 4184
4169static struct attribute *slab_attrs[] = { 4185static struct attribute *slab_attrs[] = {
@@ -4216,6 +4232,7 @@ static struct attribute *slab_attrs[] = {
4216 &deactivate_to_head_attr.attr, 4232 &deactivate_to_head_attr.attr,
4217 &deactivate_to_tail_attr.attr, 4233 &deactivate_to_tail_attr.attr,
4218 &deactivate_remote_frees_attr.attr, 4234 &deactivate_remote_frees_attr.attr,
4235 &order_fallback_attr.attr,
4219#endif 4236#endif
4220 NULL 4237 NULL
4221}; 4238};