Re: tcm_loopback broken in for-next of target-pending

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

 



On Tue, 2012-12-04 at 09:48 +0100, Sebastian Andrzej Siewior wrote:
> On 12/04/2012 05:44 AM, Nicholas A. Bellinger wrote:
> > Hi Sebastian,
> 
> Hi Nab,
> 
> >>     vfs_readv() returned -14 for non S_ISBLK
> >
> > Ok, this looks like a perfectly normal READ_10 of 64K (128 sectors) to
> > LBA 12349.
> >
> > Not sure why vfs_readv() of 64K is generating an -EFAULT here, but lets
> > first verify that SGLs being dispatched by tcm_loop to TCM ->  FILEIO are
> > looking as expected on your setup.
> >
> > Please try to reproduce with the following patch:
> 
> I modified it slightly in order to dump sg_virt() as well since this is
> what we pass to the function that fails:
>   vfs_readv() returned -14 for non S_ISBLK
>   SG[0]: f4188240 page: f5c1e5a0 virt:   (null) length: 4096 offset: 0
>   SG[1]: f4188258 page: f5c55da0 virt:   (null) length: 4096 offset: 0
>   SG[2]: f4188270 page: f5c54d80 virt:   (null) length: 4096 offset: 0
>   SG[3]: f4188288 page: f5c5bd20 virt:   (null) length: 4096 offset: 0
>   SG[4]: f41882a0 page: f5c5bca0 virt:   (null) length: 4096 offset: 0
>   SG[5]: f41882b8 page: f5c547e0 virt:   (null) length: 4096 offset: 0
>   SG[6]: f41882d0 page: f5c58b20 virt:   (null) length: 4096 offset: 0
>   SG[7]: f41882e8 page: f5c621e0 virt:   (null) length: 4096 offset: 0
>   SG[8]: f4188300 page: f5c54d40 virt: ff990000 length: 4096 offset: 0
>   SG[9]: f4188318 page: f5c4c800 virt:   (null) length: 4096 offset: 0
>   SG[10]: f4188330 page: f5c54ca0 virt:   (null) length: 4096 offset: 0
>   SG[11]: f4188348 page: f5c57980 virt:   (null) length: 4096 offset: 0
>   SG[12]: f4188360 page: f5c544e0 virt:   (null) length: 4096 offset: 0
>   SG[13]: f4188378 page: f5c565c0 virt:   (null) length: 4096 offset: 0
>   SG[14]: f4188390 page: f5c5bce0 virt: ff995000 length: 4096 offset: 0
>   SG[15]: f41883a8 page: f5c22980 virt:   (null) length: 4096 offset: 0
> 
> If you ask why is virt null then I got to tell you that I have highmem.
> I remember that while I fixed tcm_loop a year ago or so I pointed out
> that the code is not highmem safe but it is not a problem because all
> memory that is allocated by tcm_loop itself is non-highmem. No you got 
> highmem from somewhere.

OK, so the SGL memory dispatched into tcm_loop LLD code is setup with
GFP_KERNEL allocations from SCSI core by default, which is breaking
32-bit highmem with FILEIO backends..

One possible workaround for tcm_loop w/ highmem is make SCSI use GFP_DMA
by setting scsi_host_template->unchecked_isa_dma=1 from within the LLD. 

> The patch
> 
> diff --git a/drivers/target/target_core_file.c 
> b/drivers/target/target_core_file.c
> index 0360383..319b87a 100644
> --- a/drivers/target/target_core_file.c
> +++ b/drivers/target/target_core_file.c
> @@ -260,7 +260,7 @@ static int fd_do_readv(struct se_cmd *cmd, struct 
> scatterlist *sgl,
> 
>          for_each_sg(sgl, sg, sgl_nents, i) {
>                  iov[i].iov_len = sg->length;
> -               iov[i].iov_base = sg_virt(sg);
> +               iov[i].iov_base = kmap(sg_page(sg));
>          }
> 
>          old_fs = get_fs();
> @@ -268,6 +268,10 @@ static int fd_do_readv(struct se_cmd *cmd, struct 
> scatterlist *sgl,
>          ret = vfs_readv(fd, &iov[0], sgl_nents, &pos);
>          set_fs(old_fs);
> 
> +       for_each_sg(sgl, sg, sgl_nents, i) {
> +               kunmap(sg_page(sg));
> +       }
> +
>          kfree(iov);
>          /*
>           * Return zeros and GOOD status even if the READ did not return
> 
> Does not work. It bails out even earlier, before the XFS mount
> completes. That means the complete code is not highmem aware and it
> simply works because page_address() returns something that does not
> cause a fault and the memory is not important enough to crash the box.
> 

Mmmm..  Christoph, what do you think for the highmem FILEIO case..?

> >> commit 8f9f44f8957b262de717a48269a5ceca36c2b504
> >> Author: Nicholas Bellinger<nab@xxxxxxxxxxxxxxx>
> >> Date:   Mon Oct 1 23:29:49 2012 -0700
> >>
> >>       tcm_loop: Convert I/O path to use target_submit_cmd_map_sgls
> >>
> >>       This patch converts tcm_loop to use target_submit_cmd_map_sgls() for
> >>       I/O submission and mapping of pre-allocated SGL memory from incoming
> >>       scsi_cmnd ->  se_cmd descriptors.
> >>
> >>       This includes removing the original open-coded fabric uses of target
> >>       core callers to support transport_generic_map_mem_to_cmd() between
> >>       target_setup_cmd_from_cdb() and transport_handle_cdb_direct() logic.
> >>
> >>       (v2: Use renamed target_submit_cmd_map_sgls)
> >>
> >>       Reported-by: Christoph Hellwig<hch@xxxxxx>
> >>       Reviewed-by: Christoph Hellwig<hch@xxxxxx>
> >>       Signed-off-by: Nicholas Bellinger<nab@xxxxxxxxxxxxxxx>
> >>
> >
> > Very strange.  This is a non functional change for tcm_loop code using
> > the exact same underlying target_core_mod functions for se_cmd setup ->
> > SGL mapping ->  se_cmd I/O dispatch ub target_submit_cmd_map_sg(), so I
> > don't see how it would effect this bug.
> 
> Is it possible that now the memory allocation works different? I
> haven't look at the code…
> 

Nope, the target is simply accepting pre-built SGLs from the tcm_loop
SCSI LLD, and skipping internal SGL allocation+setup all-together.

--nab

--
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