diff mbox

[v2] mpt3sas: Recognize and act on iopriority info

Message ID 1481589100-3342-1-git-send-email-adam.manzanares@hgst.com (mailing list archive)
State Accepted, archived
Headers show

Commit Message

Adam Manzanares Dec. 13, 2016, 12:31 a.m. UTC
From: Adam Manzanares <adam.manzanares@wdc.com>

This patch adds support for request iopriority handling in the
mpt3sas layer. This works only when a ATA device is behind the
SATL. The ATA device also has to indicate that it supports
command priorities in the identify information that is pulled from
the SATL.

This patch depends on block: Add iocontext priority to request

v2:
 - Get iopriority class only if sysfs variable is set.

Signed-off-by: Adam Manzanares <adam.manzanares@wdc.com>
---
 drivers/scsi/mpt3sas/mpt3sas_base.h  |  6 +++++
 drivers/scsi/mpt3sas/mpt3sas_ctl.c   | 43 ++++++++++++++++++++++++++++++++++--
 drivers/scsi/mpt3sas/mpt3sas_scsih.c | 34 +++++++++++++++++++++++++++-
 3 files changed, 80 insertions(+), 3 deletions(-)

Comments

Sreekanth Reddy Dec. 13, 2016, 10:27 a.m. UTC | #1
On Tue, Dec 13, 2016 at 6:01 AM, Adam Manzanares
<adam.manzanares@hgst.com> wrote:
> From: Adam Manzanares <adam.manzanares@wdc.com>
>
> This patch adds support for request iopriority handling in the
> mpt3sas layer. This works only when a ATA device is behind the
> SATL. The ATA device also has to indicate that it supports
> command priorities in the identify information that is pulled from
> the SATL.
>
> This patch depends on block: Add iocontext priority to request
>
> v2:
>  - Get iopriority class only if sysfs variable is set.
>
> Signed-off-by: Adam Manzanares <adam.manzanares@wdc.com>

Acked-by: Sreekanth Reddy <Sreekanth.Reddy@broadcom.com>

