Re: [dm-devel] [PATCH v2 01/26] block: Convert integrity to bvec_alloc_bs(), and a bugfix

2012-09-17 Thread Kent Overstreet
On Wed, Sep 12, 2012 at 03:39:18PM -0400, Martin K. Petersen wrote:
> > "Kent" == Kent Overstreet  writes:
> 
> Kent,
> 
> Kent> To fix the bug first, I'd have to reorder struct bio_pair and then
> Kent> just delete two lines of code from bio_integrity_split(). But the
> Kent> reordering is unnecessary with the refactoring.
> 
> Well, a bug is a bug and the fix needs to go into stable. So we will
> need a patch that does not depend on your changes.

Alright, good point.

> I don't have a problem with adding a pointer so clones can point to the
> parent's vector. But embedding the vector into the bip was a feature.
> If you check the git log you'll see that originally I did use separate
> vector allocations.

Looks like that was 7878cba9f0037f5599004b03a1260b32d9050360 - If I
follow your commit message your primary goal was to back the bip vecs by
a per bio set mempool?

I didn't break that (excepting the issue Vivek noted) - but it is true
that my patch adds another allocation (when nr_vecs > BIP_INLINE_VECS,
anyways).

I don't know how big of a deal you think that extra allocation is. If
you're against it, this patch isn't really necessary for the immutable
bvecs I'm working on - just need it if we want integrity bvecs to be
shared like regular bvecs will be.

Something else I noticed is bio_integrity_add_page() doesn't merge bvecs
when possible, like the regular bio_add_page(). If changing it to merge
bvecs wouldn't break anything, then probably most integrity bvecs would
be under BIP_INLINE_VECS.

Thoughts?
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [dm-devel] [PATCH v2 01/26] block: Convert integrity to bvec_alloc_bs(), and a bugfix

2012-09-17 Thread Kent Overstreet
On Wed, Sep 12, 2012 at 03:39:18PM -0400, Martin K. Petersen wrote:
  Kent == Kent Overstreet koverstr...@google.com writes:
 
 Kent,
 
 Kent To fix the bug first, I'd have to reorder struct bio_pair and then
 Kent just delete two lines of code from bio_integrity_split(). But the
 Kent reordering is unnecessary with the refactoring.
 
 Well, a bug is a bug and the fix needs to go into stable. So we will
 need a patch that does not depend on your changes.

Alright, good point.

 I don't have a problem with adding a pointer so clones can point to the
 parent's vector. But embedding the vector into the bip was a feature.
 If you check the git log you'll see that originally I did use separate
 vector allocations.

Looks like that was 7878cba9f0037f5599004b03a1260b32d9050360 - If I
follow your commit message your primary goal was to back the bip vecs by
a per bio set mempool?

I didn't break that (excepting the issue Vivek noted) - but it is true
that my patch adds another allocation (when nr_vecs  BIP_INLINE_VECS,
anyways).

I don't know how big of a deal you think that extra allocation is. If
you're against it, this patch isn't really necessary for the immutable
bvecs I'm working on - just need it if we want integrity bvecs to be
shared like regular bvecs will be.

Something else I noticed is bio_integrity_add_page() doesn't merge bvecs
when possible, like the regular bio_add_page(). If changing it to merge
bvecs wouldn't break anything, then probably most integrity bvecs would
be under BIP_INLINE_VECS.

Thoughts?
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [dm-devel] [PATCH v2 01/26] block: Convert integrity to bvec_alloc_bs(), and a bugfix

2012-09-12 Thread Martin K. Petersen
> "Kent" == Kent Overstreet  writes:

Kent,

Kent> To fix the bug first, I'd have to reorder struct bio_pair and then
Kent> just delete two lines of code from bio_integrity_split(). But the
Kent> reordering is unnecessary with the refactoring.

Well, a bug is a bug and the fix needs to go into stable. So we will
need a patch that does not depend on your changes.

I don't have a problem with adding a pointer so clones can point to the
parent's vector. But embedding the vector into the bip was a feature.
If you check the git log you'll see that originally I did use separate
vector allocations.

-- 
Martin K. Petersen  Oracle Linux Engineering
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [dm-devel] [PATCH v2 01/26] block: Convert integrity to bvec_alloc_bs(), and a bugfix

