Messages in this thread | | | Subject | Re: Regression - locking (all from 2.6.28) | From | Catalin Marinas <> | Date | Fri, 06 Mar 2009 16:40:16 +0000 |
| |
On Wed, 2009-03-04 at 16:54 -0800, Dave Hansen wrote: > On Tue, 2009-03-03 at 15:01 +0000, Catalin Marinas wrote: > > > + /* mem_map scanning */ > > > + for_each_online_node(i) { > > > + struct page *page, *end; > > > + > > > + page = NODE_MEM_MAP(i); > > > + end = page + NODE_DATA(i)->node_spanned_pages; > > > + > > > + scan_block(page, end, NULL); > > > + } [...] > One completely unoptimized thing you can do which will scan a 'struct > page' at a time is this: > > for_each_online_node(i) { > unsigned long pfn; > for (pfn = node_start_pfn(i); pfn < node_end_pfn(i); pfn++) { > struct page *page; > if (!pfn_valid(pfn)) > continue; > page = pfn_to_page(pfn); > scan_block(page, page+1, NULL); > } > }
It seems that node_start_pfn() isn't present on all the architectures. I ended up with something like below:
+ /* struct page scanning for each node */ + for_each_online_node(i) { + pg_data_t *pgdat = NODE_DATA(i); + unsigned long start_pfn = pgdat->node_start_pfn; + unsigned long end_pfn = start_pfn + + pgdat->node_spanned_pages - 1; + unsigned long pfn; + + for (pfn = start_pfn; pfn < end_pfn; pfn++) { + struct page *page; + + if (!pfn_valid(pfn)) + continue; + page = pfn_to_page(pfn); + /* only scan if page is in use */ + if (page_count(page) == 0) + continue; + scan_block(page, page + 1, NULL); + } + }
Are the pgdat->node_start_pfn and pgdat->node_spanned_pages always valid? Thanks.
-- Catalin
| |