一般情况下ukey->reval_seq和udpif->reval_seq是一样的,所以在revalidate_ukey函数里need_revalidate是false。
但是如果添加或者删除了openflow rule的规则,udpif->reval_seq会加1。
(gdb) bt
#0 set_tables_version (ofproto_=0x1169f50, version=0xa) at ofproto/ofproto-dpif.c:2017
#1 0x00000000004234b3 in ofproto_bump_tables_version (ofproto=0x1169f50) at ofproto/ofproto.c:473
#2 handle_flow_mod__ (ofproto=ofproto@entry=0x1169f50, fm=fm@entry=0x7fff92440b50, req=req@entry=0x7fff92440b00)
at ofproto/ofproto.c:6215
#3 0x00000000004235c1 in handle_flow_mod (ofconn=ofconn@entry=0x11f2030, oh=0x11f5060) at ofproto/ofproto.c:6190
#4 0x0000000000423f0c in handle_single_part_openflow (type=OFPTYPE_FLOW_MOD, oh=<optimized out>, ofconn=0x11f2030)
at ofproto/ofproto.c:8504
#5 handle_openflow (ofconn=0x11f2030, msgs=0x7fff924411a0) at ofproto/ofproto.c:8685
#6 0x0000000000457044 in ofconn_run (handle_openflow=0x423a00 <handle_openflow>, ofconn=0x11f2030)
at ofproto/connmgr.c:1329
#7 connmgr_run (mgr=0x116a4d0, handle_openflow=handle_openflow@entry=0x423a00 <handle_openflow>)
at ofproto/connmgr.c:356
#8 0x000000000041def6 in ofproto_run (p=0x1169f50) at ofproto/ofproto.c:1890
#9 0x000000000040b6a4 in bridge_run__ () at vswitchd/bridge.c:3250
#10 0x0000000000411053 in bridge_run () at vswitchd/bridge.c:3309
#11 0x0000000000406d7d in main (argc=<optimized out>, argv=<optimized out>) at vswitchd/ovs-vswitchd.c:127
(gdb) bt
#0 ofproto_flow_mod_start (ofproto=0x1169f50, ofm=0x7fff924409c0) at ofproto/ofproto.c:8020
#1 0x000000000042348d in handle_flow_mod__ (ofproto=ofproto@entry=0x1169f50, fm=fm@entry=0x7fff92440b50, req=req@entry=0x7fff92440b00) at ofproto/ofproto.c:6213
#2 0x00000000004235c1 in handle_flow_mod (ofconn=ofconn@entry=0x11f27c0, oh=0x11f4da0) at ofproto/ofproto.c:6190
#3 0x0000000000423f0c in handle_single_part_openflow (type=OFPTYPE_FLOW_MOD, oh=<optimized out>, ofconn=0x11f27c0) at ofproto/ofproto.c:8504
#4 handle_openflow (ofconn=0x11f27c0, msgs=0x7fff924411a0) at ofproto/ofproto.c:8685
#5 0x0000000000457044 in ofconn_run (handle_openflow=0x423a00 <handle_openflow>, ofconn=0x11f27c0) at ofproto/connmgr.c:1329
#6 connmgr_run (mgr=0x116a4d0, handle_openflow=handle_openflow@entry=0x423a00 <handle_openflow>) at ofproto/connmgr.c:356
#7 0x000000000041def6 in ofproto_run (p=0x1169f50) at ofproto/ofproto.c:1890
#8 0x000000000040b6a4 in bridge_run__ () at vswitchd/bridge.c:3250
#9 0x0000000000411053 in bridge_run () at vswitchd/bridge.c:3309
#10 0x0000000000406d7d in main (argc=<optimized out>, argv=<optimized out>) at vswitchd/ovs-vswitchd.c:127
在type_run()中打印backer->need_revalidate值是REV_FLOW_TABLE。
这时revalidate_ukey()中need_revalidate会是true,should_revalidate()会被掉到。
static bool
should_revalidate(const struct udpif *udpif, uint64_t packets,
long long int used)
{
long long int metric, now, duration;
if (!used) {
/* Always revalidate the first time a flow is dumped. */
return true;
}
if (udpif->dump_duration < ofproto_max_revalidator / 2) {
/* We are likely to handle full revalidation for the flows. */
return true;
}
/* Calculate the mean time between seeing these packets. If this
* exceeds the threshold, then delete the flow rather than performing
* costly revalidation for flows that aren't being hit frequently.
*
* This is targeted at situations where the dump_duration is high (~1s),
* and revalidation is triggered by a call to udpif_revalidate(). In
* these situations, revalidation of all flows causes fluctuations in the
* flow_limit due to the interaction with the dump_duration and max_idle.
* This tends to result in deletion of low-throughput flows anyway, so
* skip the revalidation and just delete those flows. */
packets = MAX(packets, 1);
now = MAX(used, time_msec());
duration = now - used;
metric = duration / packets;
if (metric < 1000 / ofproto_min_revalidate_pps) {
/* The flow is receiving more than min-revalidate-pps, so keep it. */
return true;
}
return false;
}
ofproto_max_revalidator系统默认是500,就是0.5秒。如果dump所有flow的时间大于0.25秒。并且flow的pps很小的话,那么这个flow就很有可能被删掉。并且很有可能所以的flow都会被删掉。在支持offload的老系统上,由于rtnl_lock的原因,这个很有可能被触发。可以通过下面的配置来缓解这个问题:
ovs-vsctl set Open_vSwitch . other_config:max-revalidator=10000