mirror of
https://github.com/openvswitch/ovs
synced 2025-08-31 06:15:47 +00:00
ofproto/bond: Implement bond megaflow using recirculation
Infrastructure to enable megaflow support for bond ports using recirculation. This patch adds the following features: * Generate RECIRC action when bond can benefit from recirculation. * Populate post recirculation rules in a hidden table. Currently table 254. * Uses post recirculation rules for bond rebalancing * A recirculation implementation in dpif-netdev. The goal of this patch is to be able to megaflow bond outputs and thus greatly improve performance. However, this patch does not actually improve the megaflow generation. It is left for a later commit. Signed-off-by: Andy Zhou <azhou@nicira.com> Acked-by: Ben Pfaff <blp@nicira.com>
This commit is contained in:
@@ -68,6 +68,9 @@ VLOG_DEFINE_THIS_MODULE(dpif_netdev);
|
||||
#define NETDEV_RULE_PRIORITY 0x8000
|
||||
|
||||
#define NR_THREADS 1
|
||||
/* Use per thread recirc_depth to prevent recirculation loop. */
|
||||
#define MAX_RECIRC_DEPTH 5
|
||||
DEFINE_STATIC_PER_THREAD_DATA(uint32_t, recirc_depth, 0)
|
||||
|
||||
/* Configuration parameters. */
|
||||
enum { MAX_FLOWS = 65536 }; /* Maximum number of flows in flow table. */
|
||||
@@ -1997,8 +2000,9 @@ dp_netdev_count_packet(struct dp_netdev *dp, enum dp_stat_type type)
|
||||
}
|
||||
|
||||
static void
|
||||
dp_netdev_port_input(struct dp_netdev *dp, struct ofpbuf *packet,
|
||||
struct pkt_metadata *md)
|
||||
dp_netdev_input(struct dp_netdev *dp, struct ofpbuf *packet,
|
||||
struct pkt_metadata *md)
|
||||
OVS_REQ_RDLOCK(dp->port_rwlock)
|
||||
{
|
||||
struct dp_netdev_flow *netdev_flow;
|
||||
struct flow key;
|
||||
@@ -2027,6 +2031,17 @@ dp_netdev_port_input(struct dp_netdev *dp, struct ofpbuf *packet,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dp_netdev_port_input(struct dp_netdev *dp, struct ofpbuf *packet,
|
||||
struct pkt_metadata *md)
|
||||
OVS_REQ_RDLOCK(dp->port_rwlock)
|
||||
{
|
||||
uint32_t *recirc_depth = recirc_depth_get();
|
||||
|
||||
*recirc_depth = 0;
|
||||
dp_netdev_input(dp, packet, md);
|
||||
}
|
||||
|
||||
static int
|
||||
dp_netdev_output_userspace(struct dp_netdev *dp, struct ofpbuf *packet,
|
||||
int queue_no, int type, const struct flow *flow,
|
||||
@@ -2096,6 +2111,7 @@ dp_execute_cb(void *aux_, struct ofpbuf *packet,
|
||||
struct dp_netdev_execute_aux *aux = aux_;
|
||||
int type = nl_attr_type(a);
|
||||
struct dp_netdev_port *p;
|
||||
uint32_t *depth = recirc_depth_get();
|
||||
|
||||
switch ((enum ovs_action_attr)type) {
|
||||
case OVS_ACTION_ATTR_OUTPUT:
|
||||
@@ -2122,23 +2138,40 @@ dp_execute_cb(void *aux_, struct ofpbuf *packet,
|
||||
break;
|
||||
}
|
||||
|
||||
case OVS_ACTION_ATTR_RECIRC: {
|
||||
const struct ovs_action_recirc *act;
|
||||
case OVS_ACTION_ATTR_RECIRC:
|
||||
if (*depth < MAX_RECIRC_DEPTH) {
|
||||
uint32_t old_recirc_id = md->recirc_id;
|
||||
uint32_t old_dp_hash = md->dp_hash;
|
||||
const struct ovs_action_recirc *act;
|
||||
struct ofpbuf *recirc_packet;
|
||||
|
||||
act = nl_attr_get(a);
|
||||
md->recirc_id = act->recirc_id;
|
||||
md->dp_hash = 0;
|
||||
recirc_packet = may_steal ? packet : ofpbuf_clone(packet);
|
||||
|
||||
if (act->hash_alg == OVS_RECIRC_HASH_ALG_L4) {
|
||||
struct flow flow;
|
||||
act = nl_attr_get(a);
|
||||
md->recirc_id = act->recirc_id;
|
||||
md->dp_hash = 0;
|
||||
|
||||
flow_extract(packet, md, &flow);
|
||||
md->dp_hash = flow_hash_symmetric_l4(&flow, act->hash_bias);
|
||||
if (act->hash_alg == OVS_RECIRC_HASH_ALG_L4) {
|
||||
struct flow flow;
|
||||
|
||||
flow_extract(recirc_packet, md, &flow);
|
||||
md->dp_hash = flow_hash_symmetric_l4(&flow, act->hash_bias);
|
||||
if (!md->dp_hash) {
|
||||
md->dp_hash = 1; /* 0 is not valid */
|
||||
}
|
||||
}
|
||||
|
||||
(*depth)++;
|
||||
dp_netdev_input(aux->dp, recirc_packet, md);
|
||||
(*depth)--;
|
||||
|
||||
md->recirc_id = old_recirc_id;
|
||||
md->recirc_id = old_dp_hash;
|
||||
break;
|
||||
} else {
|
||||
VLOG_WARN("Packet dropped. Max recirculation depth exceeded.");
|
||||
}
|
||||
|
||||
dp_netdev_port_input(aux->dp, packet, md);
|
||||
break;
|
||||
}
|
||||
|
||||
case OVS_ACTION_ATTR_PUSH_VLAN:
|
||||
case OVS_ACTION_ATTR_POP_VLAN:
|
||||
@@ -2150,7 +2183,6 @@ dp_execute_cb(void *aux_, struct ofpbuf *packet,
|
||||
case __OVS_ACTION_ATTR_MAX:
|
||||
OVS_NOT_REACHED();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
|
Reference in New Issue
Block a user