Re: [PATCH 13/14] target/rd: Add DIF protection into rd_execute_rw

2014-01-13 Thread Nicholas A. Bellinger
On Sun, 2014-01-12 at 13:53 +0200, Sagi Grimberg wrote:
 SNIP
 
  I wander how we can skip  sbc_dif_verify_ if the transport already
  offloaded DIF verify.
  I think that the transport should signal the core layer that it is able
  to offload DIF (ADD/STRIP/PASS/VERIFY), in which case the core should
  turn off the backstore DIF verify emulation to sustain performance.
  So IBLOCK + PSCSI backends will need to be a non interleaved protection
  PASS for fast path operation, and backend protection emulation is
  reserved for RAMDISK and perhaps a special FILEIO full emulation mode.
 
 But can't we avoid that if transport already verified? This will kill 
 performance.
 

Sure, this will end up being configurable per backend if the fabric does
a CHECK + STRIP, or CHECK + PASS.

--nab



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


Re: [PATCH 13/14] target/rd: Add DIF protection into rd_execute_rw

2014-01-12 Thread Sagi Grimberg

SNIP


I wander how we can skip  sbc_dif_verify_ if the transport already
offloaded DIF verify.
I think that the transport should signal the core layer that it is able
to offload DIF (ADD/STRIP/PASS/VERIFY), in which case the core should
turn off the backstore DIF verify emulation to sustain performance.

So IBLOCK + PSCSI backends will need to be a non interleaved protection
PASS for fast path operation, and backend protection emulation is
reserved for RAMDISK and perhaps a special FILEIO full emulation mode.


But can't we avoid that if transport already verified? This will kill 
performance.


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


Re: [PATCH 13/14] target/rd: Add DIF protection into rd_execute_rw

2014-01-10 Thread Martin K. Petersen
 Sagi == Sagi Grimberg sa...@mellanox.com writes:

Sagi I wander how we can skip sbc_dif_verify_ if the transport
Sagi already offloaded DIF verify.  I think that the transport should
Sagi signal the core layer that it is able to offload DIF
Sagi (ADD/STRIP/PASS/VERIFY), in which case the core should turn off
Sagi the backstore DIF verify emulation to sustain performance.

Yeah, for SAS and FC it would be nice to leverage DIX and let the ASIC
do the actual checking and splitting. I assume the same is true for your
hw.

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


Re: [PATCH 13/14] target/rd: Add DIF protection into rd_execute_rw

2014-01-09 Thread Sagi Grimberg

On 1/8/2014 10:36 PM, Nicholas A. Bellinger wrote:

From: Nicholas Bellinger n...@linux-iscsi.org

This patch adds support for DIF protection into rd_execute_rw() code
for WRITE/READ I/O using sbc_dif_verify_[write,read]() logic.

It also adds rd_get_prot_table() for locating protection SGLs
assoicated with the ramdisk backend device.

Cc: Martin K. Petersen martin.peter...@oracle.com
Cc: Christoph Hellwig h...@lst.de
Cc: Hannes Reinecke h...@suse.de
Cc: Sagi Grimberg sa...@mellanox.com
Cc: Or Gerlitz ogerl...@mellanox.com
Signed-off-by: Nicholas Bellinger n...@linux-iscsi.org
---
  drivers/target/target_core_rd.c |   67 +++
  1 file changed, 67 insertions(+)

diff --git a/drivers/target/target_core_rd.c b/drivers/target/target_core_rd.c
index dd99844..3fd51eb 100644
--- a/drivers/target/target_core_rd.c
+++ b/drivers/target/target_core_rd.c
@@ -363,6 +363,26 @@ static struct rd_dev_sg_table *rd_get_sg_table(struct 
rd_dev *rd_dev, u32 page)
return NULL;
  }
  
+static struct rd_dev_sg_table *rd_get_prot_table(struct rd_dev *rd_dev, u32 page)

+{
+   struct rd_dev_sg_table *sg_table;
+   u32 i, sg_per_table = (RD_MAX_ALLOCATION_SIZE /
+   sizeof(struct scatterlist));
+
+   i = page / sg_per_table;
+   if (i  rd_dev-sg_prot_count) {
+   sg_table = rd_dev-sg_prot_array[i];
+   if ((sg_table-page_start_offset = page) 
+(sg_table-page_end_offset = page))
+   return sg_table;
+   }
+
+   pr_err(Unable to locate struct prot rd_dev_sg_table for page: %u\n,
+   page);
+
+   return NULL;
+}
+
  static sense_reason_t
  rd_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,
  enum dma_data_direction data_direction)
