mirror of
https://github.com/openvswitch/ovs
synced 2025-08-30 22:05:19 +00:00
tunnels: Don't initialize unnecessary packet metadata.
The addition of Geneve options to packet metadata significantly expanded its size. It was reported that this can decrease performance for DPDK ports by up to 25% since we need to initialize the whole structure on each packet receive. It is not really necessary to zero out the entire structure because miniflow_extract() only copies the tunnel metadata when particular fields indicate that it is valid. Therefore, as long as we zero out these fields when the metadata is initialized and ensure that the rest of the structure is correctly set in the presence of a tunnel, we can avoid touching the tunnel fields on packet reception. Reported-by: Ciara Loftus <ciara.loftus@intel.com> Tested-by: Ciara Loftus <ciara.loftus@intel.com> Signed-off-by: Jesse Gross <jesse@nicira.com> Acked-by: Ben Pfaff <blp@nicira.com>
This commit is contained in:
@@ -235,7 +235,7 @@ enum pmd_cycles_counter_type {
|
||||
|
||||
/* A port in a netdev-based datapath. */
|
||||
struct dp_netdev_port {
|
||||
struct pkt_metadata md;
|
||||
odp_port_t port_no;
|
||||
struct netdev *netdev;
|
||||
struct cmap_node node; /* Node in dp_netdev's 'ports'. */
|
||||
struct netdev_saved_flags *sf;
|
||||
@@ -1085,7 +1085,7 @@ do_add_port(struct dp_netdev *dp, const char *devname, const char *type,
|
||||
}
|
||||
}
|
||||
port = xzalloc(sizeof *port);
|
||||
port->md = PKT_METADATA_INITIALIZER(port_no);
|
||||
port->port_no = port_no;
|
||||
port->netdev = netdev;
|
||||
port->rxq = xmalloc(sizeof *port->rxq * netdev_n_rxq(netdev));
|
||||
port->type = xstrdup(type);
|
||||
@@ -1190,7 +1190,7 @@ dp_netdev_lookup_port(const struct dp_netdev *dp, odp_port_t port_no)
|
||||
struct dp_netdev_port *port;
|
||||
|
||||
CMAP_FOR_EACH_WITH_HASH (port, node, hash_port_no(port_no), &dp->ports) {
|
||||
if (port->md.in_port.odp_port == port_no) {
|
||||
if (port->port_no == port_no) {
|
||||
return port;
|
||||
}
|
||||
}
|
||||
@@ -1300,8 +1300,7 @@ static void
|
||||
do_del_port(struct dp_netdev *dp, struct dp_netdev_port *port)
|
||||
OVS_REQUIRES(dp->port_mutex)
|
||||
{
|
||||
cmap_remove(&dp->ports, &port->node,
|
||||
hash_odp_port(port->md.in_port.odp_port));
|
||||
cmap_remove(&dp->ports, &port->node, hash_odp_port(port->port_no));
|
||||
seq_change(dp->port_seq);
|
||||
if (netdev_is_pmd(port->netdev)) {
|
||||
int numa_id = netdev_get_numa_id(port->netdev);
|
||||
@@ -1323,7 +1322,7 @@ answer_port_query(const struct dp_netdev_port *port,
|
||||
{
|
||||
dpif_port->name = xstrdup(netdev_get_name(port->netdev));
|
||||
dpif_port->type = xstrdup(port->type);
|
||||
dpif_port->port_no = port->md.in_port.odp_port;
|
||||
dpif_port->port_no = port->port_no;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -1450,7 +1449,7 @@ dpif_netdev_port_dump_next(const struct dpif *dpif, void *state_,
|
||||
state->name = xstrdup(netdev_get_name(port->netdev));
|
||||
dpif_port->name = state->name;
|
||||
dpif_port->type = port->type;
|
||||
dpif_port->port_no = port->md.in_port.odp_port;
|
||||
dpif_port->port_no = port->port_no;
|
||||
|
||||
retval = 0;
|
||||
} else {
|
||||
@@ -2540,7 +2539,7 @@ dp_netdev_process_rxq_port(struct dp_netdev_pmd_thread *pmd,
|
||||
|
||||
/* XXX: initialize md in netdev implementation. */
|
||||
for (i = 0; i < cnt; i++) {
|
||||
packets[i]->md = port->md;
|
||||
pkt_metadata_init(&packets[i]->md, port->port_no);
|
||||
}
|
||||
cycles_count_start(pmd);
|
||||
dp_netdev_input(pmd, packets, cnt);
|
||||
@@ -3652,12 +3651,12 @@ dpif_dummy_change_port_number(struct unixctl_conn *conn, int argc OVS_UNUSED,
|
||||
}
|
||||
|
||||
/* Remove old port. */
|
||||
cmap_remove(&dp->ports, &old_port->node, hash_port_no(old_port->md.in_port.odp_port));
|
||||
cmap_remove(&dp->ports, &old_port->node, hash_port_no(old_port->port_no));
|
||||
ovsrcu_postpone(free, old_port);
|
||||
|
||||
/* Insert new port (cmap semantics mean we cannot re-insert 'old_port'). */
|
||||
new_port = xmemdup(old_port, sizeof *old_port);
|
||||
new_port->md.in_port.odp_port = port_no;
|
||||
new_port->port_no = port_no;
|
||||
cmap_insert(&dp->ports, &new_port->node, hash_port_no(port_no));
|
||||
|
||||
seq_change(dp->port_seq);
|
||||
@@ -3688,7 +3687,7 @@ dpif_dummy_delete_port(struct unixctl_conn *conn, int argc OVS_UNUSED,
|
||||
ovs_mutex_lock(&dp->port_mutex);
|
||||
if (get_port_by_name(dp, argv[2], &port)) {
|
||||
unixctl_command_reply_error(conn, "unknown port");
|
||||
} else if (port->md.in_port.odp_port == ODPP_LOCAL) {
|
||||
} else if (port->port_no == ODPP_LOCAL) {
|
||||
unixctl_command_reply_error(conn, "can't delete local port");
|
||||
} else {
|
||||
do_del_port(dp, port);
|
||||
|
Reference in New Issue
Block a user