aboutsummaryrefslogtreecommitdiffstats
path: root/mm/page_alloc.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2006-03-23 23:44:19 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2006-03-23 23:44:19 -0500
commit1ebbe2b20091d306453a5cf480a87e6cd28ae76f (patch)
treef5cd7a0fa69b8b1938cb5a0faed2e7b0628072a5 /mm/page_alloc.c
parentac58c9059da8886b5e8cde012a80266b18ca146e (diff)
parent674a396c6d2ba0341ebdd7c1c9950f32f018e2dd (diff)
Merge branch 'linus'
Diffstat (limited to 'mm/page_alloc.c')
-rw-r--r--mm/page_alloc.c113
1 files changed, 64 insertions, 49 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 234bd4895d14..b7f14a4799a5 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -55,7 +55,6 @@ unsigned long totalhigh_pages __read_mostly;
55long nr_swap_pages; 55long nr_swap_pages;
56int percpu_pagelist_fraction; 56int percpu_pagelist_fraction;
57 57
58static void fastcall free_hot_cold_page(struct page *page, int cold);
59static void __free_pages_ok(struct page *page, unsigned int order); 58static void __free_pages_ok(struct page *page, unsigned int order);
60 59
61/* 60/*
@@ -190,7 +189,7 @@ static void prep_compound_page(struct page *page, unsigned long order)
190 for (i = 0; i < nr_pages; i++) { 189 for (i = 0; i < nr_pages; i++) {
191 struct page *p = page + i; 190 struct page *p = page + i;
192 191
193 SetPageCompound(p); 192 __SetPageCompound(p);
194 set_page_private(p, (unsigned long)page); 193 set_page_private(p, (unsigned long)page);
195 } 194 }
196} 195}
@@ -209,10 +208,24 @@ static void destroy_compound_page(struct page *page, unsigned long order)
209 if (unlikely(!PageCompound(p) | 208 if (unlikely(!PageCompound(p) |
210 (page_private(p) != (unsigned long)page))) 209 (page_private(p) != (unsigned long)page)))
211 bad_page(page); 210 bad_page(page);
212 ClearPageCompound(p); 211 __ClearPageCompound(p);
213 } 212 }
214} 213}
215 214
215static inline void prep_zero_page(struct page *page, int order, gfp_t gfp_flags)
216{
217 int i;
218
219 BUG_ON((gfp_flags & (__GFP_WAIT | __GFP_HIGHMEM)) == __GFP_HIGHMEM);
220 /*
221 * clear_highpage() will use KM_USER0, so it's a bug to use __GFP_ZERO
222 * and __GFP_HIGHMEM from hard or soft interrupt context.
223 */
224 BUG_ON((gfp_flags & __GFP_HIGHMEM) && in_interrupt());
225 for (i = 0; i < (1 << order); i++)
226 clear_highpage(page + i);
227}
228
216/* 229/*
217 * function for dealing with page's order in buddy system. 230 * function for dealing with page's order in buddy system.
218 * zone->lock is already acquired when we use these. 231 * zone->lock is already acquired when we use these.
@@ -423,11 +436,6 @@ static void __free_pages_ok(struct page *page, unsigned int order)
423 mutex_debug_check_no_locks_freed(page_address(page), 436 mutex_debug_check_no_locks_freed(page_address(page),
424 PAGE_SIZE<<order); 437 PAGE_SIZE<<order);
425 438
426#ifndef CONFIG_MMU
427 for (i = 1 ; i < (1 << order) ; ++i)
428 __put_page(page + i);
429#endif
430
431 for (i = 0 ; i < (1 << order) ; ++i) 439 for (i = 0 ; i < (1 << order) ; ++i)
432 reserved += free_pages_check(page + i); 440 reserved += free_pages_check(page + i);
433 if (reserved) 441 if (reserved)
@@ -448,28 +456,23 @@ void fastcall __init __free_pages_bootmem(struct page *page, unsigned int order)
448 if (order == 0) { 456 if (order == 0) {
449 __ClearPageReserved(page); 457 __ClearPageReserved(page);
450 set_page_count(page, 0); 458 set_page_count(page, 0);
451 459 set_page_refcounted(page);
452 free_hot_cold_page(page, 0); 460 __free_page(page);
453 } else { 461 } else {
454 LIST_HEAD(list);
455 int loop; 462 int loop;
456 463
464 prefetchw(page);
457 for (loop = 0; loop < BITS_PER_LONG; loop++) { 465 for (loop = 0; loop < BITS_PER_LONG; loop++) {
458 struct page *p = &page[loop]; 466 struct page *p = &page[loop];
459 467
460 if (loop + 16 < BITS_PER_LONG) 468 if (loop + 1 < BITS_PER_LONG)
461 prefetchw(p + 16); 469 prefetchw(p + 1);
462 __ClearPageReserved(p); 470 __ClearPageReserved(p);
463 set_page_count(p, 0); 471 set_page_count(p, 0);
464 } 472 }
465 473
466 arch_free_page(page, order); 474 set_page_refcounted(page);
467 475 __free_pages(page, order);
468 mod_page_state(pgfree, 1 << order);
469
470 list_add(&page->lru, &list);
471 kernel_map_pages(page, 1 << order, 0);
472 free_pages_bulk(page_zone(page), 1, &list, order);
473 } 476 }
474} 477}
475 478
@@ -507,7 +510,7 @@ static inline void expand(struct zone *zone, struct page *page,
507/* 510/*
508 * This page is about to be returned from the page allocator 511 * This page is about to be returned from the page allocator
509 */ 512 */
510static int prep_new_page(struct page *page, int order) 513static int prep_new_page(struct page *page, int order, gfp_t gfp_flags)
511{ 514{
512 if (unlikely(page_mapcount(page) | 515 if (unlikely(page_mapcount(page) |
513 (page->mapping != NULL) | 516 (page->mapping != NULL) |
@@ -536,8 +539,15 @@ static int prep_new_page(struct page *page, int order)
536 1 << PG_referenced | 1 << PG_arch_1 | 539 1 << PG_referenced | 1 << PG_arch_1 |
537 1 << PG_checked | 1 << PG_mappedtodisk); 540 1 << PG_checked | 1 << PG_mappedtodisk);
538 set_page_private(page, 0); 541 set_page_private(page, 0);
539 set_page_refs(page, order); 542 set_page_refcounted(page);
540 kernel_map_pages(page, 1 << order, 1); 543 kernel_map_pages(page, 1 << order, 1);
544
545 if (gfp_flags & __GFP_ZERO)
546 prep_zero_page(page, order, gfp_flags);
547
548 if (order && (gfp_flags & __GFP_COMP))
549 prep_compound_page(page, order);
550
541 return 0; 551 return 0;
542} 552}
543 553
@@ -593,13 +603,14 @@ static int rmqueue_bulk(struct zone *zone, unsigned int order,
593/* 603/*
594 * Called from the slab reaper to drain pagesets on a particular node that 604 * Called from the slab reaper to drain pagesets on a particular node that
595 * belong to the currently executing processor. 605 * belong to the currently executing processor.
606 * Note that this function must be called with the thread pinned to
607 * a single processor.
596 */ 608 */
597void drain_node_pages(int nodeid) 609void drain_node_pages(int nodeid)
598{ 610{
599 int i, z; 611 int i, z;
600 unsigned long flags; 612 unsigned long flags;
601 613
602 local_irq_save(flags);
603 for (z = 0; z < MAX_NR_ZONES; z++) { 614 for (z = 0; z < MAX_NR_ZONES; z++) {
604 struct zone *zone = NODE_DATA(nodeid)->node_zones + z; 615 struct zone *zone = NODE_DATA(nodeid)->node_zones + z;
605 struct per_cpu_pageset *pset; 616 struct per_cpu_pageset *pset;
@@ -609,11 +620,14 @@ void drain_node_pages(int nodeid)
609 struct per_cpu_pages *pcp; 620 struct per_cpu_pages *pcp;
610 621
611 pcp = &pset->pcp[i]; 622 pcp = &pset->pcp[i];
612 free_pages_bulk(zone, pcp->count, &pcp->list, 0); 623 if (pcp->count) {
613 pcp->count = 0; 624 local_irq_save(flags);
625 free_pages_bulk(zone, pcp->count, &pcp->list, 0);
626 pcp->count = 0;
627 local_irq_restore(flags);
628 }
614 } 629 }
615 } 630 }
616 local_irq_restore(flags);
617} 631}
618#endif 632#endif
619 633
@@ -743,13 +757,22 @@ void fastcall free_cold_page(struct page *page)
743 free_hot_cold_page(page, 1); 757 free_hot_cold_page(page, 1);
744} 758}
745 759
746static inline void prep_zero_page(struct page *page, int order, gfp_t gfp_flags) 760/*
761 * split_page takes a non-compound higher-order page, and splits it into
762 * n (1<<order) sub-pages: page[0..n]
763 * Each sub-page must be freed individually.
764 *
765 * Note: this is probably too low level an operation for use in drivers.
766 * Please consult with lkml before using this in your driver.
767 */
768void split_page(struct page *page, unsigned int order)
747{ 769{
748 int i; 770 int i;
749 771
750 BUG_ON((gfp_flags & (__GFP_WAIT | __GFP_HIGHMEM)) == __GFP_HIGHMEM); 772 BUG_ON(PageCompound(page));
751 for(i = 0; i < (1 << order); i++) 773 BUG_ON(!page_count(page));
752 clear_highpage(page + i); 774 for (i = 1; i < (1 << order); i++)
775 set_page_refcounted(page + i);
753} 776}
754 777
755/* 778/*
@@ -795,14 +818,8 @@ again:
795 put_cpu(); 818 put_cpu();
796 819
797 BUG_ON(bad_range(zone, page)); 820 BUG_ON(bad_range(zone, page));
798 if (prep_new_page(page, order)) 821 if (prep_new_page(page, order, gfp_flags))
799 goto again; 822 goto again;
800
801 if (gfp_flags & __GFP_ZERO)
802 prep_zero_page(page, order, gfp_flags);
803
804 if (order && (gfp_flags & __GFP_COMP))
805 prep_compound_page(page, order);
806 return page; 823 return page;
807 824
808failed: 825failed:
@@ -1214,24 +1231,22 @@ DEFINE_PER_CPU(long, nr_pagecache_local) = 0;
1214 1231
1215static void __get_page_state(struct page_state *ret, int nr, cpumask_t *cpumask) 1232static void __get_page_state(struct page_state *ret, int nr, cpumask_t *cpumask)
1216{ 1233{
1217 int cpu = 0; 1234 unsigned cpu;
1218 1235
1219 memset(ret, 0, nr * sizeof(unsigned long)); 1236 memset(ret, 0, nr * sizeof(unsigned long));
1220 cpus_and(*cpumask, *cpumask, cpu_online_map); 1237 cpus_and(*cpumask, *cpumask, cpu_online_map);
1221 1238
1222 cpu = first_cpu(*cpumask); 1239 for_each_cpu_mask(cpu, *cpumask) {
1223 while (cpu < NR_CPUS) { 1240 unsigned long *in;
1224 unsigned long *in, *out, off; 1241 unsigned long *out;
1225 1242 unsigned off;
1226 if (!cpu_isset(cpu, *cpumask)) 1243 unsigned next_cpu;
1227 continue;
1228 1244
1229 in = (unsigned long *)&per_cpu(page_states, cpu); 1245 in = (unsigned long *)&per_cpu(page_states, cpu);
1230 1246
1231 cpu = next_cpu(cpu, *cpumask); 1247 next_cpu = next_cpu(cpu, *cpumask);
1232 1248 if (likely(next_cpu < NR_CPUS))
1233 if (likely(cpu < NR_CPUS)) 1249 prefetch(&per_cpu(page_states, next_cpu));
1234 prefetch(&per_cpu(page_states, cpu));
1235 1250
1236 out = (unsigned long *)ret; 1251 out = (unsigned long *)ret;
1237 for (off = 0; off < nr; off++) 1252 for (off = 0; off < nr; off++)
@@ -1764,7 +1779,7 @@ void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone,
1764 continue; 1779 continue;
1765 page = pfn_to_page(pfn); 1780 page = pfn_to_page(pfn);
1766 set_page_links(page, zone, nid, pfn); 1781 set_page_links(page, zone, nid, pfn);
1767 set_page_count(page, 1); 1782 init_page_count(page);
1768 reset_page_mapcount(page); 1783 reset_page_mapcount(page);
1769 SetPageReserved(page); 1784 SetPageReserved(page);
1770 INIT_LIST_HEAD(&page->lru); 1785 INIT_LIST_HEAD(&page->lru);