* [PATCH] [SCSI] sd: workaround invalid OPTIMAL TRANSFER LENGTH @ 2013-04-03 20:21 Mike Snitzer 2013-04-03 20:38 ` Ewan Milne 2013-04-25 1:19 ` Martin K. Petersen 0 siblings, 2 replies; 4+ messages in thread From: Mike Snitzer @ 2013-04-03 20:21 UTC (permalink / raw) To: linux-scsi; +Cc: Martin K. Petersen Workaround disk firmware that improperly sets OPTIMAL TRANSFER LENGTH to 0xFFFFFFFF (aka UINT_MAX or 4294967295U) by assuming this _optional_ BLOCK LIMITS VPD field was not specified (0). It should be noted that a disk firmware fix is being developed but that these disks are already in the wild (and when optimal_io_size is so large it prevents standard Linux distribution installers, e.g. Anaconda, from creating partitions smaller than 4GB via libparted due to parted looking to align the created partitions relative to optimal_io_size). The disk model in this instance is "SEAGATE ST900MM0006". The BLOCK LIMITS VPD page for this disk is: # sg_inq --vpd --page=0xb0 /dev/sdb VPD INQUIRY: Block limits page (SBC) Optimal transfer length granularity: 1 blocks Maximum transfer length: 0 blocks Optimal transfer length: 4294967295 blocks Maximum prefetch, xdread, xdwrite transfer length: 0 blocks Maximum unmap LBA count: 0 Maximum unmap block descriptor count: 0 Optimal unmap granularity: 0 Unmap granularity alignment valid: 0 Unmap granularity alignment: 0 Before this fix: # cat /sys/block/sdb/queue/optimal_io_size 4294966784 After this fix: # cat /sys/block/sdb/queue/optimal_io_size 0 Signed-off-by: Mike Snitzer <snitzer@redhat.com> --- drivers/scsi/sd.c | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 7992635..34638c1 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -2516,6 +2516,7 @@ static void sd_read_app_tag_own(struct scsi_disk *sdkp, unsigned char *buffer) */ static void sd_read_block_limits(struct scsi_disk *sdkp) { + unsigned int optimal_transfer_length; unsigned int sector_sz = sdkp->device->sector_size; const int vpd_len = 64; unsigned char *buffer = kmalloc(vpd_len, GFP_KERNEL); @@ -2527,8 +2528,11 @@ static void sd_read_block_limits(struct scsi_disk *sdkp) blk_queue_io_min(sdkp->disk->queue, get_unaligned_be16(&buffer[6]) * sector_sz); + optimal_transfer_length = get_unaligned_be32(&buffer[12]); + if (optimal_transfer_length == UINT_MAX) + optimal_transfer_length = 0; /* firmware bug, use 0 instead */ blk_queue_io_opt(sdkp->disk->queue, - get_unaligned_be32(&buffer[12]) * sector_sz); + optimal_transfer_length * sector_sz); if (buffer[3] == 0x3c) { unsigned int lba_count, desc_count; ^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH] [SCSI] sd: workaround invalid OPTIMAL TRANSFER LENGTH 2013-04-03 20:21 [PATCH] [SCSI] sd: workaround invalid OPTIMAL TRANSFER LENGTH Mike Snitzer @ 2013-04-03 20:38 ` Ewan Milne 2013-04-25 1:19 ` Martin K. Petersen 1 sibling, 0 replies; 4+ messages in thread From: Ewan Milne @ 2013-04-03 20:38 UTC (permalink / raw) To: Mike Snitzer; +Cc: linux-scsi, Martin K. Petersen On Wed, 2013-04-03 at 16:21 -0400, Mike Snitzer wrote: > Workaround disk firmware that improperly sets OPTIMAL TRANSFER LENGTH to > 0xFFFFFFFF (aka UINT_MAX or 4294967295U) by assuming this _optional_ > BLOCK LIMITS VPD field was not specified (0). > Acked-by: Ewan D. Milne <emilne@redhat.com> ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] [SCSI] sd: workaround invalid OPTIMAL TRANSFER LENGTH 2013-04-03 20:21 [PATCH] [SCSI] sd: workaround invalid OPTIMAL TRANSFER LENGTH Mike Snitzer 2013-04-03 20:38 ` Ewan Milne @ 2013-04-25 1:19 ` Martin K. Petersen 2013-04-25 1:44 ` Mike Snitzer 1 sibling, 1 reply; 4+ messages in thread From: Martin K. Petersen @ 2013-04-25 1:19 UTC (permalink / raw) To: Mike Snitzer; +Cc: linux-scsi, Martin K. Petersen >>>>> "Mike" == Mike Snitzer <snitzer@redhat.com> writes: Mike, Following up on our discussion at LSF/MM last week... Mike> Workaround disk firmware that improperly sets OPTIMAL TRANSFER Mike> LENGTH to 0xFFFFFFFF (aka UINT_MAX or 4294967295U) by assuming Mike> this _optional_ BLOCK LIMITS VPD field was not specified (0). My only real objection is that UINT_MAX appears to be completely coincidental. What if the next drive specifies UINT_MAX-1 or $RANDOM? Lacking a decent heuristic I'd rather just blacklist the offending drive using the skip_vpd_pages knob we already have in place. -- Martin K. Petersen Oracle Linux Engineering [SCSI] Workaround for disks that report bad optimal transfer length Not all disks fill out the VPD pages correctly. Add a blacklist flag that allows us ignore the SBC-3 VPD pages for a given device. The BLIST_SKIP_VPD_PAGES flag triggers our existing skip_vpd_pages scsi_device parameter to bypass VPD scanning. Also blacklist the offending Seagate drive model. Reported-by: Mike Snitzer <snitzer@redhat.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c index 43fca91..f969aca 100644 --- a/drivers/scsi/scsi_devinfo.c +++ b/drivers/scsi/scsi_devinfo.c @@ -228,6 +228,7 @@ static struct { {"SanDisk", "ImageMate CF-SD1", NULL, BLIST_FORCELUN}, {"SEAGATE", "ST34555N", "0930", BLIST_NOTQ}, /* Chokes on tagged INQUIRY */ {"SEAGATE", "ST3390N", "9546", BLIST_NOTQ}, + {"SEAGATE", "ST900MM0006", NULL, BLIST_SKIP_VPD_PAGES}, {"SGI", "RAID3", "*", BLIST_SPARSELUN}, {"SGI", "RAID5", "*", BLIST_SPARSELUN}, {"SGI", "TP9100", "*", BLIST_REPORTLUN2}, diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 3e58b22..b9e39e0 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -924,6 +924,9 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, if (*bflags & BLIST_NO_DIF) sdev->no_dif = 1; + if (*bflags & BLIST_SKIP_VPD_PAGES) + sdev->skip_vpd_pages = 1; + transport_configure_device(&sdev->sdev_gendev); if (sdev->host->hostt->slave_configure) { diff --git a/include/scsi/scsi_devinfo.h b/include/scsi/scsi_devinfo.h index cc1f3e7..447d2d7 100644 --- a/include/scsi/scsi_devinfo.h +++ b/include/scsi/scsi_devinfo.h @@ -31,4 +31,5 @@ #define BLIST_MAX_512 0x800000 /* maximum 512 sector cdb length */ #define BLIST_ATTACH_PQ3 0x1000000 /* Scan: Attach to PQ3 devices */ #define BLIST_NO_DIF 0x2000000 /* Disable T10 PI (DIF) */ +#define BLIST_SKIP_VPD_PAGES 0x4000000 /* Ignore SBC-3 VPD pages */ #endif ^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: sd: workaround invalid OPTIMAL TRANSFER LENGTH 2013-04-25 1:19 ` Martin K. Petersen @ 2013-04-25 1:44 ` Mike Snitzer 0 siblings, 0 replies; 4+ messages in thread From: Mike Snitzer @ 2013-04-25 1:44 UTC (permalink / raw) To: Martin K. Petersen; +Cc: linux-scsi On Wed, Apr 24 2013 at 9:19pm -0400, Martin K. Petersen <martin.petersen@oracle.com> wrote: > >>>>> "Mike" == Mike Snitzer <snitzer@redhat.com> writes: > > Mike, > > Following up on our discussion at LSF/MM last week... > > Mike> Workaround disk firmware that improperly sets OPTIMAL TRANSFER > Mike> LENGTH to 0xFFFFFFFF (aka UINT_MAX or 4294967295U) by assuming > Mike> this _optional_ BLOCK LIMITS VPD field was not specified (0). > > My only real objection is that UINT_MAX appears to be completely > coincidental. What if the next drive specifies UINT_MAX-1 or $RANDOM? > > Lacking a decent heuristic I'd rather just blacklist the offending drive > using the skip_vpd_pages knob we already have in place. OK, sounds fine to me, thanks. ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2013-04-25 1:44 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2013-04-03 20:21 [PATCH] [SCSI] sd: workaround invalid OPTIMAL TRANSFER LENGTH Mike Snitzer 2013-04-03 20:38 ` Ewan Milne 2013-04-25 1:19 ` Martin K. Petersen 2013-04-25 1:44 ` Mike Snitzer
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).