[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20231011034344.104398-8-npiggin@gmail.com>
Date: Wed, 11 Oct 2023 13:43:44 +1000
From: Nicholas Piggin <npiggin@...il.com>
To: netdev@...r.kernel.org
Cc: Nicholas Piggin <npiggin@...il.com>,
dev@...nvswitch.org,
Pravin B Shelar <pshelar@....org>,
Aaron Conole <aconole@...hat.com>,
"Eelco Chaudron" <echaudro@...hat.com>,
"Ilya Maximets" <imaximet@...hat.com>,
"Flavio Leitner" <fbl@...hat.com>
Subject: [PATCH 7/7] net: openvswitch: Reduce stack usage in ovs_dp_process_packet
The upcall in ovs_dp_process_packet some stack and is not involved in
the recursive call. Move it out of line, reducing stack overhead of
ovs_dp_process_packet from 144 to 96 bytes.
Signed-off-by: Nicholas Piggin <npiggin@...il.com>
---
net/openvswitch/datapath.c | 56 ++++++++++++++++++++++----------------
1 file changed, 32 insertions(+), 24 deletions(-)
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index 11c69415c605..fdc24b1e9bbc 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -242,6 +242,37 @@ void ovs_dp_detach_port(struct vport *p)
ovs_vport_del(p);
}
+static noinline_for_stack
+void do_packet_upcall(struct sk_buff *skb, struct sw_flow_key *key,
+ const struct vport *p, struct datapath *dp)
+{
+ struct dp_upcall_info upcall;
+ int error;
+
+ memset(&upcall, 0, sizeof(upcall));
+ upcall.cmd = OVS_PACKET_CMD_MISS;
+
+ if (dp->user_features & OVS_DP_F_DISPATCH_UPCALL_PER_CPU)
+ upcall.portid =
+ ovs_dp_get_upcall_portid(dp, smp_processor_id());
+ else
+ upcall.portid = ovs_vport_find_upcall_portid(p, skb);
+
+ upcall.mru = OVS_CB(skb)->mru;
+ error = ovs_dp_upcall(dp, skb, key, &upcall, 0);
+ switch (error) {
+ case 0:
+ case -EAGAIN:
+ case -ERESTARTSYS:
+ case -EINTR:
+ consume_skb(skb);
+ break;
+ default:
+ kfree_skb(skb);
+ break;
+ }
+}
+
/* Must be called with rcu_read_lock. */
void ovs_dp_process_packet(struct sk_buff *skb, struct sw_flow_key *key)
{
@@ -261,30 +292,7 @@ void ovs_dp_process_packet(struct sk_buff *skb, struct sw_flow_key *key)
flow = ovs_flow_tbl_lookup_stats(&dp->table, key, skb_get_hash(skb),
&n_mask_hit, &n_cache_hit);
if (unlikely(!flow)) {
- struct dp_upcall_info upcall;
-
- memset(&upcall, 0, sizeof(upcall));
- upcall.cmd = OVS_PACKET_CMD_MISS;
-
- if (dp->user_features & OVS_DP_F_DISPATCH_UPCALL_PER_CPU)
- upcall.portid =
- ovs_dp_get_upcall_portid(dp, smp_processor_id());
- else
- upcall.portid = ovs_vport_find_upcall_portid(p, skb);
-
- upcall.mru = OVS_CB(skb)->mru;
- error = ovs_dp_upcall(dp, skb, key, &upcall, 0);
- switch (error) {
- case 0:
- case -EAGAIN:
- case -ERESTARTSYS:
- case -EINTR:
- consume_skb(skb);
- break;
- default:
- kfree_skb(skb);
- break;
- }
+ do_packet_upcall(skb, key, p, dp);
stats_counter = &stats->n_missed;
goto out;
}
--
2.42.0
Powered by blists - more mailing lists