[pve-devel] [PATCH pve-kernel 2/2] backport iSCSI fix from 4.4-rc5

Thomas Lamprecht t.lamprecht at proxmox.com
Fri Jan 8 17:05:31 CET 2016


backport ca369d51b3e1649be4a72addd6d6a168cfb3f537 from 4.4-rc5
to fix problems with connecting and writing to a iscsi device.

See forum thread 24821 for some details.
---
 Makefile                                           |   2 +
 ...Fix-device-imposed-transfer-length-limits.patch | 167 +++++++++++++++++++++
 2 files changed, 169 insertions(+)
 create mode 100644 iSCSI-block-sd-Fix-device-imposed-transfer-length-limits.patch

diff --git a/Makefile b/Makefile
index 389af54..68d27ce 100644
--- a/Makefile
+++ b/Makefile
@@ -241,6 +241,8 @@ ${KERNEL_SRC}/README ${KERNEL_CFG_ORG}: ${KERNELSRCTAR}
 	cd ${KERNEL_SRC}; patch -p1 <../apparmor-socket-mediation.patch
 	cd ${KERNEL_SRC}; patch -p1 <../CVE-2015-8709-ptrace-require-mapped-uids-gids.patch
 	cd ${KERNEL_SRC}; patch -p1 <../CVE-2015-7513-KVM-x86-Reload-pit-counters-for-all-channels.patch
+	# backport iSCSI fix from 4.4rc5
+	cd ${KERNEL_SRC}; patch -p1 <../iSCSI-block-sd-Fix-device-imposed-transfer-length-limits.patch
 	# backport aacraid update from kernel 4.4rc5
 	cd ${KERNEL_SRC}; patch -p1 <../0001-aacraid-fix-for-LD.patch
 	cd ${KERNEL_SRC}; patch -p1 <../0002-aacraid-add-power-management.patch
