From: Christoph Hellwig <hch@lst.de>
To: marcelo@conectiva.com.br
Cc: riel@conectiva.com.br, linux-mm@kvack.org
Subject: [PATCH] for_each_pgdat/for_each_zone
Date: Tue, 6 Aug 2002 16:11:09 +0200 [thread overview]
Message-ID: <20020806161109.A2543@lst.de> (raw)
These patches from wli and Rik allow easy traversal of all pgdat's or
zones in the system and cleanup some VM code nicely. It has been in
-rmap for ages and in 2.5 for a few weeks.
Adopted to mainline by me.
diff -uNr -Xdontdiff -p linux-2.4.20-pre1/include/linux/mmzone.h linux/include/linux/mmzone.h
--- linux-2.4.20-pre1/include/linux/mmzone.h Tue Aug 6 11:27:18 2002
+++ linux/include/linux/mmzone.h Tue Aug 6 15:00:46 2002
@@ -158,6 +158,60 @@ extern void free_area_init_core(int nid,
extern pg_data_t contig_page_data;
+/**
+ * for_each_pgdat - helper macro to iterate over all nodes
+ * @pgdat - pg_data_t * variable
+ *
+ * Meant to help with common loops of the form
+ * pgdat = pgdat_list;
+ * while(pgdat) {
+ * ...
+ * pgdat = pgdat->node_next;
+ * }
+ */
+#define for_each_pgdat(pgdat) \
+ for (pgdat = pgdat_list; pgdat; pgdat = pgdat->node_next)
+
+
+/*
+ * next_zone - helper magic for for_each_zone()
+ * Thanks to William Lee Irwin III for this piece of ingenuity.
+ */
+static inline zone_t *next_zone(zone_t *zone)
+{
+ pg_data_t *pgdat = zone->zone_pgdat;
+
+ if (zone - pgdat->node_zones < MAX_NR_ZONES - 1)
+ zone++;
+
+ else if (pgdat->node_next) {
+ pgdat = pgdat->node_next;
+ zone = pgdat->node_zones;
+ } else
+ zone = NULL;
+
+ return zone;
+}
+
+/**
+ * for_each_zone - helper macro to iterate over all memory zones
+ * @zone - zone_t * variable
+ *
+ * The user only needs to declare the zone variable, for_each_zone
+ * fills it in. This basically means for_each_zone() is an
+ * easier to read version of this piece of code:
+ *
+ * for(pgdat = pgdat_list; pgdat; pgdat = pgdat->node_next)
+ * for(i = 0; i < MAX_NR_ZONES; ++i) {
+ * zone_t * z = pgdat->node_zones + i;
+ * ...
+ * }
+ * }
+ */
+#define for_each_zone(zone) \
+ for(zone = pgdat_list->node_zones; zone; zone = next_zone(zone))
+
+
#ifndef CONFIG_DISCONTIGMEM
#define NODE_DATA(nid) (&contig_page_data)
diff -uNr -Xdontdiff -p linux-2.4.20-pre1/mm/bootmem.c linux/mm/bootmem.c
--- linux-2.4.20-pre1/mm/bootmem.c Tue Aug 6 11:29:29 2002
+++ linux/mm/bootmem.c Tue Aug 6 15:09:19 2002
@@ -324,15 +324,14 @@ unsigned long __init free_all_bootmem (v
void * __init __alloc_bootmem (unsigned long size, unsigned long align, unsigned long goal)
{
- pg_data_t *pgdat = pgdat_list;
+ pg_data_t *pgdat;
void *ptr;
- while (pgdat) {
+ for_each_pgdat(pgdat)
if ((ptr = __alloc_bootmem_core(pgdat->bdata, size,
align, goal)))
return(ptr);
- pgdat = pgdat->node_next;
- }
+
/*
* Whoops, we cannot satisfy the allocation request.
*/
diff -uNr -Xdontdiff -p linux-2.4.20-pre1/mm/page_alloc.c linux/mm/page_alloc.c
--- linux-2.4.20-pre1/mm/page_alloc.c Tue Aug 6 11:27:49 2002
+++ linux/mm/page_alloc.c Tue Aug 6 15:07:05 2002
@@ -456,16 +456,12 @@ void free_pages(unsigned long addr, unsi
*/
unsigned int nr_free_pages (void)
{
- unsigned int sum;
+ unsigned int sum = 0;
zone_t *zone;
- pg_data_t *pgdat = pgdat_list;
- sum = 0;
- while (pgdat) {
- for (zone = pgdat->node_zones; zone < pgdat->node_zones + MAX_NR_ZONES; zone++)
- sum += zone->free_pages;
- pgdat = pgdat->node_next;
- }
+ for_each_zone(zone)
+ sum += zone->free_pages;
+
return sum;
}
@@ -474,10 +470,10 @@ unsigned int nr_free_pages (void)
*/
unsigned int nr_free_buffer_pages (void)
{
- pg_data_t *pgdat = pgdat_list;
+ pg_data_t *pgdat;
unsigned int sum = 0;
- do {
+ for_each_pgdat(pgdat) {
zonelist_t *zonelist = pgdat->node_zonelists + (GFP_USER & GFP_ZONEMASK);
zone_t **zonep = zonelist->zones;
zone_t *zone;
@@ -488,9 +484,7 @@ unsigned int nr_free_buffer_pages (void)
if (size > high)
sum += size - high;
}
-
- pgdat = pgdat->node_next;
- } while (pgdat);
+ }
return sum;
}
@@ -498,13 +492,12 @@ unsigned int nr_free_buffer_pages (void)
#if CONFIG_HIGHMEM
unsigned int nr_free_highpages (void)
{
- pg_data_t *pgdat = pgdat_list;
+ pg_data_t *pgdat;
unsigned int pages = 0;
- while (pgdat) {
+ for_each_pgdat(pgdat)
pages += pgdat->node_zones[ZONE_HIGHMEM].free_pages;
- pgdat = pgdat->node_next;
- }
+
return pages;
}
#endif
diff -uNr -Xdontdiff -p linux-2.4.20-pre1/mm/vmscan.c linux/mm/vmscan.c
--- linux-2.4.20-pre1/mm/vmscan.c Tue Aug 6 11:28:13 2002
+++ linux/mm/vmscan.c Tue Aug 6 15:08:56 2002
@@ -649,10 +649,9 @@ static void kswapd_balance(void)
do {
need_more_balance = 0;
- pgdat = pgdat_list;
- do
+
+ for_each_pgdat(pgdat)
need_more_balance |= kswapd_balance_pgdat(pgdat);
- while ((pgdat = pgdat->node_next));
} while (need_more_balance);
}
@@ -675,12 +674,10 @@ static int kswapd_can_sleep(void)
{
pg_data_t * pgdat;
- pgdat = pgdat_list;
- do {
- if (kswapd_can_sleep_pgdat(pgdat))
- continue;
- return 0;
- } while ((pgdat = pgdat->node_next));
+ for_each_pgdat(pgdat) {
+ if (!kswapd_can_sleep_pgdat(pgdat))
+ return 0;
+ }
return 1;
}
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/
reply other threads:[~2002-08-06 14:11 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20020806161109.A2543@lst.de \
--to=hch@lst.de \
--cc=linux-mm@kvack.org \
--cc=marcelo@conectiva.com.br \
--cc=riel@conectiva.com.br \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.