Allow clients to use the whole priority range.  Note that this changes
the semantics of PVECTOR_FOR_EACH_PRIORITY so that the iteration still
continues for entries at the given priority.

Suggested-by: Ben Pfaff <b...@ovn.org>
Signed-off-by: Jarno Rajahalme <ja...@ovn.org>
---
 lib/classifier.c |  4 ++--
 lib/pvector.c    | 12 +++++-------
 lib/pvector.h    | 14 ++++++--------
 3 files changed, 13 insertions(+), 17 deletions(-)

diff --git a/lib/classifier.c b/lib/classifier.c
index 2b24724..54941ed 100644
--- a/lib/classifier.c
+++ b/lib/classifier.c
@@ -960,7 +960,7 @@ classifier_lookup__(const struct classifier *cls, 
cls_version_t version,
 
     /* Main loop. */
     struct cls_subtable *subtable;
-    PVECTOR_FOR_EACH_PRIORITY (subtable, hard_pri, 2, sizeof *subtable,
+    PVECTOR_FOR_EACH_PRIORITY (subtable, hard_pri + 1, 2, sizeof *subtable,
                                &cls->subtables) {
         struct cls_conjunction_set *conj_set;
 
@@ -1232,7 +1232,7 @@ classifier_rule_overlaps(const struct classifier *cls,
     struct cls_subtable *subtable;
 
     /* Iterate subtables in the descending max priority order. */
-    PVECTOR_FOR_EACH_PRIORITY (subtable, target->priority - 1, 2,
+    PVECTOR_FOR_EACH_PRIORITY (subtable, target->priority, 2,
                                sizeof(struct cls_subtable), &cls->subtables) {
         struct {
             struct minimask mask;
diff --git a/lib/pvector.c b/lib/pvector.c
index 04c2e65..aaeee92 100644
--- a/lib/pvector.c
+++ b/lib/pvector.c
@@ -95,10 +95,6 @@ static void
 pvector_impl_sort(struct pvector_impl *impl)
 {
     qsort(impl->vector, impl->size, sizeof *impl->vector, pvector_entry_cmp);
-    /* Trim gaps. */
-    while (impl->size && impl->vector[impl->size - 1].priority == INT_MIN) {
-        impl->size = impl->size - 1;
-    }
 }
 
 /* Returns the index of the 'ptr' in the vector, or -1 if none is found. */
@@ -163,9 +159,11 @@ pvector_remove(struct pvector *pvec, void *ptr)
     index = pvector_impl_find(temp, ptr);
     ovs_assert(index >= 0);
     /* Now at the index of the entry to be deleted.
-     * Clear in place, publish will sort and clean these off. */
-    temp->vector[index].ptr = NULL;
-    temp->vector[index].priority = INT_MIN;
+     * Swap another entry in if needed, publish will sort anyway. */
+    temp->size--;
+    if (index != temp->size) {
+        temp->vector[index] = temp->vector[temp->size];
+    }
 }
 
 /* Change entry's 'priority' and keep the vector ordered. */
diff --git a/lib/pvector.h b/lib/pvector.h
index 263e783..b175b21 100644
--- a/lib/pvector.h
+++ b/lib/pvector.h
@@ -54,8 +54,6 @@
  * 'temp' may contain NULL pointers and it may be in unsorted order.  It is
  * sorted before it is published at 'impl', which also removes the NULLs from
  * the published vector.
- *
- * Clients should not use priority INT_MIN.
  */
 
 struct pvector_entry {
@@ -129,7 +127,7 @@ static inline bool pvector_is_empty(const struct pvector *);
  * has to be started.
  *
  * The PVECTOR_FOR_EACH_PRIORITY limits the iteration to entries with higher
- * than given priority and allows for object lookahead.
+ * than or equal to the given priority and allows for object lookahead.
  *
  * The iteration loop must be completed without entering the OVS RCU quiescent
  * period.  That is, an old iteration loop must not be continued after any
@@ -145,7 +143,7 @@ static inline struct pvector_cursor 
pvector_cursor_init(const struct pvector *,
                                                         size_t n_ahead,
                                                         size_t obj_size);
 static inline void *pvector_cursor_next(struct pvector_cursor *,
-                                        int stop_at_priority,
+                                        int lowest_priority,
                                         size_t n_ahead, size_t obj_size);
 static inline void pvector_cursor_lookahead(const struct pvector_cursor *,
                                             int n, size_t size);
@@ -154,8 +152,8 @@ static inline void pvector_cursor_lookahead(const struct 
pvector_cursor *,
     for (struct pvector_cursor cursor__ = pvector_cursor_init(PVECTOR, 0, 0); \
          ((PTR) = pvector_cursor_next(&cursor__, INT_MIN, 0, 0)) != NULL; )
 
-/* Loop while priority is higher than 'PRIORITY' and prefetch objects
- * of size 'SZ' 'N' objects ahead from the current object. */
+/* Loop while priority is higher than or equal to 'PRIORITY' and prefetch
+ * objects of size 'SZ' 'N' objects ahead from the current object. */
 #define PVECTOR_FOR_EACH_PRIORITY(PTR, PRIORITY, N, SZ, PVECTOR)        \
     for (struct pvector_cursor cursor__ = pvector_cursor_init(PVECTOR, N, SZ); 
\
          ((PTR) = pvector_cursor_next(&cursor__, PRIORITY, N, SZ)) != NULL; )
@@ -193,11 +191,11 @@ pvector_cursor_init(const struct pvector *pvec,
 }
 
 static inline void *pvector_cursor_next(struct pvector_cursor *cursor,
-                                        int stop_at_priority,
+                                        int lowest_priority,
                                         size_t n_ahead, size_t obj_size)
 {
     if (++cursor->entry_idx < cursor->size &&
-        cursor->vector[cursor->entry_idx].priority > stop_at_priority) {
+        cursor->vector[cursor->entry_idx].priority >= lowest_priority) {
         if (n_ahead) {
             pvector_cursor_lookahead(cursor, n_ahead, obj_size);
         }
-- 
2.1.4

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to