]> git.proxmox.com Git - pve-kernel-jessie.git/commitdiff
backport iSCSI fix from 4.4-rc5
authorThomas Lamprecht <t.lamprecht@proxmox.com>
Fri, 8 Jan 2016 16:05:31 +0000 (17:05 +0100)
committerDietmar Maurer <dietmar@proxmox.com>
Sun, 10 Jan 2016 14:03:57 +0000 (15:03 +0100)
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
iSCSI-block-sd-Fix-device-imposed-transfer-length-limits.patch [new file with mode: 0644]

index 6c092ccad4672a98607f6235438971f86e1dfb58..871ef7095f953db5515cce9260ddf138f5329b34 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -243,6 +243,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 (file)
index 0000000..fcd2625
--- /dev/null
@@ -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,
+ };