diff mbox series

[V3,05/25] smartpqi: add support for raid1 writes

Message ID 160763248937.26927.6012524710393214473.stgit@brunhilda (mailing list archive)
State Changes Requested
Headers show
Series smartpqi updates | expand

Commit Message

Don Brace Dec. 10, 2020, 8:34 p.m. UTC
* Add raid1 write IU.
* Add in raid1 write support.

Reviewed-by: Scott Benesh <scott.benesh@microchip.com>
Reviewed-by: Scott Teel <scott.teel@microchip.com>
Reviewed-by: Kevin Barnett <kevin.barnett@microchip.com>
Signed-off-by: Don Brace <don.brace@microchip.com>
---
 drivers/scsi/smartpqi/smartpqi.h      |   37 +++++
 drivers/scsi/smartpqi/smartpqi_init.c |  235 +++++++++++++++++++++++----------
 2 files changed, 196 insertions(+), 76 deletions(-)

Comments

Martin Wilck Jan. 7, 2021, 4:44 p.m. UTC | #1
On Thu, 2020-12-10 at 14:34 -0600, Don Brace wrote:
> * Add raid1 write IU.
> * Add in raid1 write support.
> 
> Reviewed-by: Scott Benesh <scott.benesh@microchip.com>
> Reviewed-by: Scott Teel <scott.teel@microchip.com>
> Reviewed-by: Kevin Barnett <kevin.barnett@microchip.com>
> Signed-off-by: Don Brace <don.brace@microchip.com>
> ---
>  drivers/scsi/smartpqi/smartpqi.h      |   37 +++++
>  drivers/scsi/smartpqi/smartpqi_init.c |  235
> +++++++++++++++++++++++----------
>  2 files changed, 196 insertions(+), 76 deletions(-)
> 
> diff --git a/drivers/scsi/smartpqi/smartpqi.h
> b/drivers/scsi/smartpqi/smartpqi.h
> index e9844210c4a0..225ec6843c68 100644
> --- a/drivers/scsi/smartpqi/smartpqi.h
> +++ b/drivers/scsi/smartpqi/smartpqi.h
> @@ -313,6 +313,36 @@ struct pqi_aio_path_request {
>                 sg_descriptors[PQI_MAX_EMBEDDED_SG_DESCRIPTORS];
>  };
>  
> +#define PQI_RAID1_NVME_XFER_LIMIT      (32 * 1024)     /* 32 KiB */
> +struct pqi_aio_r1_path_request {
> +       struct pqi_iu_header header;
> +       __le16  request_id;
> +       __le16  volume_id;      /* ID of the RAID volume */
> +       __le32  it_nexus_1;     /* IT nexus of the 1st drive in the
> RAID volume */
> +       __le32  it_nexus_2;     /* IT nexus of the 2nd drive in the
> RAID volume */
> +       __le32  it_nexus_3;     /* IT nexus of the 3rd drive in the
> RAID volume */
> +       __le32  data_length;    /* total bytes to read/write */
> +       u8      data_direction : 2;
> +       u8      partial : 1;
> +       u8      memory_type : 1;
> +       u8      fence : 1;
> +       u8      encryption_enable : 1;
> +       u8      reserved : 2;
> +       u8      task_attribute : 3;
> +       u8      command_priority : 4;
> +       u8      reserved2 : 1;
> +       __le16  data_encryption_key_index;
> +       u8      cdb[16];
> +       __le16  error_index;
> +       u8      num_sg_descriptors;
> +       u8      cdb_length;
> +       u8      num_drives;     /* number of drives in the RAID
> volume (2 or 3) */
> +       u8      reserved3[3];
> +       __le32  encrypt_tweak_lower;
> +       __le32  encrypt_tweak_upper;
> +       struct pqi_sg_descriptor
> sg_descriptors[PQI_MAX_EMBEDDED_SG_DESCRIPTORS];
> +};
> +
>  #define PQI_RAID56_XFER_LIMIT_4K       0x1000 /* 4Kib */
>  #define PQI_RAID56_XFER_LIMIT_8K       0x2000 /* 8Kib */
>  struct pqi_aio_r56_path_request {
> @@ -520,6 +550,7 @@ struct pqi_raid_error_info {
>  #define PQI_REQUEST_IU_AIO_PATH_IO                     0x15
>  #define PQI_REQUEST_IU_AIO_PATH_RAID5_IO               0x18
>  #define PQI_REQUEST_IU_AIO_PATH_RAID6_IO               0x19
> +#define PQI_REQUEST_IU_AIO_PATH_RAID1_IO               0x1A
>  #define PQI_REQUEST_IU_GENERAL_ADMIN                   0x60
>  #define PQI_REQUEST_IU_REPORT_VENDOR_EVENT_CONFIG      0x72
>  #define PQI_REQUEST_IU_SET_VENDOR_EVENT_CONFIG         0x73
> @@ -972,14 +1003,12 @@ struct pqi_scsi_dev_raid_map_data {
>         u16     strip_size;
>         u32     first_group;
>         u32     last_group;
> -       u32     current_group;
>         u32     map_row;
>         u32     aio_handle;
>         u64     disk_block;
>         u32     disk_block_cnt;
>         u8      cdb[16];
>         u8      cdb_length;
> -       int     offload_to_mirror;
>  
>         /* RAID1 specific */
>  #define NUM_RAID1_MAP_ENTRIES 3
> @@ -1040,8 +1069,7 @@ struct pqi_scsi_dev {
>         u16     phys_connector[8];
>         bool    raid_bypass_configured; /* RAID bypass configured */
>         bool    raid_bypass_enabled;    /* RAID bypass enabled */
> -       int     offload_to_mirror;      /* Send next RAID bypass
> request */
> -                                       /* to mirror drive. */
> +       u32     next_bypass_group;
>         struct raid_map *raid_map;      /* RAID bypass map */
>  
>         struct pqi_sas_port *sas_port;
> @@ -1247,6 +1275,7 @@ struct pqi_ctrl_info {
>         u8              soft_reset_handshake_supported : 1;
>         u8              raid_iu_timeout_supported: 1;
>         u8              tmf_iu_timeout_supported: 1;
> +       u8              enable_r1_writes : 1;
>         u8              enable_r5_writes : 1;
>         u8              enable_r6_writes : 1;
>  
> diff --git a/drivers/scsi/smartpqi/smartpqi_init.c
> b/drivers/scsi/smartpqi/smartpqi_init.c
> index c813cec10003..8da9031c9c0b 100644
> --- a/drivers/scsi/smartpqi/smartpqi_init.c
> +++ b/drivers/scsi/smartpqi/smartpqi_init.c
> @@ -67,6 +67,10 @@ static int pqi_aio_submit_io(struct pqi_ctrl_info
> *ctrl_info,
>         struct scsi_cmnd *scmd, u32 aio_handle, u8 *cdb,
>         unsigned int cdb_length, struct pqi_queue_group *queue_group,
>         struct pqi_encryption_info *encryption_info, bool
> raid_bypass);
> +static  int pqi_aio_submit_r1_write_io(struct pqi_ctrl_info
> *ctrl_info,
> +       struct scsi_cmnd *scmd, struct pqi_queue_group *queue_group,
> +       struct pqi_encryption_info *encryption_info, struct
> pqi_scsi_dev *device,
> +       struct pqi_scsi_dev_raid_map_data *rmd);
>  static int pqi_aio_submit_r56_write_io(struct pqi_ctrl_info
> *ctrl_info,
>         struct scsi_cmnd *scmd, struct pqi_queue_group *queue_group,
>         struct pqi_encryption_info *encryption_info, struct
> pqi_scsi_dev *device,
> @@ -1717,7 +1721,7 @@ static void pqi_scsi_update_device(struct
> pqi_scsi_dev *existing_device,
>                 sizeof(existing_device->box));
>         memcpy(existing_device->phys_connector, new_device-
> >phys_connector,
>                 sizeof(existing_device->phys_connector));
> -       existing_device->offload_to_mirror = 0;
> +       existing_device->next_bypass_group = 0;
>         kfree(existing_device->raid_map);
>         existing_device->raid_map = new_device->raid_map;
>         existing_device->raid_bypass_configured =
> @@ -2250,7 +2254,10 @@ static bool
> pqi_aio_raid_level_supported(struct pqi_ctrl_info *ctrl_info,
>         case SA_RAID_0:
>                 break;
>         case SA_RAID_1:
> -               is_supported = false;
> +               fallthrough;

Nit: fallthrough isn't necessary here.

> +       case SA_RAID_ADM:
> +               if (rmd->is_write && !ctrl_info->enable_r1_writes)
> +                       is_supported = false;
>                 break;
>         case SA_RAID_5:
>                 if (rmd->is_write && !ctrl_info->enable_r5_writes)
> @@ -2260,10 +2267,6 @@ static bool
> pqi_aio_raid_level_supported(struct pqi_ctrl_info *ctrl_info,
>                 if (rmd->is_write && !ctrl_info->enable_r6_writes)
>                         is_supported = false;
>                 break;
> -       case SA_RAID_ADM:
> -               if (rmd->is_write)
> -                       is_supported = false;
> -               break;
>         default:
>                 is_supported = false;
>         }
> @@ -2385,64 +2388,6 @@ static int
> pci_get_aio_common_raid_map_values(struct pqi_ctrl_info *ctrl_info,
>         return 0;
>  }
>  
> -static int pqi_calc_aio_raid_adm(struct pqi_scsi_dev_raid_map_data
> *rmd,
> -                               struct pqi_scsi_dev *device)
> -{
> -       /* RAID ADM */
> -       /*
> -        * Handles N-way mirrors  (R1-ADM) and R10 with # of drives
> -        * divisible by 3.
> -        */
> -       rmd->offload_to_mirror = device->offload_to_mirror;
> -
> -       if (rmd->offload_to_mirror == 0)  {
> -               /* use physical disk in the first mirrored group. */
> -               rmd->map_index %= rmd->data_disks_per_row;
> -       } else {
> -               do {
> -                       /*
> -                        * Determine mirror group that map_index
> -                        * indicates.
> -                        */
> -                       rmd->current_group =
> -                               rmd->map_index / rmd-
> >data_disks_per_row;
> -
> -                       if (rmd->offload_to_mirror !=
> -                                       rmd->current_group) {
> -                               if (rmd->current_group <
> -                                       rmd->layout_map_count - 1) {
> -                                       /*
> -                                        * Select raid index from
> -                                        * next group.
> -                                        */
> -                                       rmd->map_index += rmd-
> >data_disks_per_row;
> -                                       rmd->current_group++;
> -                               } else {
> -                                       /*
> -                                        * Select raid index from
> first
> -                                        * group.
> -                                        */
> -                                       rmd->map_index %= rmd-
> >data_disks_per_row;
> -                                       rmd->current_group = 0;
> -                               }
> -                       }
> -               } while (rmd->offload_to_mirror != rmd-
> >current_group);
> -       }
> -
> -       /* Set mirror group to use next time. */
> -       rmd->offload_to_mirror =
> -               (rmd->offload_to_mirror >= rmd->layout_map_count - 1)
> ?
> -                       0 : rmd->offload_to_mirror + 1;
> -       device->offload_to_mirror = rmd->offload_to_mirror;
> -       /*
> -        * Avoid direct use of device->offload_to_mirror within this
> -        * function since multiple threads might simultaneously
> -        * increment it beyond the range of device->layout_map_count
> -1.
> -        */
> -
> -       return 0;
> -}
> -
>  static int pqi_calc_aio_r5_or_r6(struct pqi_scsi_dev_raid_map_data
> *rmd,
>                                 struct raid_map *raid_map)
>  {
> @@ -2577,12 +2522,34 @@ static void pqi_set_aio_cdb(struct
> pqi_scsi_dev_raid_map_data *rmd)
>         }
>  }
>  
> +static void pqi_calc_aio_r1_nexus(struct raid_map *raid_map,
> +                               struct pqi_scsi_dev_raid_map_data
> *rmd)
> +{
> +       u32 index;
> +       u32 group;
> +
> +       group = rmd->map_index / rmd->data_disks_per_row;
> +
> +       index = rmd->map_index - (group * rmd->data_disks_per_row);
> +       rmd->it_nexus[0] = raid_map->disk_data[index].aio_handle;
> +       index += rmd->data_disks_per_row;
> +       rmd->it_nexus[1] = raid_map->disk_data[index].aio_handle;
> +       if (rmd->layout_map_count > 2) {
> +               index += rmd->data_disks_per_row;
> +               rmd->it_nexus[2] = raid_map-
> >disk_data[index].aio_handle;
> +       }
> +
> +       rmd->num_it_nexus_entries = rmd->layout_map_count;
> +}
> +
>  static int pqi_raid_bypass_submit_scsi_cmd(struct pqi_ctrl_info
> *ctrl_info,
>         struct pqi_scsi_dev *device, struct scsi_cmnd *scmd,
>         struct pqi_queue_group *queue_group)
>  {
> -       struct raid_map *raid_map;
>         int rc;
> +       struct raid_map *raid_map;
> +       u32 group;
> +       u32 next_bypass_group;
>         struct pqi_encryption_info *encryption_info_ptr;
>         struct pqi_encryption_info encryption_info;
>         struct pqi_scsi_dev_raid_map_data rmd = {0};
> @@ -2605,13 +2572,18 @@ static int
> pqi_raid_bypass_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info,
>         if (rc)
>                 return PQI_RAID_BYPASS_INELIGIBLE;
>  
> -       /* RAID 1 */
> -       if (device->raid_level == SA_RAID_1) {
> -               if (device->offload_to_mirror)
> -                       rmd.map_index += rmd.data_disks_per_row;
> -               device->offload_to_mirror = !device-
> >offload_to_mirror;
> -       } else if (device->raid_level == SA_RAID_ADM) {
> -               rc = pqi_calc_aio_raid_adm(&rmd, device);
> +       if (device->raid_level == SA_RAID_1 ||
> +               device->raid_level == SA_RAID_ADM) {
> +               if (rmd.is_write) {
> +                       pqi_calc_aio_r1_nexus(raid_map, &rmd);
> +               } else {
> +                       group = device->next_bypass_group;
> +                       next_bypass_group = group + 1;
> +                       if (next_bypass_group >=
> rmd.layout_map_count)
> +                               next_bypass_group = 0;
> +                       device->next_bypass_group =
> next_bypass_group;
> +                       rmd.map_index += group *
> rmd.data_disks_per_row;
> +               }
>         } else if ((device->raid_level == SA_RAID_5 ||
>                 device->raid_level == SA_RAID_6) &&
>                 (rmd.layout_map_count > 1 || rmd.is_write)) {
> @@ -2655,6 +2627,10 @@ static int
> pqi_raid_bypass_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info,
>                         return pqi_aio_submit_io(ctrl_info, scmd,
> rmd.aio_handle,
>                                 rmd.cdb, rmd.cdb_length, queue_group,
>                                 encryption_info_ptr, true);
> +               case SA_RAID_1:
> +               case SA_RAID_ADM:
> +                       return pqi_aio_submit_r1_write_io(ctrl_info,
> scmd, queue_group,
> +                               encryption_info_ptr, device, &rmd);
>                 case SA_RAID_5:
>                 case SA_RAID_6:
>                         return pqi_aio_submit_r56_write_io(ctrl_info,
> scmd, queue_group,
> @@ -4982,6 +4958,44 @@ static int pqi_build_raid_sg_list(struct
> pqi_ctrl_info *ctrl_info,
>         return 0;
>  }
>  
> +static int pqi_build_aio_r1_sg_list(struct pqi_ctrl_info *ctrl_info,
> +       struct pqi_aio_r1_path_request *request, struct scsi_cmnd
> *scmd,
> +       struct pqi_io_request *io_request)
> +{
> +       u16 iu_length;
> +       int sg_count;
> +       bool chained;
> +       unsigned int num_sg_in_iu;
> +       struct scatterlist *sg;
> +       struct pqi_sg_descriptor *sg_descriptor;
> +
> +       sg_count = scsi_dma_map(scmd);
> +       if (sg_count < 0)
> +               return sg_count;
> +
> +       iu_length = offsetof(struct pqi_aio_r1_path_request,
> sg_descriptors) -
> +               PQI_REQUEST_HEADER_LENGTH;
> +       num_sg_in_iu = 0;
> +
> +       if (sg_count == 0)
> +               goto out;
> +
> +       sg = scsi_sglist(scmd);
> +       sg_descriptor = request->sg_descriptors;
> +
> +       num_sg_in_iu = pqi_build_sg_list(sg_descriptor, sg, sg_count,
> io_request,
> +               ctrl_info->max_sg_per_iu, &chained);
> +
> +       request->partial = chained;
> +       iu_length += num_sg_in_iu * sizeof(*sg_descriptor);
> +
> +out:
> +       put_unaligned_le16(iu_length, &request->header.iu_length);
> +       request->num_sg_descriptors = num_sg_in_iu;
> +
> +       return 0;
> +}
> +
>  static int pqi_build_aio_r56_sg_list(struct pqi_ctrl_info
> *ctrl_info,
>         struct pqi_aio_r56_path_request *request, struct scsi_cmnd
> *scmd,
>         struct pqi_io_request *io_request)
> @@ -5424,6 +5438,83 @@ static int pqi_aio_submit_io(struct
> pqi_ctrl_info *ctrl_info,
>         return 0;
>  }
>  
> +static  int pqi_aio_submit_r1_write_io(struct pqi_ctrl_info
> *ctrl_info,
> +       struct scsi_cmnd *scmd, struct pqi_queue_group *queue_group,
> +       struct pqi_encryption_info *encryption_info, struct
> pqi_scsi_dev *device,
> +       struct pqi_scsi_dev_raid_map_data *rmd)
> +
> +{
> +       int rc;
> +       struct pqi_io_request *io_request;
> +       struct pqi_aio_r1_path_request *r1_request;
> +
> +       io_request = pqi_alloc_io_request(ctrl_info);
> +       io_request->io_complete_callback = pqi_aio_io_complete;
> +       io_request->scmd = scmd;
> +       io_request->raid_bypass = true;
> +
> +       r1_request = io_request->iu;
> +       memset(r1_request, 0, offsetof(struct
> pqi_aio_r1_path_request, sg_descriptors));
> +
> +       r1_request->header.iu_type =
> PQI_REQUEST_IU_AIO_PATH_RAID1_IO;
> +
> +       put_unaligned_le16(*(u16 *)device->scsi3addr & 0x3fff,
> &r1_request->volume_id);
> +       r1_request->num_drives = rmd->num_it_nexus_entries;
> +       put_unaligned_le32(rmd->it_nexus[0], &r1_request-
> >it_nexus_1);
> +       put_unaligned_le32(rmd->it_nexus[1], &r1_request-
> >it_nexus_2);
> +       if (rmd->num_it_nexus_entries == 3)
> +               put_unaligned_le32(rmd->it_nexus[2], &r1_request-
> >it_nexus_3);
> +
> +       put_unaligned_le32(scsi_bufflen(scmd), &r1_request-
> >data_length);
> +       r1_request->task_attribute = SOP_TASK_ATTRIBUTE_SIMPLE;
> +       put_unaligned_le16(io_request->index, &r1_request-
> >request_id);
> +       r1_request->error_index = r1_request->request_id;
> +       if (rmd->cdb_length > sizeof(r1_request->cdb))
> +               rmd->cdb_length = sizeof(r1_request->cdb);
> +       r1_request->cdb_length = rmd->cdb_length;
> +       memcpy(r1_request->cdb, rmd->cdb, rmd->cdb_length);
> +
> +       switch (scmd->sc_data_direction) {
> +       case DMA_TO_DEVICE:
> +               r1_request->data_direction = SOP_READ_FLAG;
> +               break;

Same question as for previous patch, how would anything else than
DMA_TO_DEVICE be possible here?

> +       case DMA_FROM_DEVICE:
> +               r1_request->data_direction = SOP_WRITE_FLAG;
> +               break;
> +       case DMA_NONE:
> +               r1_request->data_direction = SOP_NO_DIRECTION_FLAG;
> +               break;
> +       case DMA_BIDIRECTIONAL:
> +               r1_request->data_direction = SOP_BIDIRECTIONAL;
> +               break;
> +       default:
> +               dev_err(&ctrl_info->pci_dev->dev,
> +                       "unknown data direction: %d\n",
> +                       scmd->sc_data_direction);
> +               break;
> +       }
> +
> +       if (encryption_info) {
> +               r1_request->encryption_enable = true;
> +               put_unaligned_le16(encryption_info-
> >data_encryption_key_index,
> +                               &r1_request-
> >data_encryption_key_index);
> +               put_unaligned_le32(encryption_info-
> >encrypt_tweak_lower,
> +                               &r1_request->encrypt_tweak_lower);
> +               put_unaligned_le32(encryption_info-
> >encrypt_tweak_upper,
> +                               &r1_request->encrypt_tweak_upper);
> +       }
> +
> +       rc = pqi_build_aio_r1_sg_list(ctrl_info, r1_request, scmd,
> io_request);
> +       if (rc) {
> +               pqi_free_io_request(io_request);
> +               return SCSI_MLQUEUE_HOST_BUSY;
> +       }
> +
> +       pqi_start_io(ctrl_info, queue_group, AIO_PATH, io_request);
> +
> +       return 0;
> +}
> +
>  static int pqi_aio_submit_r56_write_io(struct pqi_ctrl_info
> *ctrl_info,
>         struct scsi_cmnd *scmd, struct pqi_queue_group *queue_group,
>         struct pqi_encryption_info *encryption_info, struct
> pqi_scsi_dev *device,
>
Don Brace Jan. 9, 2021, 4:56 p.m. UTC | #2
Subject: Re: [PATCH V3 05/25] smartpqi: add support for raid1 writes
> @@ static bool pqi_aio_raid_level_supported(struct pqi_ctrl_info 
> *ctrl_info,
>         case SA_RAID_0:
>                 break;
>         case SA_RAID_1:
> -               is_supported = false;
> +               fallthrough;

Nit: fallthrough isn't necessary here.
Don: removed fallthrough
>
> +static  int pqi_aio_submit_r1_write_io(struct pqi_ctrl_info
> *ctrl_info,
> +       struct scsi_cmnd *scmd, struct pqi_queue_group *queue_group,
> +       struct pqi_encryption_info *encryption_info, struct
> pqi_scsi_dev *device,
> +       struct pqi_scsi_dev_raid_map_data *rmd)
> +
> +       switch (scmd->sc_data_direction) {
> +       case DMA_TO_DEVICE:
> +               r1_request->data_direction = SOP_READ_FLAG;
> +               break;

Same question as for previous patch, how would anything else than DMA_TO_DEVICE be possible here?

Don: changed direction to write, added comment.

Thank-you Martin for your review. I'll upload a V4 after I complete the other reviews.

Don Brace
diff mbox series

Patch

diff --git a/drivers/scsi/smartpqi/smartpqi.h b/drivers/scsi/smartpqi/smartpqi.h
index e9844210c4a0..225ec6843c68 100644
--- a/drivers/scsi/smartpqi/smartpqi.h
+++ b/drivers/scsi/smartpqi/smartpqi.h
@@ -313,6 +313,36 @@  struct pqi_aio_path_request {
 		sg_descriptors[PQI_MAX_EMBEDDED_SG_DESCRIPTORS];
 };
 
+#define PQI_RAID1_NVME_XFER_LIMIT	(32 * 1024)	/* 32 KiB */
+struct pqi_aio_r1_path_request {
+	struct pqi_iu_header header;
+	__le16	request_id;
+	__le16	volume_id;	/* ID of the RAID volume */
+	__le32	it_nexus_1;	/* IT nexus of the 1st drive in the RAID volume */
+	__le32	it_nexus_2;	/* IT nexus of the 2nd drive in the RAID volume */
+	__le32	it_nexus_3;	/* IT nexus of the 3rd drive in the RAID volume */
+	__le32	data_length;	/* total bytes to read/write */
+	u8	data_direction : 2;
+	u8	partial : 1;
+	u8	memory_type : 1;
+	u8	fence : 1;
+	u8	encryption_enable : 1;
+	u8	reserved : 2;
+	u8	task_attribute : 3;
+	u8	command_priority : 4;
+	u8	reserved2 : 1;
+	__le16	data_encryption_key_index;
+	u8	cdb[16];
+	__le16	error_index;
+	u8	num_sg_descriptors;
+	u8	cdb_length;
+	u8	num_drives;	/* number of drives in the RAID volume (2 or 3) */
+	u8	reserved3[3];
+	__le32	encrypt_tweak_lower;
+	__le32	encrypt_tweak_upper;
+	struct pqi_sg_descriptor sg_descriptors[PQI_MAX_EMBEDDED_SG_DESCRIPTORS];
+};
+
 #define PQI_RAID56_XFER_LIMIT_4K	0x1000 /* 4Kib */
 #define PQI_RAID56_XFER_LIMIT_8K	0x2000 /* 8Kib */
 struct pqi_aio_r56_path_request {
@@ -520,6 +550,7 @@  struct pqi_raid_error_info {
 #define PQI_REQUEST_IU_AIO_PATH_IO			0x15
 #define PQI_REQUEST_IU_AIO_PATH_RAID5_IO		0x18
 #define PQI_REQUEST_IU_AIO_PATH_RAID6_IO		0x19
+#define PQI_REQUEST_IU_AIO_PATH_RAID1_IO		0x1A
 #define PQI_REQUEST_IU_GENERAL_ADMIN			0x60
 #define PQI_REQUEST_IU_REPORT_VENDOR_EVENT_CONFIG	0x72
 #define PQI_REQUEST_IU_SET_VENDOR_EVENT_CONFIG		0x73
@@ -972,14 +1003,12 @@  struct pqi_scsi_dev_raid_map_data {
 	u16	strip_size;
 	u32	first_group;
 	u32	last_group;
-	u32	current_group;
 	u32	map_row;
 	u32	aio_handle;
 	u64	disk_block;
 	u32	disk_block_cnt;
 	u8	cdb[16];
 	u8	cdb_length;
-	int	offload_to_mirror;
 
 	/* RAID1 specific */
 #define NUM_RAID1_MAP_ENTRIES 3
@@ -1040,8 +1069,7 @@  struct pqi_scsi_dev {
 	u16	phys_connector[8];
 	bool	raid_bypass_configured;	/* RAID bypass configured */
 	bool	raid_bypass_enabled;	/* RAID bypass enabled */
-	int	offload_to_mirror;	/* Send next RAID bypass request */
-					/* to mirror drive. */
+	u32	next_bypass_group;
 	struct raid_map *raid_map;	/* RAID bypass map */
 
 	struct pqi_sas_port *sas_port;
@@ -1247,6 +1275,7 @@  struct pqi_ctrl_info {
 	u8		soft_reset_handshake_supported : 1;
 	u8		raid_iu_timeout_supported: 1;
 	u8		tmf_iu_timeout_supported: 1;
+	u8		enable_r1_writes : 1;
 	u8		enable_r5_writes : 1;
 	u8		enable_r6_writes : 1;
 
diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c
index c813cec10003..8da9031c9c0b 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -67,6 +67,10 @@  static int pqi_aio_submit_io(struct pqi_ctrl_info *ctrl_info,
 	struct scsi_cmnd *scmd, u32 aio_handle, u8 *cdb,
 	unsigned int cdb_length, struct pqi_queue_group *queue_group,
 	struct pqi_encryption_info *encryption_info, bool raid_bypass);
+static  int pqi_aio_submit_r1_write_io(struct pqi_ctrl_info *ctrl_info,
+	struct scsi_cmnd *scmd, struct pqi_queue_group *queue_group,
+	struct pqi_encryption_info *encryption_info, struct pqi_scsi_dev *device,
+	struct pqi_scsi_dev_raid_map_data *rmd);
 static int pqi_aio_submit_r56_write_io(struct pqi_ctrl_info *ctrl_info,
 	struct scsi_cmnd *scmd, struct pqi_queue_group *queue_group,
 	struct pqi_encryption_info *encryption_info, struct pqi_scsi_dev *device,
@@ -1717,7 +1721,7 @@  static void pqi_scsi_update_device(struct pqi_scsi_dev *existing_device,
 		sizeof(existing_device->box));
 	memcpy(existing_device->phys_connector, new_device->phys_connector,
 		sizeof(existing_device->phys_connector));
-	existing_device->offload_to_mirror = 0;
+	existing_device->next_bypass_group = 0;
 	kfree(existing_device->raid_map);
 	existing_device->raid_map = new_device->raid_map;
 	existing_device->raid_bypass_configured =
@@ -2250,7 +2254,10 @@  static bool pqi_aio_raid_level_supported(struct pqi_ctrl_info *ctrl_info,
 	case SA_RAID_0:
 		break;
 	case SA_RAID_1:
-		is_supported = false;
+		fallthrough;
+	case SA_RAID_ADM:
+		if (rmd->is_write && !ctrl_info->enable_r1_writes)
+			is_supported = false;
 		break;
 	case SA_RAID_5:
 		if (rmd->is_write && !ctrl_info->enable_r5_writes)
@@ -2260,10 +2267,6 @@  static bool pqi_aio_raid_level_supported(struct pqi_ctrl_info *ctrl_info,
 		if (rmd->is_write && !ctrl_info->enable_r6_writes)
 			is_supported = false;
 		break;
-	case SA_RAID_ADM:
-		if (rmd->is_write)
-			is_supported = false;
-		break;
 	default:
 		is_supported = false;
 	}
@@ -2385,64 +2388,6 @@  static int pci_get_aio_common_raid_map_values(struct pqi_ctrl_info *ctrl_info,
 	return 0;
 }
 
-static int pqi_calc_aio_raid_adm(struct pqi_scsi_dev_raid_map_data *rmd,
-				struct pqi_scsi_dev *device)
-{
-	/* RAID ADM */
-	/*
-	 * Handles N-way mirrors  (R1-ADM) and R10 with # of drives
-	 * divisible by 3.
-	 */
-	rmd->offload_to_mirror = device->offload_to_mirror;
-
-	if (rmd->offload_to_mirror == 0)  {
-		/* use physical disk in the first mirrored group. */
-		rmd->map_index %= rmd->data_disks_per_row;
-	} else {
-		do {
-			/*
-			 * Determine mirror group that map_index
-			 * indicates.
-			 */
-			rmd->current_group =
-				rmd->map_index / rmd->data_disks_per_row;
-
-			if (rmd->offload_to_mirror !=
-					rmd->current_group) {
-				if (rmd->current_group <
-					rmd->layout_map_count - 1) {
-					/*
-					 * Select raid index from
-					 * next group.
-					 */
-					rmd->map_index += rmd->data_disks_per_row;
-					rmd->current_group++;
-				} else {
-					/*
-					 * Select raid index from first
-					 * group.
-					 */
-					rmd->map_index %= rmd->data_disks_per_row;
-					rmd->current_group = 0;
-				}
-			}
-		} while (rmd->offload_to_mirror != rmd->current_group);
-	}
-
-	/* Set mirror group to use next time. */
-	rmd->offload_to_mirror =
-		(rmd->offload_to_mirror >= rmd->layout_map_count - 1) ?
-			0 : rmd->offload_to_mirror + 1;
-	device->offload_to_mirror = rmd->offload_to_mirror;
-	/*
-	 * Avoid direct use of device->offload_to_mirror within this
-	 * function since multiple threads might simultaneously
-	 * increment it beyond the range of device->layout_map_count -1.
-	 */
-
-	return 0;
-}
-
 static int pqi_calc_aio_r5_or_r6(struct pqi_scsi_dev_raid_map_data *rmd,
 				struct raid_map *raid_map)
 {
@@ -2577,12 +2522,34 @@  static void pqi_set_aio_cdb(struct pqi_scsi_dev_raid_map_data *rmd)
 	}
 }
 
+static void pqi_calc_aio_r1_nexus(struct raid_map *raid_map,
+				struct pqi_scsi_dev_raid_map_data *rmd)
+{
+	u32 index;
+	u32 group;
+
+	group = rmd->map_index / rmd->data_disks_per_row;
+
+	index = rmd->map_index - (group * rmd->data_disks_per_row);
+	rmd->it_nexus[0] = raid_map->disk_data[index].aio_handle;
+	index += rmd->data_disks_per_row;
+	rmd->it_nexus[1] = raid_map->disk_data[index].aio_handle;
+	if (rmd->layout_map_count > 2) {
+		index += rmd->data_disks_per_row;
+		rmd->it_nexus[2] = raid_map->disk_data[index].aio_handle;
+	}
+
+	rmd->num_it_nexus_entries = rmd->layout_map_count;
+}
+
 static int pqi_raid_bypass_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info,
 	struct pqi_scsi_dev *device, struct scsi_cmnd *scmd,
 	struct pqi_queue_group *queue_group)
 {
-	struct raid_map *raid_map;
 	int rc;
+	struct raid_map *raid_map;
+	u32 group;
+	u32 next_bypass_group;
 	struct pqi_encryption_info *encryption_info_ptr;
 	struct pqi_encryption_info encryption_info;
 	struct pqi_scsi_dev_raid_map_data rmd = {0};
@@ -2605,13 +2572,18 @@  static int pqi_raid_bypass_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info,
 	if (rc)
 		return PQI_RAID_BYPASS_INELIGIBLE;
 
-	/* RAID 1 */
-	if (device->raid_level == SA_RAID_1) {
-		if (device->offload_to_mirror)
-			rmd.map_index += rmd.data_disks_per_row;
-		device->offload_to_mirror = !device->offload_to_mirror;
-	} else if (device->raid_level == SA_RAID_ADM) {
-		rc = pqi_calc_aio_raid_adm(&rmd, device);
+	if (device->raid_level == SA_RAID_1 ||
+		device->raid_level == SA_RAID_ADM) {
+		if (rmd.is_write) {
+			pqi_calc_aio_r1_nexus(raid_map, &rmd);
+		} else {
+			group = device->next_bypass_group;
+			next_bypass_group = group + 1;
+			if (next_bypass_group >= rmd.layout_map_count)
+				next_bypass_group = 0;
+			device->next_bypass_group = next_bypass_group;
+			rmd.map_index += group * rmd.data_disks_per_row;
+		}
 	} else if ((device->raid_level == SA_RAID_5 ||
 		device->raid_level == SA_RAID_6) &&
 		(rmd.layout_map_count > 1 || rmd.is_write)) {
@@ -2655,6 +2627,10 @@  static int pqi_raid_bypass_submit_scsi_cmd(struct pqi_ctrl_info *ctrl_info,
 			return pqi_aio_submit_io(ctrl_info, scmd, rmd.aio_handle,
 				rmd.cdb, rmd.cdb_length, queue_group,
 				encryption_info_ptr, true);
+		case SA_RAID_1:
+		case SA_RAID_ADM:
+			return pqi_aio_submit_r1_write_io(ctrl_info, scmd, queue_group,
+				encryption_info_ptr, device, &rmd);
 		case SA_RAID_5:
 		case SA_RAID_6:
 			return pqi_aio_submit_r56_write_io(ctrl_info, scmd, queue_group,
@@ -4982,6 +4958,44 @@  static int pqi_build_raid_sg_list(struct pqi_ctrl_info *ctrl_info,
 	return 0;
 }
 
+static int pqi_build_aio_r1_sg_list(struct pqi_ctrl_info *ctrl_info,
+	struct pqi_aio_r1_path_request *request, struct scsi_cmnd *scmd,
+	struct pqi_io_request *io_request)
+{
+	u16 iu_length;
+	int sg_count;
+	bool chained;
+	unsigned int num_sg_in_iu;
+	struct scatterlist *sg;
+	struct pqi_sg_descriptor *sg_descriptor;
+
+	sg_count = scsi_dma_map(scmd);
+	if (sg_count < 0)
+		return sg_count;
+
+	iu_length = offsetof(struct pqi_aio_r1_path_request, sg_descriptors) -
+		PQI_REQUEST_HEADER_LENGTH;
+	num_sg_in_iu = 0;
+
+	if (sg_count == 0)
+		goto out;
+
+	sg = scsi_sglist(scmd);
+	sg_descriptor = request->sg_descriptors;
+
+	num_sg_in_iu = pqi_build_sg_list(sg_descriptor, sg, sg_count, io_request,
+		ctrl_info->max_sg_per_iu, &chained);
+
+	request->partial = chained;
+	iu_length += num_sg_in_iu * sizeof(*sg_descriptor);
+
+out:
+	put_unaligned_le16(iu_length, &request->header.iu_length);
+	request->num_sg_descriptors = num_sg_in_iu;
+
+	return 0;
+}
+
 static int pqi_build_aio_r56_sg_list(struct pqi_ctrl_info *ctrl_info,
 	struct pqi_aio_r56_path_request *request, struct scsi_cmnd *scmd,
 	struct pqi_io_request *io_request)
@@ -5424,6 +5438,83 @@  static int pqi_aio_submit_io(struct pqi_ctrl_info *ctrl_info,
 	return 0;
 }
 
+static  int pqi_aio_submit_r1_write_io(struct pqi_ctrl_info *ctrl_info,
+	struct scsi_cmnd *scmd, struct pqi_queue_group *queue_group,
+	struct pqi_encryption_info *encryption_info, struct pqi_scsi_dev *device,
+	struct pqi_scsi_dev_raid_map_data *rmd)
+
+{
+	int rc;
+	struct pqi_io_request *io_request;
+	struct pqi_aio_r1_path_request *r1_request;
+
+	io_request = pqi_alloc_io_request(ctrl_info);
+	io_request->io_complete_callback = pqi_aio_io_complete;
+	io_request->scmd = scmd;
+	io_request->raid_bypass = true;
+
+	r1_request = io_request->iu;
+	memset(r1_request, 0, offsetof(struct pqi_aio_r1_path_request, sg_descriptors));
+
+	r1_request->header.iu_type = PQI_REQUEST_IU_AIO_PATH_RAID1_IO;
+
+	put_unaligned_le16(*(u16 *)device->scsi3addr & 0x3fff, &r1_request->volume_id);
+	r1_request->num_drives = rmd->num_it_nexus_entries;
+	put_unaligned_le32(rmd->it_nexus[0], &r1_request->it_nexus_1);
+	put_unaligned_le32(rmd->it_nexus[1], &r1_request->it_nexus_2);
+	if (rmd->num_it_nexus_entries == 3)
+		put_unaligned_le32(rmd->it_nexus[2], &r1_request->it_nexus_3);
+
+	put_unaligned_le32(scsi_bufflen(scmd), &r1_request->data_length);
+	r1_request->task_attribute = SOP_TASK_ATTRIBUTE_SIMPLE;
+	put_unaligned_le16(io_request->index, &r1_request->request_id);
+	r1_request->error_index = r1_request->request_id;
+	if (rmd->cdb_length > sizeof(r1_request->cdb))
+		rmd->cdb_length = sizeof(r1_request->cdb);
+	r1_request->cdb_length = rmd->cdb_length;
+	memcpy(r1_request->cdb, rmd->cdb, rmd->cdb_length);
+
+	switch (scmd->sc_data_direction) {
+	case DMA_TO_DEVICE:
+		r1_request->data_direction = SOP_READ_FLAG;
+		break;
+	case DMA_FROM_DEVICE:
+		r1_request->data_direction = SOP_WRITE_FLAG;
+		break;
+	case DMA_NONE:
+		r1_request->data_direction = SOP_NO_DIRECTION_FLAG;
+		break;
+	case DMA_BIDIRECTIONAL:
+		r1_request->data_direction = SOP_BIDIRECTIONAL;
+		break;
+	default:
+		dev_err(&ctrl_info->pci_dev->dev,
+			"unknown data direction: %d\n",
+			scmd->sc_data_direction);
+		break;
+	}
+
+	if (encryption_info) {
+		r1_request->encryption_enable = true;
+		put_unaligned_le16(encryption_info->data_encryption_key_index,
+				&r1_request->data_encryption_key_index);
+		put_unaligned_le32(encryption_info->encrypt_tweak_lower,
+				&r1_request->encrypt_tweak_lower);
+		put_unaligned_le32(encryption_info->encrypt_tweak_upper,
+				&r1_request->encrypt_tweak_upper);
+	}
+
+	rc = pqi_build_aio_r1_sg_list(ctrl_info, r1_request, scmd, io_request);
+	if (rc) {
+		pqi_free_io_request(io_request);
+		return SCSI_MLQUEUE_HOST_BUSY;
+	}
+
+	pqi_start_io(ctrl_info, queue_group, AIO_PATH, io_request);
+
+	return 0;
+}
+
 static int pqi_aio_submit_r56_write_io(struct pqi_ctrl_info *ctrl_info,
 	struct scsi_cmnd *scmd, struct pqi_queue_group *queue_group,
 	struct pqi_encryption_info *encryption_info, struct pqi_scsi_dev *device,