@@ -377,6 +397,7 @@ rd_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, 
u32 sgl_nents,
u32 rd_page;
u32 src_len;
u64 tmp;
+   sense_reason_t rc;
  
  	if (dev-rd_flags  RDF_NULLIO) {

target_complete_cmd(cmd, SAM_STAT_GOOD);
@@ -399,6 +420,29 @@ rd_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, 
u32 sgl_nents,
data_direction == DMA_FROM_DEVICE ? Read : Write,
cmd-t_task_lba, rd_size, rd_page, rd_offset);
  
+	if ((cmd-se_cmd_flags  SCF_PROT)  se_dev-dev_attrib.pi_prot_type 

+   data_direction == DMA_TO_DEVICE) {
+   sector_t sector = cmd-data_length / 
se_dev-dev_attrib.block_size;
+   struct rd_dev_sg_table *prot_table;
+   struct scatterlist *prot_sg;
+   u32 prot_offset, prot_page;
+
+   tmp = cmd-t_task_lba * se_dev-prot_length;
+   prot_offset = do_div(tmp, PAGE_SIZE);
+   prot_page = tmp;
+
+   prot_table = rd_get_prot_table(dev, prot_page);
+   if (!prot_table)
+   return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+
+   prot_sg = prot_table-sg_table[prot_page - 
prot_table-page_start_offset];
+
+   rc = sbc_dif_verify_write(cmd, cmd-t_task_lba, sector, 0,
+ prot_sg, prot_offset);
+   if (rc)
+   return rc;
+   }
+
src_len = PAGE_SIZE - rd_offset;
sg_miter_start(m, sgl, sgl_nents,
data_direction == DMA_FROM_DEVICE ?
@@ -460,6 +504,29 @@ rd_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, 
u32 sgl_nents,
}
sg_miter_stop(m);
  
+	if ((cmd-se_cmd_flags  SCF_PROT)  se_dev-dev_attrib.pi_prot_type 

+   data_direction == DMA_FROM_DEVICE) {
+   sector_t sector = cmd-data_length / 
se_dev-dev_attrib.block_size;
+   struct rd_dev_sg_table *prot_table;
+   struct scatterlist *prot_sg;
+   u32 prot_offset, prot_page;
+
+   tmp = cmd-t_task_lba * se_dev-prot_length;
+   prot_offset = do_div(tmp, PAGE_SIZE);
+   prot_page = tmp;
+
+   prot_table = rd_get_prot_table(dev, prot_page);
+   if (!prot_table)
+   return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+
+   prot_sg = prot_table-sg_table[prot_page - 
prot_table-page_start_offset];
+
+   rc = sbc_dif_verify_read(cmd, cmd-t_task_lba, sector, 0,
+prot_sg, prot_offset);
+   if (rc)
+   return rc;
+   }
+
target_complete_cmd(cmd, SAM_STAT_GOOD);
return 0;
  }


I wander how we can skip  sbc_dif_verify_ if the transport already 
offloaded DIF verify.
I think that the transport should signal the core layer that it is able 
to offload DIF (ADD/STRIP/PASS/VERIFY), in which case the core should 
turn off the backstore DIF verify emulation to sustain performance. I 
assume that if backstore DIF verify is 

Re: [PATCH 13/14] target/rd: Add DIF protection into rd_execute_rw

2014-01-09 Thread Nicholas A. Bellinger
On Thu, 2014-01-09 at 12:32 +0200, Sagi Grimberg wrote:
 On 1/8/2014 10:36 PM, Nicholas A. Bellinger wrote:
  From: Nicholas Bellinger n...@linux-iscsi.org
 
  This patch adds support for DIF protection into rd_execute_rw() code
  for WRITE/READ I/O using sbc_dif_verify_[write,read]() logic.
 
  It also adds rd_get_prot_table() for locating protection SGLs
  assoicated with the ramdisk backend device.
 
  Cc: Martin K. Petersen martin.peter...@oracle.com
  Cc: Christoph Hellwig h...@lst.de
  Cc: Hannes Reinecke h...@suse.de
  Cc: Sagi Grimberg sa...@mellanox.com
  Cc: Or Gerlitz ogerl...@mellanox.com
  Signed-off-by: Nicholas Bellinger n...@linux-iscsi.org
  ---
drivers/target/target_core_rd.c |   67 
  +++
