make balance_classzone() use list.h

William Lee Irwin III (wli@holomorphy.com)
Sun, 2 Jun 2002 16:13:12 -0700


balance_classzone() does a number of open-coded list operations. This
adjusts balance_classzone() to use generic list.h operations as well
as renaming __freed and restructuring some of the control flow to use
if (unlikely(...))) goto handle_rare_case; for additional conciseness
and reducing the number of indentation levels required.

Against 2.5.19

Cheers,
Bill

===== mm/page_alloc.c 1.72 vs edited =====
--- 1.72/mm/page_alloc.c Sun Jun 2 15:49:05 2002
+++ edited/mm/page_alloc.c Sun Jun 2 16:02:35 2002
@@ -265,8 +265,9 @@
static struct page * FASTCALL(balance_classzone(zone_t *, unsigned int, unsigned int, int *));
static struct page * balance_classzone(zone_t * classzone, unsigned int gfp_mask, unsigned int order, int * freed)
{
- struct page * page = NULL;
- int __freed = 0;
+ struct page *tmp, *page = NULL;
+ list_t *save, *entry, *local_pages;
+ int nr_pages, reclaimed = 0;

if (!(gfp_mask & __GFP_WAIT))
goto out;
@@ -275,52 +276,57 @@
current->allocation_order = order;
current->flags |= PF_MEMALLOC | PF_FREE_PAGES;

- __freed = try_to_free_pages(classzone, gfp_mask, order);
+ reclaimed = try_to_free_pages(classzone, gfp_mask, order);

current->flags &= ~(PF_MEMALLOC | PF_FREE_PAGES);

- if (current->nr_local_pages) {
- struct list_head * entry, * local_pages;
- struct page * tmp;
- int nr_pages;
-
- local_pages = &current->local_pages;
-
- if (likely(__freed)) {
- /* pick from the last inserted so we're lifo */
- entry = local_pages->next;
- do {
- tmp = list_entry(entry, struct page, list);
- if (tmp->index == order && memclass(page_zone(tmp), classzone)) {
- list_del(entry);
- current->nr_local_pages--;
- set_page_count(tmp, 1);
- page = tmp;
-
- BUG_ON(PagePrivate(page));
- BUG_ON(page->mapping);
- BUG_ON(PageLocked(page));
- BUG_ON(PageLRU(page));
- BUG_ON(PageActive(page));
- BUG_ON(PageDirty(page));
- BUG_ON(PageWriteback(page));
- break;
- }
- } while ((entry = entry->next) != local_pages);
- }
-
- nr_pages = current->nr_local_pages;
- /* free in reverse order so that the global order will be lifo */
- while ((entry = local_pages->prev) != local_pages) {
- list_del(entry);
- tmp = list_entry(entry, struct page, list);
- __free_pages_ok(tmp, tmp->index);
- BUG_ON(!nr_pages--);
- }
- current->nr_local_pages = 0;
+ if (!current->nr_local_pages)
+ goto out;
+
+ local_pages = &current->local_pages;
+
+ if (unlikely(!reclaimed))
+ goto reverse_free;
+
+ /* pick from the last inserted so we're lifo */
+ list_for_each_safe(entry, save, local_pages) {
+ tmp = list_entry(entry, struct page, list);
+
+ if (tmp->index != order)
+ continue;
+ if (memclass(page_zone(tmp), classzone))
+ continue;
+
+ list_del(entry);
+ current->nr_local_pages--;
+ set_page_count(tmp, 1);
+ page = tmp;
+
+ BUG_ON(PagePrivate(page));
+ BUG_ON(page->mapping);
+ BUG_ON(PageLocked(page));
+ BUG_ON(PageLRU(page));
+ BUG_ON(PageActive(page));
+ BUG_ON(PageDirty(page));
+ BUG_ON(PageWriteback(page));
+ break;
+ }
+
+reverse_free:
+ nr_pages = current->nr_local_pages;
+ /* free in reverse order so that the global order will be lifo */
+ while (!list_empt(local_pages)) {
+ entry = local_pages->prev;
+ list_del(entry);
+ tmp = list_entry(entry, struct page, list);
+ __free_pages_ok(tmp, tmp->index);
+ BUG_ON(!nr_pages);
+ nr_pages--;
}
- out:
- *freed = __freed;
+ BUG_ON(nr_pages);
+ current->nr_local_pages = 0;
+out:
+ *freed = reclaimed;
return page;
}

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/