Commit a97c3b80 authored by Linus Torvalds's avatar Linus Torvalds

Merge penguin:v2.5/linux

into athlon.transmeta.com:/home/torvalds/v2.5/linux
parents 8e018235 748261c0
...@@ -87,13 +87,16 @@ static void scsi_dump_status(int level); ...@@ -87,13 +87,16 @@ static void scsi_dump_status(int level);
struct scsi_host_sg_pool { struct scsi_host_sg_pool {
int size; int size;
char *name;
kmem_cache_t *slab; kmem_cache_t *slab;
mempool_t *pool; mempool_t *pool;
}; };
static const int scsi_host_sg_pool_sizes[SG_MEMPOOL_NR] = { 8, 16, 32, 64, MAX_PHYS_SEGMENTS }; #define SP(x) { x, "sgpool-" #x }
struct scsi_host_sg_pool scsi_sg_pools[SG_MEMPOOL_NR]; struct scsi_host_sg_pool scsi_sg_pools[SG_MEMPOOL_NR] = {
SP(8), SP(16), SP(32), SP(64), SP(MAX_PHYS_SEGMENTS)
};
#undef SP
/* /*
static const char RCSid[] = "$Header: /vger/u4/cvs/linux/drivers/scsi/scsi.c,v 1.38 1997/01/19 23:07:18 davem Exp $"; static const char RCSid[] = "$Header: /vger/u4/cvs/linux/drivers/scsi/scsi.c,v 1.38 1997/01/19 23:07:18 davem Exp $";
*/ */
...@@ -2489,7 +2492,6 @@ void scsi_free_sgtable(struct scatterlist *sgl, int index) ...@@ -2489,7 +2492,6 @@ void scsi_free_sgtable(struct scatterlist *sgl, int index)
static int __init init_scsi(void) static int __init init_scsi(void)
{ {
struct proc_dir_entry *generic; struct proc_dir_entry *generic;
char name[16];
int i; int i;
printk(KERN_INFO "SCSI subsystem driver " REVISION "\n"); printk(KERN_INFO "SCSI subsystem driver " REVISION "\n");
...@@ -2499,18 +2501,15 @@ static int __init init_scsi(void) ...@@ -2499,18 +2501,15 @@ static int __init init_scsi(void)
*/ */
for (i = 0; i < SG_MEMPOOL_NR; i++) { for (i = 0; i < SG_MEMPOOL_NR; i++) {
struct scsi_host_sg_pool *sgp = scsi_sg_pools + i; struct scsi_host_sg_pool *sgp = scsi_sg_pools + i;
int size = scsi_host_sg_pool_sizes[i] * sizeof(struct scatterlist); int size = sgp->size * sizeof(struct scatterlist);
snprintf(name, sizeof(name) - 1, "sgpool-%d", scsi_host_sg_pool_sizes[i]); sgp->slab = kmem_cache_create(sgp->name, size, 0, SLAB_HWCACHE_ALIGN, NULL, NULL);
sgp->slab = kmem_cache_create(name, size, 0, SLAB_HWCACHE_ALIGN, NULL, NULL);
if (!sgp->slab) if (!sgp->slab)
panic("SCSI: can't init sg slab\n"); panic("SCSI: can't init sg slab\n");
sgp->pool = mempool_create(SG_MEMPOOL_SIZE, scsi_pool_alloc, scsi_pool_free, sgp->slab); sgp->pool = mempool_create(SG_MEMPOOL_SIZE, scsi_pool_alloc, scsi_pool_free, sgp->slab);
if (!sgp->pool) if (!sgp->pool)
panic("SCSI: can't init sg mempool\n"); panic("SCSI: can't init sg mempool\n");
sgp->size = size;
} }
/* /*
......
...@@ -33,20 +33,24 @@ static kmem_cache_t *bio_slab; ...@@ -33,20 +33,24 @@ static kmem_cache_t *bio_slab;
struct biovec_pool { struct biovec_pool {
int size; int size;
char *name;
kmem_cache_t *slab; kmem_cache_t *slab;
mempool_t *pool; mempool_t *pool;
}; };
static struct biovec_pool bvec_array[BIOVEC_NR_POOLS];
/* /*
* if you change this list, also change bvec_alloc or things will * if you change this list, also change bvec_alloc or things will
* break badly! cannot be bigger than what you can fit into an * break badly! cannot be bigger than what you can fit into an
* unsigned short * unsigned short
*/ */
static const int bvec_pool_sizes[BIOVEC_NR_POOLS] = { 1, 4, 16, 64, 128, 256 };
#define BIO_MAX_PAGES (bvec_pool_sizes[BIOVEC_NR_POOLS - 1]) #define BV(x) { x, "biovec-" #x }
static struct biovec_pool bvec_array[BIOVEC_NR_POOLS] = {
BV(1), BV(4), BV(16), BV(64), BV(128), BV(256)
};
#undef BV
#define BIO_MAX_PAGES (bvec_array[BIOVEC_NR_POOLS - 1].size)
static void *slab_pool_alloc(int gfp_mask, void *data) static void *slab_pool_alloc(int gfp_mask, void *data)
{ {
...@@ -64,7 +68,7 @@ static inline struct bio_vec *bvec_alloc(int gfp_mask, int nr, int *idx) ...@@ -64,7 +68,7 @@ static inline struct bio_vec *bvec_alloc(int gfp_mask, int nr, int *idx)
struct bio_vec *bvl; struct bio_vec *bvl;
/* /*
* see comment near bvec_pool_sizes define! * see comment near bvec_array define!
*/ */
switch (nr) { switch (nr) {
case 1 : *idx = 0; break; case 1 : *idx = 0; break;
...@@ -452,21 +456,17 @@ int bio_endio(struct bio *bio, int uptodate, int nr_sectors) ...@@ -452,21 +456,17 @@ int bio_endio(struct bio *bio, int uptodate, int nr_sectors)
static void __init biovec_init_pool(void) static void __init biovec_init_pool(void)
{ {
char name[16];
int i, size; int i, size;
memset(&bvec_array, 0, sizeof(bvec_array));
for (i = 0; i < BIOVEC_NR_POOLS; i++) { for (i = 0; i < BIOVEC_NR_POOLS; i++) {
struct biovec_pool *bp = bvec_array + i; struct biovec_pool *bp = bvec_array + i;
size = bvec_pool_sizes[i] * sizeof(struct bio_vec); size = bp->size * sizeof(struct bio_vec);
printk("biovec: init pool %d, %d entries, %d bytes\n", i, printk("biovec: init pool %d, %d entries, %d bytes\n", i,
bvec_pool_sizes[i], size); bp->size, size);
snprintf(name, sizeof(name) - 1,"biovec-%d",bvec_pool_sizes[i]); bp->slab = kmem_cache_create(bp->name, size, 0,
bp->slab = kmem_cache_create(name, size, 0,
SLAB_HWCACHE_ALIGN, NULL, NULL); SLAB_HWCACHE_ALIGN, NULL, NULL);
if (!bp->slab) if (!bp->slab)
panic("biovec: can't init slab cache\n"); panic("biovec: can't init slab cache\n");
...@@ -474,7 +474,7 @@ static void __init biovec_init_pool(void) ...@@ -474,7 +474,7 @@ static void __init biovec_init_pool(void)
slab_pool_free, bp->slab); slab_pool_free, bp->slab);
if (!bp->pool) if (!bp->pool)
panic("biovec: can't init mempool\n"); panic("biovec: can't init mempool\n");
bp->size = size; bp->size = size;
} }
} }
......
...@@ -1283,6 +1283,7 @@ void __init vfs_caches_init(unsigned long mempages) ...@@ -1283,6 +1283,7 @@ void __init vfs_caches_init(unsigned long mempages)
dcache_init(mempages); dcache_init(mempages);
inode_init(mempages); inode_init(mempages);
files_init(mempages);
mnt_init(mempages); mnt_init(mempages);
bdev_cache_init(); bdev_cache_init();
cdev_cache_init(); cdev_cache_init();
......
...@@ -186,3 +186,17 @@ int fs_may_remount_ro(struct super_block *sb) ...@@ -186,3 +186,17 @@ int fs_may_remount_ro(struct super_block *sb)
file_list_unlock(); file_list_unlock();
return 0; return 0;
} }
void __init files_init(unsigned long mempages)
{
int n;
/* One file with associated inode and dcache is very roughly 1K.
* Per default don't use more than 10% of our memory for files.
*/
n = (mempages * (PAGE_SIZE / 1024)) / 10;
files_stat.max_files = n;
if (files_stat.max_files < NR_FILE)
files_stat.max_files = NR_FILE;
}
...@@ -1048,15 +1048,9 @@ void __init mnt_init(unsigned long mempages) ...@@ -1048,15 +1048,9 @@ void __init mnt_init(unsigned long mempages)
if (!mnt_cache) if (!mnt_cache)
panic("Cannot create vfsmount cache"); panic("Cannot create vfsmount cache");
mempages >>= (16 - PAGE_SHIFT); order = 0;
mempages *= sizeof(struct list_head); mount_hashtable = (struct list_head *)
for (order = 0; ((1UL << order) << PAGE_SHIFT) < mempages; order++) __get_free_pages(GFP_ATOMIC, order);
;
do {
mount_hashtable = (struct list_head *)
__get_free_pages(GFP_ATOMIC, order);
} while (mount_hashtable == NULL && --order >= 0);
if (!mount_hashtable) if (!mount_hashtable)
panic("Failed to allocate mount hash table\n"); panic("Failed to allocate mount hash table\n");
......
...@@ -455,6 +455,8 @@ nfs_read_super(struct super_block *sb, void *raw_data, int silent) ...@@ -455,6 +455,8 @@ nfs_read_super(struct super_block *sb, void *raw_data, int silent)
server->namelen = maxlen; server->namelen = maxlen;
sb->s_maxbytes = fsinfo.maxfilesize; sb->s_maxbytes = fsinfo.maxfilesize;
if (sb->s_maxbytes > MAX_LFS_FILESIZE)
sb->s_maxbytes = MAX_LFS_FILESIZE;
/* Fire up the writeback cache */ /* Fire up the writeback cache */
if (nfs_reqlist_alloc(server) < 0) { if (nfs_reqlist_alloc(server) < 0) {
......
...@@ -1130,7 +1130,7 @@ struct super_block *ntfs_read_super(struct super_block *sb, void *options, ...@@ -1130,7 +1130,7 @@ struct super_block *ntfs_read_super(struct super_block *sb, void *options,
/* Inform the kernel about which super operations are available. */ /* Inform the kernel about which super operations are available. */
sb->s_op = &ntfs_super_operations; sb->s_op = &ntfs_super_operations;
sb->s_magic = NTFS_SUPER_MAGIC; sb->s_magic = NTFS_SUPER_MAGIC;
sb->s_maxbytes = ~0ULL >> 1; sb->s_maxbytes = MAX_LFS_FILESIZE;
ntfs_debug(DEBUG_OTHER, "Reading special files\n"); ntfs_debug(DEBUG_OTHER, "Reading special files\n");
if (ntfs_load_special_files(vol)) { if (ntfs_load_special_files(vol)) {
ntfs_error("Error loading special files\n"); ntfs_error("Error loading special files\n");
......
...@@ -1544,7 +1544,7 @@ udf_read_super(struct super_block *sb, void *options, int silent) ...@@ -1544,7 +1544,7 @@ udf_read_super(struct super_block *sb, void *options, int silent)
iput(inode); iput(inode);
goto error_out; goto error_out;
} }
sb->s_maxbytes = ~0ULL; sb->s_maxbytes = MAX_LFS_FILESIZE;
return sb; return sb;
error_out: error_out:
......
...@@ -207,6 +207,7 @@ extern void update_atime (struct inode *); ...@@ -207,6 +207,7 @@ extern void update_atime (struct inode *);
extern void buffer_init(unsigned long); extern void buffer_init(unsigned long);
extern void inode_init(unsigned long); extern void inode_init(unsigned long);
extern void mnt_init(unsigned long); extern void mnt_init(unsigned long);
extern void files_init(unsigned long);
/* bh state bits */ /* bh state bits */
enum bh_state_bits { enum bh_state_bits {
...@@ -518,6 +519,14 @@ extern int init_private_file(struct file *, struct dentry *, int); ...@@ -518,6 +519,14 @@ extern int init_private_file(struct file *, struct dentry *, int);
#define MAX_NON_LFS ((1UL<<31) - 1) #define MAX_NON_LFS ((1UL<<31) - 1)
/* Page cache limit. The filesystems should put that into their s_maxbytes
limits, otherwise bad things can happen in VM. */
#if BITS_PER_LONG==32
#define MAX_LFS_FILESIZE (((u64)PAGE_CACHE_SIZE << (BITS_PER_LONG-1))-1)
#elif BITS_PER_LONG==64
#define MAX_LFS_FILESIZE 0x7fffffffffffffff
#endif
#define FL_POSIX 1 #define FL_POSIX 1
#define FL_FLOCK 2 #define FL_FLOCK 2
#define FL_BROKEN 4 /* broken flock() emulation */ #define FL_BROKEN 4 /* broken flock() emulation */
...@@ -1512,8 +1521,6 @@ static inline int is_mounted(kdev_t dev) ...@@ -1512,8 +1521,6 @@ static inline int is_mounted(kdev_t dev)
} }
return 0; return 0;
} }
unsigned long generate_cluster(kdev_t, int b[], int);
unsigned long generate_cluster_swab32(kdev_t, int b[], int);
extern kdev_t ROOT_DEV; extern kdev_t ROOT_DEV;
extern char root_device_name[]; extern char root_device_name[];
......
...@@ -247,19 +247,30 @@ static unsigned long __init free_all_bootmem_core(pg_data_t *pgdat) ...@@ -247,19 +247,30 @@ static unsigned long __init free_all_bootmem_core(pg_data_t *pgdat)
bootmem_data_t *bdata = pgdat->bdata; bootmem_data_t *bdata = pgdat->bdata;
unsigned long i, count, total = 0; unsigned long i, count, total = 0;
unsigned long idx; unsigned long idx;
unsigned long *map;
if (!bdata->node_bootmem_map) BUG(); if (!bdata->node_bootmem_map) BUG();
count = 0; count = 0;
idx = bdata->node_low_pfn - (bdata->node_boot_start >> PAGE_SHIFT); idx = bdata->node_low_pfn - (bdata->node_boot_start >> PAGE_SHIFT);
for (i = 0; i < idx; i++, page++) { map = bdata->node_bootmem_map;
if (!test_bit(i, bdata->node_bootmem_map)) { for (i = 0; i < idx; ) {
unsigned long v = ~map[i / BITS_PER_LONG];
if (v) {
unsigned long m;
for (m = 1; m && i < idx; m<<=1, page++, i++) {
if (v & m) {
count++; count++;
ClearPageReserved(page); ClearPageReserved(page);
set_page_count(page, 1); set_page_count(page, 1);
__free_page(page); __free_page(page);
} }
} }
} else {
i+=BITS_PER_LONG;
page+=BITS_PER_LONG;
}
}
total += count; total += count;
/* /*
......
...@@ -186,8 +186,6 @@ typedef struct cpucache_s { ...@@ -186,8 +186,6 @@ typedef struct cpucache_s {
* manages a cache. * manages a cache.
*/ */
#define CACHE_NAMELEN 20 /* max name length for a slab cache */
struct kmem_cache_s { struct kmem_cache_s {
/* 1) each alloc & free */ /* 1) each alloc & free */
/* full, partial first, then free */ /* full, partial first, then free */
...@@ -225,7 +223,7 @@ struct kmem_cache_s { ...@@ -225,7 +223,7 @@ struct kmem_cache_s {
unsigned long failures; unsigned long failures;
/* 3) cache creation/removal */ /* 3) cache creation/removal */
char name[CACHE_NAMELEN]; const char *name;
struct list_head next; struct list_head next;
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
/* 4) per-cpu data */ /* 4) per-cpu data */
...@@ -335,6 +333,7 @@ typedef struct cache_sizes { ...@@ -335,6 +333,7 @@ typedef struct cache_sizes {
kmem_cache_t *cs_dmacachep; kmem_cache_t *cs_dmacachep;
} cache_sizes_t; } cache_sizes_t;
/* These are the default caches for kmalloc. Custom caches can have other sizes. */
static cache_sizes_t cache_sizes[] = { static cache_sizes_t cache_sizes[] = {
#if PAGE_SIZE == 4096 #if PAGE_SIZE == 4096
{ 32, NULL, NULL}, { 32, NULL, NULL},
...@@ -353,6 +352,29 @@ static cache_sizes_t cache_sizes[] = { ...@@ -353,6 +352,29 @@ static cache_sizes_t cache_sizes[] = {
{131072, NULL, NULL}, {131072, NULL, NULL},
{ 0, NULL, NULL} { 0, NULL, NULL}
}; };
/* Must match cache_sizes above. Out of line to keep cache footprint low. */
#define CN(x) { x, x " (DMA)" }
static struct {
char *name;
char *name_dma;
} cache_names[] = {
#if PAGE_SIZE == 4096
CN("size-32"),
#endif
CN("size-64"),
CN("size-128"),
CN("size-256"),
CN("size-512"),
CN("size-1024"),
CN("size-2048"),
CN("size-4096"),
CN("size-8192"),
CN("size-16384"),
CN("size-32768"),
CN("size-65536"),
CN("size-131072")
};
#undef CN
/* internal cache of cache description objs */ /* internal cache of cache description objs */
static kmem_cache_t cache_cache = { static kmem_cache_t cache_cache = {
...@@ -437,7 +459,6 @@ void __init kmem_cache_init(void) ...@@ -437,7 +459,6 @@ void __init kmem_cache_init(void)
void __init kmem_cache_sizes_init(void) void __init kmem_cache_sizes_init(void)
{ {
cache_sizes_t *sizes = cache_sizes; cache_sizes_t *sizes = cache_sizes;
char name[20];
/* /*
* Fragmentation resistance on low memory - only use bigger * Fragmentation resistance on low memory - only use bigger
* page orders on machines with more than 32MB of memory. * page orders on machines with more than 32MB of memory.
...@@ -450,9 +471,9 @@ void __init kmem_cache_sizes_init(void) ...@@ -450,9 +471,9 @@ void __init kmem_cache_sizes_init(void)
* eliminates "false sharing". * eliminates "false sharing".
* Note for systems short on memory removing the alignment will * Note for systems short on memory removing the alignment will
* allow tighter packing of the smaller caches. */ * allow tighter packing of the smaller caches. */
sprintf(name,"size-%Zd",sizes->cs_size);
if (!(sizes->cs_cachep = if (!(sizes->cs_cachep =
kmem_cache_create(name, sizes->cs_size, kmem_cache_create(cache_names[sizes-cache_sizes].name,
sizes->cs_size,
0, SLAB_HWCACHE_ALIGN, NULL, NULL))) { 0, SLAB_HWCACHE_ALIGN, NULL, NULL))) {
BUG(); BUG();
} }
...@@ -462,9 +483,10 @@ void __init kmem_cache_sizes_init(void) ...@@ -462,9 +483,10 @@ void __init kmem_cache_sizes_init(void)
offslab_limit = sizes->cs_size-sizeof(slab_t); offslab_limit = sizes->cs_size-sizeof(slab_t);
offslab_limit /= 2; offslab_limit /= 2;
} }
sprintf(name, "size-%Zd(DMA)",sizes->cs_size); sizes->cs_dmacachep = kmem_cache_create(
sizes->cs_dmacachep = kmem_cache_create(name, sizes->cs_size, 0, cache_names[sizes-cache_sizes].name_dma,
SLAB_CACHE_DMA|SLAB_HWCACHE_ALIGN, NULL, NULL); sizes->cs_size, 0,
SLAB_CACHE_DMA|SLAB_HWCACHE_ALIGN, NULL, NULL);
if (!sizes->cs_dmacachep) if (!sizes->cs_dmacachep)
BUG(); BUG();
sizes++; sizes++;
...@@ -604,6 +626,11 @@ static void kmem_slab_destroy (kmem_cache_t *cachep, slab_t *slabp) ...@@ -604,6 +626,11 @@ static void kmem_slab_destroy (kmem_cache_t *cachep, slab_t *slabp)
* Cannot be called within a int, but can be interrupted. * Cannot be called within a int, but can be interrupted.
* The @ctor is run when new pages are allocated by the cache * The @ctor is run when new pages are allocated by the cache
* and the @dtor is run before the pages are handed back. * and the @dtor is run before the pages are handed back.
*
* @name must be valid until the cache is destroyed. This implies that
* the module calling this has to destroy the cache before getting
* unloaded.
*
* The flags are * The flags are
* *
* %SLAB_POISON - Poison the slab with a known test pattern (a5a5a5a5) * %SLAB_POISON - Poison the slab with a known test pattern (a5a5a5a5)
...@@ -632,7 +659,6 @@ kmem_cache_create (const char *name, size_t size, size_t offset, ...@@ -632,7 +659,6 @@ kmem_cache_create (const char *name, size_t size, size_t offset,
* Sanity checks... these are all serious usage bugs. * Sanity checks... these are all serious usage bugs.
*/ */
if ((!name) || if ((!name) ||
((strlen(name) >= CACHE_NAMELEN - 1)) ||
in_interrupt() || in_interrupt() ||
(size < BYTES_PER_WORD) || (size < BYTES_PER_WORD) ||
(size > (1<<MAX_OBJ_ORDER)*PAGE_SIZE) || (size > (1<<MAX_OBJ_ORDER)*PAGE_SIZE) ||
...@@ -797,8 +823,7 @@ kmem_cache_create (const char *name, size_t size, size_t offset, ...@@ -797,8 +823,7 @@ kmem_cache_create (const char *name, size_t size, size_t offset,
cachep->slabp_cache = kmem_find_general_cachep(slab_size,0); cachep->slabp_cache = kmem_find_general_cachep(slab_size,0);
cachep->ctor = ctor; cachep->ctor = ctor;
cachep->dtor = dtor; cachep->dtor = dtor;
/* Copy name over so we don't have problems with unloaded modules */ cachep->name = name;
strcpy(cachep->name, name);
#ifdef CONFIG_SMP #ifdef CONFIG_SMP
if (g_cpucache_up) if (g_cpucache_up)
...@@ -811,10 +836,20 @@ kmem_cache_create (const char *name, size_t size, size_t offset, ...@@ -811,10 +836,20 @@ kmem_cache_create (const char *name, size_t size, size_t offset,
list_for_each(p, &cache_chain) { list_for_each(p, &cache_chain) {
kmem_cache_t *pc = list_entry(p, kmem_cache_t, next); kmem_cache_t *pc = list_entry(p, kmem_cache_t, next);
char tmp;
/* The name field is constant - no lock needed. */ /* This happens when the module gets unloaded and doesn't
if (!strcmp(pc->name, name)) destroy its slab cache and noone else reuses the vmalloc
BUG(); area of the module. Print a warning. */
if (__get_user(tmp,pc->name)) {
printk("SLAB: cache with size %d has lost its name\n",
pc->objsize);
continue;
}
if (!strcmp(pc->name,name)) {
printk("kmem_cache_create: duplicate cache %s\n",name);
up(&cache_chain_sem);
BUG();
}
} }
} }
...@@ -1878,6 +1913,7 @@ static int proc_getdata (char*page, char**start, off_t off, int count) ...@@ -1878,6 +1913,7 @@ static int proc_getdata (char*page, char**start, off_t off, int count)
unsigned long num_objs; unsigned long num_objs;
unsigned long active_slabs = 0; unsigned long active_slabs = 0;
unsigned long num_slabs; unsigned long num_slabs;
const char *name;
cachep = list_entry(p, kmem_cache_t, next); cachep = list_entry(p, kmem_cache_t, next);
spin_lock_irq(&cachep->spinlock); spin_lock_irq(&cachep->spinlock);
...@@ -1906,8 +1942,15 @@ static int proc_getdata (char*page, char**start, off_t off, int count) ...@@ -1906,8 +1942,15 @@ static int proc_getdata (char*page, char**start, off_t off, int count)
num_slabs+=active_slabs; num_slabs+=active_slabs;
num_objs = num_slabs*cachep->num; num_objs = num_slabs*cachep->num;
name = cachep->name;
{
char tmp;
if (__get_user(tmp, name))
name = "broken";
}
len += sprintf(page+len, "%-17s %6lu %6lu %6u %4lu %4lu %4u", len += sprintf(page+len, "%-17s %6lu %6lu %6u %4lu %4lu %4u",
cachep->name, active_objs, num_objs, cachep->objsize, name, active_objs, num_objs, cachep->objsize,
active_slabs, num_slabs, (1<<cachep->gfporder)); active_slabs, num_slabs, (1<<cachep->gfporder));
#if STATS #if STATS
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment