From: Hannes Reinecke <h...@suse.de>

Enable host tagset for smartpqi; with this we can use the request
tag to look command from the pool avoiding the list iteration in
the hot path.

Signed-off-by: Hannes Reinecke <h...@suse.de>
[jpg: Mod ctrl_info->next_io_request_slot calc]
Signed-off-by: John Garry <john.ga...@huawei.com>
---
 drivers/scsi/smartpqi/smartpqi_init.c | 45 ++++++++++++++++++---------
 1 file changed, 31 insertions(+), 14 deletions(-)

diff --git a/drivers/scsi/smartpqi/smartpqi_init.c 
b/drivers/scsi/smartpqi/smartpqi_init.c
index bd38c8cea56e..870ed1400a9e 100644
--- a/drivers/scsi/smartpqi/smartpqi_init.c
+++ b/drivers/scsi/smartpqi/smartpqi_init.c
@@ -575,22 +575,33 @@ static inline void pqi_reinit_io_request(struct 
pqi_io_request *io_request)
 }
 
 static struct pqi_io_request *pqi_alloc_io_request(
-       struct pqi_ctrl_info *ctrl_info)
+       struct pqi_ctrl_info *ctrl_info, struct scsi_cmnd *scmd)
 {
        struct pqi_io_request *io_request;
-       u16 i = ctrl_info->next_io_request_slot;        /* benignly racy */
+       unsigned int limit = PQI_RESERVED_IO_SLOTS;
+       u16 i;
 
-       while (1) {
+       if (scmd) {
+               u32 blk_tag = blk_mq_unique_tag(scmd->request);
+
+               i = blk_mq_unique_tag_to_tag(blk_tag) + limit;
                io_request = &ctrl_info->io_request_pool[i];
-               if (atomic_inc_return(&io_request->refcount) == 1)
-                       break;
-               atomic_dec(&io_request->refcount);
-               i = (i + 1) % ctrl_info->max_io_slots;
+               if (WARN_ON(atomic_inc_return(&io_request->refcount) > 1)) {
+                       atomic_dec(&io_request->refcount);
+                       return NULL;
+               }
+       } else {
+               i = ctrl_info->next_io_request_slot;    /* benignly racy */
+               while (1) {
+                       io_request = &ctrl_info->io_request_pool[i];
+                       if (atomic_inc_return(&io_request->refcount) == 1)
+                               break;
+                       atomic_dec(&io_request->refcount);
+                       i = (i + 1) % limit;
+               }
+               ctrl_info->next_io_request_slot = (i + 1) % limit;
        }
 
-       /* benignly racy */
-       ctrl_info->next_io_request_slot = (i + 1) % ctrl_info->max_io_slots;
-
        pqi_reinit_io_request(io_request);
 
        return io_request;
@@ -4075,7 +4086,7 @@ static int pqi_submit_raid_request_synchronous(struct 
pqi_ctrl_info *ctrl_info,
 
        atomic_inc(&ctrl_info->sync_cmds_outstanding);
 
-       io_request = pqi_alloc_io_request(ctrl_info);
+       io_request = pqi_alloc_io_request(ctrl_info, NULL);
 
        put_unaligned_le16(io_request->index,
                &(((struct pqi_raid_path_request *)request)->request_id));
@@ -5032,7 +5043,9 @@ static inline int pqi_raid_submit_scsi_cmd(struct 
pqi_ctrl_info *ctrl_info,
 {
        struct pqi_io_request *io_request;
 
-       io_request = pqi_alloc_io_request(ctrl_info);
+       io_request = pqi_alloc_io_request(ctrl_info, scmd);
+       if (!io_request)
+               return SCSI_MLQUEUE_HOST_BUSY;
 
        return pqi_raid_submit_scsi_cmd_with_io_request(ctrl_info, io_request,
                device, scmd, queue_group);
@@ -5230,7 +5243,10 @@ static int pqi_aio_submit_io(struct pqi_ctrl_info 
*ctrl_info,
        struct pqi_io_request *io_request;
        struct pqi_aio_path_request *request;
 
-       io_request = pqi_alloc_io_request(ctrl_info);
+       io_request = pqi_alloc_io_request(ctrl_info, scmd);
+       if (!io_request)
+               return SCSI_MLQUEUE_HOST_BUSY;
+
        io_request->io_complete_callback = pqi_aio_io_complete;
        io_request->scmd = scmd;
        io_request->raid_bypass = raid_bypass;
@@ -5657,7 +5673,7 @@ static int pqi_lun_reset(struct pqi_ctrl_info *ctrl_info,
        DECLARE_COMPLETION_ONSTACK(wait);
        struct pqi_task_management_request *request;
 
-       io_request = pqi_alloc_io_request(ctrl_info);
+       io_request = pqi_alloc_io_request(ctrl_info, NULL);
        io_request->io_complete_callback = pqi_lun_reset_complete;
        io_request->context = &wait;
 
@@ -6504,6 +6520,7 @@ static struct scsi_host_template pqi_driver_template = {
        .map_queues = pqi_map_queues,
        .sdev_attrs = pqi_sdev_attrs,
        .shost_attrs = pqi_shost_attrs,
+       .host_tagset = 1,
 };
 
 static int pqi_register_scsi(struct pqi_ctrl_info *ctrl_info)
-- 
2.26.2

Reply via email to