X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=vswitchd%2Fbridge.c;h=6a4ebe58d2741155e9d679f41c92a34229019207;hb=c1a543a8d6d2847983b6b0defd1e19777da85715;hp=449957a9f5372242a40fc1822e1cb5356f22b36c;hpb=5d27908667cfa34f7786fdc88e9e09078453637a;p=openvswitch diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index 449957a9..6a4ebe58 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -148,6 +148,7 @@ static void bridge_add_ofproto_ports(struct bridge *); static void bridge_del_ofproto_ports(struct bridge *); static void bridge_refresh_ofp_port(struct bridge *); static void bridge_configure_datapath_id(struct bridge *); +static void bridge_configure_flow_eviction_threshold(struct bridge *); static void bridge_configure_netflow(struct bridge *); static void bridge_configure_sflow(struct bridge *, int *sflow_bridge_number); static void bridge_configure_remotes(struct bridge *, @@ -216,6 +217,7 @@ bridge_init(const char *remote) { /* Create connection to database. */ idl = ovsdb_idl_create(remote, &ovsrec_idl_class, true); + ovsdb_idl_set_lock(idl, "ovs_vswitchd"); ovsdb_idl_omit_alert(idl, &ovsrec_open_vswitch_col_cur_cfg); ovsdb_idl_omit_alert(idl, &ovsrec_open_vswitch_col_statistics); @@ -411,6 +413,7 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg) } bridge_configure_mirrors(br); bridge_configure_datapath_id(br); + bridge_configure_flow_eviction_threshold(br); bridge_configure_remotes(br, managers, n_managers); bridge_configure_netflow(br); bridge_configure_sflow(br, &sflow_bridge_number); @@ -961,6 +964,22 @@ bridge_get_other_config(const struct ovsrec_bridge *br_cfg, const char *key) &ovsrec_bridge_col_other_config, key); } +/* Set Flow eviction threshold */ +static void +bridge_configure_flow_eviction_threshold(struct bridge *br) +{ + const char *threshold_str; + unsigned threshold; + + threshold_str = bridge_get_other_config(br->cfg, "flow-eviction-threshold"); + if (threshold_str) { + threshold = strtoul(threshold_str, NULL, 10); + } else { + threshold = OFPROTO_FLOW_EVICTON_THRESHOLD_DEFAULT; + } + ofproto_set_flow_eviction_threshold(br->ofproto, threshold); +} + static void bridge_pick_local_hw_addr(struct bridge *br, uint8_t ea[ETH_ADDR_LEN], struct iface **hw_addr_iface) @@ -1391,6 +1410,24 @@ bridge_run(void) bool database_changed; struct bridge *br; + /* (Re)configure if necessary. */ + database_changed = ovsdb_idl_run(idl); + if (ovsdb_idl_is_lock_contended(idl)) { + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1); + struct bridge *br, *next_br; + + VLOG_ERR_RL(&rl, "another ovs-vswitchd process is running, " + "disabling this process until it goes away"); + + HMAP_FOR_EACH_SAFE (br, next_br, node, &all_bridges) { + bridge_destroy(br); + } + return; + } else if (!ovsdb_idl_has_lock(idl)) { + return; + } + cfg = ovsrec_open_vswitch_first(idl); + /* Let each bridge do the work that it needs to do. */ datapath_destroyed = false; HMAP_FOR_EACH (br, node, &all_bridges) { @@ -1403,10 +1440,6 @@ bridge_run(void) } } - /* (Re)configure if necessary. */ - database_changed = ovsdb_idl_run(idl); - cfg = ovsrec_open_vswitch_first(idl); - /* Re-configure SSL. We do this on every trip through the main loop, * instead of just when the database changes, because the contents of the * key and certificate files can change without the database changing. @@ -1495,16 +1528,18 @@ bridge_run(void) void bridge_wait(void) { - struct bridge *br; - - HMAP_FOR_EACH (br, node, &all_bridges) { - ofproto_wait(br->ofproto); - } ovsdb_idl_wait(idl); - poll_timer_wait_until(stats_timer); + if (!hmap_is_empty(&all_bridges)) { + struct bridge *br; - if (db_limiter > time_msec()) { - poll_timer_wait_until(db_limiter); + HMAP_FOR_EACH (br, node, &all_bridges) { + ofproto_wait(br->ofproto); + } + poll_timer_wait_until(stats_timer); + + if (db_limiter > time_msec()) { + poll_timer_wait_until(db_limiter); + } } } @@ -2474,6 +2509,7 @@ iface_configure_qos(struct iface *iface, const struct ovsrec_qos *qos) } else { struct iface_delete_queues_cbdata cbdata; struct shash details; + bool queue_zero; size_t i; /* Configure top-level Qos for 'iface'. */ @@ -2489,16 +2525,28 @@ iface_configure_qos(struct iface *iface, const struct ovsrec_qos *qos) netdev_dump_queues(iface->netdev, iface_delete_queues, &cbdata); /* Configure queues for 'iface'. */ + queue_zero = false; for (i = 0; i < qos->n_queues; i++) { const struct ovsrec_queue *queue = qos->value_queues[i]; unsigned int queue_id = qos->key_queues[i]; + if (queue_id == 0) { + queue_zero = true; + } + shash_from_ovs_idl_map(queue->key_other_config, queue->value_other_config, queue->n_other_config, &details); netdev_set_queue(iface->netdev, queue_id, &details); shash_destroy(&details); } + if (!queue_zero) { + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1); + VLOG_WARN_RL(&rl, "interface %s: QoS configured without a default " + "queue (queue 0). Packets not directed to a " + "correctly configured queue may be dropped.", + iface->name); + } } netdev_set_policing(iface->netdev, @@ -2718,7 +2766,6 @@ mirror_configure(struct mirror *m, const struct ovsrec_mirror *cfg) &s.srcs, &s.n_srcs); mirror_collect_ports(m, cfg->select_dst_port, cfg->n_select_dst_port, &s.dsts, &s.n_dsts); - } /* Get VLAN selection. */