Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'for-5.16/scsi-ma-2021-10-29' of git://git.kernel.dk/linux-block

Pull SCSI multi-actuator support from Jens Axboe:
"This adds SCSI support for the recently merged block multi-actuator
support. Since this was sitting on top of the block tree, the SCSI
side asked me to queue it up."

* tag 'for-5.16/scsi-ma-2021-10-29' of git://git.kernel.dk/linux-block:
doc: Fix typo in request queue sysfs documentation
doc: document sysfs queue/independent_access_ranges attributes
libata: support concurrent positioning ranges log
scsi: sd: add concurrent positioning ranges support

+224 -12
+32 -1
Documentation/block/queue-sysfs.rst
··· 4 4 5 5 This text file will detail the queue files that are located in the sysfs tree 6 6 for each block device. Note that stacked devices typically do not export 7 - any settings, since their queue merely functions are a remapping target. 7 + any settings, since their queue merely functions as a remapping target. 8 8 These files are the ones found in the /sys/block/xxx/queue/ directory. 9 9 10 10 Files denoted with a RO postfix are readonly and the RW postfix means ··· 285 285 sequential zones of zoned block devices (devices with a zoned attributed 286 286 that reports "host-managed" or "host-aware"). This value is always 0 for 287 287 regular block devices. 288 + 289 + independent_access_ranges (RO) 290 + ------------------------------ 291 + 292 + The presence of this sub-directory of the /sys/block/xxx/queue/ directory 293 + indicates that the device is capable of executing requests targeting 294 + different sector ranges in parallel. For instance, single LUN multi-actuator 295 + hard-disks will have an independent_access_ranges directory if the device 296 + correctly advertizes the sector ranges of its actuators. 297 + 298 + The independent_access_ranges directory contains one directory per access 299 + range, with each range described using the sector (RO) attribute file to 300 + indicate the first sector of the range and the nr_sectors (RO) attribute file 301 + to indicate the total number of sectors in the range starting from the first 302 + sector of the range. For example, a dual-actuator hard-disk will have the 303 + following independent_access_ranges entries.:: 304 + 305 + $ tree /sys/block/<device>/queue/independent_access_ranges/ 306 + /sys/block/<device>/queue/independent_access_ranges/ 307 + |-- 0 308 + | |-- nr_sectors 309 + | `-- sector 310 + `-- 1 311 + |-- nr_sectors 312 + `-- sector 313 + 314 + The sector and nr_sectors attributes use 512B sector unit, regardless of 315 + the actual block size of the device. Independent access ranges do not 316 + overlap and include all sectors within the device capacity. The access 317 + ranges are numbered in increasing order of the range start sector, 318 + that is, the sector attribute of range 0 always has the value 0. 288 319 289 320 Jens Axboe <jens.axboe@oracle.com>, February 2009
+55 -2
drivers/ata/libata-core.c
··· 2459 2459 } 2460 2460 } 2461 2461 2462 + static void ata_dev_config_cpr(struct ata_device *dev) 2463 + { 2464 + unsigned int err_mask; 2465 + size_t buf_len; 2466 + int i, nr_cpr = 0; 2467 + struct ata_cpr_log *cpr_log = NULL; 2468 + u8 *desc, *buf = NULL; 2469 + 2470 + if (!ata_identify_page_supported(dev, 2471 + ATA_LOG_CONCURRENT_POSITIONING_RANGES)) 2472 + goto out; 2473 + 2474 + /* 2475 + * Read IDENTIFY DEVICE data log, page 0x47 2476 + * (concurrent positioning ranges). We can have at most 255 32B range 2477 + * descriptors plus a 64B header. 2478 + */ 2479 + buf_len = (64 + 255 * 32 + 511) & ~511; 2480 + buf = kzalloc(buf_len, GFP_KERNEL); 2481 + if (!buf) 2482 + goto out; 2483 + 2484 + err_mask = ata_read_log_page(dev, ATA_LOG_IDENTIFY_DEVICE, 2485 + ATA_LOG_CONCURRENT_POSITIONING_RANGES, 2486 + buf, buf_len >> 9); 2487 + if (err_mask) 2488 + goto out; 2489 + 2490 + nr_cpr = buf[0]; 2491 + if (!nr_cpr) 2492 + goto out; 2493 + 2494 + cpr_log = kzalloc(struct_size(cpr_log, cpr, nr_cpr), GFP_KERNEL); 2495 + if (!cpr_log) 2496 + goto out; 2497 + 2498 + cpr_log->nr_cpr = nr_cpr; 2499 + desc = &buf[64]; 2500 + for (i = 0; i < nr_cpr; i++, desc += 32) { 2501 + cpr_log->cpr[i].num = desc[0]; 2502 + cpr_log->cpr[i].num_storage_elements = desc[1]; 2503 + cpr_log->cpr[i].start_lba = get_unaligned_le64(&desc[8]); 2504 + cpr_log->cpr[i].num_lbas = get_unaligned_le64(&desc[16]); 2505 + } 2506 + 2507 + out: 2508 + swap(dev->cpr_log, cpr_log); 2509 + kfree(cpr_log); 2510 + kfree(buf); 2511 + } 2512 + 2462 2513 static void ata_dev_print_features(struct ata_device *dev) 2463 2514 { 2464 2515 if (!(dev->flags & ATA_DFLAG_FEATURES_MASK)) 2465 2516 return; 2466 2517 2467 2518 ata_dev_info(dev, 2468 - "Features:%s%s%s%s%s\n", 2519 + "Features:%s%s%s%s%s%s\n", 2469 2520 dev->flags & ATA_DFLAG_TRUSTED ? " Trust" : "", 2470 2521 dev->flags & ATA_DFLAG_DA ? " Dev-Attention" : "", 2471 2522 dev->flags & ATA_DFLAG_DEVSLP ? " Dev-Sleep" : "", 2472 2523 dev->flags & ATA_DFLAG_NCQ_SEND_RECV ? " NCQ-sndrcv" : "", 2473 - dev->flags & ATA_DFLAG_NCQ_PRIO ? " NCQ-prio" : ""); 2524 + dev->flags & ATA_DFLAG_NCQ_PRIO ? " NCQ-prio" : "", 2525 + dev->cpr_log ? " CPR" : ""); 2474 2526 } 2475 2527 2476 2528 /** ··· 2686 2634 ata_dev_config_sense_reporting(dev); 2687 2635 ata_dev_config_zac(dev); 2688 2636 ata_dev_config_trusted(dev); 2637 + ata_dev_config_cpr(dev); 2689 2638 dev->cdb_len = 32; 2690 2639 2691 2640 if (ata_msg_drv(ap) && print_info)
+39 -9
drivers/ata/libata-scsi.c
··· 1895 1895 */ 1896 1896 static unsigned int ata_scsiop_inq_00(struct ata_scsi_args *args, u8 *rbuf) 1897 1897 { 1898 - int num_pages; 1898 + int i, num_pages = 0; 1899 1899 static const u8 pages[] = { 1900 1900 0x00, /* page 0x00, this page */ 1901 1901 0x80, /* page 0x80, unit serial no page */ ··· 1905 1905 0xb1, /* page 0xb1, block device characteristics page */ 1906 1906 0xb2, /* page 0xb2, thin provisioning page */ 1907 1907 0xb6, /* page 0xb6, zoned block device characteristics */ 1908 + 0xb9, /* page 0xb9, concurrent positioning ranges */ 1908 1909 }; 1909 1910 1910 - num_pages = sizeof(pages); 1911 - if (!(args->dev->flags & ATA_DFLAG_ZAC)) 1912 - num_pages--; 1911 + for (i = 0; i < sizeof(pages); i++) { 1912 + if (pages[i] == 0xb6 && 1913 + !(args->dev->flags & ATA_DFLAG_ZAC)) 1914 + continue; 1915 + rbuf[num_pages + 4] = pages[i]; 1916 + num_pages++; 1917 + } 1913 1918 rbuf[3] = num_pages; /* number of supported VPD pages */ 1914 - memcpy(rbuf + 4, pages, num_pages); 1915 1919 return 0; 1916 1920 } 1917 1921 ··· 2121 2117 put_unaligned_be32(args->dev->zac_zones_optimal_open, &rbuf[8]); 2122 2118 put_unaligned_be32(args->dev->zac_zones_optimal_nonseq, &rbuf[12]); 2123 2119 put_unaligned_be32(args->dev->zac_zones_max_open, &rbuf[16]); 2120 + 2121 + return 0; 2122 + } 2123 + 2124 + static unsigned int ata_scsiop_inq_b9(struct ata_scsi_args *args, u8 *rbuf) 2125 + { 2126 + struct ata_cpr_log *cpr_log = args->dev->cpr_log; 2127 + u8 *desc = &rbuf[64]; 2128 + int i; 2129 + 2130 + /* SCSI Concurrent Positioning Ranges VPD page: SBC-5 rev 1 or later */ 2131 + rbuf[1] = 0xb9; 2132 + put_unaligned_be16(64 + (int)cpr_log->nr_cpr * 32 - 4, &rbuf[3]); 2133 + 2134 + for (i = 0; i < cpr_log->nr_cpr; i++, desc += 32) { 2135 + desc[0] = cpr_log->cpr[i].num; 2136 + desc[1] = cpr_log->cpr[i].num_storage_elements; 2137 + put_unaligned_be64(cpr_log->cpr[i].start_lba, &desc[8]); 2138 + put_unaligned_be64(cpr_log->cpr[i].num_lbas, &desc[16]); 2139 + } 2124 2140 2125 2141 return 0; 2126 2142 } ··· 4144 4120 ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b2); 4145 4121 break; 4146 4122 case 0xb6: 4147 - if (dev->flags & ATA_DFLAG_ZAC) { 4123 + if (dev->flags & ATA_DFLAG_ZAC) 4148 4124 ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b6); 4149 - break; 4150 - } 4151 - fallthrough; 4125 + else 4126 + ata_scsi_set_invalid_field(dev, cmd, 2, 0xff); 4127 + break; 4128 + case 0xb9: 4129 + if (dev->cpr_log) 4130 + ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b9); 4131 + else 4132 + ata_scsi_set_invalid_field(dev, cmd, 2, 0xff); 4133 + break; 4152 4134 default: 4153 4135 ata_scsi_set_invalid_field(dev, cmd, 2, 0xff); 4154 4136 break;
+81
drivers/scsi/sd.c
··· 3088 3088 sdkp->security = 1; 3089 3089 } 3090 3090 3091 + static inline sector_t sd64_to_sectors(struct scsi_disk *sdkp, u8 *buf) 3092 + { 3093 + return logical_to_sectors(sdkp->device, get_unaligned_be64(buf)); 3094 + } 3095 + 3096 + /** 3097 + * sd_read_cpr - Query concurrent positioning ranges 3098 + * @sdkp: disk to query 3099 + */ 3100 + static void sd_read_cpr(struct scsi_disk *sdkp) 3101 + { 3102 + struct blk_independent_access_ranges *iars = NULL; 3103 + unsigned char *buffer = NULL; 3104 + unsigned int nr_cpr = 0; 3105 + int i, vpd_len, buf_len = SD_BUF_SIZE; 3106 + u8 *desc; 3107 + 3108 + /* 3109 + * We need to have the capacity set first for the block layer to be 3110 + * able to check the ranges. 3111 + */ 3112 + if (sdkp->first_scan) 3113 + return; 3114 + 3115 + if (!sdkp->capacity) 3116 + goto out; 3117 + 3118 + /* 3119 + * Concurrent Positioning Ranges VPD: there can be at most 256 ranges, 3120 + * leading to a maximum page size of 64 + 256*32 bytes. 3121 + */ 3122 + buf_len = 64 + 256*32; 3123 + buffer = kmalloc(buf_len, GFP_KERNEL); 3124 + if (!buffer || scsi_get_vpd_page(sdkp->device, 0xb9, buffer, buf_len)) 3125 + goto out; 3126 + 3127 + /* We must have at least a 64B header and one 32B range descriptor */ 3128 + vpd_len = get_unaligned_be16(&buffer[2]) + 3; 3129 + if (vpd_len > buf_len || vpd_len < 64 + 32 || (vpd_len & 31)) { 3130 + sd_printk(KERN_ERR, sdkp, 3131 + "Invalid Concurrent Positioning Ranges VPD page\n"); 3132 + goto out; 3133 + } 3134 + 3135 + nr_cpr = (vpd_len - 64) / 32; 3136 + if (nr_cpr == 1) { 3137 + nr_cpr = 0; 3138 + goto out; 3139 + } 3140 + 3141 + iars = disk_alloc_independent_access_ranges(sdkp->disk, nr_cpr); 3142 + if (!iars) { 3143 + nr_cpr = 0; 3144 + goto out; 3145 + } 3146 + 3147 + desc = &buffer[64]; 3148 + for (i = 0; i < nr_cpr; i++, desc += 32) { 3149 + if (desc[0] != i) { 3150 + sd_printk(KERN_ERR, sdkp, 3151 + "Invalid Concurrent Positioning Range number\n"); 3152 + nr_cpr = 0; 3153 + break; 3154 + } 3155 + 3156 + iars->ia_range[i].sector = sd64_to_sectors(sdkp, desc + 8); 3157 + iars->ia_range[i].nr_sectors = sd64_to_sectors(sdkp, desc + 16); 3158 + } 3159 + 3160 + out: 3161 + disk_set_independent_access_ranges(sdkp->disk, iars); 3162 + if (nr_cpr && sdkp->nr_actuators != nr_cpr) { 3163 + sd_printk(KERN_NOTICE, sdkp, 3164 + "%u concurrent positioning ranges\n", nr_cpr); 3165 + sdkp->nr_actuators = nr_cpr; 3166 + } 3167 + 3168 + kfree(buffer); 3169 + } 3170 + 3091 3171 /* 3092 3172 * Determine the device's preferred I/O size for reads and writes 3093 3173 * unless the reported value is unreasonably small, large, not a ··· 3283 3203 sd_read_app_tag_own(sdkp, buffer); 3284 3204 sd_read_write_same(sdkp, buffer); 3285 3205 sd_read_security(sdkp, buffer); 3206 + sd_read_cpr(sdkp); 3286 3207 } 3287 3208 3288 3209 /*
+1
drivers/scsi/sd.h
··· 106 106 u8 protection_type;/* Data Integrity Field */ 107 107 u8 provisioning_mode; 108 108 u8 zeroing_mode; 109 + u8 nr_actuators; /* Number of actuators */ 109 110 unsigned ATO : 1; /* state of disk ATO bit */ 110 111 unsigned cache_override : 1; /* temp override of WCE,RCD */ 111 112 unsigned WCE : 1; /* state of disk WCE bit */
+1
include/linux/ata.h
··· 329 329 ATA_LOG_SECURITY = 0x06, 330 330 ATA_LOG_SATA_SETTINGS = 0x08, 331 331 ATA_LOG_ZONED_INFORMATION = 0x09, 332 + ATA_LOG_CONCURRENT_POSITIONING_RANGES = 0x47, 332 333 333 334 /* Identify device SATA settings log:*/ 334 335 ATA_LOG_DEVSLP_OFFSET = 0x30,
+15
include/linux/libata.h
··· 676 676 struct ata_ering_entry ring[ATA_ERING_SIZE]; 677 677 }; 678 678 679 + struct ata_cpr { 680 + u8 num; 681 + u8 num_storage_elements; 682 + u64 start_lba; 683 + u64 num_lbas; 684 + }; 685 + 686 + struct ata_cpr_log { 687 + u8 nr_cpr; 688 + struct ata_cpr cpr[]; 689 + }; 690 + 679 691 struct ata_device { 680 692 struct ata_link *link; 681 693 unsigned int devno; /* 0 or 1 */ ··· 746 734 u32 zac_zones_optimal_open; 747 735 u32 zac_zones_optimal_nonseq; 748 736 u32 zac_zones_max_open; 737 + 738 + /* Concurrent positioning ranges */ 739 + struct ata_cpr_log *cpr_log; 749 740 750 741 /* error history */ 751 742 int spdn_cnt;