X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=ofproto%2Fofproto.c;h=c8edb2d4761296d73705b8a679d6e53f4a938764;hb=6b900de4efd368be88ef3db88b1eff8f835a7cf7;hp=44a6f9d2b32ba6a80304c0aaddc6242719687edc;hpb=c278bb82a36c9a479b611dfa8482c3c23cca633e;p=sliver-openvswitch.git diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c index 44a6f9d2b..c8edb2d47 100644 --- a/ofproto/ofproto.c +++ b/ofproto/ofproto.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "bitmap.h" #include "byte-order.h" #include "classifier.h" @@ -229,6 +230,7 @@ static size_t n_ofproto_classes; static size_t allocated_ofproto_classes; unsigned flow_eviction_threshold = OFPROTO_FLOW_EVICTION_THRESHOLD_DEFAULT; +unsigned n_handler_threads; enum ofproto_flow_miss_model flow_miss_model = OFPROTO_HANDLE_MISS_AUTO; /* Map from datapath name to struct ofproto, for use by unixctl commands. */ @@ -628,6 +630,18 @@ ofproto_set_mac_table_config(struct ofproto *ofproto, unsigned idle_time, } } +/* Sets number of upcall handler threads. The default is + * (number of online cores - 1). */ +void +ofproto_set_n_handler_threads(unsigned limit) +{ + if (limit) { + n_handler_threads = limit; + } else { + n_handler_threads = MAX(1, sysconf(_SC_NPROCESSORS_ONLN) - 1); + } +} + void ofproto_set_dp_desc(struct ofproto *p, const char *dp_desc) { @@ -3345,7 +3359,6 @@ add_flow(struct ofproto *ofproto, struct ofconn *ofconn, struct rule *victim; struct rule *rule; uint8_t table_id; - bool overlaps; int error; error = check_table_id(ofproto, fm->table_id); @@ -3402,13 +3415,18 @@ add_flow(struct ofproto *ofproto, struct ofconn *ofconn, } /* Check for overlap, if requested. */ - ovs_rwlock_rdlock(&table->cls.rwlock); - overlaps = classifier_rule_overlaps(&table->cls, &rule->cr); - ovs_rwlock_unlock(&table->cls.rwlock); - if (fm->flags & OFPFF_CHECK_OVERLAP && overlaps) { - cls_rule_destroy(&rule->cr); - ofproto->ofproto_class->rule_dealloc(rule); - return OFPERR_OFPFMFC_OVERLAP; + if (fm->flags & OFPFF_CHECK_OVERLAP) { + bool overlaps; + + ovs_rwlock_rdlock(&table->cls.rwlock); + overlaps = classifier_rule_overlaps(&table->cls, &rule->cr); + ovs_rwlock_unlock(&table->cls.rwlock); + + if (overlaps) { + cls_rule_destroy(&rule->cr); + ofproto->ofproto_class->rule_dealloc(rule); + return OFPERR_OFPFMFC_OVERLAP; + } } /* FIXME: Implement OFPFF12_RESET_COUNTS */ @@ -5459,7 +5477,8 @@ oftable_enable_eviction(struct oftable *table, /* Removes 'rule' from the oftable that contains it. */ static void oftable_remove_rule__(struct ofproto *ofproto, struct classifier *cls, - struct rule *rule) OVS_REQ_WRLOCK(cls->rwlock) + struct rule *rule) + OVS_REQ_WRLOCK(cls->rwlock) OVS_RELEASES(rule->evict) { classifier_remove(cls, &rule->cr); if (rule->meter_id) {