summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@home.transmeta.com>2002-09-19 08:40:45 -0700
committerLinus Torvalds <torvalds@home.transmeta.com>2002-09-19 08:40:45 -0700
commit2188a61733d33ca69bb49c92a2a31b93099028c4 (patch)
tree4c1cd1c823ce987c34750ccb8af5e3d4a83aa0f3 /include
parent075ee9780bae0f5e1b59567dbdd463d1234d23f5 (diff)
parentc7ea169dbcf0fed457edead3cb615f0c5fe8995e (diff)
Merge home.transmeta.com:/home/torvalds/v2.5/akpm
into home.transmeta.com:/home/torvalds/v2.5/linux
Diffstat (limited to 'include')
-rw-r--r--include/asm-alpha/mmzone.h8
-rw-r--r--include/asm-alpha/numnodes.h12
-rw-r--r--include/asm-i386/mmzone.h16
-rw-r--r--include/asm-i386/numaq.h9
-rw-r--r--include/asm-i386/numnodes.h (renamed from include/asm-i386/max_numnodes.h)0
-rw-r--r--include/asm-i386/page.h2
-rw-r--r--include/asm-mips64/mmzone.h1
-rw-r--r--include/asm-mips64/pgtable.h8
-rw-r--r--include/linux/fs.h8
-rw-r--r--include/linux/gfp.h19
-rw-r--r--include/linux/mm.h7
-rw-r--r--include/linux/mmzone.h23
-rw-r--r--include/linux/mpage.h8
-rw-r--r--include/linux/sysctl.h13
-rw-r--r--include/linux/uio.h6
-rw-r--r--include/linux/writeback.h30
16 files changed, 108 insertions, 62 deletions
diff --git a/include/asm-alpha/mmzone.h b/include/asm-alpha/mmzone.h
index 572569df5dd4..4059862d4b3d 100644
--- a/include/asm-alpha/mmzone.h
+++ b/include/asm-alpha/mmzone.h
@@ -36,18 +36,14 @@ extern plat_pg_data_t *plat_node_data[];
#ifdef CONFIG_ALPHA_WILDFIRE
# define ALPHA_PA_TO_NID(pa) ((pa) >> 36) /* 16 nodes max due 43bit kseg */
-#define NODE_MAX_MEM_SIZE (64L * 1024L * 1024L * 1024L) /* 64 GB */
-#define MAX_NUMNODES WILDFIRE_MAX_QBB
+# define NODE_MAX_MEM_SIZE (64L * 1024L * 1024L * 1024L) /* 64 GB */
#else
# define ALPHA_PA_TO_NID(pa) (0)
-#define NODE_MAX_MEM_SIZE (~0UL)
-#define MAX_NUMNODES 1
+# define NODE_MAX_MEM_SIZE (~0UL)
#endif
#define PHYSADDR_TO_NID(pa) ALPHA_PA_TO_NID(pa)
#define PLAT_NODE_DATA(n) (plat_node_data[(n)])
-#define PLAT_NODE_DATA_STARTNR(n) \
- (PLAT_NODE_DATA(n)->gendata.node_start_mapnr)
#define PLAT_NODE_DATA_SIZE(n) (PLAT_NODE_DATA(n)->gendata.node_size)
#if 1
diff --git a/include/asm-alpha/numnodes.h b/include/asm-alpha/numnodes.h
new file mode 100644
index 000000000000..4ff6b3ecfbed
--- /dev/null
+++ b/include/asm-alpha/numnodes.h
@@ -0,0 +1,12 @@
+#ifndef _ASM_MAX_NUMNODES_H
+#define _ASM_MAX_NUMNODES_H
+
+/*
+ * Currently the Wildfire is the only discontigmem/NUMA capable Alpha core.
+ */
+#if defined(CONFIG_ALPHA_WILDFIRE) || defined(CONFIG_ALPHA_GENERIC)
+# include <asm/core_wildfire.h>
+# define MAX_NUMNODES WILDFIRE_MAX_QBB
+#endif
+
+#endif /* _ASM_MAX_NUMNODES_H */
diff --git a/include/asm-i386/mmzone.h b/include/asm-i386/mmzone.h
index d2994f116f03..00a5d7ffbed9 100644
--- a/include/asm-i386/mmzone.h
+++ b/include/asm-i386/mmzone.h
@@ -6,12 +6,13 @@
#ifndef _ASM_MMZONE_H_
#define _ASM_MMZONE_H_
+#include <asm/smp.h>
+
#ifdef CONFIG_DISCONTIGMEM
#ifdef CONFIG_X86_NUMAQ
#include <asm/numaq.h>
#else
-#define pa_to_nid(pa) (0)
#define pfn_to_nid(pfn) (0)
#ifdef CONFIG_NUMA
#define _cpu_to_node(cpu) 0
@@ -44,7 +45,6 @@ extern struct pglist_data *node_data[];
#define alloc_bootmem_low_pages_node(ignore, x) \
__alloc_bootmem_node(NODE_DATA(0), (x), PAGE_SIZE, 0)
-#define node_startnr(nid) (node_data[nid]->node_start_mapnr)
#define node_size(nid) (node_data[nid]->node_size)
#define node_localnr(pfn, nid) ((pfn) - node_data[nid]->node_start_pfn)
@@ -55,7 +55,7 @@ extern struct pglist_data *node_data[];
/*
* Given a kernel address, find the home node of the underlying memory.
*/
-#define kvaddr_to_nid(kaddr) pa_to_nid(__pa(kaddr))
+#define kvaddr_to_nid(kaddr) pfn_to_nid(__pa(kaddr) >> PAGE_SHIFT)
/*
* Return a pointer to the node data for node n.
@@ -64,6 +64,8 @@ extern struct pglist_data *node_data[];
#define node_mem_map(nid) (NODE_DATA(nid)->node_mem_map)
#define node_start_pfn(nid) (NODE_DATA(nid)->node_start_pfn)
+#define node_end_pfn(nid) (NODE_DATA(nid)->node_start_pfn + \
+ NODE_DATA(nid)->node_size)
#define local_mapnr(kvaddr) \
( (__pa(kvaddr) >> PAGE_SHIFT) - node_start_pfn(kvaddr_to_nid(kvaddr)) )
@@ -74,5 +76,13 @@ extern struct pglist_data *node_data[];
#define pfn_to_page(pfn) (node_mem_map(pfn_to_nid(pfn)) + node_localnr(pfn, pfn_to_nid(pfn)))
#define page_to_pfn(page) ((page - page_zone(page)->zone_mem_map) + page_zone(page)->zone_start_pfn)
#define pmd_page(pmd) (pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT))
+/*
+ * pfn_valid should be made as fast as possible, and the current definition
+ * is valid for machines that are NUMA, but still contiguous, which is what
+ * is currently supported. A more generalised, but slower definition would
+ * be something like this - mbligh:
+ * ( pfn_to_pgdat(pfn) && (pfn < node_end_pfn(pfn_to_nid(pfn))) )
+ */
+#define pfn_valid(pfn) (pfn < num_physpages)
#endif /* CONFIG_DISCONTIGMEM */
#endif /* _ASM_MMZONE_H_ */
diff --git a/include/asm-i386/numaq.h b/include/asm-i386/numaq.h
index ed10442f1dcc..b32b28c12c73 100644
--- a/include/asm-i386/numaq.h
+++ b/include/asm-i386/numaq.h
@@ -32,17 +32,18 @@
/*
* for now assume that 64Gb is max amount of RAM for whole system
- * 64Gb * 1024Mb/Gb = 65536 Mb
- * 65536 Mb / 256Mb = 256
+ * 64Gb / 4096bytes/page = 16777216 pages
*/
+#define MAX_NR_PAGES 16777216
#define MAX_ELEMENTS 256
-#define ELEMENT_REPRESENTS 8 /* 256 Mb */
+#define PAGES_PER_ELEMENT (16777216/256)
+#define pfn_to_pgdat(pfn) NODE_DATA(pfn_to_nid(pfn))
+#define PHYSADDR_TO_NID(pa) pfn_to_nid(pa >> PAGE_SHIFT)
#define MAX_NUMNODES 8
#ifdef CONFIG_NUMA
#define _cpu_to_node(cpu) (cpu_to_logical_apicid(cpu) >> 4)
#endif /* CONFIG_NUMA */
-extern int pa_to_nid(u64);
extern int pfn_to_nid(unsigned long);
extern void get_memcfg_numaq(void);
#define get_memcfg_numa() get_memcfg_numaq()
diff --git a/include/asm-i386/max_numnodes.h b/include/asm-i386/numnodes.h
index 2b63299604ef..2b63299604ef 100644
--- a/include/asm-i386/max_numnodes.h
+++ b/include/asm-i386/numnodes.h
diff --git a/include/asm-i386/page.h b/include/asm-i386/page.h
index 5a09fd4b72f1..f9fe284b9057 100644
--- a/include/asm-i386/page.h
+++ b/include/asm-i386/page.h
@@ -145,10 +145,10 @@ static __inline__ int get_order(unsigned long size)
#ifndef CONFIG_DISCONTIGMEM
#define pfn_to_page(pfn) (mem_map + (pfn))
#define page_to_pfn(page) ((unsigned long)((page) - mem_map))
+#define pfn_valid(pfn) ((pfn) < max_mapnr)
#endif /* !CONFIG_DISCONTIGMEM */
#define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
-#define pfn_valid(pfn) ((pfn) < max_mapnr)
#define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT)
#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
diff --git a/include/asm-mips64/mmzone.h b/include/asm-mips64/mmzone.h
index 5e643b114269..d60ad12acd75 100644
--- a/include/asm-mips64/mmzone.h
+++ b/include/asm-mips64/mmzone.h
@@ -24,7 +24,6 @@ extern plat_pg_data_t *plat_node_data[];
#define PHYSADDR_TO_NID(pa) NASID_TO_COMPACT_NODEID(NASID_GET(pa))
#define PLAT_NODE_DATA(n) (plat_node_data[n])
-#define PLAT_NODE_DATA_STARTNR(n) (PLAT_NODE_DATA(n)->gendata.node_start_mapnr)
#define PLAT_NODE_DATA_SIZE(n) (PLAT_NODE_DATA(n)->gendata.node_size)
#define PLAT_NODE_DATA_LOCALNR(p, n) \
(((p) >> PAGE_SHIFT) - PLAT_NODE_DATA(n)->gendata.node_start_pfn)
diff --git a/include/asm-mips64/pgtable.h b/include/asm-mips64/pgtable.h
index ded7d0a0a986..b32768e57d16 100644
--- a/include/asm-mips64/pgtable.h
+++ b/include/asm-mips64/pgtable.h
@@ -373,10 +373,10 @@ extern inline void pgd_clear(pgd_t *pgdp)
#ifndef CONFIG_DISCONTIGMEM
#define pte_page(x) (mem_map+(unsigned long)((pte_val(x) >> PAGE_SHIFT)))
#else
-#define mips64_pte_pagenr(x) \
- (PLAT_NODE_DATA_STARTNR(PHYSADDR_TO_NID(pte_val(x))) + \
- PLAT_NODE_DATA_LOCALNR(pte_val(x), PHYSADDR_TO_NID(pte_val(x))))
-#define pte_page(x) (mem_map+mips64_pte_pagenr(x))
+
+#define pte_page(x) ( NODE_MEM_MAP(PHYSADDR_TO_NID(pte_val(x))) +
+ PLAT_NODE_DATA_LOCALNR(pte_val(x), PHYSADDR_TO_NID(pte_val(x))) )
+
#endif
/*
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 804ea47301f5..56f2bab87d7f 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -279,6 +279,7 @@ struct iattr {
*/
struct page;
struct address_space;
+struct writeback_control;
struct address_space_operations {
int (*writepage)(struct page *);
@@ -286,10 +287,10 @@ struct address_space_operations {
int (*sync_page)(struct page *);
/* Write back some dirty pages from this mapping. */
- int (*writepages)(struct address_space *, int *nr_to_write);
+ int (*writepages)(struct address_space *, struct writeback_control *);
/* Perform a writeback as a memory-freeing operation. */
- int (*vm_writeback)(struct page *, int *nr_to_write);
+ int (*vm_writeback)(struct page *, struct writeback_control *);
/* Set a page dirty */
int (*set_page_dirty)(struct page *page);
@@ -1259,7 +1260,8 @@ extern loff_t generic_file_llseek(struct file *file, loff_t offset, int origin);
extern loff_t remote_llseek(struct file *file, loff_t offset, int origin);
extern int generic_file_open(struct inode * inode, struct file * filp);
-extern int generic_vm_writeback(struct page *page, int *nr_to_write);
+extern int generic_vm_writeback(struct page *page,
+ struct writeback_control *wbc);
extern struct file_operations generic_ro_fops;
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index 10021357c093..437572e2240b 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -39,18 +39,25 @@
* can allocate highmem pages, the *get*page*() variants return
* virtual kernel addresses to the allocated page(s).
*/
-extern struct page * FASTCALL(_alloc_pages(unsigned int gfp_mask, unsigned int order));
extern struct page * FASTCALL(__alloc_pages(unsigned int gfp_mask, unsigned int order, struct zonelist *zonelist));
extern struct page * alloc_pages_node(int nid, unsigned int gfp_mask, unsigned int order);
+/*
+ * We get the zone list from the current node and the gfp_mask.
+ * This zone list contains a maximum of MAXNODES*MAX_NR_ZONES zones.
+ *
+ * For the normal case of non-DISCONTIGMEM systems the NODE_DATA() gets
+ * optimized to &contig_page_data at compile-time.
+ */
static inline struct page * alloc_pages(unsigned int gfp_mask, unsigned int order)
{
- /*
- * Gets optimized away by the compiler.
- */
- if (order >= MAX_ORDER)
+ pg_data_t *pgdat = NODE_DATA(numa_node_id());
+ unsigned int idx = (gfp_mask & GFP_ZONEMASK);
+
+ if (unlikely(order >= MAX_ORDER))
return NULL;
- return _alloc_pages(gfp_mask, order);
+
+ return __alloc_pages(gfp_mask, order, pgdat->node_zonelists + idx);
}
#define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0)
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 7483c39e28dd..c63e4947387f 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -15,7 +15,10 @@
#include <linux/rbtree.h>
#include <linux/fs.h>
+#ifndef CONFIG_DISCONTIGMEM /* Don't use mapnrs, do it properly */
extern unsigned long max_mapnr;
+#endif
+
extern unsigned long num_physpages;
extern void * high_memory;
extern int page_cluster;
@@ -345,8 +348,10 @@ static inline int page_mapped(struct page *page)
#define VM_FAULT_MINOR 1
#define VM_FAULT_MAJOR 2
-/* The array of struct pages */
+#ifndef CONFIG_DISCONTIGMEM
+/* The array of struct pages - for discontigmem use pgdat->lmem_map */
extern struct page *mem_map;
+#endif
extern void show_free_areas(void);
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 8ebf441bdb47..580c39c4dcc1 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -10,11 +10,14 @@
#include <linux/wait.h>
#include <linux/cache.h>
#include <asm/atomic.h>
+#ifdef CONFIG_DISCONTIGMEM
+#include <asm/numnodes.h>
+#endif
+#ifndef MAX_NUMNODES
+#define MAX_NUMNODES 1
+#endif
-/*
- * Free memory management - zoned buddy allocator.
- */
-
+/* Free memory management - zoned buddy allocator. */
#ifndef CONFIG_FORCE_MAX_ZONEORDER
#define MAX_ORDER 11
#else
@@ -112,7 +115,6 @@ struct zone {
struct page *zone_mem_map;
/* zone_start_pfn == zone_start_paddr >> PAGE_SHIFT */
unsigned long zone_start_pfn;
- unsigned long zone_start_mapnr;
/*
* rarely used fields:
@@ -138,7 +140,7 @@ struct zone {
* footprint of this construct is very small.
*/
struct zonelist {
- struct zone *zones[MAX_NR_ZONES+1]; // NULL delimited
+ struct zone *zones[MAX_NUMNODES * MAX_NR_ZONES + 1]; // NULL delimited
};
#define GFP_ZONEMASK 0x0f
@@ -163,7 +165,6 @@ typedef struct pglist_data {
unsigned long *valid_addr_bitmap;
struct bootmem_data *bdata;
unsigned long node_start_pfn;
- unsigned long node_start_mapnr;
unsigned long node_size;
int node_id;
struct pglist_data *pgdat_next;
@@ -187,10 +188,12 @@ memclass(struct zone *pgzone, struct zone *classzone)
* prototypes for the discontig memory code.
*/
struct page;
-void free_area_init_core(int nid, pg_data_t *pgdat, struct page **gmap,
- unsigned long *zones_size, unsigned long paddr, unsigned long *zholes_size,
- struct page *pmap);
+extern void calculate_totalpages (pg_data_t *pgdat, unsigned long *zones_size,
+ unsigned long *zholes_size);
+extern void free_area_init_core(pg_data_t *pgdat, unsigned long *zones_size,
+ unsigned long *zholes_size);
void get_zone_counts(unsigned long *active, unsigned long *inactive);
+extern void build_all_zonelists(void);
extern pg_data_t contig_page_data;
diff --git a/include/linux/mpage.h b/include/linux/mpage.h
index 52253d90f55d..86aa7b676274 100644
--- a/include/linux/mpage.h
+++ b/include/linux/mpage.h
@@ -10,14 +10,16 @@
* nested includes. Get it right in the .c file).
*/
+struct writeback_control;
+
int mpage_readpages(struct address_space *mapping, struct list_head *pages,
unsigned nr_pages, get_block_t get_block);
int mpage_readpage(struct page *page, get_block_t get_block);
int mpage_writepages(struct address_space *mapping,
- int *nr_to_write, get_block_t get_block);
+ struct writeback_control *wbc, get_block_t get_block);
static inline int
-generic_writepages(struct address_space *mapping, int *nr_to_write)
+generic_writepages(struct address_space *mapping, struct writeback_control *wbc)
{
- return mpage_writepages(mapping, nr_to_write, NULL);
+ return mpage_writepages(mapping, wbc, NULL);
}
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 3127165e7c13..9fd7d5c05605 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -128,7 +128,6 @@ enum
KERN_TAINTED=53, /* int: various kernel tainted flags */
KERN_CADPID=54, /* int: PID of the process to notify on CAD */
KERN_PIDMAX=55, /* int: PID # limit */
- KERN_HUGETLB_PAGE_NUM=56, /* int: Number of available Huge Pages */
};
@@ -147,12 +146,12 @@ enum
VM_PAGE_CLUSTER=10, /* int: set number of pages to swap together */
VM_DIRTY_BACKGROUND=11, /* dirty_background_ratio */
VM_DIRTY_ASYNC=12, /* dirty_async_ratio */
- VM_DIRTY_SYNC=13, /* dirty_sync_ratio */
- VM_DIRTY_WB_CS=14, /* dirty_writeback_centisecs */
- VM_DIRTY_EXPIRE_CS=15, /* dirty_expire_centisecs */
- VM_NR_PDFLUSH_THREADS=16, /* nr_pdflush_threads */
- VM_OVERCOMMIT_RATIO=17, /* percent of RAM to allow overcommit in */
- VM_PAGEBUF=18 /* struct: Control pagebuf parameters */
+ VM_DIRTY_WB_CS=13, /* dirty_writeback_centisecs */
+ VM_DIRTY_EXPIRE_CS=14, /* dirty_expire_centisecs */
+ VM_NR_PDFLUSH_THREADS=15, /* nr_pdflush_threads */
+ VM_OVERCOMMIT_RATIO=16, /* percent of RAM to allow overcommit in */
+ VM_PAGEBUF=17, /* struct: Control pagebuf parameters */
+ VM_HUGETLB_PAGES=18, /* int: Number of available Huge Pages */
};
diff --git a/include/linux/uio.h b/include/linux/uio.h
index ec098c8e6793..85b2f0ec9d3f 100644
--- a/include/linux/uio.h
+++ b/include/linux/uio.h
@@ -35,7 +35,11 @@ struct iovec
#endif
/*
- * Total number of bytes covered by an iovec
+ * Total number of bytes covered by an iovec.
+ *
+ * NOTE that it is not safe to use this function until all the iovec's
+ * segment lengths have been validated. Because the individual lengths can
+ * overflow a size_t when added together.
*/
static inline size_t iov_length(const struct iovec *iov, unsigned long nr_segs)
{
diff --git a/include/linux/writeback.h b/include/linux/writeback.h
index 5de884cd6a7c..c35b96eb6a90 100644
--- a/include/linux/writeback.h
+++ b/include/linux/writeback.h
@@ -27,22 +27,29 @@ static inline int current_is_pdflush(void)
* fs/fs-writeback.c
*/
enum writeback_sync_modes {
- WB_SYNC_NONE = 0, /* Don't wait on anything */
- WB_SYNC_LAST = 1, /* Wait on the last-written mapping */
- WB_SYNC_ALL = 2, /* Wait on every mapping */
- WB_SYNC_HOLD = 3, /* Hold the inode on sb_dirty for sys_sync() */
+ WB_SYNC_NONE, /* Don't wait on anything */
+ WB_SYNC_ALL, /* Wait on every mapping */
+ WB_SYNC_HOLD, /* Hold the inode on sb_dirty for sys_sync() */
};
-void writeback_unlocked_inodes(int *nr_to_write,
- enum writeback_sync_modes sync_mode,
- unsigned long *older_than_this);
+/*
+ * A control structure which tells the writeback code what to do
+ */
+struct writeback_control {
+ struct backing_dev_info *bdi; /* If !NULL, only write back this
+ queue */
+ enum writeback_sync_modes sync_mode;
+ unsigned long *older_than_this; /* If !NULL, only write back inodes
+ older than this */
+ long nr_to_write; /* Write this many pages, and decrement
+ this for each page written */
+};
+
+void writeback_inodes(struct writeback_control *wbc);
void wake_up_inode(struct inode *inode);
void __wait_on_inode(struct inode * inode);
void sync_inodes_sb(struct super_block *, int wait);
void sync_inodes(int wait);
-void writeback_backing_dev(struct backing_dev_info *bdi, int *nr_to_write,
- enum writeback_sync_modes sync_mode,
- unsigned long *older_than_this);
/* writeback.h requires fs.h; it, too, is not included from here. */
static inline void wait_on_inode(struct inode *inode)
@@ -57,7 +64,6 @@ static inline void wait_on_inode(struct inode *inode)
/* These 5 are exported to sysctl. */
extern int dirty_background_ratio;
extern int dirty_async_ratio;
-extern int dirty_sync_ratio;
extern int dirty_writeback_centisecs;
extern int dirty_expire_centisecs;
@@ -65,7 +71,7 @@ extern int dirty_expire_centisecs;
void balance_dirty_pages(struct address_space *mapping);
void balance_dirty_pages_ratelimited(struct address_space *mapping);
int pdflush_operation(void (*fn)(unsigned long), unsigned long arg0);
-int do_writepages(struct address_space *mapping, int *nr_to_write);
+int do_writepages(struct address_space *mapping, struct writeback_control *wbc);
/* pdflush.c */
extern int nr_pdflush_threads; /* Global so it can be exported to sysctl