diff --git a/iSCSI-block-sd-Fix-device-imposed-transfer-length-limits.patch b/iSCSI-block-sd-Fix-device-imposed-transfer-length-limits.patch
new file mode 100644
index 0000000..fcd2625
--- /dev/null
+++ b/iSCSI-block-sd-Fix-device-imposed-transfer-length-limits.patch
@@ -0,0 +1,167 @@
+diff -Naur a/block/blk-settings.c b/block/blk-settings.c
+--- a/block/blk-settings.c	2015-12-01 18:36:05.000000000 +0100
++++ b/block/blk-settings.c	2015-12-18 12:02:27.076000000 +0100
+@@ -112,7 +112,7 @@
+ 	lim->max_integrity_segments = 0;
+ 	lim->seg_boundary_mask = BLK_SEG_BOUNDARY_MASK;
+ 	lim->max_segment_size = BLK_MAX_SEGMENT_SIZE;
+-	lim->max_sectors = lim->max_hw_sectors = BLK_SAFE_MAX_SECTORS;
++	lim->max_sectors = lim->max_dev_sectors = lim->max_hw_sectors = BLK_SAFE_MAX_SECTORS;
+ 	lim->chunk_sectors = 0;
+ 	lim->max_write_same_sectors = 0;
+ 	lim->max_discard_sectors = 0;
+@@ -147,6 +147,7 @@
+ 	lim->max_hw_sectors = UINT_MAX;
+ 	lim->max_segment_size = UINT_MAX;
+ 	lim->max_sectors = UINT_MAX;
++	lim->max_dev_sectors = UINT_MAX;
+ 	lim->max_write_same_sectors = UINT_MAX;
+ }
+ EXPORT_SYMBOL(blk_set_stacking_limits);
+@@ -544,6 +540,7 @@
+ 
+ 	t->max_sectors = min_not_zero(t->max_sectors, b->max_sectors);
+ 	t->max_hw_sectors = min_not_zero(t->max_hw_sectors, b->max_hw_sectors);
++	t->max_dev_sectors = min_not_zero(t->max_dev_sectors, b->max_dev_sectors);
+ 	t->max_write_same_sectors = min(t->max_write_same_sectors,
+ 					b->max_write_same_sectors);
+ 	t->bounce_pfn = min_not_zero(t->bounce_pfn, b->bounce_pfn);
+diff -Naur a/block/blk-sysfs.c b/block/blk-sysfs.c
+--- a/block/blk-sysfs.c	2015-12-01 18:36:05.000000000 +0100
++++ b/block/blk-sysfs.c	2015-12-18 12:06:20.040000000 +0100
+@@ -174,6 +174,9 @@
+ 	if (ret < 0)
+ 		return ret;
+ 
++	max_hw_sectors_kb = min_not_zero(max_hw_sectors_kb, (unsigned long)
++					q->limits.max_dev_sectors >> 1);
++
+ 	if (max_sectors_kb > max_hw_sectors_kb || max_sectors_kb < page_kb)
+ 		return -EINVAL;
+ 
+diff -Naur a/drivers/scsi/sd.c b/drivers/scsi/sd.c
+--- a/drivers/scsi/sd.c	2015-12-01 18:36:07.000000000 +0100
++++ b/drivers/scsi/sd.c	2015-12-18 13:27:08.472000000 +0100
+@@ -2224,11 +2224,8 @@
+ 		}
+ 	}
+ 
+-	if (sdkp->capacity > 0xffffffff) {
++	if (sdkp->capacity > 0xffffffff)
+ 		sdp->use_16_for_rw = 1;
+-		sdkp->max_xfer_blocks = SD_MAX_XFER_BLOCKS;
+-	} else
+-		sdkp->max_xfer_blocks = SD_DEF_XFER_BLOCKS;
+ 
+ 	/* Rescale capacity to 512-byte units */
+ 	if (sector_size == 4096)
+@@ -2545,7 +2542,6 @@
+ {
+ 	unsigned int sector_sz = sdkp->device->sector_size;
+ 	const int vpd_len = 64;
+-	u32 max_xfer_length;
+ 	unsigned char *buffer = kmalloc(vpd_len, GFP_KERNEL);
+ 
+ 	if (!buffer ||
+@@ -2553,14 +2549,11 @@
+ 	    scsi_get_vpd_page(sdkp->device, 0xb0, buffer, vpd_len))
+ 		goto out;
+ 
+-	max_xfer_length = get_unaligned_be32(&buffer[8]);
+-	if (max_xfer_length)
+-		sdkp->max_xfer_blocks = max_xfer_length;
+-
+ 	blk_queue_io_min(sdkp->disk->queue,
+ 			 get_unaligned_be16(&buffer[6]) * sector_sz);
+-	blk_queue_io_opt(sdkp->disk->queue,
+-			 get_unaligned_be32(&buffer[12]) * sector_sz);
++
++	sdkp->max_xfer_blocks = get_unaligned_be32(&buffer[8]);
++	sdkp->opt_xfer_blocks = get_unaligned_be32(&buffer[12]);
+ 
+ 	if (buffer[3] == 0x3c) {
+ 		unsigned int lba_count, desc_count;
+@@ -2709,6 +2702,11 @@
+ 	return 0;
+ }
+ 
++static inline u32 logical_to_sectors(struct scsi_device *sdev, u32 blocks)
++{
++	return blocks << (ilog2(sdev->sector_size) - 9);
++}
++
+ /**
+  *	sd_revalidate_disk - called the first time a new disk is seen,
+  *	performs disk spin up, read_capacity, etc.
+@@ -2718,8 +2716,9 @@
+ {
+ 	struct scsi_disk *sdkp = scsi_disk(disk);
+ 	struct scsi_device *sdp = sdkp->device;
++	struct request_queue *q = sdkp->disk->queue;
+ 	unsigned char *buffer;
+-	unsigned int max_xfer;
++	unsigned int dev_max, rw_max;
+ 
+ 	SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp,
+ 				      "sd_revalidate_disk\n"));
+@@ -2767,11 +2766,26 @@
+ 	 */
+ 	sd_set_flush_flag(sdkp);
+ 
+-	max_xfer = sdkp->max_xfer_blocks;
+-	max_xfer <<= ilog2(sdp->sector_size) - 9;
++	/* Initial block count limit based on CDB TRANSFER LENGTH field size. */
++	dev_max = sdp->use_16_for_rw ? SD_MAX_XFER_BLOCKS : SD_DEF_XFER_BLOCKS;
++
++	/* Some devices report a maximum block count for READ/WRITE requests. */
++	dev_max = min_not_zero(dev_max, sdkp->max_xfer_blocks);
++	q->limits.max_dev_sectors = logical_to_sectors(sdp, dev_max);
++
++	/*
++	 * Use the device's preferred I/O size for reads and writes
++	 * unless the reported value is unreasonably large (or garbage).
++	 */
++	if (sdkp->opt_xfer_blocks && sdkp->opt_xfer_blocks <= dev_max &&
++	    sdkp->opt_xfer_blocks <= SD_DEF_XFER_BLOCKS)
++		rw_max = q->limits.io_opt =
++			logical_to_sectors(sdp, sdkp->opt_xfer_blocks);
++	else
++		rw_max = BLK_DEF_MAX_SECTORS;
+ 
+-	sdkp->disk->queue->limits.max_sectors =
+-		min_not_zero(queue_max_hw_sectors(sdkp->disk->queue), max_xfer);
++	/* Combine with controller limits */
++	q->limits.max_sectors = min(rw_max, queue_max_hw_sectors(q));
+ 
+ 	set_capacity(disk, sdkp->capacity);
+ 	sd_config_write_same(sdkp);
+diff -Naur a/drivers/scsi/sd.h b/drivers/scsi/sd.h
+--- a/drivers/scsi/sd.h	2015-12-01 18:36:07.000000000 +0100
++++ b/drivers/scsi/sd.h	2015-12-18 13:28:56.716000000 +0100
+@@ -67,6 +67,7 @@
+ 	atomic_t	openers;
+ 	sector_t	capacity;	/* size in 512-byte sectors */
+ 	u32		max_xfer_blocks;
++	u32		opt_xfer_blocks;
+ 	u32		max_ws_blocks;
+ 	u32		max_unmap_blocks;
+ 	u32		unmap_granularity;
+diff -Naur a/include/linux/blkdev.h b/include/linux/blkdev.h
+--- a/include/linux/blkdev.h	2015-12-01 18:36:07.000000000 +0100
++++ b/include/linux/blkdev.h	2015-12-18 13:30:55.772000000 +0100
+@@ -260,6 +260,7 @@
+ 	unsigned long		seg_boundary_mask;
+ 
+ 	unsigned int		max_hw_sectors;
++	unsigned int		max_dev_sectors;
+ 	unsigned int		chunk_sectors;
+ 	unsigned int		max_sectors;
+ 	unsigned int		max_segment_size;
+@@ -1138,6 +1138,7 @@
+ enum blk_default_limits {
+ 	BLK_MAX_SEGMENTS	= 128,
+ 	BLK_SAFE_MAX_SECTORS	= 255,
++	BLK_DEF_MAX_SECTORS	= 2560,
+ 	BLK_MAX_SEGMENT_SIZE	= 65536,
+ 	BLK_SEG_BOUNDARY_MASK	= 0xFFFFFFFFUL,
+ };
-- 
2.1.4





More information about the pve-devel mailing list