1 file changed, 67 insertions(+)
 
  diff --git a/drivers/target/target_core_rd.c 
  b/drivers/target/target_core_rd.c
  index dd99844..3fd51eb 100644
  --- a/drivers/target/target_core_rd.c
  +++ b/drivers/target/target_core_rd.c
  @@ -363,6 +363,26 @@ static struct rd_dev_sg_table *rd_get_sg_table(struct 
  rd_dev *rd_dev, u32 page)
  return NULL;
}

  +static struct rd_dev_sg_table *rd_get_prot_table(struct rd_dev *rd_dev, 
  u32 page)
  +{
  +   struct rd_dev_sg_table *sg_table;
  +   u32 i, sg_per_table = (RD_MAX_ALLOCATION_SIZE /
  +   sizeof(struct scatterlist));
  +
  +   i = page / sg_per_table;
  +   if (i  rd_dev-sg_prot_count) {
  +   sg_table = rd_dev-sg_prot_array[i];
  +   if ((sg_table-page_start_offset = page) 
  +(sg_table-page_end_offset = page))
  +   return sg_table;
  +   }
  +
  +   pr_err(Unable to locate struct prot rd_dev_sg_table for page: %u\n,
  +   page);
  +
  +   return NULL;
  +}
  +
static sense_reason_t
rd_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,
enum dma_data_direction data_direction)
  @@ -377,6 +397,7 @@ rd_execute_rw(struct se_cmd *cmd, struct scatterlist 
  *sgl, u32 sgl_nents,
  u32 rd_page;
  u32 src_len;
  u64 tmp;
  +   sense_reason_t rc;

  if (dev-rd_flags  RDF_NULLIO) {
  target_complete_cmd(cmd, SAM_STAT_GOOD);
  @@ -399,6 +420,29 @@ rd_execute_rw(struct se_cmd *cmd, struct scatterlist 
  *sgl, u32 sgl_nents,
  data_direction == DMA_FROM_DEVICE ? Read : Write,
  cmd-t_task_lba, rd_size, rd_page, rd_offset);

  +   if ((cmd-se_cmd_flags  SCF_PROT)  se_dev-dev_attrib.pi_prot_type 
  +   data_direction == DMA_TO_DEVICE) {
  +   sector_t sector = cmd-data_length / 
  se_dev-dev_attrib.block_size;
  +   struct rd_dev_sg_table *prot_table;
  +   struct scatterlist *prot_sg;
  +   u32 prot_offset, prot_page;
  +
  +   tmp = cmd-t_task_lba * se_dev-prot_length;
  +   prot_offset = do_div(tmp, PAGE_SIZE);
  +   prot_page = tmp;
  +
  +   prot_table = rd_get_prot_table(dev, prot_page);
  +   if (!prot_table)
  +   return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
  +
  +   prot_sg = prot_table-sg_table[prot_page - 
  prot_table-page_start_offset];
  +
  +   rc = sbc_dif_verify_write(cmd, cmd-t_task_lba, sector, 0,
  + prot_sg, prot_offset);
  +   if (rc)
  +   return rc;
  +   }
  +
  src_len = PAGE_SIZE - rd_offset;
  sg_miter_start(m, sgl, sgl_nents,
  data_direction == DMA_FROM_DEVICE ?
  @@ -460,6 +504,29 @@ rd_execute_rw(struct se_cmd *cmd, struct scatterlist 
  *sgl, u32 sgl_nents,
  }
  sg_miter_stop(m);

  +   if ((cmd-se_cmd_flags  SCF_PROT)  se_dev-dev_attrib.pi_prot_type 
  +   data_direction == DMA_FROM_DEVICE) {
  +   sector_t sector = cmd-data_length / 
  se_dev-dev_attrib.block_size;
  +   struct rd_dev_sg_table *prot_table;
  +   struct scatterlist *prot_sg;
  +   u32 prot_offset, prot_page;
  +
  +   tmp = cmd-t_task_lba * se_dev-prot_length;
  +   prot_offset = do_div(tmp, PAGE_SIZE);
  +   prot_page = tmp;
  +
  +   prot_table = rd_get_prot_table(dev, prot_page);
  +   if (!prot_table)
  +   return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
  +
  +   prot_sg = prot_table-sg_table[prot_page - 
  prot_table-page_start_offset];
  +
  +   rc = sbc_dif_verify_read(cmd, cmd-t_task_lba, sector, 0,
  +prot_sg, prot_offset);
  +   if (rc)
  +   return rc;
  +   }
  +
  target_complete_cmd(cmd, SAM_STAT_GOOD);
  return 0;
}
 
 I wander how we can skip  sbc_dif_verify_ if the transport already 
 offloaded DIF verify.
 I think that the transport should signal the core layer that it is able 
 to offload DIF (ADD/STRIP/PASS/VERIFY), in which case the core should 
 turn off the backstore DIF verify emulation to 

[PATCH 13/14] target/rd: Add DIF protection into rd_execute_rw

2014-01-08 Thread Nicholas A. Bellinger
From: Nicholas Bellinger n...@linux-iscsi.org

This patch adds support for DIF protection into rd_execute_rw() code
for WRITE/READ I/O using sbc_dif_verify_[write,read]() logic.

It also adds rd_get_prot_table() for locating protection SGLs
assoicated with the ramdisk backend device.

Cc: Martin K. Petersen martin.peter...@oracle.com
Cc: Christoph Hellwig h...@lst.de
Cc: Hannes Reinecke h...@suse.de
Cc: Sagi Grimberg sa...@mellanox.com
Cc: Or Gerlitz ogerl...@mellanox.com
Signed-off-by: Nicholas Bellinger n...@linux-iscsi.org
---
 drivers/target/target_core_rd.c |   67 +++
 1 file changed, 67 insertions(+)

diff --git a/drivers/target/target_core_rd.c b/drivers/target/target_core_rd.c
index dd99844..3fd51eb 100644
--- a/drivers/target/target_core_rd.c
+++ b/drivers/target/target_core_rd.c
@@ -363,6 +363,26 @@ static struct rd_dev_sg_table *rd_get_sg_table(struct 
rd_dev *rd_dev, u32 page)
return NULL;
 }
 
+static struct rd_dev_sg_table *rd_get_prot_table(struct rd_dev *rd_dev, u32 
page)
+{
+   struct rd_dev_sg_table *sg_table;
+   u32 i, sg_per_table = (RD_MAX_ALLOCATION_SIZE /
+   sizeof(struct scatterlist));
+
+   i = page / sg_per_table;
+   if (i  rd_dev-sg_prot_count) {
+   sg_table = rd_dev-sg_prot_array[i];
+   if ((sg_table-page_start_offset = page) 
+(sg_table-page_end_offset = page))
+   return sg_table;
+   }
+
+   pr_err(Unable to locate struct prot rd_dev_sg_table for page: %u\n,
+   page);
+
+   return NULL;
+}
+
 static sense_reason_t
 rd_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,
  enum dma_data_direction data_direction)
