All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jens Axboe <axboe@suse.de>
To: Dave Olien <dmo@osdl.org>
Cc: dm-devel@redhat.com, linux-kernel@vger.kernel.org, agk@sourceware.org
Subject: Re: [RFC] [PATCH] bio-set patch on latest bk source tree
Date: Tue, 1 Feb 2005 08:55:52 +0100	[thread overview]
Message-ID: <20050201075551.GC4137@suse.de> (raw)
In-Reply-To: <20050201010431.GA4244@osdl.org>

On Mon, Jan 31 2005, Dave Olien wrote:
> 
> Hi, Jens,
> 
> I sent you a patch for review about a week ago.  Here is that same
> patch, applied to the latest bk kernel.  Thanks in advance for the review

Thanks Dave, I think we should queue this up with Andrew soonish. A few
minor things need fixing, though:

> ===== drivers/md/dm.c 1.61 vs edited =====
> --- 1.61/drivers/md/dm.c	2005-01-25 13:50:21 -08:00
> +++ edited/drivers/md/dm.c	2005-01-31 11:37:27 -08:00
> @@ -96,10 +96,16 @@ struct mapped_device {
>  static kmem_cache_t *_io_cache;
>  static kmem_cache_t *_tio_cache;
>  
> +static struct bio_set *dm_set;
> +
>  static int __init local_init(void)
>  {
>  	int r;
>  
> +	dm_set = bioset_create(512, 512, 1);
> +	if (!dm_set)
> +		return -ENOMEM;
> +

You consistently use 512, that's a _lot_ of reserved bio's/vecs! For the
full range of bio_vec pools, that will eat quite a large piece of memory
per bio_set allocated. The idea with a mempool isn't to have a huge free
number of elements, but rather just a few to maintain progress with
memory pressure. I think this 512 should be heavily reduced.

>  static int zero_map(struct dm_target *ti, struct bio *bio,
> ===== fs/bio.c 1.73 vs edited =====
> --- 1.73/fs/bio.c	2005-01-20 21:02:13 -08:00
> +++ edited/fs/bio.c	2005-01-31 14:50:37 -08:00
> @@ -28,7 +28,6 @@
>  
>  #define BIO_POOL_SIZE 256
>  
> -static mempool_t *bio_pool;
>  static kmem_cache_t *bio_slab;
>  
>  #define BIOVEC_NR_POOLS 6
> @@ -40,11 +39,10 @@ static kmem_cache_t *bio_slab;
>  #define BIO_SPLIT_ENTRIES 8	
>  mempool_t *bio_split_pool;
>  
> -struct biovec_pool {
> +struct biovec_slab {
>  	int nr_vecs;
>  	char *name; 
>  	kmem_cache_t *slab;
> -	mempool_t *pool;
>  };
>  
>  /*
> @@ -54,15 +52,32 @@ struct biovec_pool {
>   */
>  
>  #define BV(x) { .nr_vecs = x, .name = "biovec-"__stringify(x) }
> -static struct biovec_pool bvec_array[BIOVEC_NR_POOLS] = {
> +static struct biovec_slab bvec_slabs[BIOVEC_NR_POOLS] = {
>  	BV(1), BV(4), BV(16), BV(64), BV(128), BV(BIO_MAX_PAGES),
>  };
>  #undef BV
>  
> -static inline struct bio_vec *bvec_alloc(int gfp_mask, int nr, unsigned long *idx)
> +/*
> + * bio_set is used to allow other portions of the IO system to
> + * allocate their own private memory pools for bio and iovec structures.
> + * These memory pools in turn all allocate from the bio_slab
> + * and the bvec_slabs[].
> + */
> +struct bio_set {
> +	mempool_t *bio_pool;
> +	mempool_t *bvec_pools[BIOVEC_NR_POOLS];
> +};
> +
> +/*
> + * fs_bio_set is the bio_set containing bio and iovec memory pools used by
> + * IO code that does not need private memory pools.
> + */
> +static struct bio_set *fs_bio_set;
> +
> +static inline struct bio_vec *bvec_alloc_bs(int gfp_mask, int nr, unsigned long *idx, struct bio_set *bs)
>  {
> -	struct biovec_pool *bp;
>  	struct bio_vec *bvl;
> +	struct biovec_slab *bp;
>  
>  	/*
>  	 * see comment near bvec_array define!
> @@ -80,26 +95,27 @@ static inline struct bio_vec *bvec_alloc
>  	/*
>  	 * idx now points to the pool we want to allocate from
>  	 */
> -	bp = bvec_array + *idx;
>  
> -	bvl = mempool_alloc(bp->pool, gfp_mask);
> +	bp = bvec_slabs + *idx;
> +	bvl = mempool_alloc(bs->bvec_pools[*idx], gfp_mask);
>  	if (bvl)
>  		memset(bvl, 0, bp->nr_vecs * sizeof(struct bio_vec));
> +
>  	return bvl;
>  }
>  
>  /*
> - * default destructor for a bio allocated with bio_alloc()
> + * default destructor for a bio allocated with bio_alloc_bs()
>   */
>  static void bio_destructor(struct bio *bio)
>  {
>  	const int pool_idx = BIO_POOL_IDX(bio);
> -	struct biovec_pool *bp = bvec_array + pool_idx;
> +	struct bio_set *bs = bio->bi_set;
>  
>  	BIO_BUG_ON(pool_idx >= BIOVEC_NR_POOLS);
>  
> -	mempool_free(bio->bi_io_vec, bp->pool);
> -	mempool_free(bio, bio_pool);
> +	mempool_free(bio->bi_io_vec, bs->bvec_pools[pool_idx]);
> +	mempool_free(bio, bs->bio_pool);
>  }
>  
>  inline void bio_init(struct bio *bio)
> @@ -121,18 +137,21 @@ inline void bio_init(struct bio *bio)
>  }
>  
>  /**
> - * bio_alloc - allocate a bio for I/O
> + * bio_alloc_bs - allocate a bio for I/O
>   * @gfp_mask:   the GFP_ mask given to the slab allocator
>   * @nr_iovecs:	number of iovecs to pre-allocate

bs is awefully close to 'block size' when it comes to acronyms in this
area, I would prefer if you just called it bio_alloc_bioset() instead.

> +void bioset_free(struct bio_set *bs)
> +{
> +	if (!bs->bio_pool)
> +		mempool_destroy(bs->bio_pool);

That check looks suspect, surely you mean to check for non-NULL.

> +
> +	biovec_free_pools(bs);
> +
> +	kfree(bs);
> +}
> +
> +struct bio_set *bioset_create(int bio_pool_size, int bvec_pool_size, int scale)
> +{
> +	struct bio_set *bs = kmalloc(sizeof(*bs), GFP_KERNEL);
> +
> +	if (!bs)
> +		return NULL;
> +
> +	memset(bs, 0, sizeof(*bs));
> +	bs->bio_pool = mempool_create(bio_pool_size, mempool_alloc_slab,
> +			mempool_free_slab, bio_slab);
> +
> +	if (!bs->bio_pool) 
> +		goto bad;
> +	
> +	if (biovec_create_pools(bs, bvec_pool_size, scale))
> +		goto bad;
> +
> +	return bs;
> +
> +bad:
> +	bioset_free(bs);
> +	return NULL;
> +}

Please drop the last goto

        if (!biovec_create_pools(bs, bvec_pool_size, scale))
                return bs;

is nicer.

-- 
Jens Axboe

--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel

WARNING: multiple messages have this Message-ID (diff)
From: Jens Axboe <axboe@suse.de>
To: Dave Olien <dmo@osdl.org>
Cc: linux-kernel@vger.kernel.org, dm-devel@redhat.com,
	agk@sourceware.org, kevcorry@us.ibm.com
Subject: Re: [RFC] [PATCH] bio-set patch on latest bk source tree
Date: Tue, 1 Feb 2005 08:55:52 +0100	[thread overview]
Message-ID: <20050201075551.GC4137@suse.de> (raw)
In-Reply-To: <20050201010431.GA4244@osdl.org>

On Mon, Jan 31 2005, Dave Olien wrote:
> 
> Hi, Jens,
> 
> I sent you a patch for review about a week ago.  Here is that same
> patch, applied to the latest bk kernel.  Thanks in advance for the review

Thanks Dave, I think we should queue this up with Andrew soonish. A few
minor things need fixing, though:

> ===== drivers/md/dm.c 1.61 vs edited =====
> --- 1.61/drivers/md/dm.c	2005-01-25 13:50:21 -08:00
> +++ edited/drivers/md/dm.c	2005-01-31 11:37:27 -08:00
> @@ -96,10 +96,16 @@ struct mapped_device {
>  static kmem_cache_t *_io_cache;
>  static kmem_cache_t *_tio_cache;
>  
> +static struct bio_set *dm_set;
> +
>  static int __init local_init(void)
>  {
>  	int r;
>  
> +	dm_set = bioset_create(512, 512, 1);
> +	if (!dm_set)
> +		return -ENOMEM;
> +

You consistently use 512, that's a _lot_ of reserved bio's/vecs! For the
full range of bio_vec pools, that will eat quite a large piece of memory
per bio_set allocated. The idea with a mempool isn't to have a huge free
number of elements, but rather just a few to maintain progress with
memory pressure. I think this 512 should be heavily reduced.

>  static int zero_map(struct dm_target *ti, struct bio *bio,
> ===== fs/bio.c 1.73 vs edited =====
> --- 1.73/fs/bio.c	2005-01-20 21:02:13 -08:00
> +++ edited/fs/bio.c	2005-01-31 14:50:37 -08:00
> @@ -28,7 +28,6 @@
>  
>  #define BIO_POOL_SIZE 256
>  
> -static mempool_t *bio_pool;
>  static kmem_cache_t *bio_slab;
>  
>  #define BIOVEC_NR_POOLS 6
> @@ -40,11 +39,10 @@ static kmem_cache_t *bio_slab;
>  #define BIO_SPLIT_ENTRIES 8	
>  mempool_t *bio_split_pool;
>  
> -struct biovec_pool {
> +struct biovec_slab {
>  	int nr_vecs;
>  	char *name; 
>  	kmem_cache_t *slab;
> -	mempool_t *pool;
>  };
>  
>  /*
> @@ -54,15 +52,32 @@ struct biovec_pool {
>   */
>  
>  #define BV(x) { .nr_vecs = x, .name = "biovec-"__stringify(x) }
> -static struct biovec_pool bvec_array[BIOVEC_NR_POOLS] = {
> +static struct biovec_slab bvec_slabs[BIOVEC_NR_POOLS] = {
>  	BV(1), BV(4), BV(16), BV(64), BV(128), BV(BIO_MAX_PAGES),
>  };
>  #undef BV
>  
> -static inline struct bio_vec *bvec_alloc(int gfp_mask, int nr, unsigned long *idx)
> +/*
> + * bio_set is used to allow other portions of the IO system to
> + * allocate their own private memory pools for bio and iovec structures.
> + * These memory pools in turn all allocate from the bio_slab
> + * and the bvec_slabs[].
> + */
> +struct bio_set {
> +	mempool_t *bio_pool;
> +	mempool_t *bvec_pools[BIOVEC_NR_POOLS];
> +};
> +
> +/*
> + * fs_bio_set is the bio_set containing bio and iovec memory pools used by
> + * IO code that does not need private memory pools.
> + */
> +static struct bio_set *fs_bio_set;
> +
> +static inline struct bio_vec *bvec_alloc_bs(int gfp_mask, int nr, unsigned long *idx, struct bio_set *bs)
>  {
> -	struct biovec_pool *bp;
>  	struct bio_vec *bvl;
> +	struct biovec_slab *bp;
>  
>  	/*
>  	 * see comment near bvec_array define!
> @@ -80,26 +95,27 @@ static inline struct bio_vec *bvec_alloc
>  	/*
>  	 * idx now points to the pool we want to allocate from
>  	 */
> -	bp = bvec_array + *idx;
>  
> -	bvl = mempool_alloc(bp->pool, gfp_mask);
> +	bp = bvec_slabs + *idx;
> +	bvl = mempool_alloc(bs->bvec_pools[*idx], gfp_mask);
>  	if (bvl)
>  		memset(bvl, 0, bp->nr_vecs * sizeof(struct bio_vec));
> +
>  	return bvl;
>  }
>  
>  /*
> - * default destructor for a bio allocated with bio_alloc()
> + * default destructor for a bio allocated with bio_alloc_bs()
>   */
>  static void bio_destructor(struct bio *bio)
>  {
>  	const int pool_idx = BIO_POOL_IDX(bio);
> -	struct biovec_pool *bp = bvec_array + pool_idx;
> +	struct bio_set *bs = bio->bi_set;
>  
>  	BIO_BUG_ON(pool_idx >= BIOVEC_NR_POOLS);
>  
> -	mempool_free(bio->bi_io_vec, bp->pool);
> -	mempool_free(bio, bio_pool);
> +	mempool_free(bio->bi_io_vec, bs->bvec_pools[pool_idx]);
> +	mempool_free(bio, bs->bio_pool);
>  }
>  
>  inline void bio_init(struct bio *bio)
> @@ -121,18 +137,21 @@ inline void bio_init(struct bio *bio)
>  }
>  
>  /**
> - * bio_alloc - allocate a bio for I/O
> + * bio_alloc_bs - allocate a bio for I/O
>   * @gfp_mask:   the GFP_ mask given to the slab allocator
>   * @nr_iovecs:	number of iovecs to pre-allocate

bs is awefully close to 'block size' when it comes to acronyms in this
area, I would prefer if you just called it bio_alloc_bioset() instead.

> +void bioset_free(struct bio_set *bs)
> +{
> +	if (!bs->bio_pool)
> +		mempool_destroy(bs->bio_pool);

That check looks suspect, surely you mean to check for non-NULL.

> +
> +	biovec_free_pools(bs);
> +
> +	kfree(bs);
> +}
> +
> +struct bio_set *bioset_create(int bio_pool_size, int bvec_pool_size, int scale)
> +{
> +	struct bio_set *bs = kmalloc(sizeof(*bs), GFP_KERNEL);
> +
> +	if (!bs)
> +		return NULL;
> +
> +	memset(bs, 0, sizeof(*bs));
> +	bs->bio_pool = mempool_create(bio_pool_size, mempool_alloc_slab,
> +			mempool_free_slab, bio_slab);
> +
> +	if (!bs->bio_pool) 
> +		goto bad;
> +	
> +	if (biovec_create_pools(bs, bvec_pool_size, scale))
> +		goto bad;
> +
> +	return bs;
> +
> +bad:
> +	bioset_free(bs);
> +	return NULL;
> +}

Please drop the last goto

        if (!biovec_create_pools(bs, bvec_pool_size, scale))
                return bs;

is nicer.

-- 
Jens Axboe


  reply	other threads:[~2005-02-01  7:55 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-02-01  1:04 [RFC] [PATCH] bio-set patch on latest bk source tree Dave Olien
2005-02-01  1:04 ` Dave Olien
2005-02-01  7:55 ` Jens Axboe [this message]
2005-02-01  7:55   ` Jens Axboe
2005-02-01 19:16   ` Dave Olien
2005-02-01 19:16     ` [dm-devel] " Dave Olien

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=20050201075551.GC4137@suse.de \
    --to=axboe@suse.de \
    --cc=agk@sourceware.org \
    --cc=dm-devel@redhat.com \
    --cc=dmo@osdl.org \
    --cc=linux-kernel@vger.kernel.org \
    /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.