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 <npig...@gmail.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

_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to