aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicholas Bellinger <nab@linux-iscsi.org>2014-01-07 18:24:14 -0500
committerNicholas Bellinger <nab@linux-iscsi.org>2014-01-18 21:22:05 -0500
commitd7e8eb5d9216c6a4f963aa6d07e29680af17d739 (patch)
tree2697c2a5e59174ce97e5e393b01edd32b8a55462
parent4442dc8a92b8f9ad8ee9e7f8438f4c04c03a22dc (diff)
target/rd: Add support for protection SGL setup + release
This patch adds rd_build_prot_space() + rd_release_prot_space() logic to setup + release protection information scatterlists. It also adds rd_init_prot() + rd_free_prot() se_subsystem_api callbacks used by target core code for setup + release of protection information. v2 changes: - Drop unused sg_table from rd_release_prot_space (Wei) - Drop rd_release_prot_space call from rd_free_device Cc: Martin K. Petersen <martin.petersen@oracle.com> Cc: Christoph Hellwig <hch@lst.de> Cc: Hannes Reinecke <hare@suse.de> Cc: Sagi Grimberg <sagig@mellanox.com> Cc: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
-rw-r--r--drivers/target/target_core_rd.c74
-rw-r--r--drivers/target/target_core_rd.h4
2 files changed, 78 insertions, 0 deletions
diff --git a/drivers/target/target_core_rd.c b/drivers/target/target_core_rd.c
index e9fa879ac27f..660961d9e106 100644
--- a/drivers/target/target_core_rd.c
+++ b/drivers/target/target_core_rd.c
@@ -223,6 +223,61 @@ static int rd_build_device_space(struct rd_dev *rd_dev)
223 return 0; 223 return 0;
224} 224}
225 225
226static void rd_release_prot_space(struct rd_dev *rd_dev)
227{
228 u32 page_count;
229
230 if (!rd_dev->sg_prot_array || !rd_dev->sg_prot_count)
231 return;
232
233 page_count = rd_release_sgl_table(rd_dev, rd_dev->sg_prot_array,
234 rd_dev->sg_prot_count);
235
236 pr_debug("CORE_RD[%u] - Released protection space for Ramdisk"
237 " Device ID: %u, pages %u in %u tables total bytes %lu\n",
238 rd_dev->rd_host->rd_host_id, rd_dev->rd_dev_id, page_count,
239 rd_dev->sg_table_count, (unsigned long)page_count * PAGE_SIZE);
240
241 rd_dev->sg_prot_array = NULL;
242 rd_dev->sg_prot_count = 0;
243}
244
245static int rd_build_prot_space(struct rd_dev *rd_dev, int prot_length)
246{
247 struct rd_dev_sg_table *sg_table;
248 u32 total_sg_needed, sg_tables;
249 u32 max_sg_per_table = (RD_MAX_ALLOCATION_SIZE /
250 sizeof(struct scatterlist));
251 int rc;
252
253 if (rd_dev->rd_flags & RDF_NULLIO)
254 return 0;
255
256 total_sg_needed = rd_dev->rd_page_count / prot_length;
257
258 sg_tables = (total_sg_needed / max_sg_per_table) + 1;
259
260 sg_table = kzalloc(sg_tables * sizeof(struct rd_dev_sg_table), GFP_KERNEL);
261 if (!sg_table) {
262 pr_err("Unable to allocate memory for Ramdisk protection"
263 " scatterlist tables\n");
264 return -ENOMEM;
265 }
266
267 rd_dev->sg_prot_array = sg_table;
268 rd_dev->sg_prot_count = sg_tables;
269
270 rc = rd_allocate_sgl_table(rd_dev, sg_table, total_sg_needed, 0xff);
271 if (rc)
272 return rc;
273
274 pr_debug("CORE_RD[%u] - Built Ramdisk Device ID: %u prot space of"
275 " %u pages in %u tables\n", rd_dev->rd_host->rd_host_id,
276 rd_dev->rd_dev_id, total_sg_needed, rd_dev->sg_prot_count);
277
278 return 0;
279}
280
226static struct se_device *rd_alloc_device(struct se_hba *hba, const char *name) 281static struct se_device *rd_alloc_device(struct se_hba *hba, const char *name)
227{ 282{
228 struct rd_dev *rd_dev; 283 struct rd_dev *rd_dev;
@@ -479,6 +534,23 @@ static sector_t rd_get_blocks(struct se_device *dev)
479 return blocks_long; 534 return blocks_long;
480} 535}
481 536
537static int rd_init_prot(struct se_device *dev)
538{
539 struct rd_dev *rd_dev = RD_DEV(dev);
540
541 if (!dev->dev_attrib.pi_prot_type)
542 return 0;
543
544 return rd_build_prot_space(rd_dev, dev->prot_length);
545}
546
547static void rd_free_prot(struct se_device *dev)
548{
549 struct rd_dev *rd_dev = RD_DEV(dev);
550
551 rd_release_prot_space(rd_dev);
552}
553
482static struct sbc_ops rd_sbc_ops = { 554static struct sbc_ops rd_sbc_ops = {
483 .execute_rw = rd_execute_rw, 555 .execute_rw = rd_execute_rw,
484}; 556};
@@ -504,6 +576,8 @@ static struct se_subsystem_api rd_mcp_template = {
504 .show_configfs_dev_params = rd_show_configfs_dev_params, 576 .show_configfs_dev_params = rd_show_configfs_dev_params,
505 .get_device_type = sbc_get_device_type, 577 .get_device_type = sbc_get_device_type,
506 .get_blocks = rd_get_blocks, 578 .get_blocks = rd_get_blocks,
579 .init_prot = rd_init_prot,
580 .free_prot = rd_free_prot,
507}; 581};
508 582
509int __init rd_module_init(void) 583int __init rd_module_init(void)
diff --git a/drivers/target/target_core_rd.h b/drivers/target/target_core_rd.h
index 1789d1e14395..cc46a6a89b38 100644
--- a/drivers/target/target_core_rd.h
+++ b/drivers/target/target_core_rd.h
@@ -33,8 +33,12 @@ struct rd_dev {
33 u32 rd_page_count; 33 u32 rd_page_count;
34 /* Number of SG tables in sg_table_array */ 34 /* Number of SG tables in sg_table_array */
35 u32 sg_table_count; 35 u32 sg_table_count;
36 /* Number of SG tables in sg_prot_array */
37 u32 sg_prot_count;
36 /* Array of rd_dev_sg_table_t containing scatterlists */ 38 /* Array of rd_dev_sg_table_t containing scatterlists */
37 struct rd_dev_sg_table *sg_table_array; 39 struct rd_dev_sg_table *sg_table_array;
40 /* Array of rd_dev_sg_table containing protection scatterlists */
41 struct rd_dev_sg_table *sg_prot_array;
38 /* Ramdisk HBA device is connected to */ 42 /* Ramdisk HBA device is connected to */
39 struct rd_host *rd_host; 43 struct rd_host *rd_host;
40} ____cacheline_aligned; 44} ____cacheline_aligned;