From: Tom Herbert <tom@herbertland.com>
To: netdev@vger.kernel.org
Cc: Tom Herbert <tom@herbertland.com>
Subject: [RFC PATCH 10/11] ptq: Hook up receive side of Per Queue Threads
Date: Wed, 24 Jun 2020 10:17:49 -0700 [thread overview]
Message-ID: <20200624171749.11927-11-tom@herbertland.com> (raw)
In-Reply-To: <20200624171749.11927-1-tom@herbertland.com>
Add code to set the queue in an rflow as opposed to just setting the
CPU in an rps_dev_flow entry. set_rps_qid is the analogue for
set_rps_cpu but for setting queues. In get_rps_cpu, a check is
performed that identifier in the sock_flow_table refers to a queue;
when it does call set_rps_qid after converting the global qid in the
sock_flow_table to a device qid.
In rps_record_sock_flow check is there is a per task receive queue
for current (i.e. current->ptq_queues.rxq_id != NO_QUEUE). If there
is a queue then set in sock_flow_table instead of setting the running
CPU. Subsequently, the receive queue for the flow can be programmed
by aRFS logic (ndo_rx_flow_steer).
---
include/linux/netdevice.h | 28 ++++++++++++++++++++++++----
net/core/dev.c | 36 ++++++++++++++++++++++++++++++++++++
2 files changed, 60 insertions(+), 4 deletions(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index ca163925211a..3b39be470720 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -731,12 +731,25 @@ static inline void rps_dev_flow_set_cpu(struct rps_dev_flow *dev_flow, u16 cpu)
if (WARN_ON(cpu > RPS_MAX_CPU))
return;
- /* Set the rflow target to the CPU atomically */
+ /* Set the device flow target to the CPU atomically */
cpu_qid.use_qid = 0;
cpu_qid.cpu = cpu;
dev_flow->cpu_qid = cpu_qid;
}
+static inline void rps_dev_flow_set_qid(struct rps_dev_flow *dev_flow, u16 qid)
+{
+ struct rps_cpu_qid cpu_qid;
+
+ if (WARN_ON(qid > RPS_MAX_QID))
+ return;
+
+ /* Set the device flow target to the CPU atomically */
+ cpu_qid.use_qid = 1;
+ cpu_qid.qid = qid;
+ dev_flow->cpu_qid = cpu_qid;
+}
+
/*
* The rps_dev_flow_table structure contains a table of flow mappings.
*/
@@ -797,11 +810,18 @@ static inline void rps_record_sock_flow(struct rps_sock_flow_table *table,
u32 hash)
{
if (table && hash) {
- u32 val = hash & table->cpu_masks.hash_mask;
unsigned int index = hash & table->mask;
+ u32 val;
- /* We only give a hint, preemption can change CPU under us */
- val |= raw_smp_processor_id();
+#ifdef CONFIG_PER_THREAD_QUEUES
+ if (current->ptq_queues.rxq_id != NO_QUEUE)
+ val = RPS_SOCK_FLOW_USE_QID |
+ (hash & table->queue_masks.hash_mask) |
+ current->ptq_queues.rxq_id;
+ else
+#endif
+ val = (hash & table->cpu_masks.hash_mask) |
+ raw_smp_processor_id();
if (table->ents[index] != val)
table->ents[index] = val;
diff --git a/net/core/dev.c b/net/core/dev.c
index f4478c9b1c9c..1cad776e8847 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -4308,6 +4308,25 @@ set_rps_cpu(struct net_device *dev, struct sk_buff *skb,
return rflow;
}
+static struct rps_dev_flow *
+set_rps_qid(struct net_device *dev, struct sk_buff *skb,
+ struct rps_dev_flow *rflow, u16 qid)
+{
+ if (qid > RPS_MAX_QID) {
+ rps_dev_flow_clear(rflow);
+ return rflow;
+ }
+
+#ifdef CONFIG_RFS_ACCEL
+ /* Should we steer this flow to a different hardware queue? */
+ if (skb_rx_queue_recorded(skb) && (dev->features & NETIF_F_NTUPLE) &&
+ qid != skb_get_rx_queue(skb) && qid < dev->real_num_rx_queues)
+ set_arfs_queue(dev, skb, rflow, qid);
+#endif
+ rps_dev_flow_set_qid(rflow, qid);
+ return rflow;
+}
+
/*
* get_rps_cpu is called from netif_receive_skb and returns the target
* CPU from the RPS map of the receiving queue for a given skb.
@@ -4356,6 +4375,10 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb,
/* First check into global flow table if there is a match */
ident = sock_flow_table->ents[hash & sock_flow_table->mask];
+
+ if (ident == RPS_SOCK_FLOW_NO_IDENT)
+ goto try_rps;
+
comparator = ((ident & RPS_SOCK_FLOW_USE_QID) ?
sock_flow_table->queue_masks.hash_mask :
sock_flow_table->cpu_masks.hash_mask);
@@ -4372,8 +4395,21 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb,
* CPU. Proceed accordingly.
*/
if (ident & RPS_SOCK_FLOW_USE_QID) {
+ u16 dqid, gqid;
+
/* A queue identifier is in the sock_flow_table entry */
+ gqid = ident & sock_flow_table->queue_masks.mask;
+ dqid = netdev_rx_gqid_to_dqid(dev, gqid);
+
+ /* rflow has desired receive qid. Just set the qid in
+ * HW and return to use current CPU. Note that we
+ * don't consider OOO in this case.
+ */
+ rflow = set_rps_qid(dev, skb, rflow, dqid);
+
+ *rflowp = rflow;
+
/* Don't use aRFS to set CPU in this case, skip to
* trying RPS
*/
--
2.25.1
next prev parent reply other threads:[~2020-06-24 17:19 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-06-24 17:17 [RFC PATCH 00/11] ptq: Per Thread Queues Tom Herbert
2020-06-24 17:17 ` [RFC PATCH 01/11] cgroup: Export cgroup_{procs,threads}_start and cgroup_procs_next Tom Herbert
2020-06-24 17:17 ` [RFC PATCH 02/11] net: Create netqueue.h and define NO_QUEUE Tom Herbert
2020-06-24 17:17 ` [RFC PATCH 03/11] arfs: Create set_arfs_queue Tom Herbert
2020-06-24 17:17 ` [RFC PATCH 04/11] net-sysfs: Create rps_create_sock_flow_table Tom Herbert
2020-06-24 17:17 ` [RFC PATCH 05/11] net: Infrastructure for per queue aRFS Tom Herbert
2020-06-28 8:55 ` kernel test robot
2020-06-24 17:17 ` [RFC PATCH 06/11] net: Function to check against maximum number for RPS queues Tom Herbert
2020-06-24 17:17 ` [RFC PATCH 07/11] net: Introduce global queues Tom Herbert
2020-06-24 23:00 ` kernel test robot
2020-06-24 23:58 ` kernel test robot
2020-06-25 0:23 ` kernel test robot
2020-06-30 21:06 ` Jonathan Lemon
2020-06-24 17:17 ` [RFC PATCH 08/11] ptq: Per Thread Queues Tom Herbert
2020-06-24 21:20 ` kernel test robot
2020-06-25 1:50 ` [RFC PATCH] ptq: null_pcdesc can be static kernel test robot
2020-06-25 7:26 ` [RFC PATCH 08/11] ptq: Per Thread Queues kernel test robot
2020-06-24 17:17 ` [RFC PATCH 09/11] ptq: Hook up transmit side of Per Queue Threads Tom Herbert
2020-06-24 17:17 ` Tom Herbert [this message]
2020-06-24 17:17 ` [RFC PATCH 11/11] doc: Documentation for Per Thread Queues Tom Herbert
2020-06-25 2:20 ` kernel test robot
2020-06-25 23:00 ` Jacob Keller
2020-06-29 6:28 ` Saeed Mahameed
2020-06-29 15:10 ` Tom Herbert
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200624171749.11927-11-tom@herbertland.com \
--to=tom@herbertland.com \
--cc=netdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.