[PATCH] target/file: Update hw_max_sectors based on current block_size

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

 



From: Nicholas Bellinger <nab@xxxxxxxxxxxxxxx>

This patch allows FILEIO to update hw_max_sectors based on the current
block_size.  This is required because vfs_[writev,readv]() can accept
a maximum of 2048 iovecs per call, so the enforced hw_max_sectors really
needs to be calculated based on block_size.

This addresses a >= v3.5 bug where block_size=512 was rejecting > 1M
sized I/O requests, because FD_MAX_SECTORS was hardcoded to 2048 for
the block_size=4096 case.

Reported-by: Henrik Goldman <hg@xxxxxxxxxxxxxxx>
Cc: Henrik Goldman <hg@xxxxxxxxxxxxxxx>
Signed-off-by: Nicholas Bellinger <nab@xxxxxxxxxxxxxxx>
---
 drivers/target/target_core_device.c  |    4 ++++
 drivers/target/target_core_file.c    |   33 +++++++++++++++++++++++++++++----
 drivers/target/target_core_file.h    |    5 ++++-
 include/target/target_core_backend.h |    1 +
 4 files changed, 38 insertions(+), 5 deletions(-)

diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c
index 207b340..3d70ef6 100644
--- a/drivers/target/target_core_device.c
+++ b/drivers/target/target_core_device.c
@@ -1106,6 +1106,10 @@ int se_dev_set_block_size(struct se_device *dev, u32 block_size)
 	dev->dev_attrib.block_size = block_size;
 	pr_debug("dev[%p]: SE Device block_size changed to %u\n",
 			dev, block_size);
+
+	if (dev->transport->update_hw_max_sectors)
+		dev->transport->update_hw_max_sectors(dev);
+
 	return 0;
 }
 
diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c
index 0e34cda..c1238ba 100644
--- a/drivers/target/target_core_file.c
+++ b/drivers/target/target_core_file.c
@@ -66,9 +66,8 @@ static int fd_attach_hba(struct se_hba *hba, u32 host_id)
 	pr_debug("CORE_HBA[%d] - TCM FILEIO HBA Driver %s on Generic"
 		" Target Core Stack %s\n", hba->hba_id, FD_VERSION,
 		TARGET_CORE_MOD_VERSION);
-	pr_debug("CORE_HBA[%d] - Attached FILEIO HBA: %u to Generic"
-		" MaxSectors: %u\n",
-		hba->hba_id, fd_host->fd_host_id, FD_MAX_SECTORS);
+	pr_debug("CORE_HBA[%d] - Attached FILEIO HBA: %u to Generic\n",
+		hba->hba_id, fd_host->fd_host_id);
 
 	return 0;
 }
@@ -220,7 +219,7 @@ static int fd_configure_device(struct se_device *dev)
 	}
 
 	dev->dev_attrib.hw_block_size = fd_dev->fd_block_size;
-	dev->dev_attrib.hw_max_sectors = FD_MAX_SECTORS;
+	dev->transport->update_hw_max_sectors(dev);
 	dev->dev_attrib.hw_queue_depth = FD_MAX_DEVICE_QUEUE_DEPTH;
 
 	if (fd_dev->fbd_flags & FDBD_HAS_BUFFERED_IO_WCE) {
@@ -708,6 +707,31 @@ static struct sbc_ops fd_sbc_ops = {
 	.execute_unmap		= fd_execute_unmap,
 };
 
+static void fd_update_hw_max_sectors(struct se_device *dev)
+{
+	u32 hw_max_sectors;
+
+	switch (dev->dev_attrib.block_size) {
+	case 4096:
+		hw_max_sectors = FD_MAX_SECTORS_4K;
+		break;
+	case 2048:
+		hw_max_sectors = FD_MAX_SECTORS_2k;
+		break;
+	case 1024:
+		hw_max_sectors = FD_MAX_SECTORS_1K;
+		break;
+	case 512:
+	default:
+		hw_max_sectors = FD_MAX_SECTORS_512;
+		break;
+	}
+
+	dev->dev_attrib.hw_max_sectors = hw_max_sectors;
+	pr_debug("FILEIO: Updated hw_max_sectors to %u\n",
+		 dev->dev_attrib.hw_max_sectors);
+}
+
 static sense_reason_t
 fd_parse_cdb(struct se_cmd *cmd)
 {
@@ -730,6 +754,7 @@ static struct se_subsystem_api fileio_template = {
 	.show_configfs_dev_params = fd_show_configfs_dev_params,
 	.get_device_type	= sbc_get_device_type,
 	.get_blocks		= fd_get_blocks,
+	.update_hw_max_sectors	= fd_update_hw_max_sectors,
 };
 
 static int __init fileio_module_init(void)
diff --git a/drivers/target/target_core_file.h b/drivers/target/target_core_file.h
index 37ffc5b..e847430 100644
--- a/drivers/target/target_core_file.h
+++ b/drivers/target/target_core_file.h
@@ -7,7 +7,10 @@
 #define FD_DEVICE_QUEUE_DEPTH	32
 #define FD_MAX_DEVICE_QUEUE_DEPTH 128
 #define FD_BLOCKSIZE		512
-#define FD_MAX_SECTORS		2048
+#define FD_MAX_SECTORS_4K	2048
+#define FD_MAX_SECTORS_2k	4096
+#define FD_MAX_SECTORS_1K	8192
+#define FD_MAX_SECTORS_512	16384
 
 #define RRF_EMULATE_CDB		0x01
 #define RRF_GOT_LBA		0x02
diff --git a/include/target/target_core_backend.h b/include/target/target_core_backend.h
index 39e0114..c68e46d 100644
--- a/include/target/target_core_backend.h
+++ b/include/target/target_core_backend.h
@@ -39,6 +39,7 @@ struct se_subsystem_api {
 	unsigned int (*get_lbppbe)(struct se_device *);
 	unsigned int (*get_io_min)(struct se_device *);
 	unsigned int (*get_io_opt)(struct se_device *);
+	void (*update_hw_max_sectors)(struct se_device *);
 	unsigned char *(*get_sense_buffer)(struct se_cmd *);
 	bool (*get_write_cache)(struct se_device *);
 };
-- 
1.7.10.4

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