On NUMA machines the kworker of iscsi created always jump around
across node boundaries. If it work on the different node even
different cpu package with the softirq of network interface, memcpy
with in iscsi_tcp_segment_recv will be slow down, and iscsi got an
terrible performance.

In this patch, we trace the cpu of softirq, and tell queue_work_on
to execute iscsi_xmitworker on the same NUMA node.

Signed-off-by: Biaoxiang Ye <[email protected]>
---
 drivers/scsi/iscsi_tcp.c |  8 ++++++++
 drivers/scsi/libiscsi.c  | 12 +++++++++---
 2 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
index 7bedbe8..dbac244 100644
--- a/drivers/scsi/iscsi_tcp.c
+++ b/drivers/scsi/iscsi_tcp.c
@@ -127,6 +127,7 @@ static void iscsi_sw_tcp_data_ready(struct sock *sk)
        struct iscsi_conn *conn;
        struct iscsi_tcp_conn *tcp_conn;
        read_descriptor_t rd_desc;
+       int current_cpu;
 
        read_lock_bh(&sk->sk_callback_lock);
        conn = sk->sk_user_data;
@@ -136,6 +137,13 @@ static void iscsi_sw_tcp_data_ready(struct sock *sk)
        }
        tcp_conn = conn->dd_data;
 
+       /* save intimate cpu when in softirq */
+       if (!sock_owned_by_user_nocheck(sk)) {
+               current_cpu = smp_processor_id();
+               if (conn->xmitwork.intimate_cpu != current_cpu)
+                       conn->xmitwork.intimate_cpu = current_cpu;
+       }
+
        /*
         * Use rd_desc to pass 'conn' to iscsi_tcp_recv.
         * We set count to 1 because we want the network layer to
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index ebd47c0..3bbe326 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -87,9 +87,15 @@ inline void iscsi_conn_queue_work(struct iscsi_conn *conn)
 {
        struct Scsi_Host *shost = conn->session->host;
        struct iscsi_host *ihost = shost_priv(shost);
+       int intimate_cpu = conn->xmitwork.intimate_cpu;
 
-       if (ihost->workq)
-               queue_work(ihost->workq, &conn->xmitwork);
+       if (ihost->workq) {
+               /* we expect it to be excuted on the same numa of the intimate 
cpu */
+               if ((intimate_cpu >= 0) && cpu_possible(intimate_cpu))
+                       queue_work_on(intimate_cpu, ihost->workq, 
&conn->xmitwork);
+               else
+                       queue_work(ihost->workq, &conn->xmitwork);
+       }
 }
 EXPORT_SYMBOL_GPL(iscsi_conn_queue_work);
 
@@ -2627,7 +2633,7 @@ struct Scsi_Host *iscsi_host_alloc(struct 
scsi_host_template *sht,
        if (xmit_can_sleep) {
                snprintf(ihost->workq_name, sizeof(ihost->workq_name),
                        "iscsi_q_%d", shost->host_no);
-               ihost->workq = create_singlethread_workqueue(ihost->workq_name);
+               ihost->workq = 
create_singlethread_dynamic_workqueue(ihost->workq_name);
                if (!ihost->workq)
                        goto free_host;
        }
-- 
1.8.3.1


-- 
You received this message because you are subscribed to the Google Groups 
"open-iscsi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/open-iscsi/1563991180-11532-3-git-send-email-yebiaoxiang%40huawei.com.

Reply via email to