&flow, &initial_tci,
upcall->packet);
if (fitness == ODP_FIT_ERROR) {
- ofpbuf_delete(upcall->packet);
continue;
}
flow_extract(upcall->packet, flow.skb_priority, flow.tun_id,
if (process_special(ofproto, &flow, upcall->packet)) {
ofproto_update_local_port_stats(&ofproto->up,
0, upcall->packet->size);
- ofpbuf_delete(upcall->packet);
ofproto->n_matches++;
continue;
}
}
}
HMAP_FOR_EACH_SAFE (miss, next_miss, hmap_node, &todo) {
- ofpbuf_list_delete(&miss->packets);
hmap_remove(&todo, &miss->hmap_node);
free(miss);
}
upcall->key_len, &flow,
&initial_tci, upcall->packet);
if (fitness == ODP_FIT_ERROR) {
- ofpbuf_delete(upcall->packet);
return;
}
} else {
VLOG_WARN_RL(&rl, "invalid user cookie : 0x%"PRIx64, upcall->userdata);
}
- ofpbuf_delete(upcall->packet);
}
static int
handle_upcalls(struct ofproto_dpif *ofproto, unsigned int max_batch)
{
struct dpif_upcall misses[FLOW_MISS_MAX_BATCH];
+ struct ofpbuf miss_bufs[FLOW_MISS_MAX_BATCH];
+ uint64_t miss_buf_stubs[FLOW_MISS_MAX_BATCH][4096 / 8];
+ int n_processed;
int n_misses;
int i;
- assert (max_batch <= FLOW_MISS_MAX_BATCH);
+ assert(max_batch <= FLOW_MISS_MAX_BATCH);
+ n_processed = 0;
n_misses = 0;
- for (i = 0; i < max_batch; i++) {
+ for (n_processed = 0; n_processed < max_batch; n_processed++) {
struct dpif_upcall *upcall = &misses[n_misses];
+ struct ofpbuf *buf = &miss_bufs[n_misses];
int error;
- error = dpif_recv(ofproto->dpif, upcall);
+ ofpbuf_use_stub(buf, miss_buf_stubs[n_misses],
+ sizeof miss_buf_stubs[n_misses]);
+ error = dpif_recv(ofproto->dpif, upcall, buf);
if (error) {
+ ofpbuf_uninit(buf);
break;
}
switch (upcall->type) {
case DPIF_UC_ACTION:
handle_userspace_upcall(ofproto, upcall);
+ ofpbuf_uninit(buf);
break;
case DPIF_UC_MISS:
}
handle_miss_upcalls(ofproto, misses, n_misses);
+ for (i = 0; i < n_misses; i++) {
+ ofpbuf_uninit(&miss_bufs[i]);
+ }
- return i;
+ return n_processed;
}
\f
/* Flow expiration. */