2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-31 14:25:26 +00:00

ofproto-dpif-xlate: Take control of the qdscp map.

This will make locking easier in future patches.

Signed-off-by: Ethan Jackson <ethan@nicira.com>
Acked-by: Ben Pfaff <blp@nicira.com>
This commit is contained in:
Ethan Jackson
2013-07-06 10:25:06 -07:00
parent 9d189a50e6
commit 55954f6e14
4 changed files with 96 additions and 94 deletions

View File

@@ -114,6 +114,8 @@ struct xport {
enum ofputil_port_config config; /* OpenFlow port configuration. */
int stp_port_no; /* STP port number or 0 if not in use. */
struct hmap skb_priorities; /* Map of 'skb_priority_to_dscp's. */
bool may_enable; /* May be enabled in bonds. */
bool is_tunnel; /* Is a tunnel port. */
@@ -164,6 +166,16 @@ struct xlate_ctx {
* The bundle's name and vlan mode are initialized in lookup_input_bundle() */
static struct xbundle ofpp_none_bundle;
/* Node in 'xport''s 'skb_priorities' map. Used to maintain a map from
* 'priority' (the datapath's term for QoS queue) to the dscp bits which all
* traffic egressing the 'ofport' with that priority should be marked with. */
struct skb_priority_to_dscp {
struct hmap_node hmap_node; /* Node in 'ofport_dpif''s 'skb_priorities'. */
uint32_t skb_priority; /* Priority of this queue (see struct flow). */
uint8_t dscp; /* DSCP bits to mark outgoing traffic with. */
};
static struct hmap xbridges = HMAP_INITIALIZER(&xbridges);
static struct hmap xbundles = HMAP_INITIALIZER(&xbundles);
static struct hmap xports = HMAP_INITIALIZER(&xports);
@@ -187,6 +199,11 @@ static struct xbridge *xbridge_lookup(const struct ofproto_dpif *);
static struct xbundle *xbundle_lookup(const struct ofbundle *);
static struct xport *xport_lookup(struct ofport_dpif *);
static struct xport *get_ofp_port(const struct xbridge *, ofp_port_t ofp_port);
static struct skb_priority_to_dscp *get_skb_priority(const struct xport *,
uint32_t skb_priority);
static void clear_skb_priorities(struct xport *);
static bool dscp_from_skb_priority(const struct xport *, uint32_t skb_priority,
uint8_t *dscp);
void
xlate_ofproto_set(struct ofproto_dpif *ofproto, const char *name,
@@ -335,10 +352,12 @@ xlate_ofport_set(struct ofproto_dpif *ofproto, struct ofbundle *ofbundle,
odp_port_t odp_port, const struct netdev *netdev,
const struct cfm *cfm, const struct bfd *bfd,
struct ofport_dpif *peer, int stp_port_no,
const struct ofproto_port_queue *qdscp_list, size_t n_qdscp,
enum ofputil_port_config config, bool is_tunnel,
bool may_enable)
{
struct xport *xport = xport_lookup(ofport);
size_t i;
if (!xport) {
xport = xzalloc(sizeof *xport);
@@ -346,6 +365,7 @@ xlate_ofport_set(struct ofproto_dpif *ofproto, struct ofbundle *ofbundle,
xport->xbridge = xbridge_lookup(ofproto);
xport->ofp_port = ofp_port;
hmap_init(&xport->skb_priorities);
hmap_insert(&xports, &xport->hmap_node, hash_pointer(ofport, 0));
hmap_insert(&xport->xbridge->xports, &xport->ofp_node,
hash_ofp_port(xport->ofp_port));
@@ -389,6 +409,24 @@ xlate_ofport_set(struct ofproto_dpif *ofproto, struct ofbundle *ofbundle,
if (xport->xbundle) {
list_insert(&xport->xbundle->xports, &xport->bundle_node);
}
clear_skb_priorities(xport);
for (i = 0; i < n_qdscp; i++) {
struct skb_priority_to_dscp *pdscp;
uint32_t skb_priority;
if (ofproto_dpif_queue_to_priority(xport->xbridge->ofproto,
qdscp_list[i].queue,
&skb_priority)) {
continue;
}
pdscp = xmalloc(sizeof *pdscp);
pdscp->skb_priority = skb_priority;
pdscp->dscp = (qdscp_list[i].dscp << 2) & IP_DSCP_MASK;
hmap_insert(&xport->skb_priorities, &pdscp->hmap_node,
hash_int(pdscp->skb_priority, 0));
}
}
void
@@ -409,6 +447,9 @@ xlate_ofport_remove(struct ofport_dpif *ofport)
list_remove(&xport->bundle_node);
}
clear_skb_priorities(xport);
hmap_destroy(&xport->skb_priorities);
hmap_remove(&xports, &xport->hmap_node);
hmap_remove(&xport->xbridge->xports, &xport->ofp_node);
@@ -1362,8 +1403,7 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port,
flow_skb_mark = flow->skb_mark;
flow_nw_tos = flow->nw_tos;
if (ofproto_dpif_dscp_from_priority(xport->ofport, flow->skb_priority,
&dscp)) {
if (dscp_from_skb_priority(xport, flow->skb_priority, &dscp)) {
wc->masks.nw_tos |= IP_ECN_MASK;
flow->nw_tos &= ~IP_DSCP_MASK;
flow->nw_tos |= dscp;
@@ -2261,6 +2301,41 @@ xlate_out_copy(struct xlate_out *dst, const struct xlate_out *src)
src->odp_actions.size);
}
static struct skb_priority_to_dscp *
get_skb_priority(const struct xport *xport, uint32_t skb_priority)
{
struct skb_priority_to_dscp *pdscp;
uint32_t hash;
hash = hash_int(skb_priority, 0);
HMAP_FOR_EACH_IN_BUCKET (pdscp, hmap_node, hash, &xport->skb_priorities) {
if (pdscp->skb_priority == skb_priority) {
return pdscp;
}
}
return NULL;
}
static bool
dscp_from_skb_priority(const struct xport *xport, uint32_t skb_priority,
uint8_t *dscp)
{
struct skb_priority_to_dscp *pdscp = get_skb_priority(xport, skb_priority);
*dscp = pdscp ? pdscp->dscp : 0;
return pdscp != NULL;
}
static void
clear_skb_priorities(struct xport *xport)
{
struct skb_priority_to_dscp *pdscp, *next;
HMAP_FOR_EACH_SAFE (pdscp, next, hmap_node, &xport->skb_priorities) {
hmap_remove(&xport->skb_priorities, &pdscp->hmap_node);
free(pdscp);
}
}
static bool
actions_output_to_local_port(const struct xlate_ctx *ctx)
{

View File

@@ -127,8 +127,9 @@ void xlate_ofport_set(struct ofproto_dpif *, struct ofbundle *,
struct ofport_dpif *, ofp_port_t, odp_port_t,
const struct netdev *, const struct cfm *,
const struct bfd *, struct ofport_dpif *peer,
int stp_port_no, enum ofputil_port_config,
bool is_tunnel, bool may_enable);
int stp_port_no, const struct ofproto_port_queue *qdscp,
size_t n_qdscp, enum ofputil_port_config, bool is_tunnel,
bool may_enable);
void xlate_ofport_remove(struct ofport_dpif *);
void xlate_actions(struct xlate_in *, struct xlate_out *);

View File

@@ -298,7 +298,9 @@ struct ofport_dpif {
enum stp_state stp_state; /* Always STP_DISABLED if STP not in use. */
long long int stp_state_entered;
struct hmap priorities; /* Map of attached 'priority_to_dscp's. */
/* Queue to DSCP mapping. */
struct ofproto_port_queue *qdscp;
size_t n_qdscp;
/* Linux VLAN device support (e.g. "eth0.10" for VLAN 10.)
*
@@ -310,16 +312,6 @@ struct ofport_dpif {
int vlandev_vid;
};
/* Node in 'ofport_dpif''s 'priorities' map. Used to maintain a map from
* 'priority' (the datapath's term for QoS queue) to the dscp bits which all
* traffic egressing the 'ofport' with that priority should be marked with. */
struct priority_to_dscp {
struct hmap_node hmap_node; /* Node in 'ofport_dpif''s 'priorities' map. */
uint32_t priority; /* Priority of this queue (see struct flow). */
uint8_t dscp; /* DSCP bits to mark outgoing traffic with. */
};
/* Linux VLAN device support (e.g. "eth0.10" for VLAN 10.)
*
* This is deprecated. It is only for compatibility with broken device drivers
@@ -355,7 +347,6 @@ static void port_run_fast(struct ofport_dpif *);
static void port_wait(struct ofport_dpif *);
static int set_bfd(struct ofport *, const struct smap *);
static int set_cfm(struct ofport *, const struct cfm_settings *);
static void ofport_clear_priorities(struct ofport_dpif *);
static void ofport_update_peer(struct ofport_dpif *);
static void run_fast_rl(void);
@@ -794,6 +785,7 @@ type_run(const char *type)
ofport->up.ofp_port, ofport->odp_port,
ofport->up.netdev, ofport->cfm,
ofport->bfd, ofport->peer, stp_port,
ofport->qdscp, ofport->n_qdscp,
ofport->up.pp.config, ofport->is_tunnel,
ofport->may_enable);
}
@@ -1688,7 +1680,8 @@ port_construct(struct ofport *port_)
port->stp_state = STP_DISABLED;
port->is_tunnel = false;
port->peer = NULL;
hmap_init(&port->priorities);
port->qdscp = NULL;
port->n_qdscp = 0;
port->realdev_ofp_port = 0;
port->vlandev_vid = 0;
port->carrier_seq = netdev_get_carrier_resets(netdev);
@@ -1782,8 +1775,7 @@ port_destruct(struct ofport *port_)
dpif_sflow_del_port(ofproto->sflow, port->odp_port);
}
ofport_clear_priorities(port);
hmap_destroy(&port->priorities);
free(port->qdscp);
}
static void
@@ -2186,88 +2178,24 @@ ofproto_dpif_queue_to_priority(const struct ofproto_dpif *ofproto,
return dpif_queue_to_priority(ofproto->backer->dpif, queue_id, priority);
}
static struct priority_to_dscp *
get_priority(const struct ofport_dpif *ofport, uint32_t priority)
{
struct priority_to_dscp *pdscp;
uint32_t hash;
hash = hash_int(priority, 0);
HMAP_FOR_EACH_IN_BUCKET (pdscp, hmap_node, hash, &ofport->priorities) {
if (pdscp->priority == priority) {
return pdscp;
}
}
return NULL;
}
bool
ofproto_dpif_dscp_from_priority(const struct ofport_dpif *ofport,
uint32_t priority, uint8_t *dscp)
{
struct priority_to_dscp *pdscp = get_priority(ofport, priority);
*dscp = pdscp ? pdscp->dscp : 0;
return pdscp != NULL;
}
static void
ofport_clear_priorities(struct ofport_dpif *ofport)
{
struct priority_to_dscp *pdscp, *next;
HMAP_FOR_EACH_SAFE (pdscp, next, hmap_node, &ofport->priorities) {
hmap_remove(&ofport->priorities, &pdscp->hmap_node);
free(pdscp);
}
}
static int
set_queues(struct ofport *ofport_,
const struct ofproto_port_queue *qdscp_list,
set_queues(struct ofport *ofport_, const struct ofproto_port_queue *qdscp,
size_t n_qdscp)
{
struct ofport_dpif *ofport = ofport_dpif_cast(ofport_);
struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofport->up.ofproto);
struct hmap new = HMAP_INITIALIZER(&new);
size_t i;
for (i = 0; i < n_qdscp; i++) {
struct priority_to_dscp *pdscp;
uint32_t priority;
uint8_t dscp;
dscp = (qdscp_list[i].dscp << 2) & IP_DSCP_MASK;
if (dpif_queue_to_priority(ofproto->backer->dpif, qdscp_list[i].queue,
&priority)) {
continue;
}
pdscp = get_priority(ofport, priority);
if (pdscp) {
hmap_remove(&ofport->priorities, &pdscp->hmap_node);
} else {
pdscp = xmalloc(sizeof *pdscp);
pdscp->priority = priority;
pdscp->dscp = dscp;
ofproto->backer->need_revalidate = REV_RECONFIGURE;
}
if (pdscp->dscp != dscp) {
pdscp->dscp = dscp;
ofproto->backer->need_revalidate = REV_RECONFIGURE;
}
hmap_insert(&new, &pdscp->hmap_node, hash_int(pdscp->priority, 0));
}
if (!hmap_is_empty(&ofport->priorities)) {
ofport_clear_priorities(ofport);
if (ofport->n_qdscp != n_qdscp
|| (n_qdscp && memcmp(ofport->qdscp, qdscp,
n_qdscp * sizeof *qdscp))) {
ofproto->backer->need_revalidate = REV_RECONFIGURE;
free(ofport->qdscp);
ofport->qdscp = n_qdscp
? xmemdup(qdscp, n_qdscp * sizeof *qdscp)
: NULL;
ofport->n_qdscp = n_qdscp;
}
hmap_swap(&new, &ofport->priorities);
hmap_destroy(&new);
return 0;
}

View File

@@ -74,8 +74,6 @@ ofp_port_t vsp_realdev_to_vlandev(const struct ofproto_dpif *,
ofp_port_t realdev_ofp_port,
ovs_be16 vlan_tci);
bool ofproto_dpif_dscp_from_priority(const struct ofport_dpif *,
uint32_t priority, uint8_t *dscp);
int ofproto_dpif_queue_to_priority(const struct ofproto_dpif *,
uint32_t queue_id, uint32_t *priority);