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

ata: libata: Move sector_buf from struct ata_port to struct ata_device

The 512B buffer sector_buf field of struct ata_port is used for scanning
devices as well as during error recovery with ata EH. This buffer is
thus useless if a port does not have a device connected to it.
And also given that commands using this buffer are issued to devices,
and not to ports, move this buffer definition from struct ata_port to
struct ata_device.

This change slightly increases system memory usage for systems using a
port-multiplier as in that case we do not need a per-device buffer for
scanning devices (PMP does not allow parallel scanning) nor for EH (as
when entering EH we are guaranteed that all commands to all devices
connected to the PMP have completed or have been aborted). However,
this change reduces memory usage on systems that have many ports with
only few devices rives connected, which is a much more common use case
than the PMP use case.

Suggested-by: Niklas Cassel <cassel@kernel.org>
Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Reviewed-by: Niklas Cassel <cassel@kernel.org>

+33 -43
+26 -37
drivers/ata/libata-core.c
··· 2125 2125 2126 2126 static int ata_log_supported(struct ata_device *dev, u8 log) 2127 2127 { 2128 - struct ata_port *ap = dev->link->ap; 2129 - 2130 2128 if (dev->quirks & ATA_QUIRK_NO_LOG_DIR) 2131 2129 return 0; 2132 2130 2133 - if (ata_read_log_page(dev, ATA_LOG_DIRECTORY, 0, ap->sector_buf, 1)) 2131 + if (ata_read_log_page(dev, ATA_LOG_DIRECTORY, 0, dev->sector_buf, 1)) 2134 2132 return 0; 2135 - return get_unaligned_le16(&ap->sector_buf[log * 2]); 2133 + return get_unaligned_le16(&dev->sector_buf[log * 2]); 2136 2134 } 2137 2135 2138 2136 static bool ata_identify_page_supported(struct ata_device *dev, u8 page) 2139 2137 { 2140 - struct ata_port *ap = dev->link->ap; 2141 2138 unsigned int err, i; 2142 2139 2143 2140 if (dev->quirks & ATA_QUIRK_NO_ID_DEV_LOG) ··· 2157 2160 * Read IDENTIFY DEVICE data log, page 0, to figure out if the page is 2158 2161 * supported. 2159 2162 */ 2160 - err = ata_read_log_page(dev, ATA_LOG_IDENTIFY_DEVICE, 0, ap->sector_buf, 2161 - 1); 2163 + err = ata_read_log_page(dev, ATA_LOG_IDENTIFY_DEVICE, 0, 2164 + dev->sector_buf, 1); 2162 2165 if (err) 2163 2166 return false; 2164 2167 2165 - for (i = 0; i < ap->sector_buf[8]; i++) { 2166 - if (ap->sector_buf[9 + i] == page) 2168 + for (i = 0; i < dev->sector_buf[8]; i++) { 2169 + if (dev->sector_buf[9 + i] == page) 2167 2170 return true; 2168 2171 } 2169 2172 ··· 2215 2218 2216 2219 static void ata_dev_config_ncq_send_recv(struct ata_device *dev) 2217 2220 { 2218 - struct ata_port *ap = dev->link->ap; 2219 2221 unsigned int err_mask; 2220 2222 2221 2223 if (!ata_log_supported(dev, ATA_LOG_NCQ_SEND_RECV)) { ··· 2222 2226 return; 2223 2227 } 2224 2228 err_mask = ata_read_log_page(dev, ATA_LOG_NCQ_SEND_RECV, 2225 - 0, ap->sector_buf, 1); 2229 + 0, dev->sector_buf, 1); 2226 2230 if (!err_mask) { 2227 2231 u8 *cmds = dev->ncq_send_recv_cmds; 2228 2232 2229 2233 dev->flags |= ATA_DFLAG_NCQ_SEND_RECV; 2230 - memcpy(cmds, ap->sector_buf, ATA_LOG_NCQ_SEND_RECV_SIZE); 2234 + memcpy(cmds, dev->sector_buf, ATA_LOG_NCQ_SEND_RECV_SIZE); 2231 2235 2232 2236 if (dev->quirks & ATA_QUIRK_NO_NCQ_TRIM) { 2233 2237 ata_dev_dbg(dev, "disabling queued TRIM support\n"); ··· 2239 2243 2240 2244 static void ata_dev_config_ncq_non_data(struct ata_device *dev) 2241 2245 { 2242 - struct ata_port *ap = dev->link->ap; 2243 2246 unsigned int err_mask; 2244 2247 2245 2248 if (!ata_log_supported(dev, ATA_LOG_NCQ_NON_DATA)) { ··· 2247 2252 return; 2248 2253 } 2249 2254 err_mask = ata_read_log_page(dev, ATA_LOG_NCQ_NON_DATA, 2250 - 0, ap->sector_buf, 1); 2251 - if (!err_mask) { 2252 - u8 *cmds = dev->ncq_non_data_cmds; 2253 - 2254 - memcpy(cmds, ap->sector_buf, ATA_LOG_NCQ_NON_DATA_SIZE); 2255 - } 2255 + 0, dev->sector_buf, 1); 2256 + if (!err_mask) 2257 + memcpy(dev->ncq_non_data_cmds, dev->sector_buf, 2258 + ATA_LOG_NCQ_NON_DATA_SIZE); 2256 2259 } 2257 2260 2258 2261 static void ata_dev_config_ncq_prio(struct ata_device *dev) 2259 2262 { 2260 - struct ata_port *ap = dev->link->ap; 2261 2263 unsigned int err_mask; 2262 2264 2263 2265 if (!ata_identify_page_supported(dev, ATA_LOG_SATA_SETTINGS)) ··· 2263 2271 err_mask = ata_read_log_page(dev, 2264 2272 ATA_LOG_IDENTIFY_DEVICE, 2265 2273 ATA_LOG_SATA_SETTINGS, 2266 - ap->sector_buf, 2267 - 1); 2274 + dev->sector_buf, 1); 2268 2275 if (err_mask) 2269 2276 goto not_supported; 2270 2277 2271 - if (!(ap->sector_buf[ATA_LOG_NCQ_PRIO_OFFSET] & BIT(3))) 2278 + if (!(dev->sector_buf[ATA_LOG_NCQ_PRIO_OFFSET] & BIT(3))) 2272 2279 goto not_supported; 2273 2280 2274 2281 dev->flags |= ATA_DFLAG_NCQ_PRIO; ··· 2383 2392 2384 2393 static void ata_dev_config_zac(struct ata_device *dev) 2385 2394 { 2386 - struct ata_port *ap = dev->link->ap; 2387 2395 unsigned int err_mask; 2388 - u8 *identify_buf = ap->sector_buf; 2396 + u8 *identify_buf = dev->sector_buf; 2389 2397 2390 2398 dev->zac_zones_optimal_open = U32_MAX; 2391 2399 dev->zac_zones_optimal_nonseq = U32_MAX; ··· 2436 2446 2437 2447 static void ata_dev_config_trusted(struct ata_device *dev) 2438 2448 { 2439 - struct ata_port *ap = dev->link->ap; 2440 2449 u64 trusted_cap; 2441 2450 unsigned int err; 2442 2451 ··· 2449 2460 } 2450 2461 2451 2462 err = ata_read_log_page(dev, ATA_LOG_IDENTIFY_DEVICE, ATA_LOG_SECURITY, 2452 - ap->sector_buf, 1); 2463 + dev->sector_buf, 1); 2453 2464 if (err) 2454 2465 return; 2455 2466 2456 - trusted_cap = get_unaligned_le64(&ap->sector_buf[40]); 2467 + trusted_cap = get_unaligned_le64(&dev->sector_buf[40]); 2457 2468 if (!(trusted_cap & (1ULL << 63))) { 2458 2469 ata_dev_dbg(dev, 2459 2470 "Trusted Computing capability qword not valid!\n"); ··· 2481 2492 2482 2493 err_mask = ata_read_log_page(dev, ATA_LOG_IDENTIFY_DEVICE, 2483 2494 ATA_LOG_SUPPORTED_CAPABILITIES, 2484 - ap->sector_buf, 1); 2495 + dev->sector_buf, 1); 2485 2496 if (err_mask) 2486 2497 goto not_supported; 2487 2498 2488 2499 /* Check Command Duration Limit Supported bits */ 2489 - val = get_unaligned_le64(&ap->sector_buf[168]); 2500 + val = get_unaligned_le64(&dev->sector_buf[168]); 2490 2501 if (!(val & BIT_ULL(63)) || !(val & BIT_ULL(0))) 2491 2502 goto not_supported; 2492 2503 ··· 2499 2510 * We must have support for the sense data for successful NCQ commands 2500 2511 * log indicated by the successful NCQ command sense data supported bit. 2501 2512 */ 2502 - val = get_unaligned_le64(&ap->sector_buf[8]); 2513 + val = get_unaligned_le64(&dev->sector_buf[8]); 2503 2514 if (!(val & BIT_ULL(63)) || !(val & BIT_ULL(47))) { 2504 2515 ata_dev_warn(dev, 2505 2516 "CDL supported but Successful NCQ Command Sense Data is not supported\n"); ··· 2519 2530 */ 2520 2531 err_mask = ata_read_log_page(dev, ATA_LOG_IDENTIFY_DEVICE, 2521 2532 ATA_LOG_CURRENT_SETTINGS, 2522 - ap->sector_buf, 1); 2533 + dev->sector_buf, 1); 2523 2534 if (err_mask) 2524 2535 goto not_supported; 2525 2536 2526 - val = get_unaligned_le64(&ap->sector_buf[8]); 2537 + val = get_unaligned_le64(&dev->sector_buf[8]); 2527 2538 cdl_enabled = val & BIT_ULL(63) && val & BIT_ULL(21); 2528 2539 if (dev->flags & ATA_DFLAG_CDL_ENABLED) { 2529 2540 if (!cdl_enabled) { ··· 2580 2591 * Command duration limits is supported: cache the CDL log page 18h 2581 2592 * (command duration descriptors). 2582 2593 */ 2583 - err_mask = ata_read_log_page(dev, ATA_LOG_CDL, 0, ap->sector_buf, 1); 2594 + err_mask = ata_read_log_page(dev, ATA_LOG_CDL, 0, dev->sector_buf, 1); 2584 2595 if (err_mask) { 2585 2596 ata_dev_warn(dev, "Read Command Duration Limits log failed\n"); 2586 2597 goto not_supported; 2587 2598 } 2588 2599 2589 - memcpy(dev->cdl, ap->sector_buf, ATA_LOG_CDL_SIZE); 2600 + memcpy(dev->cdl, dev->sector_buf, ATA_LOG_CDL_SIZE); 2590 2601 dev->flags |= ATA_DFLAG_CDL; 2591 2602 2592 2603 return; ··· 2678 2689 2679 2690 static void ata_dev_config_devslp(struct ata_device *dev) 2680 2691 { 2681 - u8 *sata_setting = dev->link->ap->sector_buf; 2692 + u8 *sata_setting = dev->sector_buf; 2682 2693 unsigned int err_mask; 2683 2694 int i, j; 2684 2695 ··· 3748 3759 int ata_dev_reread_id(struct ata_device *dev, unsigned int readid_flags) 3749 3760 { 3750 3761 unsigned int class = dev->class; 3751 - u16 *id = (void *)dev->link->ap->sector_buf; 3762 + u16 *id = (void *)dev->sector_buf; 3752 3763 int rc; 3753 3764 3754 3765 /* read ID data */
+1 -1
drivers/ata/libata-eh.c
··· 3284 3284 int i; 3285 3285 3286 3286 for (i = 0; i < ATA_EH_UA_TRIES; i++) { 3287 - u8 *sense_buffer = dev->link->ap->sector_buf; 3287 + u8 *sense_buffer = dev->sector_buf; 3288 3288 u8 sense_key = 0; 3289 3289 unsigned int err_mask; 3290 3290
+1 -2
drivers/ata/libata-pmp.c
··· 648 648 static int sata_pmp_revalidate(struct ata_device *dev, unsigned int new_class) 649 649 { 650 650 struct ata_link *link = dev->link; 651 - struct ata_port *ap = link->ap; 652 - u32 *gscr = (void *)ap->sector_buf; 651 + u32 *gscr = (void *)dev->sector_buf; 653 652 int rc; 654 653 655 654 ata_eh_about_to_do(link, NULL, ATA_EH_REVALIDATE);
+1 -1
drivers/ata/libata-sata.c
··· 1448 1448 static int ata_eh_read_log_10h(struct ata_device *dev, 1449 1449 int *tag, struct ata_taskfile *tf) 1450 1450 { 1451 - u8 *buf = dev->link->ap->sector_buf; 1451 + u8 *buf = dev->sector_buf; 1452 1452 unsigned int err_mask; 1453 1453 u8 csum; 1454 1454 int i;
+1 -1
drivers/ata/libata-zpodd.c
··· 112 112 if (!ret || sense_key != NOT_READY) 113 113 return false; 114 114 115 - sense_buf = dev->link->ap->sector_buf; 115 + sense_buf = dev->sector_buf; 116 116 ret = atapi_eh_request_sense(dev, sense_buf, sense_key); 117 117 if (ret) 118 118 return false;
+3 -1
include/linux/libata.h
··· 769 769 int spdn_cnt; 770 770 /* ering is CLEAR_END, read comment above CLEAR_END */ 771 771 struct ata_ering ering; 772 + 773 + /* For EH */ 774 + u8 sector_buf[ATA_SECT_SIZE] ____cacheline_aligned; 772 775 }; 773 776 774 777 /* Fields between ATA_DEVICE_CLEAR_BEGIN and ATA_DEVICE_CLEAR_END are ··· 919 916 #endif 920 917 /* owned by EH */ 921 918 u8 *ncq_sense_buf; 922 - u8 sector_buf[ATA_SECT_SIZE] ____cacheline_aligned; 923 919 }; 924 920 925 921 /* The following initializer overrides a method to NULL whether one of