diff mbox series

[2/6] scsi: iscsi: Speed up session unblocking and removal.

Message ID 20220226230435.38733-3-michael.christie@oracle.com
State New
Headers show
Series iscsi: Speed up failover with lots of devices. | expand

Commit Message

Mike Christie Feb. 26, 2022, 11:04 p.m. UTC
When the iscsi class was added upstream blocking a queue was fast because
it just set some flag bits and didn't handle IO that was in the process
of being sent to the driver. That's no longer the case so blocking a queue
is expensive and we can end up with a backlog of blocks by the time we
have relogged in and are trying to start the queues.

For the session unblock case, this has try to cancel the block and
recovery work in case they are still queued so we can avoid unneeded queue
manipulations. For removal we also now try to cancel all the recovery
related works since a couple lines down we will set the session and device
state so running those functions are not necessary.

Signed-off-by: Mike Christie <michael.christie@oracle.com>
---
 drivers/scsi/scsi_transport_iscsi.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

Comments

Lee Duncan Feb. 28, 2022, 4:05 p.m. UTC | #1
On 2/26/22 15:04, Mike Christie wrote:
> When the iscsi class was added upstream blocking a queue was fast because
> it just set some flag bits and didn't handle IO that was in the process
> of being sent to the driver. That's no longer the case so blocking a queue
> is expensive and we can end up with a backlog of blocks by the time we
> have relogged in and are trying to start the queues.
> 
> For the session unblock case, this has try to cancel the block and
> recovery work in case they are still queued so we can avoid unneeded queue
> manipulations. For removal we also now try to cancel all the recovery
> related works since a couple lines down we will set the session and device
> state so running those functions are not necessary.
> 
> Signed-off-by: Mike Christie <michael.christie@oracle.com>
> ---
>   drivers/scsi/scsi_transport_iscsi.c | 9 +++++----
>   1 file changed, 5 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
> index c58126e8cd88..732938f5436b 100644
> --- a/drivers/scsi/scsi_transport_iscsi.c
> +++ b/drivers/scsi/scsi_transport_iscsi.c
> @@ -1944,7 +1944,8 @@ static void __iscsi_unblock_session(struct work_struct *work)
>    */
>   void iscsi_unblock_session(struct iscsi_cls_session *session)
>   {
> -	flush_work(&session->block_work);
> +	if (!cancel_work_sync(&session->block_work))
> +		cancel_delayed_work_sync(&session->recovery_work);
>   
>   	queue_work(iscsi_eh_timer_workq, &session->unblock_work);
>   	/*
> @@ -2177,9 +2178,9 @@ void iscsi_remove_session(struct iscsi_cls_session *session)
>   		list_del(&session->sess_list);
>   	spin_unlock_irqrestore(&sesslock, flags);
>   
> -	flush_work(&session->block_work);
> -	flush_work(&session->unblock_work);
> -	cancel_delayed_work_sync(&session->recovery_work);
> +	if (!cancel_work_sync(&session->block_work))
> +		cancel_delayed_work_sync(&session->recovery_work);
> +	cancel_work_sync(&session->unblock_work);
>   	/*
>   	 * If we are blocked let commands flow again. The lld or iscsi
>   	 * layer should set up the queuecommand to fail commands.

Reviewed-by: Lee Duncan <lduncan@suse.com>
Chris Leech Feb. 28, 2022, 8:06 p.m. UTC | #2
On 2/26/22 3:04 PM, Mike Christie wrote:
> When the iscsi class was added upstream blocking a queue was fast because
> it just set some flag bits and didn't handle IO that was in the process
> of being sent to the driver. That's no longer the case so blocking a queue
> is expensive and we can end up with a backlog of blocks by the time we
> have relogged in and are trying to start the queues.
> 
> For the session unblock case, this has try to cancel the block and
> recovery work in case they are still queued so we can avoid unneeded queue
> manipulations. For removal we also now try to cancel all the recovery
> related works since a couple lines down we will set the session and device
> state so running those functions are not necessary.
> 
> Signed-off-by: Mike Christie <michael.christie@oracle.com>
> ---
>  drivers/scsi/scsi_transport_iscsi.c | 9 +++++----
>  1 file changed, 5 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
> index c58126e8cd88..732938f5436b 100644
> --- a/drivers/scsi/scsi_transport_iscsi.c
> +++ b/drivers/scsi/scsi_transport_iscsi.c
> @@ -1944,7 +1944,8 @@ static void __iscsi_unblock_session(struct work_struct *work)
>   */
>  void iscsi_unblock_session(struct iscsi_cls_session *session)
>  {
> -	flush_work(&session->block_work);
> +	if (!cancel_work_sync(&session->block_work))
> +		cancel_delayed_work_sync(&session->recovery_work);
>  
>  	queue_work(iscsi_eh_timer_workq, &session->unblock_work);
>  	/*
> @@ -2177,9 +2178,9 @@ void iscsi_remove_session(struct iscsi_cls_session *session)
>  		list_del(&session->sess_list);
>  	spin_unlock_irqrestore(&sesslock, flags);
>  
> -	flush_work(&session->block_work);
> -	flush_work(&session->unblock_work);
> -	cancel_delayed_work_sync(&session->recovery_work);
> +	if (!cancel_work_sync(&session->block_work))
> +		cancel_delayed_work_sync(&session->recovery_work);
> +	cancel_work_sync(&session->unblock_work);
>  	/*
>  	 * If we are blocked let commands flow again. The lld or iscsi
>  	 * layer should set up the queuecommand to fail commands.


Reviewed-by: Chris Leech <cleech@redhat.com>
diff mbox series

Patch

diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c
index c58126e8cd88..732938f5436b 100644
--- a/drivers/scsi/scsi_transport_iscsi.c
+++ b/drivers/scsi/scsi_transport_iscsi.c
@@ -1944,7 +1944,8 @@  static void __iscsi_unblock_session(struct work_struct *work)
  */
 void iscsi_unblock_session(struct iscsi_cls_session *session)
 {
-	flush_work(&session->block_work);
+	if (!cancel_work_sync(&session->block_work))
+		cancel_delayed_work_sync(&session->recovery_work);
 
 	queue_work(iscsi_eh_timer_workq, &session->unblock_work);
 	/*
@@ -2177,9 +2178,9 @@  void iscsi_remove_session(struct iscsi_cls_session *session)
 		list_del(&session->sess_list);
 	spin_unlock_irqrestore(&sesslock, flags);
 
-	flush_work(&session->block_work);
-	flush_work(&session->unblock_work);
-	cancel_delayed_work_sync(&session->recovery_work);
+	if (!cancel_work_sync(&session->block_work))
+		cancel_delayed_work_sync(&session->recovery_work);
+	cancel_work_sync(&session->unblock_work);
 	/*
 	 * If we are blocked let commands flow again. The lld or iscsi
 	 * layer should set up the queuecommand to fail commands.