Message ID | 15dec4ee-9b2c-66b3-35fe-333add83bdc4@latius.de |
---|---|
State | New |
Headers | show |
Series | Optimal I/O size of 33553920 bytes should not appear. | expand |
Hello Daniel, Sorry about the delay! > The reason is that there are devices in the wild which both report > sdkp->min_xfer_blocks == 1 and sdkp->opt_xfer_blocks == 0xFFFF. That's the first time I've seen that particular combination. Most devices will report either a physical_block_size or a min_xfer_blocks of 4KB and the intent of the check was to validate opt_xfer_blocks against those two granularities. > It seems that sdkp->opt_xfer_blocks == 0xFFFF serves the same purpose > as > q->limits.io_opt = 0 in > https://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git/tree/drivers/scsi/sd.c?h=6.5/scsi-fixes&id=06c2afb862f9da8dc5efa4b6076a0e48c3fbaaa5#n3453, > namely: to be a dummy value, indicating that no specific information is > available. 0 means the value is not reported, 0xFFFF means the device is explicitly asking us to send I/O in multiples of 0xFFFF blocks. Which probably doesn't make sense but, given that min_xfer_blocks is reported as 1 in your case, could technically be valid. I would have preferred to check that the reported opt_xfer_blocks was a nice power of two. However, there are devices out there which use internal allocation units which are not power of two. So that won't work. Alternatively we could make sure that opt_xfer_bytes is a multiple of PAGE_SIZE. I'll mull over that a bit... > (Additionally, it would be also possible to test whether the size of the > device is divisible (without remainder) by the assumed "optimal I/O > size". If it is not divisible by the assumed "optimal I/O size", it is > quite likely that the "optimal I/O size" is not useful, at least for > alignment of data onto that block device. In this case, the validation > should also fail.) Unfortunately that's not a reliable heuristic since many devices report a specific capacity requested by their customers which may not reflect the actual capacity of the device, nor whichever granularity is in use internally.
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 68b12afa0721..319400ec333d 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -3314,6 +3314,9 @@ static bool sd_validate_opt_xfer_size(struct scsi_disk *sdkp, if (sdkp->opt_xfer_blocks == 0) return false; + if (sdkp->opt_xfer_blocks == 0xffff) + return false; + if (sdkp->opt_xfer_blocks > dev_max) { sd_first_printk(KERN_WARNING, sdkp,