The mode aligns socket io jobs to RSS, receive/transmit jobs are scheduled at cpus which is mapped by RSS from rpc socket. Precondition is multiqueue device with enabled RSS and XPS.
If RSS and XPS are enabled, sockets are entirely localized to one cpu, they are not accessed from other cpus, which minimizes lock contention and keep perfect cache locality for socket data. Nevertheless, we have to pay, data, prepared by user at some cpu is forced to be accessed from rss cpu, which can be a problem, especially with NUMA. This has to be measured. When it does not work: 1. Single queue devices. It is not recommended to use such dumb hardware with vstorage. 2. RDMA. Yet not. It requires some experimenting to figure out how rdma completion jobs are scheduled. 3. IPsec without binding CSes to separate IP addresses. Signed-off-by: Alexey Kuznetsov <kuz...@acronis.com> --- fs/fuse/kio/pcs/pcs_rpc.c | 8 ++++++-- fs/fuse/kio/pcs/pcs_rpc.h | 3 +++ fs/fuse/kio/pcs/pcs_sock_io.c | 4 +++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/fs/fuse/kio/pcs/pcs_rpc.c b/fs/fuse/kio/pcs/pcs_rpc.c index 4fbb25d..2b045ed 100644 --- a/fs/fuse/kio/pcs/pcs_rpc.c +++ b/fs/fuse/kio/pcs/pcs_rpc.c @@ -36,7 +36,7 @@ #include "fuse_ktrace.h" -static unsigned int rpc_affinity_mode = RPC_AFFINITY_RETENT; +unsigned int rpc_affinity_mode = RPC_AFFINITY_RETENT; module_param(rpc_affinity_mode, uint, 0644); MODULE_PARM_DESC(rpc_affinity_mode, "RPC affinity mode"); @@ -730,6 +730,10 @@ static void pcs_rpc_affinity(struct pcs_rpc *ep, bool was_idle) ep->cpu = WORK_CPU_UNBOUND; } break; + case RPC_AFFINITY_RSS: + if (!(ep->flags & PCS_RPC_F_LOCAL) && ep->addr.type != PCS_ADDRTYPE_RDMA) + break; + fallthrough; case RPC_AFFINITY_RETENT: /* Naive socket-to-cpu binding approach */ if (time_is_before_jiffies(ep->cpu_stamp) && was_idle) { @@ -744,7 +748,7 @@ static void pcs_rpc_affinity(struct pcs_rpc *ep, bool was_idle) } break; default: - pr_err("Unknown affninity mode: %u\n", rpc_affinity_mode); + pr_err("Unknown affinity mode: %u\n", rpc_affinity_mode); } } diff --git a/fs/fuse/kio/pcs/pcs_rpc.h b/fs/fuse/kio/pcs/pcs_rpc.h index 2ff4494..ef4ab26 100644 --- a/fs/fuse/kio/pcs/pcs_rpc.h +++ b/fs/fuse/kio/pcs/pcs_rpc.h @@ -39,8 +39,11 @@ enum { RPC_AFFINITY_NONE = 0, RPC_AFFINITY_RETENT = 1, RPC_AFFINITY_SPREAD = 2, + RPC_AFFINITY_RSS = 3, }; +extern unsigned int rpc_affinity_mode; + struct pcs_rpc_params { unsigned int alloc_hdr_size; diff --git a/fs/fuse/kio/pcs/pcs_sock_io.c b/fs/fuse/kio/pcs/pcs_sock_io.c index fc76e32..46de102 100644 --- a/fs/fuse/kio/pcs/pcs_sock_io.c +++ b/fs/fuse/kio/pcs/pcs_sock_io.c @@ -548,7 +548,9 @@ static void pcs_sk_kick_queue(struct sock *sk) sio = rcu_dereference_sk_user_data(sk); if (sio) { struct pcs_rpc *ep = sio->netio.parent; - TRACE(PEER_FMT" queue\n", PEER_ARGS(ep)); + TRACE(PEER_FMT" queue cpu=%d\n", PEER_ARGS(ep), smp_processor_id()); + if (rpc_affinity_mode == RPC_AFFINITY_RSS && !(ep->flags & PCS_RPC_F_LOCAL)) + ep->cpu = smp_processor_id(); pcs_rpc_kick_queue(ep); } rcu_read_unlock(); -- 1.8.3.1 _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel