Re: [PATCH 13/14] target/rd: Add DIF protection into rd_execute_rw
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
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
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
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
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
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