-
- for (j = 0; j < t->entries_per_page; j++)
- {
- v = vnet_classify_entry_at_index
- (t, old_values, i * t->entries_per_page + j);
-
- if (vnet_classify_entry_is_busy (v))
- {
- /* Hack so we can use the packet hash routine */
- u8 * key_minus_skip;
- key_minus_skip = (u8 *) v->key;
- key_minus_skip -= t->skip_n_vectors * sizeof (u32x4);
-
- new_hash = vnet_classify_hash_packet (t, key_minus_skip);
- new_hash >>= t->log2_nbuckets;
- new_hash &= (1<<new_log2_pages) - 1;
-
- for (k = 0; k < t->entries_per_page; k++)
- {
- new_v = vnet_classify_entry_at_index (t, new_values,
- new_hash + k);
-
- if (vnet_classify_entry_is_free (new_v))
- {
- clib_memcpy (new_v, v, sizeof (vnet_classify_entry_t)
- + (t->match_n_vectors * sizeof (u32x4)));
- new_v->flags &= ~(VNET_CLASSIFY_ENTRY_FREE);
- goto doublebreak;
- }
- }
- /* Crap. Tell caller to try again */
- vnet_classify_entry_free (t, new_values);
- return 0;
- }
- doublebreak:
- ;
- }
+
+ v = vnet_classify_entry_at_index (t, old_values, i);
+
+ if (vnet_classify_entry_is_busy (v))
+ {
+ /* Hack so we can use the packet hash routine */
+ u8 *key_minus_skip;
+ key_minus_skip = (u8 *) v->key;
+ key_minus_skip -= t->skip_n_vectors * sizeof (u32x4);
+
+ new_hash = vnet_classify_hash_packet (t, key_minus_skip);
+ new_hash >>= t->log2_nbuckets;
+ new_hash &= (1 << new_log2_pages) - 1;
+
+ for (j = 0; j < t->entries_per_page; j++)
+ {
+ new_v = vnet_classify_entry_at_index (t, new_values,
+ new_hash + j);
+
+ if (vnet_classify_entry_is_free (new_v))
+ {
+ clib_memcpy (new_v, v, sizeof (vnet_classify_entry_t)
+ + (t->match_n_vectors * sizeof (u32x4)));
+ new_v->flags &= ~(VNET_CLASSIFY_ENTRY_FREE);
+ goto doublebreak;
+ }
+ }
+ /* Crap. Tell caller to try again */
+ vnet_classify_entry_free (t, new_values, new_log2_pages);
+ return 0;
+ doublebreak:
+ ;
+ }
+ }
+ return new_values;
+}
+
+static vnet_classify_entry_t *
+split_and_rehash_linear (vnet_classify_table_t * t,
+ vnet_classify_entry_t * old_values,
+ u32 old_log2_pages, u32 new_log2_pages)
+{
+ vnet_classify_entry_t *new_values, *v, *new_v;
+ int i, j, new_length_in_entries, old_length_in_entries;
+
+ new_values = vnet_classify_entry_alloc (t, new_log2_pages);
+ new_length_in_entries = (1 << new_log2_pages) * t->entries_per_page;
+ old_length_in_entries = (1 << old_log2_pages) * t->entries_per_page;
+
+ j = 0;
+ for (i = 0; i < old_length_in_entries; i++)
+ {
+ v = vnet_classify_entry_at_index (t, old_values, i);
+
+ if (vnet_classify_entry_is_busy (v))
+ {
+ for (; j < new_length_in_entries; j++)
+ {
+ new_v = vnet_classify_entry_at_index (t, new_values, j);
+
+ if (vnet_classify_entry_is_busy (new_v))
+ {
+ clib_warning ("BUG: linear rehash new entry not free!");
+ continue;
+ }
+ clib_memcpy (new_v, v, sizeof (vnet_classify_entry_t)
+ + (t->match_n_vectors * sizeof (u32x4)));
+ new_v->flags &= ~(VNET_CLASSIFY_ENTRY_FREE);
+ j++;
+ goto doublebreak;
+ }
+ /*
+ * Crap. Tell caller to try again.
+ * This should never happen...
+ */
+ clib_warning ("BUG: linear rehash failed!");
+ vnet_classify_entry_free (t, new_values, new_log2_pages);
+ return 0;
+ }
+ doublebreak:
+ ;