diff options
Diffstat (limited to 'mm')
-rw-r--r-- | mm/page_alloc.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index ed91684cb1f5..b7f14a4799a5 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -603,13 +603,14 @@ static int rmqueue_bulk(struct zone *zone, unsigned int order, | |||
603 | /* | 603 | /* |
604 | * 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 |
605 | * 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. | ||
606 | */ | 608 | */ |
607 | void drain_node_pages(int nodeid) | 609 | void drain_node_pages(int nodeid) |
608 | { | 610 | { |
609 | int i, z; | 611 | int i, z; |
610 | unsigned long flags; | 612 | unsigned long flags; |
611 | 613 | ||
612 | local_irq_save(flags); | ||
613 | for (z = 0; z < MAX_NR_ZONES; z++) { | 614 | for (z = 0; z < MAX_NR_ZONES; z++) { |
614 | struct zone *zone = NODE_DATA(nodeid)->node_zones + z; | 615 | struct zone *zone = NODE_DATA(nodeid)->node_zones + z; |
615 | struct per_cpu_pageset *pset; | 616 | struct per_cpu_pageset *pset; |
@@ -619,11 +620,14 @@ void drain_node_pages(int nodeid) | |||
619 | struct per_cpu_pages *pcp; | 620 | struct per_cpu_pages *pcp; |
620 | 621 | ||
621 | pcp = &pset->pcp[i]; | 622 | pcp = &pset->pcp[i]; |
622 | free_pages_bulk(zone, pcp->count, &pcp->list, 0); | 623 | if (pcp->count) { |
623 | 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 | } | ||
624 | } | 629 | } |
625 | } | 630 | } |
626 | local_irq_restore(flags); | ||
627 | } | 631 | } |
628 | #endif | 632 | #endif |
629 | 633 | ||