aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Manzanares <adam.manzanares@hgst.com>2016-10-17 14:27:29 -0400
committerTejun Heo <tj@kernel.org>2016-10-19 14:34:36 -0400
commit8e061784b51ec4a4efed0deaafb5bd9725bf5b06 (patch)
tree30d253d6d6a214f6514484bfe1d2c3b178fdf62e
parent5dc8b362a2374d007bc0db649b7ab6a79dd32bda (diff)
ata: Enabling ATA Command Priorities
This patch checks to see if an ATA device supports NCQ command priorities. If so and the user has specified an iocontext that indicates IO_PRIO_CLASS_RT then we build a tf with a high priority command. This is done to improve the tail latency of commands that are high priority by passing priority to the device. tj: Removed trivial ata_ncq_prio_enabled() and open-coded the test. Signed-off-by: Adam Manzanares <adam.manzanares@hgst.com> Signed-off-by: Tejun Heo <tj@kernel.org>
-rw-r--r--drivers/ata/libata-core.c35
-rw-r--r--drivers/ata/libata-scsi.c6
-rw-r--r--drivers/ata/libata.h2
-rw-r--r--include/linux/ata.h6
-rw-r--r--include/linux/libata.h3
5 files changed, 49 insertions, 3 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 223a770f78f3..8346faf63337 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -739,6 +739,7 @@ u64 ata_tf_read_block(const struct ata_taskfile *tf, struct ata_device *dev)
739 * @n_block: Number of blocks 739 * @n_block: Number of blocks
740 * @tf_flags: RW/FUA etc... 740 * @tf_flags: RW/FUA etc...
741 * @tag: tag 741 * @tag: tag
742 * @class: IO priority class
742 * 743 *
743 * LOCKING: 744 * LOCKING:
744 * None. 745 * None.
@@ -753,7 +754,7 @@ u64 ata_tf_read_block(const struct ata_taskfile *tf, struct ata_device *dev)
753 */ 754 */
754int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev, 755int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev,
755 u64 block, u32 n_block, unsigned int tf_flags, 756 u64 block, u32 n_block, unsigned int tf_flags,
756 unsigned int tag) 757 unsigned int tag, int class)
757{ 758{
758 tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; 759 tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
759 tf->flags |= tf_flags; 760 tf->flags |= tf_flags;
@@ -785,6 +786,12 @@ int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev,
785 tf->device = ATA_LBA; 786 tf->device = ATA_LBA;
786 if (tf->flags & ATA_TFLAG_FUA) 787 if (tf->flags & ATA_TFLAG_FUA)
787 tf->device |= 1 << 7; 788 tf->device |= 1 << 7;
789
790 if (dev->flags & ATA_DFLAG_NCQ_PRIO) {
791 if (class == IOPRIO_CLASS_RT)
792 tf->hob_nsect |= ATA_PRIO_HIGH <<
793 ATA_SHIFT_PRIO;
794 }
788 } else if (dev->flags & ATA_DFLAG_LBA) { 795 } else if (dev->flags & ATA_DFLAG_LBA) {
789 tf->flags |= ATA_TFLAG_LBA; 796 tf->flags |= ATA_TFLAG_LBA;
790 797
@@ -2156,6 +2163,30 @@ static void ata_dev_config_ncq_non_data(struct ata_device *dev)
2156 } 2163 }
2157} 2164}
2158 2165
2166static void ata_dev_config_ncq_prio(struct ata_device *dev)
2167{
2168 struct ata_port *ap = dev->link->ap;
2169 unsigned int err_mask;
2170
2171 err_mask = ata_read_log_page(dev,
2172 ATA_LOG_SATA_ID_DEV_DATA,
2173 ATA_LOG_SATA_SETTINGS,
2174 ap->sector_buf,
2175 1);
2176 if (err_mask) {
2177 ata_dev_dbg(dev,
2178 "failed to get Identify Device data, Emask 0x%x\n",
2179 err_mask);
2180 return;
2181 }
2182
2183 if (ap->sector_buf[ATA_LOG_NCQ_PRIO_OFFSET] & BIT(3))
2184 dev->flags |= ATA_DFLAG_NCQ_PRIO;
2185 else
2186 ata_dev_dbg(dev, "SATA page does not support priority\n");
2187
2188}
2189
2159static int ata_dev_config_ncq(struct ata_device *dev, 2190static int ata_dev_config_ncq(struct ata_device *dev,
2160 char *desc, size_t desc_sz) 2191 char *desc, size_t desc_sz)
2161{ 2192{
@@ -2205,6 +2236,8 @@ static int ata_dev_config_ncq(struct ata_device *dev,
2205 ata_dev_config_ncq_send_recv(dev); 2236 ata_dev_config_ncq_send_recv(dev);
2206 if (ata_id_has_ncq_non_data(dev->id)) 2237 if (ata_id_has_ncq_non_data(dev->id))
2207 ata_dev_config_ncq_non_data(dev); 2238 ata_dev_config_ncq_non_data(dev);
2239 if (ata_id_has_ncq_prio(dev->id))
2240 ata_dev_config_ncq_prio(dev);
2208 } 2241 }
2209 2242
2210 return 0; 2243 return 0;
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 9cceb4a875a5..2bccc3c7de48 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -50,6 +50,7 @@
50#include <linux/uaccess.h> 50#include <linux/uaccess.h>
51#include <linux/suspend.h> 51#include <linux/suspend.h>
52#include <asm/unaligned.h> 52#include <asm/unaligned.h>
53#include <linux/ioprio.h>
53 54
54#include "libata.h" 55#include "libata.h"
55#include "libata-transport.h" 56#include "libata-transport.h"
@@ -1755,6 +1756,8 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc)
1755{ 1756{
1756 struct scsi_cmnd *scmd = qc->scsicmd; 1757 struct scsi_cmnd *scmd = qc->scsicmd;
1757 const u8 *cdb = scmd->cmnd; 1758 const u8 *cdb = scmd->cmnd;
1759 struct request *rq = scmd->request;
1760 int class = IOPRIO_PRIO_CLASS(req_get_ioprio(rq));
1758 unsigned int tf_flags = 0; 1761 unsigned int tf_flags = 0;
1759 u64 block; 1762 u64 block;
1760 u32 n_block; 1763 u32 n_block;
@@ -1821,7 +1824,8 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc)
1821 qc->nbytes = n_block * scmd->device->sector_size; 1824 qc->nbytes = n_block * scmd->device->sector_size;
1822 1825
1823 rc = ata_build_rw_tf(&qc->tf, qc->dev, block, n_block, tf_flags, 1826 rc = ata_build_rw_tf(&qc->tf, qc->dev, block, n_block, tf_flags,
1824 qc->tag); 1827 qc->tag, class);
1828
1825 if (likely(rc == 0)) 1829 if (likely(rc == 0))
1826 return 0; 1830 return 0;
1827 1831
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index 3b301a48007c..8f3a5596dd67 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -66,7 +66,7 @@ extern u64 ata_tf_to_lba48(const struct ata_taskfile *tf);
66extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev, int tag); 66extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev, int tag);
67extern int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev, 67extern int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev,
68 u64 block, u32 n_block, unsigned int tf_flags, 68 u64 block, u32 n_block, unsigned int tf_flags,
69 unsigned int tag); 69 unsigned int tag, int class);
70extern u64 ata_tf_read_block(const struct ata_taskfile *tf, 70extern u64 ata_tf_read_block(const struct ata_taskfile *tf,
71 struct ata_device *dev); 71 struct ata_device *dev);
72extern unsigned ata_exec_internal(struct ata_device *dev, 72extern unsigned ata_exec_internal(struct ata_device *dev,
diff --git a/include/linux/ata.h b/include/linux/ata.h
index fdb180367ba1..af6859b3a93d 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -348,6 +348,7 @@ enum {
348 ATA_LOG_DEVSLP_DETO = 0x01, 348 ATA_LOG_DEVSLP_DETO = 0x01,
349 ATA_LOG_DEVSLP_VALID = 0x07, 349 ATA_LOG_DEVSLP_VALID = 0x07,
350 ATA_LOG_DEVSLP_VALID_MASK = 0x80, 350 ATA_LOG_DEVSLP_VALID_MASK = 0x80,
351 ATA_LOG_NCQ_PRIO_OFFSET = 0x09,
351 352
352 /* NCQ send and receive log */ 353 /* NCQ send and receive log */
353 ATA_LOG_NCQ_SEND_RECV_SUBCMDS_OFFSET = 0x00, 354 ATA_LOG_NCQ_SEND_RECV_SUBCMDS_OFFSET = 0x00,
@@ -940,6 +941,11 @@ static inline bool ata_id_has_ncq_non_data(const u16 *id)
940 return id[ATA_ID_SATA_CAPABILITY_2] & BIT(5); 941 return id[ATA_ID_SATA_CAPABILITY_2] & BIT(5);
941} 942}
942 943
944static inline bool ata_id_has_ncq_prio(const u16 *id)
945{
946 return id[ATA_ID_SATA_CAPABILITY] & BIT(12);
947}
948
943static inline bool ata_id_has_trim(const u16 *id) 949static inline bool ata_id_has_trim(const u16 *id)
944{ 950{
945 if (ata_id_major_version(id) >= 7 && 951 if (ata_id_major_version(id) >= 7 &&
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 616eef4d81ea..90b69a6293a3 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -166,6 +166,7 @@ enum {
166 ATA_DFLAG_NO_UNLOAD = (1 << 17), /* device doesn't support unload */ 166 ATA_DFLAG_NO_UNLOAD = (1 << 17), /* device doesn't support unload */
167 ATA_DFLAG_UNLOCK_HPA = (1 << 18), /* unlock HPA */ 167 ATA_DFLAG_UNLOCK_HPA = (1 << 18), /* unlock HPA */
168 ATA_DFLAG_NCQ_SEND_RECV = (1 << 19), /* device supports NCQ SEND and RECV */ 168 ATA_DFLAG_NCQ_SEND_RECV = (1 << 19), /* device supports NCQ SEND and RECV */
169 ATA_DFLAG_NCQ_PRIO = (1 << 20), /* device supports NCQ priority */
169 ATA_DFLAG_INIT_MASK = (1 << 24) - 1, 170 ATA_DFLAG_INIT_MASK = (1 << 24) - 1,
170 171
171 ATA_DFLAG_DETACH = (1 << 24), 172 ATA_DFLAG_DETACH = (1 << 24),
@@ -342,7 +343,9 @@ enum {
342 ATA_SHIFT_PIO = 0, 343 ATA_SHIFT_PIO = 0,
343 ATA_SHIFT_MWDMA = ATA_SHIFT_PIO + ATA_NR_PIO_MODES, 344 ATA_SHIFT_MWDMA = ATA_SHIFT_PIO + ATA_NR_PIO_MODES,
344 ATA_SHIFT_UDMA = ATA_SHIFT_MWDMA + ATA_NR_MWDMA_MODES, 345 ATA_SHIFT_UDMA = ATA_SHIFT_MWDMA + ATA_NR_MWDMA_MODES,
346 ATA_SHIFT_PRIO = 6,
345 347
348 ATA_PRIO_HIGH = 2,
346 /* size of buffer to pad xfers ending on unaligned boundaries */ 349 /* size of buffer to pad xfers ending on unaligned boundaries */
347 ATA_DMA_PAD_SZ = 4, 350 ATA_DMA_PAD_SZ = 4,
348 351