diff options
author | Nicholas Bellinger <nab@linux-iscsi.org> | 2013-02-27 20:53:52 -0500 |
---|---|---|
committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2013-02-27 22:03:22 -0500 |
commit | fd3a9025c0349bc9b01d627529f54e6e1e389015 (patch) | |
tree | 2b76a08283890e902756307e6e2c004c10a24099 /drivers/target | |
parent | 972b29c8f86093f44e1d781588bd5c5faae3d8e3 (diff) |
iscsi-target: Fix immediate queue starvation regression with DATAIN
This patch addresses a v3.5+ regression in iscsi-target where TX thread
process context -> handle_response_queue() execution is allowed to run
unbounded while servicing constant outgoing flow of ISTATE_SEND_DATAIN
response state.
This ends up preventing memory release of StatSN acknowledged commands
in a timely manner when under heavy large block streaming DATAIN
workloads.
The regression bug was initially introduced with:
commit 6f3c0e69a9c20441bdc6d3b2d18b83b244384ec6
Author: Andy Grover <agrover@redhat.com>
Date: Tue Apr 3 15:51:09 2012 -0700
target/iscsi: Refactor target_tx_thread immediate+response queue loops
Go ahead and follow original iscsi_target_tx_thread() logic and check
to break for immediate queue processing after each DataIN Sequence and/or
Response PDU has been sent.
Reported-by: Benjamin ESTRABAUD <be@mpstor.com>
Cc: Andy Grover <agrover@redhat.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
Diffstat (limited to 'drivers/target')
-rw-r--r-- | drivers/target/iscsi/iscsi_target.c | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 23a98e658306..af77396234a2 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c | |||
@@ -3583,6 +3583,10 @@ check_rsp_state: | |||
3583 | spin_lock_bh(&cmd->istate_lock); | 3583 | spin_lock_bh(&cmd->istate_lock); |
3584 | cmd->i_state = ISTATE_SENT_STATUS; | 3584 | cmd->i_state = ISTATE_SENT_STATUS; |
3585 | spin_unlock_bh(&cmd->istate_lock); | 3585 | spin_unlock_bh(&cmd->istate_lock); |
3586 | |||
3587 | if (atomic_read(&conn->check_immediate_queue)) | ||
3588 | return 1; | ||
3589 | |||
3586 | continue; | 3590 | continue; |
3587 | } else if (ret == 2) { | 3591 | } else if (ret == 2) { |
3588 | /* Still must send status, | 3592 | /* Still must send status, |
@@ -3672,7 +3676,7 @@ check_rsp_state: | |||
3672 | } | 3676 | } |
3673 | 3677 | ||
3674 | if (atomic_read(&conn->check_immediate_queue)) | 3678 | if (atomic_read(&conn->check_immediate_queue)) |
3675 | break; | 3679 | return 1; |
3676 | } | 3680 | } |
3677 | 3681 | ||
3678 | return 0; | 3682 | return 0; |
@@ -3716,12 +3720,15 @@ restart: | |||
3716 | signal_pending(current)) | 3720 | signal_pending(current)) |
3717 | goto transport_err; | 3721 | goto transport_err; |
3718 | 3722 | ||
3723 | get_immediate: | ||
3719 | ret = handle_immediate_queue(conn); | 3724 | ret = handle_immediate_queue(conn); |
3720 | if (ret < 0) | 3725 | if (ret < 0) |
3721 | goto transport_err; | 3726 | goto transport_err; |
3722 | 3727 | ||
3723 | ret = handle_response_queue(conn); | 3728 | ret = handle_response_queue(conn); |
3724 | if (ret == -EAGAIN) | 3729 | if (ret == 1) |
3730 | goto get_immediate; | ||
3731 | else if (ret == -EAGAIN) | ||
3725 | goto restart; | 3732 | goto restart; |
3726 | else if (ret < 0) | 3733 | else if (ret < 0) |
3727 | goto transport_err; | 3734 | goto transport_err; |