aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Lameter <clameter@sgi.com>2008-03-01 16:40:44 -0500
committerChristoph Lameter <clameter@sgi.com>2008-03-03 15:22:30 -0500
commita973e9dd1e140a65bed694a2c5c8d53e9cba1a23 (patch)
tree5a164080dae237d09c57abab9e84b750863a2ff7
parent27710bf6febe8323f78bceca002ca7d71e5012a7 (diff)
Revert "unique end pointer" patch
This only made sense for the alternate fastpath which was reverted last week. Mathieu is working on a new version that addresses the fastpath issues but that new code first needs to go through mm and it is not clear if we need the unique end pointers with his new scheme. Reviewed-by: Pekka Enberg <penberg@cs.helsinki.fi> Signed-off-by: Christoph Lameter <clameter@sgi.com>
-rw-r--r--include/linux/mm_types.h5
-rw-r--r--mm/slub.c70
2 files changed, 24 insertions, 51 deletions
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index bfee0bd1d435..34023c65d466 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -64,10 +64,7 @@ struct page {
64#if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS 64#if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS
65 spinlock_t ptl; 65 spinlock_t ptl;
66#endif 66#endif
67 struct { 67 struct kmem_cache *slab; /* SLUB: Pointer to slab */
68 struct kmem_cache *slab; /* SLUB: Pointer to slab */
69 void *end; /* SLUB: end marker */
70 };
71 struct page *first_page; /* Compound tail pages */ 68 struct page *first_page; /* Compound tail pages */
72 }; 69 };
73 union { 70 union {
diff --git a/mm/slub.c b/mm/slub.c
index 74c65af0a54f..a873953e5a11 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -291,32 +291,15 @@ static inline struct kmem_cache_cpu *get_cpu_slab(struct kmem_cache *s, int cpu)
291#endif 291#endif
292} 292}
293 293
294/*
295 * The end pointer in a slab is special. It points to the first object in the
296 * slab but has bit 0 set to mark it.
297 *
298 * Note that SLUB relies on page_mapping returning NULL for pages with bit 0
299 * in the mapping set.
300 */
301static inline int is_end(void *addr)
302{
303 return (unsigned long)addr & PAGE_MAPPING_ANON;
304}
305
306static void *slab_address(struct page *page)
307{
308 return page->end - PAGE_MAPPING_ANON;
309}
310
311static inline int check_valid_pointer(struct kmem_cache *s, 294static inline int check_valid_pointer(struct kmem_cache *s,
312 struct page *page, const void *object) 295 struct page *page, const void *object)
313{ 296{
314 void *base; 297 void *base;
315 298
316 if (object == page->end) 299 if (!object)
317 return 1; 300 return 1;
318 301
319 base = slab_address(page); 302 base = page_address(page);
320 if (object < base || object >= base + s->objects * s->size || 303 if (object < base || object >= base + s->objects * s->size ||
321 (object - base) % s->size) { 304 (object - base) % s->size) {
322 return 0; 305 return 0;
@@ -349,8 +332,7 @@ static inline void set_freepointer(struct kmem_cache *s, void *object, void *fp)
349 332
350/* Scan freelist */ 333/* Scan freelist */
351#define for_each_free_object(__p, __s, __free) \ 334#define for_each_free_object(__p, __s, __free) \
352 for (__p = (__free); (__p) != page->end; __p = get_freepointer((__s),\ 335 for (__p = (__free); __p; __p = get_freepointer((__s), __p))
353 __p))
354 336
355/* Determine object index from a given position */ 337/* Determine object index from a given position */
356static inline int slab_index(void *p, struct kmem_cache *s, void *addr) 338static inline int slab_index(void *p, struct kmem_cache *s, void *addr)
@@ -502,7 +484,7 @@ static void slab_fix(struct kmem_cache *s, char *fmt, ...)
502static void print_trailer(struct kmem_cache *s, struct page *page, u8 *p) 484static void print_trailer(struct kmem_cache *s, struct page *page, u8 *p)
503{ 485{
504 unsigned int off; /* Offset of last byte */ 486 unsigned int off; /* Offset of last byte */
505 u8 *addr = slab_address(page); 487 u8 *addr = page_address(page);
506 488
507 print_tracking(s, p); 489 print_tracking(s, p);
508 490
@@ -680,7 +662,7 @@ static int slab_pad_check(struct kmem_cache *s, struct page *page)
680 if (!(s->flags & SLAB_POISON)) 662 if (!(s->flags & SLAB_POISON))
681 return 1; 663 return 1;
682 664
683 start = slab_address(page); 665 start = page_address(page);
684 end = start + (PAGE_SIZE << s->order); 666 end = start + (PAGE_SIZE << s->order);
685 length = s->objects * s->size; 667 length = s->objects * s->size;
686 remainder = end - (start + length); 668 remainder = end - (start + length);
@@ -748,7 +730,7 @@ static int check_object(struct kmem_cache *s, struct page *page,
748 * of the free objects in this slab. May cause 730 * of the free objects in this slab. May cause
749 * another error because the object count is now wrong. 731 * another error because the object count is now wrong.
750 */ 732 */
751 set_freepointer(s, p, page->end); 733 set_freepointer(s, p, NULL);
752 return 0; 734 return 0;
753 } 735 }
754 return 1; 736 return 1;
@@ -782,18 +764,18 @@ static int on_freelist(struct kmem_cache *s, struct page *page, void *search)
782 void *fp = page->freelist; 764 void *fp = page->freelist;
783 void *object = NULL; 765 void *object = NULL;
784 766
785 while (fp != page->end && nr <= s->objects) { 767 while (fp && nr <= s->objects) {
786 if (fp == search) 768 if (fp == search)
787 return 1; 769 return 1;
788 if (!check_valid_pointer(s, page, fp)) { 770 if (!check_valid_pointer(s, page, fp)) {
789 if (object) { 771 if (object) {
790 object_err(s, page, object, 772 object_err(s, page, object,
791 "Freechain corrupt"); 773 "Freechain corrupt");
792 set_freepointer(s, object, page->end); 774 set_freepointer(s, object, NULL);
793 break; 775 break;
794 } else { 776 } else {
795 slab_err(s, page, "Freepointer corrupt"); 777 slab_err(s, page, "Freepointer corrupt");
796 page->freelist = page->end; 778 page->freelist = NULL;
797 page->inuse = s->objects; 779 page->inuse = s->objects;
798 slab_fix(s, "Freelist cleared"); 780 slab_fix(s, "Freelist cleared");
799 return 0; 781 return 0;
@@ -899,7 +881,7 @@ bad:
899 */ 881 */
900 slab_fix(s, "Marking all objects used"); 882 slab_fix(s, "Marking all objects used");
901 page->inuse = s->objects; 883 page->inuse = s->objects;
902 page->freelist = page->end; 884 page->freelist = NULL;
903 } 885 }
904 return 0; 886 return 0;
905} 887}
@@ -939,7 +921,7 @@ static int free_debug_processing(struct kmem_cache *s, struct page *page,
939 } 921 }
940 922
941 /* Special debug activities for freeing objects */ 923 /* Special debug activities for freeing objects */
942 if (!SlabFrozen(page) && page->freelist == page->end) 924 if (!SlabFrozen(page) && !page->freelist)
943 remove_full(s, page); 925 remove_full(s, page);
944 if (s->flags & SLAB_STORE_USER) 926 if (s->flags & SLAB_STORE_USER)
945 set_track(s, object, TRACK_FREE, addr); 927 set_track(s, object, TRACK_FREE, addr);
@@ -1124,7 +1106,6 @@ static struct page *new_slab(struct kmem_cache *s, gfp_t flags, int node)
1124 SetSlabDebug(page); 1106 SetSlabDebug(page);
1125 1107
1126 start = page_address(page); 1108 start = page_address(page);
1127 page->end = start + 1;
1128 1109
1129 if (unlikely(s->flags & SLAB_POISON)) 1110 if (unlikely(s->flags & SLAB_POISON))
1130 memset(start, POISON_INUSE, PAGE_SIZE << s->order); 1111 memset(start, POISON_INUSE, PAGE_SIZE << s->order);
@@ -1136,7 +1117,7 @@ static struct page *new_slab(struct kmem_cache *s, gfp_t flags, int node)
1136 last = p; 1117 last = p;
1137 } 1118 }
1138 setup_object(s, page, last); 1119 setup_object(s, page, last);
1139 set_freepointer(s, last, page->end); 1120 set_freepointer(s, last, NULL);
1140 1121
1141 page->freelist = start; 1122 page->freelist = start;
1142 page->inuse = 0; 1123 page->inuse = 0;
@@ -1152,7 +1133,7 @@ static void __free_slab(struct kmem_cache *s, struct page *page)
1152 void *p; 1133 void *p;
1153 1134
1154 slab_pad_check(s, page); 1135 slab_pad_check(s, page);
1155 for_each_object(p, s, slab_address(page)) 1136 for_each_object(p, s, page_address(page))
1156 check_object(s, page, p, 0); 1137 check_object(s, page, p, 0);
1157 ClearSlabDebug(page); 1138 ClearSlabDebug(page);
1158 } 1139 }
@@ -1162,7 +1143,6 @@ static void __free_slab(struct kmem_cache *s, struct page *page)
1162 NR_SLAB_RECLAIMABLE : NR_SLAB_UNRECLAIMABLE, 1143 NR_SLAB_RECLAIMABLE : NR_SLAB_UNRECLAIMABLE,
1163 -pages); 1144 -pages);
1164 1145
1165 page->mapping = NULL;
1166 __free_pages(page, s->order); 1146 __free_pages(page, s->order);
1167} 1147}
1168 1148
@@ -1366,7 +1346,7 @@ static void unfreeze_slab(struct kmem_cache *s, struct page *page, int tail)
1366 ClearSlabFrozen(page); 1346 ClearSlabFrozen(page);
1367 if (page->inuse) { 1347 if (page->inuse) {
1368 1348