> ---
>  drivers/scsi/mpt3sas/mpt3sas_base.h  |  6 +++++
>  drivers/scsi/mpt3sas/mpt3sas_ctl.c   | 43 ++++++++++++++++++++++++++++++++++--
>  drivers/scsi/mpt3sas/mpt3sas_scsih.c | 34 +++++++++++++++++++++++++++-
>  3 files changed, 80 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h
> index 3e71bc1..354cdc7 100644
> --- a/drivers/scsi/mpt3sas/mpt3sas_base.h
> +++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
> @@ -402,6 +402,9 @@ struct MPT3SAS_DEVICE {
>         u8      block;
>         u8      tlr_snoop_check;
>         u8      ignore_delay_remove;
> +       /* Iopriority Command Handling */
> +       u8      ncq_prio_enable;
> +
>  };
>
>  #define MPT3_CMD_NOT_USED      0x8000  /* free */
> @@ -1449,4 +1452,7 @@ mpt3sas_setup_direct_io(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
>         struct _raid_device *raid_device, Mpi2SCSIIORequest_t *mpi_request,
>         u16 smid);
>
> +/* NCQ Prio Handling Check */
> +bool scsih_ncq_prio_supp(struct scsi_device *sdev);
> +
>  #endif /* MPT3SAS_BASE_H_INCLUDED */
> diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
> index 26cdc12..3ad8339 100644
> --- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c
> +++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
> @@ -3290,8 +3290,6 @@ static DEVICE_ATTR(diag_trigger_mpi, S_IRUGO | S_IWUSR,
>
>  /*********** diagnostic trigger suppport *** END ****************************/
>
> -
> -
>  /*****************************************/
>
>  struct device_attribute *mpt3sas_host_attrs[] = {
> @@ -3367,9 +3365,50 @@ _ctl_device_handle_show(struct device *dev, struct device_attribute *attr,
>  }
>  static DEVICE_ATTR(sas_device_handle, S_IRUGO, _ctl_device_handle_show, NULL);
>
> +/**
> + * _ctl_device_ncq_io_prio_show - send prioritized io commands to device
> + * @dev - pointer to embedded device
> + * @buf - the buffer returned
> + *
> + * A sysfs 'read/write' sdev attribute, only works with SATA
> + */
> +static ssize_t
> +_ctl_device_ncq_prio_enable_show(struct device *dev,
> +                                struct device_attribute *attr, char *buf)
> +{
> +       struct scsi_device *sdev = to_scsi_device(dev);
> +       struct MPT3SAS_DEVICE *sas_device_priv_data = sdev->hostdata;
> +
> +       return snprintf(buf, PAGE_SIZE, "%d\n",
> +                       sas_device_priv_data->ncq_prio_enable);
> +}
> +
> +static ssize_t
> +_ctl_device_ncq_prio_enable_store(struct device *dev,
> +                                 struct device_attribute *attr,
> +                                 const char *buf, size_t count)
> +{
> +       struct scsi_device *sdev = to_scsi_device(dev);
> +       struct MPT3SAS_DEVICE *sas_device_priv_data = sdev->hostdata;
> +       bool ncq_prio_enable = 0;
> +
> +       if (kstrtobool(buf, &ncq_prio_enable))
> +               return -EINVAL;
> +
> +       if (!scsih_ncq_prio_supp(sdev))
> +               return -EINVAL;
> +
> +       sas_device_priv_data->ncq_prio_enable = ncq_prio_enable;
> +       return strlen(buf);
> +}
> +static DEVICE_ATTR(sas_ncq_prio_enable, S_IRUGO | S_IWUSR,
> +                  _ctl_device_ncq_prio_enable_show,
> +                  _ctl_device_ncq_prio_enable_store);
> +
>  struct device_attribute *mpt3sas_dev_attrs[] = {
>         &dev_attr_sas_address,
>         &dev_attr_sas_device_handle,
> +       &dev_attr_sas_ncq_prio_enable,
>         NULL,
>  };
>
> diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
> index 209a969..a6d1045 100644
> --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
> +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
> @@ -4030,6 +4030,8 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd)
>         struct MPT3SAS_DEVICE *sas_device_priv_data;
>         struct MPT3SAS_TARGET *sas_target_priv_data;
>         struct _raid_device *raid_device;
> +       struct request *rq = scmd->request;
> +       int class;
>         Mpi2SCSIIORequest_t *mpi_request;
>         u32 mpi_control;
>         u16 smid;
> @@ -4085,7 +4087,12 @@ scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd)
>
>         /* set tags */
>         mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ;
> -
> +       /* NCQ Prio supported, make sure control indicated high priority */
> +       if (sas_device_priv_data->ncq_prio_enable) {
> +               class = IOPRIO_PRIO_CLASS(req_get_ioprio(rq));
> +               if (class == IOPRIO_CLASS_RT)
> +                       mpi_control |= 1 << MPI2_SCSIIO_CONTROL_CMDPRI_SHIFT;
> +       }
>         /* Make sure Device is not raid volume.
>          * We do not expose raid functionality to upper layer for warpdrive.
>          */
> @@ -9031,6 +9038,31 @@ scsih_pci_mmio_enabled(struct pci_dev *pdev)
>         return PCI_ERS_RESULT_RECOVERED;
>  }
>
> +/**
> + * scsih__ncq_prio_supp - Check for NCQ command priority support
> + * @sdev: scsi device struct
> + *
> + * This is called when a user indicates they would like to enable
> + * ncq command priorities. This works only on SATA devices.
> + */
> +bool scsih_ncq_prio_supp(struct scsi_device *sdev)
> +{
> +       unsigned char *buf;
> +       bool ncq_prio_supp = false;
> +
> +       if (!scsi_device_supports_vpd(sdev))
> +               return ncq_prio_supp;
> +
> +       buf = kmalloc(SCSI_VPD_PG_LEN, GFP_KERNEL);
> +       if (!buf)
> +               return ncq_prio_supp;
> +
> +       if (!scsi_get_vpd_page(sdev, 0x89, buf, SCSI_VPD_PG_LEN))
> +               ncq_prio_supp = (buf[213] >> 4) & 1;
> +
> +       kfree(buf);
> +       return ncq_prio_supp;
> +}
>  /*
>   * The pci device ids are defined in mpi/mpi2_cnfg.h.
>   */
> --
> 2.7.4
>
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Martin K. Petersen Dec. 14, 2016, 8:41 p.m. UTC | #2
>>>>> "Adam" == Adam Manzanares <adam.manzanares@hgst.com> writes:

Adam> This patch adds support for request iopriority handling in the
Adam> mpt3sas layer. This works only when a ATA device is behind the
Adam> SATL. The ATA device also has to indicate that it supports command
Adam> priorities in the identify information that is pulled from the
Adam> SATL.

Applied to 4.10/scsi-fixes.
diff mbox

Patch

diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.h b/drivers/scsi/mpt3sas/mpt3sas_base.h
index 3e71bc1..354cdc7 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.h
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.h
@@ -402,6 +402,9 @@  struct MPT3SAS_DEVICE {
 	u8	block;
 	u8	tlr_snoop_check;
 	u8	ignore_delay_remove;
+	/* Iopriority Command Handling */
+	u8	ncq_prio_enable;
+
 };
 
 #define MPT3_CMD_NOT_USED	0x8000	/* free */
@@ -1449,4 +1452,7 @@  mpt3sas_setup_direct_io(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
 	struct _raid_device *raid_device, Mpi2SCSIIORequest_t *mpi_request,
 	u16 smid);
 
+/* NCQ Prio Handling Check */
+bool scsih_ncq_prio_supp(struct scsi_device *sdev);
+
 #endif /* MPT3SAS_BASE_H_INCLUDED */
diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
index 26cdc12..3ad8339 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
@@ -3290,8 +3290,6 @@  static DEVICE_ATTR(diag_trigger_mpi, S_IRUGO | S_IWUSR,
 
 /*********** diagnostic trigger suppport *** END ****************************/
 
-
-
 /*****************************************/
 
 struct device_attribute *mpt3sas_host_attrs[] = {
@@ -3367,9 +3365,50 @@  _ctl_device_handle_show(struct device *dev, struct device_attribute *attr,
 }
 static DEVICE_ATTR(sas_device_handle, S_IRUGO, _ctl_device_handle_show, NULL);
 
+/**
+ * _ctl_device_ncq_io_prio_show - send prioritized io commands to device
+ * @dev - pointer to embedded device
+ * @buf - the buffer returned
+ *
+ * A sysfs 'read/write' sdev attribute, only works with SATA
+ */
+static ssize_t
+_ctl_device_ncq_prio_enable_show(struct device *dev,
+				 struct device_attribute *attr, char *buf)
+{
+	struct scsi_device *sdev = to_scsi_device(dev);
+	struct MPT3SAS_DEVICE *sas_device_priv_data = sdev->hostdata;
+
+	return snprintf(buf, PAGE_SIZE, "%d\n",
+			sas_device_priv_data->ncq_prio_enable);
+}
+
+static ssize_t
+_ctl_device_ncq_prio_enable_store(struct device *dev,
+				  struct device_attribute *attr,
+				  const char *buf, size_t count)
+{
+	struct scsi_device *sdev = to_scsi_device(dev);
+	struct MPT3SAS_DEVICE *sas_device_priv_data = sdev->hostdata;
+	bool ncq_prio_enable = 0;
+
+	if (kstrtobool(buf, &ncq_prio_enable))
+		return -EINVAL;
+
+	if (!scsih_ncq_prio_supp(sdev))
+		return -EINVAL;
+
+	sas_device_priv_data->ncq_prio_enable = ncq_prio_enable;
+	return strlen(buf);
+}
+static DEVICE_ATTR(sas_ncq_prio_enable, S_IRUGO | S_IWUSR,
+		   _ctl_device_ncq_prio_enable_show,
+		   _ctl_device_ncq_prio_enable_store);
+
 struct device_attribute *mpt3sas_dev_attrs[] = {
 	&dev_attr_sas_address,
 	&dev_attr_sas_device_handle,
+	&dev_attr_sas_ncq_prio_enable,
 	NULL,
 };
 
diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
index 209a969..a6d1045 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c
@@ -4030,6 +4030,8 @@  scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd)
 	struct MPT3SAS_DEVICE *sas_device_priv_data;
 	struct MPT3SAS_TARGET *sas_target_priv_data;
 	struct _raid_device *raid_device;
+	struct request *rq = scmd->request;
+	int class;
 	Mpi2SCSIIORequest_t *mpi_request;
 	u32 mpi_control;
 	u16 smid;
@@ -4085,7 +4087,12 @@  scsih_qcmd(struct Scsi_Host *shost, struct scsi_cmnd *scmd)
 
 	/* set tags */
 	mpi_control |= MPI2_SCSIIO_CONTROL_SIMPLEQ;
-
+	/* NCQ Prio supported, make sure control indicated high priority */
+	if (sas_device_priv_data->ncq_prio_enable) {
+		class = IOPRIO_PRIO_CLASS(req_get_ioprio(rq));
+		if (class == IOPRIO_CLASS_RT)
+			mpi_control |= 1 << MPI2_SCSIIO_CONTROL_CMDPRI_SHIFT;
+	}
 	/* Make sure Device is not raid volume.
 	 * We do not expose raid functionality to upper layer for warpdrive.
 	 */
@@ -9031,6 +9038,31 @@  scsih_pci_mmio_enabled(struct pci_dev *pdev)
 	return PCI_ERS_RESULT_RECOVERED;
 }
 
+/**
+ * scsih__ncq_prio_supp - Check for NCQ command priority support
+ * @sdev: scsi device struct
+ *
+ * This is called when a user indicates they would like to enable
+ * ncq command priorities. This works only on SATA devices.
+ */
+bool scsih_ncq_prio_supp(struct scsi_device *sdev)
+{
+	unsigned char *buf;
+	bool ncq_prio_supp = false;
+
+	if (!scsi_device_supports_vpd(sdev))
+		return ncq_prio_supp;
+
+	buf = kmalloc(SCSI_VPD_PG_LEN, GFP_KERNEL);
+	if (!buf)
+		return ncq_prio_supp;
+
+	if (!scsi_get_vpd_page(sdev, 0x89, buf, SCSI_VPD_PG_LEN))
+		ncq_prio_supp = (buf[213] >> 4) & 1;
+
+	kfree(buf);
+	return ncq_prio_supp;
+}
 /*
  * The pci device ids are defined in mpi/mpi2_cnfg.h.
  */