]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
scsi: iscsi: Optimize work queue flush use
authorMike Christie <michael.christie@oracle.com>
Wed, 1 Jul 2020 19:47:47 +0000 (14:47 -0500)
committerMartin K. Petersen <martin.petersen@oracle.com>
Fri, 3 Jul 2020 03:46:14 +0000 (23:46 -0400)
There is no need for one session to flush the entire iscsi_eh_timer_workq
when removing/unblocking a session. During removal we need to make sure our
works are not running anymore. And iscsi_unblock_session only needs to make
sure its work is done. The unblock work function will flush/cancel the
works it has conflicts with.

Link: https://lore.kernel.org/r/1593632868-6808-3-git-send-email-michael.christie@oracle.com
Signed-off-by: Mike Christie <michael.christie@oracle.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/scsi_transport_iscsi.c

index d4da7d21530d9b52e1fef55cf1baa00549dca3f0..a55ea229fce87d6666e9a3b1348b78d601b517a6 100644 (file)
@@ -1978,10 +1978,11 @@ void iscsi_unblock_session(struct iscsi_cls_session *session)
 {
        queue_work(iscsi_eh_timer_workq, &session->unblock_work);
        /*
-        * make sure all the events have completed before tell the driver
-        * it is safe
+        * Blocking the session can be done from any context so we only
+        * queue the block work. Make sure the unblock work has completed
+        * because it flushes/cancels the other works and updates the state.
         */
-       flush_workqueue(iscsi_eh_timer_workq);
+       flush_work(&session->unblock_work);
 }
 EXPORT_SYMBOL_GPL(iscsi_unblock_session);
 
@@ -2205,11 +2206,9 @@ void iscsi_remove_session(struct iscsi_cls_session *session)
        list_del(&session->sess_list);
        spin_unlock_irqrestore(&sesslock, flags);
 
-       /* make sure there are no blocks/unblocks queued */
-       flush_workqueue(iscsi_eh_timer_workq);
-       /* make sure the timedout callout is not running */
-       if (!cancel_delayed_work(&session->recovery_work))
-               flush_workqueue(iscsi_eh_timer_workq);
+       flush_work(&session->block_work);
+       flush_work(&session->unblock_work);
+       cancel_delayed_work_sync(&session->recovery_work);
        /*
         * If we are blocked let commands flow again. The lld or iscsi
         * layer should set up the queuecommand to fail commands.