2012-09-12 Thread Martin K. Petersen
 Kent == Kent Overstreet koverstr...@google.com writes:

Kent,

Kent To fix the bug first, I'd have to reorder struct bio_pair and then
Kent just delete two lines of code from bio_integrity_split(). But the
Kent reordering is unnecessary with the refactoring.

Well, a bug is a bug and the fix needs to go into stable. So we will
need a patch that does not depend on your changes.

I don't have a problem with adding a pointer so clones can point to the
parent's vector. But embedding the vector into the bip was a feature.
If you check the git log you'll see that originally I did use separate
vector allocations.

-- 
Martin K. Petersen  Oracle Linux Engineering
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [dm-devel] [PATCH v2 01/26] block: Convert integrity to bvec_alloc_bs(), and a bugfix

2012-09-11 Thread Kent Overstreet
On Tue, Sep 11, 2012 at 04:36:43PM -0400, Vivek Goyal wrote:
> Also there seems to be too much happening in this patch. Please break
> it down in 2. First fix the bio integrity bug you mentioned then
> introduce your changes on top.

Oh, I forgot - the reason I squashed them into one patch is fixing the
bug came for free with the rest of the refactoring, and combining them
touches less code.

To fix the bug first, I'd have to reorder struct bio_pair and then just
delete two lines of code from bio_integrity_split(). But the reordering
is unnecessary with the refactoring.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [dm-devel] [PATCH v2 01/26] block: Convert integrity to bvec_alloc_bs(), and a bugfix

2012-09-11 Thread Kent Overstreet
On Tue, Sep 11, 2012 at 04:36:43PM -0400, Vivek Goyal wrote:
> On Mon, Sep 10, 2012 at 05:22:12PM -0700, Kent Overstreet wrote:
> > This adds a pointer to the bvec array to struct bio_integrity_payload,
> > instead of the bvecs always being inline; then the bvecs are allocated
> > with bvec_alloc_bs().
> 
> If you starting allocating bvec from same mempool for  bio and bip, 
> are you not breaking the principle of multiple allocations from a
> mempool and hence increasing the possibility of deadlock?

Argh, you're right. I should've thought about that.

It might be nice if mempools had some kind of internal watermark... here
we know we're only going to do at most 2 allocations from the same
mempool, so if we just passed the number we already had allocated to
mempool_alloc(), it could do the right thing and ensure we never
deadlocked.

I _think_ that'd let us make more efficient use of the reserve. But, for
just this it's not really worth the extra code, I think I'll just have
to add another mempool.

> Also there seems to be too much happening in this patch. Please break
> it down in 2. First fix the bio integrity bug you mentioned then
> introduce your changes on top.

Ok, I can do that.

