Skip to content

Commit

Permalink
ofproto-dpif-xlate: Make xlate_actions() caller supply action buffer.
Browse files Browse the repository at this point in the history
Until now, struct xlate_out has embedded an ofpbuf for actions and a large
stub for it, which xlate_actions() filled in during the flow translation
process.  This commit removes the embedded ofpbuf and stub, instead putting a
pointer to an ofpbuf into struct xlate_in, for a caller to fill in with a
pointer to its own structure if desired.  (If none is supplied,
xlate_actions() uses an internal scratch buffer and destroys it before
returning.)

This commit eliminates the last large data structure from
struct xlate_out, making the initialization of an entire xlate_out at
the beginning of xlate_actions() now reasonable.  More members will be
eliminated in upcoming commits, but this is no longer essential.

Signed-off-by: Ben Pfaff <[email protected]>
Acked-by: Jarno Rajahalme <[email protected]>
  • Loading branch information
blp committed Jul 31, 2015
1 parent 49a73e0 commit 1520ef4
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 86 deletions.
44 changes: 24 additions & 20 deletions ofproto/ofproto-dpif-upcall.c
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ struct upcall {

bool xout_initialized; /* True if 'xout' must be uninitialized. */
struct xlate_out xout; /* Result of xlate_actions(). */
struct ofpbuf odp_actions; /* Datapath actions from xlate_actions(). */
struct flow_wildcards wc; /* Dependencies that megaflow must match. */
struct ofpbuf put_actions; /* Actions 'put' in the fastpath. */

Expand All @@ -190,6 +191,8 @@ struct upcall {
const struct nlattr *key; /* Datapath flow key. */
size_t key_len; /* Datapath flow key length. */
const struct nlattr *out_tun_key; /* Datapath output tunnel key. */

uint64_t odp_actions_stub[1024 / 8]; /* Stub for odp_actions. */
};

/* 'udpif_key's are responsible for tracking the little bit of state udpif
Expand Down Expand Up @@ -706,7 +709,8 @@ recv_upcalls(struct handler *handler)
pkt_metadata_from_flow(&dupcall->packet.md, flow);
flow_extract(&dupcall->packet, flow);

error = process_upcall(udpif, upcall, NULL, &upcall->wc);
error = process_upcall(udpif, upcall,
&upcall->odp_actions, &upcall->wc);
if (error) {
goto cleanup;
}
Expand Down Expand Up @@ -927,6 +931,8 @@ upcall_receive(struct upcall *upcall, const struct dpif_backer *backer,
upcall->pmd_id = pmd_id;
upcall->type = type;
upcall->userdata = userdata;
ofpbuf_use_stub(&upcall->odp_actions, upcall->odp_actions_stub,
sizeof upcall->odp_actions_stub);
ofpbuf_init(&upcall->put_actions, 0);

upcall->xout_initialized = false;
Expand Down Expand Up @@ -956,8 +962,7 @@ upcall_xlate(struct udpif *udpif, struct upcall *upcall,
stats.tcp_flags = ntohs(upcall->flow->tcp_flags);

xlate_in_init(&xin, upcall->ofproto, upcall->flow, upcall->in_port, NULL,
stats.tcp_flags, upcall->packet, wc);
xin.odp_actions = odp_actions;
stats.tcp_flags, upcall->packet, wc, odp_actions);

if (upcall->type == DPIF_UC_MISS) {
xin.resubmit_stats = &stats;
Expand Down Expand Up @@ -1011,8 +1016,7 @@ upcall_xlate(struct udpif *udpif, struct upcall *upcall,

if (!upcall->xout.slow) {
ofpbuf_use_const(&upcall->put_actions,
upcall->xout.odp_actions->data,
upcall->xout.odp_actions->size);
odp_actions->data, odp_actions->size);
} else {
ofpbuf_init(&upcall->put_actions, 0);
compose_slow_path(udpif, &upcall->xout, upcall->flow,
Expand All @@ -1035,6 +1039,7 @@ upcall_uninit(struct upcall *upcall)
if (upcall->xout_initialized) {
xlate_out_uninit(&upcall->xout);
}
ofpbuf_uninit(&upcall->odp_actions);
ofpbuf_uninit(&upcall->put_actions);
if (upcall->ukey) {
if (!upcall->ukey_persists) {
Expand Down Expand Up @@ -1234,7 +1239,7 @@ handle_upcalls(struct udpif *udpif, struct upcall *upcalls,
* actions were composed assuming that the packet contained no
* VLAN. So, we must remove the VLAN header from the packet before
* trying to execute the actions. */
if (upcall->xout.odp_actions->size) {
if (upcall->odp_actions.size) {
eth_pop_vlan(CONST_CAST(struct dp_packet *, upcall->packet));
}

Expand Down Expand Up @@ -1272,15 +1277,15 @@ handle_upcalls(struct udpif *udpif, struct upcall *upcalls,
op->dop.u.flow_put.actions_len = ukey->actions->size;
}

if (upcall->xout.odp_actions->size) {
if (upcall->odp_actions.size) {
op = &ops[n_ops++];
op->ukey = NULL;
op->dop.type = DPIF_OP_EXECUTE;
op->dop.u.execute.packet = CONST_CAST(struct dp_packet *, packet);
odp_key_to_pkt_metadata(upcall->key, upcall->key_len,
&op->dop.u.execute.packet->md);
op->dop.u.execute.actions = upcall->xout.odp_actions->data;
op->dop.u.execute.actions_len = upcall->xout.odp_actions->size;
op->dop.u.execute.actions = upcall->odp_actions.data;
op->dop.u.execute.actions_len = upcall->odp_actions.size;
op->dop.u.execute.needs_help = (upcall->xout.slow & SLOW_ACTION) != 0;
op->dop.u.execute.probe = false;
}
Expand Down Expand Up @@ -1663,12 +1668,13 @@ revalidate_ukey(struct udpif *udpif, struct udpif_key *ukey,
const struct dpif_flow_stats *stats, uint64_t reval_seq)
OVS_REQUIRES(ukey->mutex)
{
uint64_t slow_path_buf[128 / 8];
uint64_t odp_actions_stub[1024 / 8];
struct ofpbuf odp_actions = OFPBUF_STUB_INITIALIZER(odp_actions_stub);

struct xlate_out xout, *xoutp;
struct netflow *netflow;
struct ofproto_dpif *ofproto;
struct dpif_flow_stats push;
struct ofpbuf xout_actions;
struct flow flow, dp_mask;
struct flow_wildcards wc;
uint64_t *dp64, *xout64;
Expand Down Expand Up @@ -1733,7 +1739,7 @@ revalidate_ukey(struct udpif *udpif, struct udpif_key *ukey,
}

xlate_in_init(&xin, ofproto, &flow, ofp_in_port, NULL, push.tcp_flags,
NULL, need_revalidate ? &wc : NULL);
NULL, need_revalidate ? &wc : NULL, &odp_actions);
if (push.n_packets) {
xin.resubmit_stats = &push;
xin.may_learn = true;
Expand All @@ -1747,16 +1753,13 @@ revalidate_ukey(struct udpif *udpif, struct udpif_key *ukey,
goto exit;
}

if (!xout.slow) {
ofpbuf_use_const(&xout_actions, xout.odp_actions->data,
xout.odp_actions->size);
} else {
ofpbuf_use_stack(&xout_actions, slow_path_buf, sizeof slow_path_buf);
if (xout.slow) {
ofpbuf_clear(&odp_actions);
compose_slow_path(udpif, &xout, &flow, flow.in_port.odp_port,
&xout_actions);
&odp_actions);
}

if (!ofpbuf_equal(&xout_actions, ukey->actions)) {
if (!ofpbuf_equal(&odp_actions, ukey->actions)) {
goto exit;
}

Expand Down Expand Up @@ -1788,6 +1791,7 @@ revalidate_ukey(struct udpif *udpif, struct udpif_key *ukey,
netflow_flow_clear(netflow, &flow);
}
xlate_out_uninit(xoutp);
ofpbuf_uninit(&odp_actions);
return ok;
}

Expand Down Expand Up @@ -1880,7 +1884,7 @@ push_ukey_ops__(struct udpif *udpif, struct ukey_op *ops, size_t n_ops)
struct xlate_in xin;

xlate_in_init(&xin, ofproto, &flow, ofp_in_port, NULL,
push->tcp_flags, NULL, NULL);
push->tcp_flags, NULL, NULL, NULL);
xin.resubmit_stats = push->n_packets ? push : NULL;
xin.may_learn = push->n_packets > 0;
xlate_actions_for_side_effects(&xin);
Expand Down
Loading

0 comments on commit 1520ef4

Please sign in to comment.