提交 32ae87ff 编写于 作者: A Andy Zhou 提交者: Pravin B Shelar

openvswitch: simplify sample action implementation

The current sample() function implementation is more complicated
than necessary in handling single user space action optimization
and skb reference counting. There is no functional changes.
Signed-off-by: NAndy Zhou <azhou@nicira.com>
Signed-off-by: NPravin B Shelar <pshelar@nicira.com>
上级 8c8b1b83
...@@ -448,7 +448,6 @@ static int sample(struct datapath *dp, struct sk_buff *skb, ...@@ -448,7 +448,6 @@ static int sample(struct datapath *dp, struct sk_buff *skb,
{ {
const struct nlattr *acts_list = NULL; const struct nlattr *acts_list = NULL;
const struct nlattr *a; const struct nlattr *a;
struct sk_buff *sample_skb;
int rem; int rem;
for (a = nla_data(attr), rem = nla_len(attr); rem > 0; for (a = nla_data(attr), rem = nla_len(attr); rem > 0;
...@@ -468,31 +467,26 @@ static int sample(struct datapath *dp, struct sk_buff *skb, ...@@ -468,31 +467,26 @@ static int sample(struct datapath *dp, struct sk_buff *skb,
rem = nla_len(acts_list); rem = nla_len(acts_list);
a = nla_data(acts_list); a = nla_data(acts_list);
/* Actions list is either empty or only contains a single user-space /* Actions list is empty, do nothing */
* action, the latter being a special case as it is the only known if (unlikely(!rem))
* usage of the sample action.
* In these special cases don't clone the skb as there are no
* side-effects in the nested actions.
* Otherwise, clone in case the nested actions have side effects.
*/
if (likely(rem == 0 || (nla_type(a) == OVS_ACTION_ATTR_USERSPACE &&
last_action(a, rem)))) {
sample_skb = skb;
skb_get(skb);
} else {
sample_skb = skb_clone(skb, GFP_ATOMIC);
if (!sample_skb) /* Skip sample action when out of memory. */
return 0; return 0;
}
/* Note that do_execute_actions() never consumes skb. /* The only known usage of sample action is having a single user-space
* In the case where skb has been cloned above it is the clone that * action. Treat this usage as a special case.
* is consumed. Otherwise the skb_get(skb) call prevents * The output_userspace() should clone the skb to be sent to the
* consumption by do_execute_actions(). Thus, it is safe to simply * user space. This skb will be consumed by its caller.
* return the error code and let the caller (also
* do_execute_actions()) free skb on error.
*/ */
return do_execute_actions(dp, sample_skb, key, a, rem); if (likely(nla_type(a) == OVS_ACTION_ATTR_USERSPACE &&
last_action(a, rem)))
return output_userspace(dp, skb, key, a);
skb = skb_clone(skb, GFP_ATOMIC);
if (!skb)
/* Skip the sample action when out of memory. */
return 0;
/* do_execute_actions() will consume the cloned skb. */
return do_execute_actions(dp, skb, key, a, rem);
} }
static int execute_set_action(struct sk_buff *skb, static int execute_set_action(struct sk_buff *skb,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册