Re: Too big sectors - exceeding fabric_max_sectors

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, 2012-11-08 at 10:10 -0800, Nicholas A. Bellinger wrote:
> On Thu, 2012-11-08 at 14:25 +0000, Prantis, Kelsey wrote:
> > On 11/7/12 4:26 PM, "Prantis, Kelsey" <kelsey.prantis@xxxxxxxxx> wrote:
> > >>So I'll try to reproduce using some different combinations of
> > >>fabric_max_sectors, but for the moment please apply the following debug
> > >>patch to dump struct scatterlist + struct bio members and try to
> > >>reproduce.
> > >
> > >Am working on applying the patch now, and will get back to you when I have
> > >a result.
> > 
> > There was quite a bit of output, which can be fetched from:
> > ftp://ftp.whamcloud.com/uploads/lio-debug.txt
> > 
> 
> Hi Kelsey,
> 
> Thanks for the log.  After an quick look, here's what I see so far:
> 

<SNIP>

> So AFAICT this looks like a iblock bio completion callback is being
> invoked more than once, that is being triggered when using multiple BIOs
> to complete a single se_cmd descriptor.
> 
> Looking at the code in question from target_core_iblock.c, I think I see
> what's going on now.  There is a double completion happening between the
> iblock_complete_cmd call in iblock_execute_rw() and iblock_bio_done()
> that appears to have been introduced with:
> 
> commit 5787cacd0bd5ee016ad807b244550d34fe2beebe
> Author: Christoph Hellwig <hch@xxxxxxxxxxxxx>
> Date:   Tue Apr 24 00:25:06 2012 -0400
> 
>     target: remove struct se_task
> 
> I'm currently testing the following patch to address this bug.
> 
> Please give it a shot with your setup.
> 
> Thanks!
> 
> --nab
> 
> diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c
> index 57d7674..305aa41 100644
> --- a/drivers/target/target_core_iblock.c
> +++ b/drivers/target/target_core_iblock.c
> @@ -658,7 +658,7 @@ static int iblock_execute_rw(struct se_cmd *cmd)
>         bio_list_init(&list);
>         bio_list_add(&list, bio);
>  
> -       atomic_set(&ibr->pending, 2);
> +       atomic_set(&ibr->pending, 1);
>         bio_cnt = 1;
>  
>         for_each_sg(sgl, sg, sgl_nents, i) {
> @@ -689,7 +689,6 @@ static int iblock_execute_rw(struct se_cmd *cmd)
>         }
>  
>         iblock_submit_bios(&list, rw);
> -       iblock_complete_cmd(cmd);
>         return 0;
>  
>  fail_put_bios:
> 
> --

Ok, a slightly updated version of this patch to make sure that
ibr->pending in incremented ahead of the possible call to
iblock_submit_bios() when bio_cnt >= IBLOCK_MAX_BIO_PER_TASK.

This is not happening in your particular case, but is still required
to ensure that iblock_bio_done() waits for all outstanding bios
to return before completing to target core.

--nab

diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c
index 57d7674..70fd5b5 100644
--- a/drivers/target/target_core_iblock.c
+++ b/drivers/target/target_core_iblock.c
@@ -658,7 +658,7 @@ static int iblock_execute_rw(struct se_cmd *cmd)
        bio_list_init(&list);
        bio_list_add(&list, bio);
 
-       atomic_set(&ibr->pending, 2);
+       atomic_set(&ibr->pending, 1);
        bio_cnt = 1;
 
        for_each_sg(sgl, sg, sgl_nents, i) {
@@ -669,16 +669,23 @@ static int iblock_execute_rw(struct se_cmd *cmd)
                 */
                while (bio_add_page(bio, sg_page(sg), sg->length, sg->offset)
                                != sg->length) {
+                       /*
+                        * Increment pending now before possible call to
+                        * iblock_submit_bios() -> async iblock_bio_done()
+                        */
+                       atomic_inc(&ibr->pending);
+
                        if (bio_cnt >= IBLOCK_MAX_BIO_PER_TASK) {
                                iblock_submit_bios(&list, rw);
                                bio_cnt = 0;
                        }
 
                        bio = iblock_get_bio(cmd, block_lba, sg_num);
-                       if (!bio)
+                       if (!bio) {
+                               atomic_dec(&ibr->pending);
                                goto fail_put_bios;
+                       }
 
-                       atomic_inc(&ibr->pending);
                        bio_list_add(&list, bio);
                        bio_cnt++;
                }
@@ -689,7 +696,6 @@ static int iblock_execute_rw(struct se_cmd *cmd)
        }
 
        iblock_submit_bios(&list, rw);
-       iblock_complete_cmd(cmd);
        return 0;
 
 fail_put_bios:


--
To unsubscribe from this list: send the line "unsubscribe target-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux SCSI]     [Kernel Newbies]     [Linux SCSI Target Infrastructure]     [Share Photos]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Device Mapper]

  Powered by Linux