On Dec 30, 2014, at 5:16 PM, Ben Pfaff <b...@nicira.com> wrote: > On Thu, Oct 30, 2014 at 11:39:44AM -0700, Jarno Rajahalme wrote: >> >> On Oct 29, 2014, at 11:46 PM, Ben Pfaff <b...@nicira.com> wrote: >> >>> A "conjunctive match" allows higher-level matches in the flow table, such >>> as set membership matches, without causing a cross-product explosion for >>> multidimensional matches. Please refer to the documentation that this >>> commit adds to ovs-ofctl(8) for a better explanation, including an example. > > ... > >>> @@ -4379,6 +4419,7 @@ modify_flows__(struct ofproto *ofproto, struct >>> ofputil_flow_mod *fm, >>> if (change_actions) { >>> ovsrcu_set(&rule->actions, rule_actions_create(fm->ofpacts, >>> fm->ofpacts_len)); >>> + set_conjunction(rule); >> >> Does the above need to be atomic for the lookup? If not, does it matter >> which is visible first? As it is now, it seems possible that the lookup is >> successful and the new actions are used when the lookup was done with the >> old conjunctions. >> >> If this is removing conjunctions, then old conjunctions could be used in the >> lookup and the new actions ignored. This is fine, I think. >> >> If this adds conjunctions, then a rule with conjunction action could be >> returned as a hard match, if the lookup is done before the conjunctions have >> been set, but the actions are set before the thread doing the lookup gets >> them. >> >> Setting the conjunctions first would result in the following: >> >> Removing conjunctions: the rule is changed to a hard match, then the >> hard_match could be returning the conjunction action. >> >> Adding conjunctions: This should be OK, new conjunctions are used, while the >> actions still point to the old actions. Since (incomplete) soft matches are >> never returned as a lookup result, the old actions would not be used any >> more. >> >> Maybe solve this by setting the conjunctions first, and then have the thread >> doing the lookup repeat the lookup if the actions of the returned rule >> contain the conjunction action? This should be pretty rare incidence, but >> this could solve the race here. >> >> Another possibility is to treat a modify which only changes actions, and >> where the conjunction is changed, added, or removed, with a >> classifier_replace, and give the conjunctions as a parameter to it? > > I'm working on getting a v3 of this patch ready. This issue has been > the major sticking point. I think I've found a simple solution, > though. Please allow me to run it by you before I post a full v3. > > Basically, one ordering is broken in the "add conjunctions" case, and > the other ordering is broken in the "remove conjunctions" case. So: > use one order if we're adding conjunctions and the other if we're > removing them. Thus: > > if (change_actions) { > /* We have to change the actions. The rule's conjunctive match set > * is a function of its actions, so we need to update that too. We > * update them in a carefully chosen order: > * > * - If we're adding a conjunctive match set where there wasn't one > * before, we set the conjunctive match set before the rule's > * actions. > * > * - To clear some nonempty conjunctive set, we set the rule's > * actions first. > * > * In either case, with the ordering reversed, a classifier lookup > * could find the conjunctive match action, which should never > * happen. > * > * Order doesn't matter for changing one nonempty conjunctive match > * set to some other nonempty set, since the actions don't matter > * either before or after the change. */ > bool conjunctive = is_conjunction(fm->ofpacts, fm->ofpacts_len); > > if (conjunctive) { > set_conjunction(rule); > } > ovsrcu_set(&rule->actions, rule_actions_create(fm->ofpacts, > fm->ofpacts_len)); > if (!conjunctive) { > set_conjunction(rule); > } > } > > Thoughts?
Reading my comments again, this seems the right thing to do. The comment block above is not very clear to me, however. How about: /* We have to change the actions. The rule's conjunctive match set * is a function of its actions, so we need to update that too. The * conjunctive match set is used in the lookup process to figure which * (if any) collection of conjunctive sets the packet matches with. * However, a rule with conjunction actions is never to be returned as * a classifier lookup result. To make sure a rule with conjunction action * is not returned as a lookup result, we update them in a carefully * chosen order: * * - If we're adding a conjunctive match set where there wasn't one * before, we have to make the conjunctive match set available to * lookups before the rule’s actions are changed, as otherwise rule * with a conjunction action could be returned as a lookup result. * * - To clear some nonempty conjunctive set, we set the rule's * actions first, so that a lookup can’t return a rule with conjunction * actions. * * - Otherwise, order doesn't matter for changing one nonempty * conjunctive match set to some other nonempty set, since the * rule’s actions are not seen by the classifier, and hence don’t * matter either before or after the change. */ Jarno _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev