2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-31 06:15:47 +00:00

lib/classifier: Simplify iteration with C99 declaration.

Hide the cursor from the classifier iteration users and move locking to
the iterators.  This will make following RCU changes simpler, as the call
sites of the iterators need not be changed at that point.

Signed-off-by: Jarno Rajahalme <jrajahalme@nicira.com>
Acked-by: YAMAMOTO Takashi <yamamoto@valinux.co.jp>
This commit is contained in:
Jarno Rajahalme
2014-07-11 02:29:07 -07:00
parent f2c214029e
commit 5f0476ce4e
6 changed files with 156 additions and 119 deletions

View File

@@ -588,11 +588,12 @@ trie_init(struct cls_classifier *cls, int trie_idx,
}
}
/* Returns true if 'cls' contains no classification rules, false otherwise. */
/* Returns true if 'cls' contains no classification rules, false otherwise.
* Checking the cmap requires no locking. */
bool
classifier_is_empty(const struct classifier *cls)
{
return cls->cls->n_rules == 0;
return cmap_is_empty(&cls->cls->subtables_map);
}
/* Returns the number of rules in 'cls'. */
@@ -1154,7 +1155,8 @@ search_subtable(const struct cls_subtable *subtable,
return NULL;
}
/* Initializes 'cursor' for iterating through rules in 'cls':
/* Initializes 'cursor' for iterating through rules in 'cls', and returns the
* first matching cls_rule via '*pnode', or NULL if there are no matches.
*
* - If 'target' is null, the cursor will visit every rule in 'cls'.
*
@@ -1162,45 +1164,68 @@ search_subtable(const struct cls_subtable *subtable,
* such that cls_rule_is_loose_match(rule, target) returns true.
*
* Ignores target->priority. */
void
cls_cursor_init(struct cls_cursor *cursor, const struct classifier *cls,
const struct cls_rule *target)
{
cursor->cls = cls->cls;
cursor->target = target && !cls_rule_is_catchall(target) ? target : NULL;
}
/* Returns the first matching cls_rule in 'cursor''s iteration, or a null
* pointer if there are no matches. */
struct cls_rule *
cls_cursor_first(struct cls_cursor *cursor)
struct cls_cursor cls_cursor_init(const struct classifier *cls,
const struct cls_rule *target,
void **pnode, const void *offset, bool safe)
OVS_NO_THREAD_SAFETY_ANALYSIS
{
struct cls_cursor cursor;
struct cls_subtable *subtable;
struct cls_rule *cls_rule = NULL;
CMAP_CURSOR_FOR_EACH (subtable, cmap_node, &cursor->subtables,
&cursor->cls->subtables_map) {
struct cls_match *rule = search_subtable(subtable, cursor);
cursor.safe = safe;
cursor.cls = cls;
cursor.target = target && !cls_rule_is_catchall(target) ? target : NULL;
/* Find first rule. */
fat_rwlock_rdlock(&cursor.cls->rwlock);
CMAP_CURSOR_FOR_EACH (subtable, cmap_node, &cursor.subtables,
&cursor.cls->cls->subtables_map) {
struct cls_match *rule = search_subtable(subtable, &cursor);
if (rule) {
cursor->subtable = subtable;
return rule->cls_rule;
cursor.subtable = subtable;
cls_rule = rule->cls_rule;
break;
}
}
*pnode = (char *)cls_rule + (ptrdiff_t)offset;
return NULL;
/* Leave locked if requested and have a rule. */
if (safe || !cls_rule) {
fat_rwlock_unlock(&cls->rwlock);
}
return cursor;
}
static void
cls_cursor_next_unlock(struct cls_cursor *cursor, struct cls_rule *rule)
OVS_NO_THREAD_SAFETY_ANALYSIS
{
/* Release the lock if no rule, or 'safe' mode. */
if (!rule || cursor->safe) {
fat_rwlock_unlock(&cursor->cls->rwlock);
}
}
/* Returns the next matching cls_rule in 'cursor''s iteration, or a null
* pointer if there are no more matches. */
struct cls_rule *
cls_cursor_next(struct cls_cursor *cursor, const struct cls_rule *rule_)
OVS_NO_THREAD_SAFETY_ANALYSIS
{
struct cls_match *rule = CONST_CAST(struct cls_match *, rule_->cls_match);
const struct cls_subtable *subtable;
struct cls_match *next;
/* Lock if not locked already. */
if (cursor->safe) {
fat_rwlock_rdlock(&cursor->cls->rwlock);
}
next = next_rule_in_list__(rule);
if (next->priority < rule->priority) {
cls_cursor_next_unlock(cursor, next->cls_rule);
return next->cls_rule;
}
@@ -1210,6 +1235,7 @@ cls_cursor_next(struct cls_cursor *cursor, const struct cls_rule *rule_)
rule = next;
CMAP_CURSOR_FOR_EACH_CONTINUE (rule, cmap_node, &cursor->rules) {
if (rule_matches(rule, cursor->target)) {
cls_cursor_next_unlock(cursor, rule->cls_rule);
return rule->cls_rule;
}
}
@@ -1219,10 +1245,12 @@ cls_cursor_next(struct cls_cursor *cursor, const struct cls_rule *rule_)
rule = search_subtable(subtable, cursor);
if (rule) {
cursor->subtable = subtable;
cls_cursor_next_unlock(cursor, rule->cls_rule);
return rule->cls_rule;
}
}
fat_rwlock_unlock(&cursor->cls->rwlock);
return NULL;
}