> Thanks
> Vivek
> 
> > 
> > This is needed eventually for immutable bio vecs - immutable bvecs
> > aren't useful if we still have to copy them, hence the need for the
> > pointer. Less code is always nice too, though.
> > 
> > Also fix an amusing bug in bio_integrity_split() - struct bio_pair
> > doesn't have the integrity bvecs after the bio_integrity_payloads, so
> > there was a buffer overrun. The code was confusing pointers with arrays.
> > 
> > Signed-off-by: Kent Overstreet 
> > CC: Jens Axboe 
> > CC: Martin K. Petersen 
> > ---
> >  fs/bio-integrity.c  | 124 
> > +---
> >  include/linux/bio.h |   5 ++-
> >  2 files changed, 43 insertions(+), 86 deletions(-)
> > 
> > diff --git a/fs/bio-integrity.c b/fs/bio-integrity.c
> > index a3f28f3..1d64f7f 100644
> > --- a/fs/bio-integrity.c
> > +++ b/fs/bio-integrity.c
> > @@ -27,48 +27,11 @@
> >  #include 
> >  #include 
> >  
> > -struct integrity_slab {
> > -   struct kmem_cache *slab;
> > -   unsigned short nr_vecs;
> > -   char name[8];
> > -};
> > -
> > -#define IS(x) { .nr_vecs = x, .name = "bip-"__stringify(x) }
> > -struct integrity_slab bip_slab[BIOVEC_NR_POOLS] __read_mostly = {
> > -   IS(1), IS(4), IS(16), IS(64), IS(128), IS(BIO_MAX_PAGES),
> > -};
> > -#undef IS
> > +#define BIP_INLINE_VECS4
> >  
> > +static struct kmem_cache *bip_slab;
> >  static struct workqueue_struct *kintegrityd_wq;
> >  
> > -static inline unsigned int vecs_to_idx(unsigned int nr)
> > -{
> > -   switch (nr) {
> > -   case 1:
> > -   return 0;
> > -   case 2 ... 4:
> > -   return 1;
> > -   case 5 ... 16:
> > -   return 2;
> > -   case 17 ... 64:
> > -   return 3;
> > -   case 65 ... 128:
> > -   return 4;
> > -   case 129 ... BIO_MAX_PAGES:
> > -   return 5;
> > -   default:
> > -   BUG();
> > -   }
> > -}
> > -
> > -static inline int use_bip_pool(unsigned int idx)
> > -{
> > -   if (idx == BIOVEC_MAX_IDX)
> > -   return 1;
> > -
> > -   return 0;
> > -}
> > -
> >  /**
> >   * bio_integrity_alloc - Allocate integrity payload and attach it to bio
> >   * @bio:   bio to attach integrity metadata to
> > @@ -84,37 +47,38 @@ struct bio_integrity_payload 
> > *bio_integrity_alloc(struct bio *bio,
> >   unsigned int nr_vecs)
> >  {
> > struct bio_integrity_payload *bip;
> > -   unsigned int idx = vecs_to_idx(nr_vecs);
> > struct bio_set *bs = bio->bi_pool;
> > +   unsigned long idx = BIO_POOL_NONE;
> > +   unsigned inline_vecs;
> > +
> > +   if (!bs) {
> > +   bip = kmalloc(sizeof(struct bio_integrity_payload) +
> > + sizeof(struct bio_vec) * nr_vecs, gfp_mask);
> > +   inline_vecs = nr_vecs;
> > +   } else {
> > +   bip = mempool_alloc(bs->bio_integrity_pool, gfp_mask);
> > +   inline_vecs = BIP_INLINE_VECS;
> > +   }
> >  
> > -   if (!bs)
> > -   bs = fs_bio_set;
> > -
> > -   BUG_ON(bio == NULL);
> > -   bip = NULL;
> > +   if (unlikely(!bip))
> > +   return NULL;
> >  
> > -   /* Lower order allocations come straight from slab */
> > -   if (!use_bip_pool(idx))
> > -   bip = kmem_cache_alloc(bip_slab[idx].slab, gfp_mask);
> > +   memset(bip, 0, sizeof(struct bio_integrity_payload));
> >  
> > -   /* Use mempool if lower order alloc failed or max vecs were requested */
> > -   if (bip == NULL) {
> > -   idx = BIOVEC_MAX_IDX;  /* so we free the payload properly later 
> > */
> > -   bip = mempool_alloc(bs->bio_integrity_pool, gfp_mask);
> > -
> > -   if (unlikely(bip == NULL)) {
> > -   printk(KERN_ERR "%s: could not alloc bip\n", __func__);
> > -   return NULL;
> > -   }
> > +   

Re: [dm-devel] [PATCH v2 01/26] block: Convert integrity to bvec_alloc_bs(), and a bugfix

2012-09-11 Thread Vivek Goyal
On Mon, Sep 10, 2012 at 05:22:12PM -0700, Kent Overstreet wrote:
> This adds a pointer to the bvec array to struct bio_integrity_payload,
> instead of the bvecs always being inline; then the bvecs are allocated
> with bvec_alloc_bs().

If you starting allocating bvec from same mempool for  bio and bip, 
are you not breaking the principle of multiple allocations from a
mempool and hence increasing the possibility of deadlock?

Also there seems to be too much happening in this patch. Please break
it down in 2. First fix the bio integrity bug you mentioned then
introduce your changes on top.

Thanks
Vivek

> 
> This is needed eventually for immutable bio vecs - immutable bvecs
> aren't useful if we still have to copy them, hence the need for the
> pointer. Less code is always nice too, though.
> 
> Also fix an amusing bug in bio_integrity_split() - struct bio_pair
> doesn't have the integrity bvecs after the bio_integrity_payloads, so
> there was a buffer overrun. The code was confusing pointers with arrays.
> 
> Signed-off-by: Kent Overstreet 
> CC: Jens Axboe 
> CC: Martin K. Petersen 
> ---
>  fs/bio-integrity.c  | 124 
> +---
>  include/linux/bio.h |   5 ++-
>  2 files changed, 43 insertions(+), 86 deletions(-)
> 
> diff --git a/fs/bio-integrity.c b/fs/bio-integrity.c
> index a3f28f3..1d64f7f 100644
> --- a/fs/bio-integrity.c
> +++ b/fs/bio-integrity.c
> @@ -27,48 +27,11 @@
>  #include 
>  #include 
>  
> -struct integrity_slab {
> - struct kmem_cache *slab;
> - unsigned short nr_vecs;
> - char name[8];
> -};
> -
> -#define IS(x) { .nr_vecs = x, .name = "bip-"__stringify(x) }
> -struct integrity_slab bip_slab[BIOVEC_NR_POOLS] __read_mostly = {
> - IS(1), IS(4), IS(16), IS(64), IS(128), IS(BIO_MAX_PAGES),
> -};
> -#undef IS
> +#define BIP_INLINE_VECS  4
>  
> +static struct kmem_cache *bip_slab;
>  static struct workqueue_struct *kintegrityd_wq;
>  
> -static inline unsigned int vecs_to_idx(unsigned int nr)
> -{
> - switch (nr) {
> - case 1:
> - return 0;
> - case 2 ... 4:
> - return 1;
> - case 5 ... 16:
> - return 2;
> - case 17 ... 64:
> - return 3;
> - case 65 ... 128:
> - return 4;
> - case 129 ... BIO_MAX_PAGES:
> - return 5;
> - default:
> - BUG();
> - }
> -}
> -
> -static inline int use_bip_pool(unsigned int idx)
> -{
> - if (idx == BIOVEC_MAX_IDX)
> - return 1;
> -
> - return 0;
> -}
> -
>  /**
>   * bio_integrity_alloc - Allocate integrity payload and attach it to bio
>   * @bio: bio to attach integrity metadata to
> @@ -84,37 +47,38 @@ struct bio_integrity_payload *bio_integrity_alloc(struct 
> bio *bio,
> unsigned int nr_vecs)
>  {
>   struct bio_integrity_payload *bip;
> - unsigned int idx = vecs_to_idx(nr_vecs);
>   struct bio_set *bs = bio->bi_pool;
> + unsigned long idx = BIO_POOL_NONE;
> + unsigned inline_vecs;
> +
> + if (!bs) {
> + bip = kmalloc(sizeof(struct bio_integrity_payload) +
> +   sizeof(struct bio_vec) * nr_vecs, gfp_mask);
> + inline_vecs = nr_vecs;
> + } else {
> + bip = mempool_alloc(bs->bio_integrity_pool, gfp_mask);
> + inline_vecs = BIP_INLINE_VECS;
> + }
>  
> - if (!bs)
> - bs = fs_bio_set;
> -
> - BUG_ON(bio == NULL);
> - bip = NULL;
> + if (unlikely(!bip))
> + return NULL;
>  
> - /* Lower order allocations come straight from slab */
> - if (!use_bip_pool(idx))
> - bip = kmem_cache_alloc(bip_slab[idx].slab, gfp_mask);
> + memset(bip, 0, sizeof(struct bio_integrity_payload));
>  
> - /* Use mempool if lower order alloc failed or max vecs were requested */
> - if (bip == NULL) {
> - idx = BIOVEC_MAX_IDX;  /* so we free the payload properly later 
> */
> - bip = mempool_alloc(bs->bio_integrity_pool, gfp_mask);
> -
> - if (unlikely(bip == NULL)) {
> - printk(KERN_ERR "%s: could not alloc bip\n", __func__);
> - return NULL;
> - }
> + if (nr_vecs > inline_vecs) {
> + bip->bip_vec = bvec_alloc_bs(gfp_mask, nr_vecs, , bs);
> + if (!bip->bip_vec)
> + goto err;
>   }
>  
> - memset(bip, 0, sizeof(*bip));
> -
>   bip->bip_slab = idx;
>   bip->bip_bio = bio;
>   bio->bi_integrity = bip;
>  
>   return bip;
> +err:
> + mempool_free(bip, bs->bio_integrity_pool);
> + return NULL;
>  }
>  EXPORT_SYMBOL(bio_integrity_alloc);
>  
> @@ -130,20 +94,19 @@ void bio_integrity_free(struct bio *bio)
>   struct bio_integrity_payload *bip = bio->bi_integrity;
>   struct bio_set *bs = bio->bi_pool;
>  
> - if (!bs)
> - bs = fs_bio_set;
> -
> - BUG_ON(bip == NULL);
> -
>  

Re: [dm-devel] [PATCH v2 01/26] block: Convert integrity to bvec_alloc_bs(), and a bugfix

2012-09-11 Thread Vivek Goyal
On Mon, Sep 10, 2012 at 05:22:12PM -0700, Kent Overstreet wrote:
 This adds a pointer to the bvec array to struct bio_integrity_payload,
 instead of the bvecs always being inline; then the bvecs are allocated
 with bvec_alloc_bs().

If you starting allocating bvec from same mempool for  bio and bip, 
are you not breaking the principle of multiple allocations from a
mempool and hence increasing the possibility of deadlock?

Also there seems to be too much happening in this patch. Please break
it down in 2. First fix the bio integrity bug you mentioned then
introduce your changes on top.

Thanks
Vivek

 
 This is needed eventually for immutable bio vecs - immutable bvecs
 aren't useful if we still have to copy them, hence the need for the
 pointer. Less code is always nice too, though.
 
 Also fix an amusing bug in bio_integrity_split() - struct bio_pair
 doesn't have the integrity bvecs after the bio_integrity_payloads, so
 there was a buffer overrun. The code was confusing pointers with arrays.
 
 Signed-off-by: Kent Overstreet koverstr...@google.com
 CC: Jens Axboe ax...@kernel.dk
 CC: Martin K. Petersen martin.peter...@oracle.com
 ---
  fs/bio-integrity.c  | 124 
 +---
  include/linux/bio.h |   5 ++-
  2 files changed, 43 insertions(+), 86 deletions(-)
 
 diff --git a/fs/bio-integrity.c b/fs/bio-integrity.c
 index a3f28f3..1d64f7f 100644
 --- a/fs/bio-integrity.c
 +++ b/fs/bio-integrity.c
 @@ -27,48 +27,11 @@
  #include linux/workqueue.h
  #include linux/slab.h
  
 -struct integrity_slab {
 - struct kmem_cache *slab;
 - unsigned short nr_vecs;
 - char name[8];
 -};
 -
 -#define IS(x) { .nr_vecs = x, .name = bip-__stringify(x) }
 -struct integrity_slab bip_slab[BIOVEC_NR_POOLS] __read_mostly = {
 - IS(1), IS(4), IS(16), IS(64), IS(128), IS(BIO_MAX_PAGES),
 -};
 -#undef IS
 +#define BIP_INLINE_VECS  4
  
 +static struct kmem_cache *bip_slab;
  static struct workqueue_struct *kintegrityd_wq;
  
 -static inline unsigned int vecs_to_idx(unsigned int nr)
 -{
 - switch (nr) {
 - case 1:
 - return 0;
 - case 2 ... 4:
 - return 1;
 - case 5 ... 16:
 - return 2;
 - case 17 ... 64:
 - return 3;
 - case 65 ... 128:
 - return 4;
 - case 129 ... BIO_MAX_PAGES:
 - return 5;
 - default:
 - BUG();
 - }
 -}
 -
 -static inline int use_bip_pool(unsigned int idx)
 -{
 - if (idx == BIOVEC_MAX_IDX)
 - return 1;
 -
 - return 0;
 -}
 -
  /**
   * bio_integrity_alloc - Allocate integrity payload and attach it to bio
   * @bio: bio to attach integrity metadata to
 @@ -84,37 +47,38 @@ struct bio_integrity_payload *bio_integrity_alloc(struct 
 bio *bio,
 unsigned int nr_vecs)
  {
   struct bio_integrity_payload *bip;
 - unsigned int idx = vecs_to_idx(nr_vecs);
   struct bio_set *bs = bio-bi_pool;
 + unsigned long idx = BIO_POOL_NONE;
 + unsigned inline_vecs;
 +
 + if (!bs) {
 + bip = kmalloc(sizeof(struct bio_integrity_payload) +
 +   sizeof(struct bio_vec) * nr_vecs, gfp_mask);
 + inline_vecs = nr_vecs;
 + } else {
 + bip = mempool_alloc(bs-bio_integrity_pool, gfp_mask);
 + inline_vecs = BIP_INLINE_VECS;
 + }
  
 - if (!bs)
 - bs = fs_bio_set;
 -
 - BUG_ON(bio == NULL);
 - bip = NULL;
 + if (unlikely(!bip))
 + return NULL;
  
 - /* Lower order allocations come straight from slab */
 - if (!use_bip_pool(idx))
 - bip = kmem_cache_alloc(bip_slab[idx].slab, gfp_mask);
 + memset(bip, 0, sizeof(struct bio_integrity_payload));
  
 - /* Use mempool if lower order alloc failed or max vecs were requested */
 - if (bip == NULL) {
 - idx = BIOVEC_MAX_IDX;  /* so we free the payload properly later 
 */
 - bip = mempool_alloc(bs-bio_integrity_pool, gfp_mask);
 -
 - if (unlikely(bip == NULL)) {
 - printk(KERN_ERR %s: could not alloc bip\n, __func__);
 - return NULL;
 - }
 + if (nr_vecs  inline_vecs) {
 + bip-bip_vec = bvec_alloc_bs(gfp_mask, nr_vecs, idx, bs);
 + if (!bip-bip_vec)
 + goto err;
   }
  
 - memset(bip, 0, sizeof(*bip));
 -
   bip-bip_slab = idx;
   bip-bip_bio = bio;
   bio-bi_integrity = bip;
  
   return bip;
 +err:
 + mempool_free(bip, bs-bio_integrity_pool);
 + return NULL;
  }
  EXPORT_SYMBOL(bio_integrity_alloc);
  
 @@ -130,20 +94,19 @@ void bio_integrity_free(struct bio *bio)
   struct bio_integrity_payload *bip = bio-bi_integrity;
   struct bio_set *bs = bio-bi_pool;
  
 - if (!bs)
 - bs = fs_bio_set;
 -
 - BUG_ON(bip == NULL);
 -
   /* A cloned bio doesn't own the integrity metadata */
   if 

Re: [dm-devel] [PATCH v2 01/26] block: Convert integrity to bvec_alloc_bs(), and a bugfix

2012-09-11 Thread Kent Overstreet
On Tue, Sep 11, 2012 at 04:36:43PM -0400, Vivek Goyal wrote:
 On Mon, Sep 10, 2012 at 05:22:12PM -0700, Kent Overstreet wrote:
  This adds a pointer to the bvec array to struct bio_integrity_payload,
  instead of the bvecs always being inline; then the bvecs are allocated
  with bvec_alloc_bs().
 
 If you starting allocating bvec from same mempool for  bio and bip, 
 are you not breaking the principle of multiple allocations from a
 mempool and hence increasing the possibility of deadlock?

Argh, you're right. I should've thought about that.

It might be nice if mempools had some kind of internal watermark... here
we know we're only going to do at most 2 allocations from the same
mempool, so if we just passed the number we already had allocated to
mempool_alloc(), it could do the right thing and ensure we never
deadlocked.

I _think_ that'd let us make more efficient use of the reserve. But, for
just this it's not really worth the extra code, I think I'll just have
to add another mempool.

 Also there seems to be too much happening in this patch. Please break
 it down in 2. First fix the bio integrity bug you mentioned then
 introduce your changes on top.

Ok, I can do that.

 Thanks
 Vivek
 
  
  This is needed eventually for immutable bio vecs - immutable bvecs
  aren't useful if we still have to copy them, hence the need for the
  pointer. Less code is always nice too, though.
  
  Also fix an amusing bug in bio_integrity_split() - struct bio_pair
  doesn't have the integrity bvecs after the bio_integrity_payloads, so
  there was a buffer overrun. The code was confusing pointers with arrays.
  
  Signed-off-by: Kent Overstreet koverstr...@google.com
  CC: Jens Axboe ax...@kernel.dk
  CC: Martin K. Petersen martin.peter...@oracle.com
  ---
   fs/bio-integrity.c  | 124 
  +---
   include/linux/bio.h |   5 ++-
   2 files changed, 43 insertions(+), 86 deletions(-)
  
  diff --git a/fs/bio-integrity.c b/fs/bio-integrity.c
  index a3f28f3..1d64f7f 100644
  --- a/fs/bio-integrity.c
  +++ b/fs/bio-integrity.c
  @@ -27,48 +27,11 @@
   #include linux/workqueue.h
   #include linux/slab.h
   
  -struct integrity_slab {
  -   struct kmem_cache *slab;
  -   unsigned short nr_vecs;
  -   char name[8];
  -};
  -
  -#define IS(x) { .nr_vecs = x, .name = bip-__stringify(x) }
  -struct integrity_slab bip_slab[BIOVEC_NR_POOLS] __read_mostly = {
  -   IS(1), IS(4), IS(16), IS(64), IS(128), IS(BIO_MAX_PAGES),
  -};
  -#undef IS
  +#define BIP_INLINE_VECS4
   
  +static struct kmem_cache *bip_slab;
   static struct workqueue_struct *kintegrityd_wq;
   
  -static inline unsigned int vecs_to_idx(unsigned int nr)
  -{
  -   switch (nr) {
  -   case 1:
  -   return 0;
  -   case 2 ... 4:
  -   return 1;
  -   case 5 ... 16:
  -   return 2;
  -   case 17 ... 64:
  -   return 3;
  -   case 65 ... 128:
  -   return 4;
  -   case 129 ... BIO_MAX_PAGES:
  -   return 5;
  -   default:
  -   BUG();
  -   }
  -}
  -
  -static inline int use_bip_pool(unsigned int idx)
  -{
  -   if (idx == BIOVEC_MAX_IDX)
  -   return 1;
  -
  -   return 0;
  -}
  -
   /**
* bio_integrity_alloc - Allocate integrity payload and attach it to bio
* @bio:   bio to attach integrity metadata to
  @@ -84,37 +47,38 @@ struct bio_integrity_payload 
  *bio_integrity_alloc(struct bio *bio,
unsigned int nr_vecs)
   {
  struct bio_integrity_payload *bip;
  -   unsigned int idx = vecs_to_idx(nr_vecs);
  struct bio_set *bs = bio-bi_pool;
  +   unsigned long idx = BIO_POOL_NONE;
  +   unsigned inline_vecs;
  +
  +   if (!bs) {
  +   bip = kmalloc(sizeof(struct bio_integrity_payload) +
  + sizeof(struct bio_vec) * nr_vecs, gfp_mask);
  +   inline_vecs = nr_vecs;
  +   } else {
  +   bip = mempool_alloc(bs-bio_integrity_pool, gfp_mask);
  +   inline_vecs = BIP_INLINE_VECS;
  +   }
   
  -   if (!bs)
  -   bs = fs_bio_set;
  -
  -   BUG_ON(bio == NULL);
  -   bip = NULL;
  +   if (unlikely(!bip))
  +   return NULL;
   
  -   /* Lower order allocations come straight from slab */
  -   if (!use_bip_pool(idx))
  -   bip = kmem_cache_alloc(bip_slab[idx].slab, gfp_mask);
  +   memset(bip, 0, sizeof(struct bio_integrity_payload));
   
  -   /* Use mempool if lower order alloc failed or max vecs were requested */
  -   if (bip == NULL) {
  -   idx = BIOVEC_MAX_IDX;  /* so we free the payload properly later 
  */
  -   bip = mempool_alloc(bs-bio_integrity_pool, gfp_mask);
  -
  -   if (unlikely(bip == NULL)) {
  -   printk(KERN_ERR %s: could not alloc bip\n, __func__);
  -   return NULL;
  -   }
  +   if (nr_vecs  inline_vecs) {
  +   bip-bip_vec = bvec_alloc_bs(gfp_mask, nr_vecs, idx, bs);
  +   if (!bip-bip_vec)
  +   goto err;
  

Re: [dm-devel] [PATCH v2 01/26] block: Convert integrity to bvec_alloc_bs(), and a bugfix

2012-09-11 Thread Kent Overstreet
On Tue, Sep 11, 2012 at 04:36:43PM -0400, Vivek Goyal wrote:
 Also there seems to be too much happening in this patch. Please break
 it down in 2. First fix the bio integrity bug you mentioned then
 introduce your changes on top.

Oh, I forgot - the reason I squashed them into one patch is fixing the
bug came for free with the rest of the refactoring, and combining them
touches less code.

To fix the bug first, I'd have to reorder struct bio_pair and then just
delete two lines of code from bio_integrity_split(). But the reordering
is unnecessary with the refactoring.
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/