@@ -377,6 +397,7 @@ rd_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, 
u32 sgl_nents,
u32 rd_page;
u32 src_len;
u64 tmp;
+   sense_reason_t rc;
 
if (dev-rd_flags  RDF_NULLIO) {
target_complete_cmd(cmd, SAM_STAT_GOOD);
@@ -399,6 +420,29 @@ rd_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, 
u32 sgl_nents,
data_direction == DMA_FROM_DEVICE ? Read : Write,
cmd-t_task_lba, rd_size, rd_page, rd_offset);
 
+   if ((cmd-se_cmd_flags  SCF_PROT)  se_dev-dev_attrib.pi_prot_type 
+   data_direction == DMA_TO_DEVICE) {
+   sector_t sector = cmd-data_length / 
se_dev-dev_attrib.block_size;
+   struct rd_dev_sg_table *prot_table;
+   struct scatterlist *prot_sg;
+   u32 prot_offset, prot_page;
+
+   tmp = cmd-t_task_lba * se_dev-prot_length;
+   prot_offset = do_div(tmp, PAGE_SIZE);
+   prot_page = tmp;
+
+   prot_table = rd_get_prot_table(dev, prot_page);
+   if (!prot_table)
+   return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+
+   prot_sg = prot_table-sg_table[prot_page - 
prot_table-page_start_offset];
+
+   rc = sbc_dif_verify_write(cmd, cmd-t_task_lba, sector, 0,
+ prot_sg, prot_offset);
+   if (rc)
+   return rc;
+   }
+
src_len = PAGE_SIZE - rd_offset;
sg_miter_start(m, sgl, sgl_nents,
data_direction == DMA_FROM_DEVICE ?
@@ -460,6 +504,29 @@ rd_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, 
u32 sgl_nents,
}
sg_miter_stop(m);
 
+   if ((cmd-se_cmd_flags  SCF_PROT)  se_dev-dev_attrib.pi_prot_type 
+   data_direction == DMA_FROM_DEVICE) {
+   sector_t sector = cmd-data_length / 
se_dev-dev_attrib.block_size;
+   struct rd_dev_sg_table *prot_table;
+   struct scatterlist *prot_sg;
+   u32 prot_offset, prot_page;
+
+   tmp = cmd-t_task_lba * se_dev-prot_length;
+   prot_offset = do_div(tmp, PAGE_SIZE);
+   prot_page = tmp;
+
+   prot_table = rd_get_prot_table(dev, prot_page);
+   if (!prot_table)
+   return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
+
+   prot_sg = prot_table-sg_table[prot_page - 
prot_table-page_start_offset];
+
+   rc = sbc_dif_verify_read(cmd, cmd-t_task_lba, sector, 0,
+prot_sg, prot_offset);
+   if (rc)
+   return rc;
+   }
+
target_complete_cmd(cmd, SAM_STAT_GOOD);
return 0;
 }
-- 
1.7.10.4

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