[ovs-dev] [PATCH 09/18] lib/bfd: Used relaxed atomics and optimize bfd_should_process_flow().
Jarno Rajahalme
jrajahalme at nicira.com
Fri Aug 22 20:58:20 UTC 2014
The atomics here do not synchronize the state of any other variables,
so we can use atomic_count and relaxed atomics.
bfd_should_process_flow() is rearranged to set the megaflow mask bits
only if necessary, and to avoid the atomic operation on non-BFD
packets.
Signed-off-by: Jarno Rajahalme <jrajahalme at nicira.com>
---
lib/bfd.c | 47 +++++++++++++++++++++++++++--------------------
1 file changed, 27 insertions(+), 20 deletions(-)
diff --git a/lib/bfd.c b/lib/bfd.c
index 5c86451..7884fc6 100644
--- a/lib/bfd.c
+++ b/lib/bfd.c
@@ -338,7 +338,7 @@ bfd_configure(struct bfd *bfd, const char *name, const struct smap *cfg,
struct netdev *netdev) OVS_EXCLUDED(mutex)
{
static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
- static atomic_uint16_t udp_src = ATOMIC_VAR_INIT(0);
+ static atomic_count udp_src = ATOMIC_COUNT_INIT(0);
int decay_min_rx;
long long int min_tx, min_rx;
@@ -385,16 +385,15 @@ bfd_configure(struct bfd *bfd, const char *name, const struct smap *cfg,
* UDP source port number MUST be used for all BFD Control packets
* associated with a particular session. The source port number SHOULD
* be unique among all BFD sessions on the system. */
- atomic_add(&udp_src, 1, &bfd->udp_src);
- bfd->udp_src = (bfd->udp_src % 16384) + 49152;
+ bfd->udp_src = (atomic_count_inc(&udp_src) % 16384) + 49152;
bfd_set_state(bfd, STATE_DOWN, DIAG_NONE);
bfd_status_changed(bfd);
}
- atomic_store(&bfd->check_tnl_key,
- smap_get_bool(cfg, "check_tnl_key", false));
+ atomic_store_relaxed(&bfd->check_tnl_key,
+ smap_get_bool(cfg, "check_tnl_key", false));
min_tx = smap_get_int(cfg, "min_tx", 100);
min_tx = MAX(min_tx, 100);
if (bfd->cfg_min_tx != min_tx) {
@@ -672,25 +671,33 @@ bfd_should_process_flow(const struct bfd *bfd_, const struct flow *flow,
struct flow_wildcards *wc)
{
struct bfd *bfd = CONST_CAST(struct bfd *, bfd_);
- bool check_tnl_key;
- memset(&wc->masks.dl_dst, 0xff, sizeof wc->masks.dl_dst);
- if (!eth_addr_is_zero(bfd->rmt_eth_dst)
- && memcmp(bfd->rmt_eth_dst, flow->dl_dst, ETH_ADDR_LEN)) {
- return false;
- }
+ if (!eth_addr_is_zero(bfd->rmt_eth_dst)) {
+ memset(&wc->masks.dl_dst, 0xff, sizeof wc->masks.dl_dst);
- memset(&wc->masks.nw_proto, 0xff, sizeof wc->masks.nw_proto);
- memset(&wc->masks.tp_dst, 0xff, sizeof wc->masks.tp_dst);
+ if (memcmp(bfd->rmt_eth_dst, flow->dl_dst, ETH_ADDR_LEN)) {
+ return false;
+ }
+ }
- atomic_read(&bfd->check_tnl_key, &check_tnl_key);
- if (check_tnl_key) {
- memset(&wc->masks.tunnel.tun_id, 0xff, sizeof wc->masks.tunnel.tun_id);
+ if (flow->dl_type == htons(ETH_TYPE_IP)) {
+ memset(&wc->masks.nw_proto, 0xff, sizeof wc->masks.nw_proto);
+ if (flow->nw_proto == IPPROTO_UDP) {
+ memset(&wc->masks.tp_dst, 0xff, sizeof wc->masks.tp_dst);
+ if (flow->tp_dst == htons(BFD_DEST_PORT)) {
+ bool check_tnl_key;
+
+ atomic_read_relaxed(&bfd->check_tnl_key, &check_tnl_key);
+ if (check_tnl_key) {
+ memset(&wc->masks.tunnel.tun_id, 0xff,
+ sizeof wc->masks.tunnel.tun_id);
+ return flow->tunnel.tun_id == htonll(0);
+ }
+ return true;
+ }
+ }
}
- return (flow->dl_type == htons(ETH_TYPE_IP)
- && flow->nw_proto == IPPROTO_UDP
- && flow->tp_dst == htons(BFD_DEST_PORT)
- && (!check_tnl_key || flow->tunnel.tun_id == htonll(0)));
+ return false;
}
void
--
1.7.10.4
More information about the dev
mailing list