diff options
| author | Nicholas Bellinger <nab@linux-iscsi.org> | 2013-10-03 16:56:14 -0400 |
|---|---|---|
| committer | Nicholas Bellinger <nab@linux-iscsi.org> | 2013-10-03 17:22:45 -0400 |
| commit | f56cbbb4b5871e5bc2838ddeeba5b29debc2a734 (patch) | |
| tree | 6ea3d9dd0b0bb7c652337ddf7d86f94268917a54 | |
| parent | e255a28598e8e63070322fc89bd34189dd660a89 (diff) | |
iscsi-target: Perform release of acknowledged tags from RX context
This patch converts iscsit_ack_from_expstatsn() to populate a local
ack_list of commands, and call iscsit_free_cmd() directly from RX
thread context, instead of using iscsit_add_cmd_to_immediate_queue()
to queue the acknowledged commands to be released from TX thread
context.
It is helpful to release the acknowledge commands as quickly as
possible, along with the associated percpu_ida tags, in order to
prevent percpu_ida_alloc() from having to steal tags from other
CPUs while waiting for iscsit_free_cmd() to happen from TX thread
context.
Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
| -rw-r--r-- | drivers/target/iscsi/iscsi_target.c | 13 |
1 files changed, 9 insertions, 4 deletions
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c index 35b61f7d6c63..38e44b9abf0f 100644 --- a/drivers/target/iscsi/iscsi_target.c +++ b/drivers/target/iscsi/iscsi_target.c | |||
| @@ -753,7 +753,8 @@ static void iscsit_unmap_iovec(struct iscsi_cmd *cmd) | |||
| 753 | 753 | ||
| 754 | static void iscsit_ack_from_expstatsn(struct iscsi_conn *conn, u32 exp_statsn) | 754 | static void iscsit_ack_from_expstatsn(struct iscsi_conn *conn, u32 exp_statsn) |
| 755 | { | 755 | { |
| 756 | struct iscsi_cmd *cmd; | 756 | LIST_HEAD(ack_list); |
| 757 | struct iscsi_cmd *cmd, *cmd_p; | ||
| 757 | 758 | ||
| 758 | conn->exp_statsn = exp_statsn; | 759 | conn->exp_statsn = exp_statsn; |
| 759 | 760 | ||
| @@ -761,19 +762,23 @@ static void iscsit_ack_from_expstatsn(struct iscsi_conn *conn, u32 exp_statsn) | |||
| 761 | return; | 762 | return; |
| 762 | 763 | ||
| 763 | spin_lock_bh(&conn->cmd_lock); | 764 | spin_lock_bh(&conn->cmd_lock); |
| 764 | list_for_each_entry(cmd, &conn->conn_cmd_list, i_conn_node) { | 765 | list_for_each_entry_safe(cmd, cmd_p, &conn->conn_cmd_list, i_conn_node) { |
| 765 | spin_lock(&cmd->istate_lock); | 766 | spin_lock(&cmd->istate_lock); |
| 766 | if ((cmd->i_state == ISTATE_SENT_STATUS) && | 767 | if ((cmd->i_state == ISTATE_SENT_STATUS) && |
| 767 | iscsi_sna_lt(cmd->stat_sn, exp_statsn)) { | 768 | iscsi_sna_lt(cmd->stat_sn, exp_statsn)) { |
| 768 | cmd->i_state = ISTATE_REMOVE; | 769 | cmd->i_state = ISTATE_REMOVE; |
| 769 | spin_unlock(&cmd->istate_lock); | 770 | spin_unlock(&cmd->istate_lock); |
| 770 | iscsit_add_cmd_to_immediate_queue(cmd, conn, | 771 | list_move_tail(&cmd->i_conn_node, &ack_list); |
| 771 | cmd->i_state); | ||
| 772 | continue; | 772 | continue; |
| 773 | } | 773 | } |
| 774 | spin_unlock(&cmd->istate_lock); | 774 | spin_unlock(&cmd->istate_lock); |
| 775 | } | 775 | } |
| 776 | spin_unlock_bh(&conn->cmd_lock); | 776 | spin_unlock_bh(&conn->cmd_lock); |
| 777 | |||
| 778 | list_for_each_entry_safe(cmd, cmd_p, &ack_list, i_conn_node) { | ||
| 779 | list_del(&cmd->i_conn_node); | ||
| 780 | iscsit_free_cmd(cmd, false); | ||
| 781 | } | ||
| 777 | } | 782 | } |
| 778 | 783 | ||
| 779 | static int iscsit_allocate_iovecs(struct iscsi_cmd *cmd) | 784 | static int iscsit_allocate_iovecs(struct iscsi_cmd *cmd) |
