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>

Changed files
+9 -4
drivers
target
+9 -4
drivers/target/iscsi/iscsi_target.c
··· 753 753 754 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 759 conn->exp_statsn = exp_statsn; 759 760 ··· 762 761 return; 763 762 764 763 spin_lock_bh(&conn->cmd_lock); 765 - list_for_each_entry(cmd, &conn->conn_cmd_list, i_conn_node) { 764 + list_for_each_entry_safe(cmd, cmd_p, &conn->conn_cmd_list, i_conn_node) { 766 765 spin_lock(&cmd->istate_lock); 767 766 if ((cmd->i_state == ISTATE_SENT_STATUS) && 768 767 iscsi_sna_lt(cmd->stat_sn, exp_statsn)) { 769 768 cmd->i_state = ISTATE_REMOVE; 770 769 spin_unlock(&cmd->istate_lock); 771 - iscsit_add_cmd_to_immediate_queue(cmd, conn, 772 - cmd->i_state); 770 + list_move_tail(&cmd->i_conn_node, &ack_list); 773 771 continue; 774 772 } 775 773 spin_unlock(&cmd->istate_lock); 776 774 } 777 775 spin_unlock_bh(&conn->cmd_lock); 776 + 777 + list_for_each_entry_safe(cmd, cmd_p, &ack_list, i_conn_node) { 778 + list_del(&cmd->i_conn_node); 779 + iscsit_free_cmd(cmd, false); 780 + } 778 781 } 779 782 780 783 static int iscsit_allocate_iovecs(struct iscsi_cmd *cmd)