aboutsummaryrefslogtreecommitdiffstats
path: root/net/openvswitch
diff options
context:
space:
mode:
authorTonghao Zhang <xiangxia.m.yue@gmail.com>2017-06-29 20:27:44 -0400
committerDavid S. Miller <davem@davemloft.net>2017-07-01 12:09:59 -0400
commit9cc9a5cb176ccb4f2cda5ac34da5a659926f125f (patch)
tree3fd2e4ecc9d5c9ef188ee1c85e25234bcde82a28 /net/openvswitch
parent7e5988df26cdd7d823ab473ad3e3ca6623a66f21 (diff)
datapath: Avoid using stack larger than 1024.
When compiling OvS-master on 4.4.0-81 kernel, there is a warning: CC [M] /root/ovs/datapath/linux/datapath.o /root/ovs/datapath/linux/datapath.c: In function 'ovs_flow_cmd_set': /root/ovs/datapath/linux/datapath.c:1221:1: warning: the frame size of 1040 bytes is larger than 1024 bytes [-Wframe-larger-than=] This patch factors out match-init and action-copy to avoid "Wframe-larger-than=1024" warning. Because mask is only used to get actions, we new a function to save some stack space. Signed-off-by: Tonghao Zhang <xiangxia.m.yue@gmail.com> Acked-by: Pravin B Shelar <pshelar@ovn.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/openvswitch')
-rw-r--r--net/openvswitch/datapath.c81
1 files changed, 58 insertions, 23 deletions
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index d772e9a4b4f8..45fe8c8a884d 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -1090,6 +1090,58 @@ static struct sw_flow_actions *get_flow_actions(struct net *net,
1090 return acts; 1090 return acts;
1091} 1091}
1092 1092
1093/* Factor out match-init and action-copy to avoid
1094 * "Wframe-larger-than=1024" warning. Because mask is only
1095 * used to get actions, we new a function to save some
1096 * stack space.
1097 *
1098 * If there are not key and action attrs, we return 0
1099 * directly. In the case, the caller will also not use the
1100 * match as before. If there is action attr, we try to get
1101 * actions and save them to *acts. Before returning from
1102 * the function, we reset the match->mask pointer. Because
1103 * we should not to return match object with dangling reference
1104 * to mask.
1105 * */
1106static int ovs_nla_init_match_and_action(struct net *net,
1107 struct sw_flow_match *match,
1108 struct sw_flow_key *key,
1109 struct nlattr **a,
1110 struct sw_flow_actions **acts,
1111 bool log)
1112{
1113 struct sw_flow_mask mask;
1114 int error = 0;
1115
1116 if (a[OVS_FLOW_ATTR_KEY]) {
1117 ovs_match_init(match, key, true, &mask);
1118 error = ovs_nla_get_match(net, match, a[OVS_FLOW_ATTR_KEY],
1119 a[OVS_FLOW_ATTR_MASK], log);
1120 if (error)
1121 goto error;
1122 }
1123
1124 if (a[OVS_FLOW_ATTR_ACTIONS]) {
1125 if (!a[OVS_FLOW_ATTR_KEY]) {
1126 OVS_NLERR(log,
1127 "Flow key attribute not present in set flow.");
1128 return -EINVAL;
1129 }
1130
1131 *acts = get_flow_actions(net, a[OVS_FLOW_ATTR_ACTIONS], key,
1132 &mask, log);
1133 if (IS_ERR(*acts)) {
1134 error = PTR_ERR(*acts);
1135 goto error;
1136 }
1137 }
1138
1139 /* On success, error is 0. */
1140error:
1141 match->mask = NULL;
1142 return error;
1143}
1144
1093static int ovs_flow_cmd_set(struct sk_buff *skb, struct genl_info *info) 1145static int ovs_flow_cmd_set(struct sk_buff *skb, struct genl_info *info)
1094{ 1146{
1095 struct net *net = sock_net(skb->sk); 1147 struct net *net = sock_net(skb->sk);
@@ -1097,7 +1149,6 @@ static int ovs_flow_cmd_set(struct sk_buff *skb, struct genl_info *info)
1097 struct ovs_header *ovs_header = info->userhdr; 1149 struct ovs_header *ovs_header = info->userhdr;
1098 struct sw_flow_key key; 1150 struct sw_flow_key key;
1099 struct sw_flow *flow; 1151 struct sw_flow *flow;
1100 struct sw_flow_mask mask;
1101 struct sk_buff *reply = NULL; 1152 struct sk_buff *reply = NULL;
1102 struct datapath *dp; 1153 struct datapath *dp;
1103 struct sw_flow_actions *old_acts = NULL, *acts = NULL; 1154 struct sw_flow_actions *old_acts = NULL, *acts = NULL;
@@ -1109,34 +1160,18 @@ static int ovs_flow_cmd_set(struct sk_buff *skb, struct genl_info *info)
1109 bool ufid_present; 1160 bool ufid_present;
1110 1161
1111 ufid_present = ovs_nla_get_ufid(&sfid, a[OVS_FLOW_ATTR_UFID], log); 1162 ufid_present = ovs_nla_get_ufid(&sfid, a[OVS_FLOW_ATTR_UFID], log);
1112 if (a[OVS_FLOW_ATTR_KEY]) { 1163 if (!a[OVS_FLOW_ATTR_KEY] && !ufid_present) {
1113 ovs_match_init(&match, &key, true, &mask);
1114 error = ovs_nla_get_match(net, &match, a[OVS_FLOW_ATTR_KEY],
1115 a[OVS_FLOW_ATTR_MASK], log);
1116 } else if (!ufid_present) {
1117 OVS_NLERR(log, 1164 OVS_NLERR(log,
1118 "Flow set message rejected, Key attribute missing."); 1165 "Flow set message rejected, Key attribute missing.");
1119 error = -EINVAL; 1166 return -EINVAL;
1120 } 1167 }
1168
1169 error = ovs_nla_init_match_and_action(net, &match, &key, a,
1170 &acts, log);
1121 if (error) 1171 if (error)
1122 goto error; 1172 goto error;
1123 1173
1124 /* Validate actions. */ 1174 if (acts) {
1125 if (a[OVS_FLOW_ATTR_ACTIONS]) {
1126 if (!a[OVS_FLOW_ATTR_KEY]) {
1127 OVS_NLERR(log,
1128 "Flow key attribute not present in set flow.");
1129 error = -EINVAL;
1130 goto error;
1131 }
1132
1133 acts = get_flow_actions(net, a[OVS_FLOW_ATTR_ACTIONS], &key,
1134 &mask, log);
1135 if (IS_ERR(acts)) {
1136 error = PTR_ERR(acts);
1137 goto error;
1138 }
1139
1140 /* Can allocate before locking if have acts. */ 1175 /* Can allocate before locking if have acts. */
1141 reply = ovs_flow_cmd_alloc_info(acts, &sfid, info, false, 1176 reply = ovs_flow_cmd_alloc_info(acts, &sfid, info, false,
1142 ufid_flags); 1177 ufid_flags);