shrinking memory consumptions

Jim Gettys jg at laptop.org
Sun Apr 1 18:23:31 EDT 2007


There are much bigger savings to be had.  If you do a "ps", you'll see
we are running not one, but two copies of bash just to start the X
server.

Anyone interested should take a stab at playing with the gpe-dm display
manager for a small display manager, rather than the remains of the
amazingly overcomplex X startup to support switching desktop
environments wer are using.

In any case, remember that OOM is a reality we have to face on our
machine, so I'd rather handle it gracefully than have the system lock
up.  So some conservatism is in order here.

Also, I mispoke slightly: On B3 systems (and the few systems we've
ECO'ed) the keyboard won't be powered down; standard B2 systems, the
keyboard controller is on the wrong power rail.
                              Regards,
                                          - Jim


On Sun, 2007-04-01 at 21:58 +0200, Jens Axboe wrote:
> Hi,
> 
> Looking over the (rarely used) block/scsi bits, we can free up ~150kb of
> kernel memory by reducing the memory tied down in memory pools. These
> are pre-allocated and basically only ever used in OOM conditions, and
> for some no longer valid reason they are sized way to aggressively. We
> only really need 1 backup, this patch plays it safe and allocates 2.
> 
> I'll push this patch locally upstream as well, perhaps we can use it
> meanwhile. 150kb is quite a bit of memory, when all you have is 128MiB
> :-)
> 
> diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
> index 4c2471e..d812123 100644
> --- a/drivers/md/dm-crypt.c
> +++ b/drivers/md/dm-crypt.c
> @@ -867,7 +867,7 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
>  		goto bad4;
>  	}
>  
> -	cc->bs = bioset_create(MIN_IOS, MIN_IOS, 4);
> +	cc->bs = bioset_create(MIN_IOS, MIN_IOS);
>  	if (!cc->bs) {
>  		ti->error = "Cannot allocate crypt bioset";
>  		goto bad_bs;
> diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c
> index 4eb73d3..8bdc8a8 100644
> --- a/drivers/md/dm-io.c
> +++ b/drivers/md/dm-io.c
> @@ -60,7 +60,7 @@ static int resize_pool(unsigned int new_ios)
>  		if (!_io_pool)
>  			return -ENOMEM;
>  
> -		_bios = bioset_create(16, 16, 4);
> +		_bios = bioset_create(16, 16);
>  		if (!_bios) {
>  			mempool_destroy(_io_pool);
>  			_io_pool = NULL;
> diff --git a/drivers/md/dm.c b/drivers/md/dm.c
> index 3668b17..11a98df 100644
> --- a/drivers/md/dm.c
> +++ b/drivers/md/dm.c
> @@ -1012,7 +1012,7 @@ static struct mapped_device *alloc_dev(int minor)
>  	if (!md->tio_pool)
>  		goto bad3;
>  
> -	md->bs = bioset_create(16, 16, 4);
> +	md->bs = bioset_create(16, 16);
>  	if (!md->bs)
>  		goto bad_no_bioset;
>  
> diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
> index 9f7482d..05d79af 100644
> --- a/drivers/scsi/scsi_lib.c
> +++ b/drivers/scsi/scsi_lib.c
> @@ -31,7 +31,7 @@
>  
> 
>  #define SG_MEMPOOL_NR		ARRAY_SIZE(scsi_sg_pools)
> -#define SG_MEMPOOL_SIZE		32
> +#define SG_MEMPOOL_SIZE		2
>  
>  struct scsi_host_sg_pool {
>  	size_t		size;
> diff --git a/fs/bio.c b/fs/bio.c
> index 7618bcb..693940d 100644
> --- a/fs/bio.c
> +++ b/fs/bio.c
> @@ -28,7 +28,7 @@
>  #include <linux/blktrace_api.h>
>  #include <scsi/sg.h>		/* for struct sg_iovec */
>  
> -#define BIO_POOL_SIZE 256
> +#define BIO_POOL_SIZE 2
>  
>  static struct kmem_cache *bio_slab __read_mostly;
>  
> @@ -38,7 +38,7 @@ static struct kmem_cache *bio_slab __read_mostly;
>   * a small number of entries is fine, not going to be performance critical.
>   * basically we just need to survive
>   */
> -#define BIO_SPLIT_ENTRIES 8	
> +#define BIO_SPLIT_ENTRIES 2
>  mempool_t *bio_split_pool __read_mostly;
>  
>  struct biovec_slab {
> @@ -1120,7 +1120,7 @@ struct bio_pair *bio_split(struct bio *bi, mempool_t *pool, int first_sectors)
>   * create memory pools for biovec's in a bio_set.
>   * use the global biovec slabs created for general use.
>   */
> -static int biovec_create_pools(struct bio_set *bs, int pool_entries, int scale)
> +static int biovec_create_pools(struct bio_set *bs, int pool_entries)
>  {
>  	int i;
>  
> @@ -1128,9 +1128,6 @@ static int biovec_create_pools(struct bio_set *bs, int pool_entries, int scale)
>  		struct biovec_slab *bp = bvec_slabs + i;
>  		mempool_t **bvp = bs->bvec_pools + i;
>  
> -		if (pool_entries > 1 && i >= scale)
> -			pool_entries >>= 1;
> -
>  		*bvp = mempool_create_slab_pool(pool_entries, bp->slab);
>  		if (!*bvp)
>  			return -ENOMEM;
> @@ -1161,7 +1158,7 @@ void bioset_free(struct bio_set *bs)
>  	kfree(bs);
>  }
>  
> -struct bio_set *bioset_create(int bio_pool_size, int bvec_pool_size, int scale)
> +struct bio_set *bioset_create(int bio_pool_size, int bvec_pool_size)
>  {
>  	struct bio_set *bs = kzalloc(sizeof(*bs), GFP_KERNEL);
>  
> @@ -1172,7 +1169,7 @@ struct bio_set *bioset_create(int bio_pool_size, int bvec_pool_size, int scale)
>  	if (!bs->bio_pool)
>  		goto bad;
>  
> -	if (!biovec_create_pools(bs, bvec_pool_size, scale))
> +	if (!biovec_create_pools(bs, bvec_pool_size))
>  		return bs;
>  
>  bad:
> @@ -1196,38 +1193,12 @@ static void __init biovec_init_slabs(void)
>  
>  static int __init init_bio(void)
>  {
> -	int megabytes, bvec_pool_entries;
> -	int scale = BIOVEC_NR_POOLS;
> -
>  	bio_slab = kmem_cache_create("bio", sizeof(struct bio), 0,
>  				SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);
>  
>  	biovec_init_slabs();
>  
> -	megabytes = nr_free_pages() >> (20 - PAGE_SHIFT);
> -
> -	/*
> -	 * find out where to start scaling
> -	 */
> -	if (megabytes <= 16)
> -		scale = 0;
> -	else if (megabytes <= 32)
> -		scale = 1;
> -	else if (megabytes <= 64)
> -		scale = 2;
> -	else if (megabytes <= 96)
> -		scale = 3;
> -	else if (megabytes <= 128)
> -		scale = 4;
> -
> -	/*
> -	 * Limit number of entries reserved -- mempools are only used when
> -	 * the system is completely unable to allocate memory, so we only
> -	 * need enough to make progress.
> -	 */
> -	bvec_pool_entries = 1 + scale;
> -
> -	fs_bio_set = bioset_create(BIO_POOL_SIZE, bvec_pool_entries, scale);
> +	fs_bio_set = bioset_create(BIO_POOL_SIZE, 2);
>  	if (!fs_bio_set)
>  		panic("bio: can't allocate bios\n");
>  
> diff --git a/include/linux/bio.h b/include/linux/bio.h
> index 08daf32..4d85262 100644
> --- a/include/linux/bio.h
> +++ b/include/linux/bio.h
> @@ -276,7 +276,7 @@ extern struct bio_pair *bio_split(struct bio *bi, mempool_t *pool,
>  extern mempool_t *bio_split_pool;
>  extern void bio_pair_release(struct bio_pair *dbio);
>  
> -extern struct bio_set *bioset_create(int, int, int);
> +extern struct bio_set *bioset_create(int, int);
>  extern void bioset_free(struct bio_set *);
>  
>  extern struct bio *bio_alloc(gfp_t, int);
> 
-- 
Jim Gettys
One Laptop Per Child





More information about the Devel mailing list