- clib_file_t *uf = pool_elt_at_index (file_main.file_pool,
- vui->vrings[q].callfd_idx);
- clib_file_del (&file_main, uf);
- vui->vrings[q].callfd_idx = ~0;
+ /* if there is old fd, delete and close it */
+ if (vui->vrings[q].callfd_idx != ~0)
+ {
+ clib_file_t *uf = pool_elt_at_index (file_main.file_pool,
+ vui->vrings[q].callfd_idx);
+ clib_file_del (&file_main, uf);
+ vui->vrings[q].callfd_idx = ~0;
+ }
+ }
+ else if (vec_len (vui->vrings) > q)
+ {
+ /* grow vrings by pair (RX + TX) */
+ vui->num_qid = (q & 1) ? (q + 1) : (q + 2);
+ }
+ else
+ {
+ u32 i, new_max_q, old_max_q = vec_len (vui->vrings);
+
+ /*
+ * Double the array size if it is less than 64 entries.
+ * Slow down thereafter.
+ */
+ if (vec_len (vui->vrings) < (VHOST_VRING_INIT_MQ_PAIR_SZ << 3))
+ new_max_q = vec_len (vui->vrings) << 1;
+ else
+ new_max_q = vec_len (vui->vrings) +
+ (VHOST_VRING_INIT_MQ_PAIR_SZ << 2);
+ if (new_max_q > (VHOST_VRING_MAX_MQ_PAIR_SZ << 1))
+ new_max_q = (VHOST_VRING_MAX_MQ_PAIR_SZ << 1);
+
+ /* sync with the worker threads, vrings may move due to realloc */
+ vlib_worker_thread_barrier_sync (vm);
+ vec_validate_aligned (vui->vrings, new_max_q - 1,
+ CLIB_CACHE_LINE_BYTES);
+ vlib_worker_thread_barrier_release (vm);
+
+ for (i = old_max_q; i < vec_len (vui->vrings); i++)
+ vhost_user_vring_init (vui, i);
+
+ /* grow vrings by pair (RX + TX) */
+ vui->num_qid = (q & 1) ? (q + 1) : (q + 2);