+static void
+preallocate_fifo_pairs (svm_fifo_segment_header_t * fsh,
+ svm_fifo_segment_create_args_t * a)
+{
+ u32 rx_fifo_size, tx_fifo_size;
+ svm_fifo_t *f;
+ u8 *rx_fifo_space, *tx_fifo_space;
+ int i;
+
+ /* Parameter check */
+ if (a->rx_fifo_size == 0 || a->tx_fifo_size == 0
+ || a->preallocated_fifo_pairs == 0)
+ return;
+
+ /* Calculate space requirements */
+ rx_fifo_size = (sizeof (*f) + a->rx_fifo_size) * a->preallocated_fifo_pairs;
+ tx_fifo_size = (sizeof (*f) + a->tx_fifo_size) * a->preallocated_fifo_pairs;
+
+ /* Allocate rx fifo space. May fail. */
+ rx_fifo_space = clib_mem_alloc_aligned_at_offset
+ (rx_fifo_size, CLIB_CACHE_LINE_BYTES, 0 /* align_offset */ ,
+ 0 /* os_out_of_memory */ );
+
+ /* Same for TX */
+ tx_fifo_space = clib_mem_alloc_aligned_at_offset
+ (tx_fifo_size, CLIB_CACHE_LINE_BYTES, 0 /* align_offset */ ,
+ 0 /* os_out_of_memory */ );
+
+ /* Make sure it worked. Clean up if it didn't... */
+ if (rx_fifo_space == 0 || tx_fifo_space == 0)
+ {
+ if (rx_fifo_space)
+ clib_mem_free (rx_fifo_space);
+ else
+ clib_warning ("rx fifo preallocation failure: size %d npairs %d",
+ a->rx_fifo_size, a->preallocated_fifo_pairs);
+
+ if (tx_fifo_space)
+ clib_mem_free (tx_fifo_space);
+ else
+ clib_warning ("tx fifo preallocation failure: size %d nfifos %d",
+ a->tx_fifo_size, a->preallocated_fifo_pairs);
+ return;
+ }
+
+ /* Carve rx fifo space */
+ f = (svm_fifo_t *) rx_fifo_space;
+ for (i = 0; i < a->preallocated_fifo_pairs; i++)
+ {
+ f->next = fsh->free_fifos[FIFO_SEGMENT_RX_FREELIST];
+ fsh->free_fifos[FIFO_SEGMENT_RX_FREELIST] = f;
+ rx_fifo_space += sizeof (*f) + a->rx_fifo_size;
+ f = (svm_fifo_t *) rx_fifo_space;
+ }
+ /* Carve tx fifo space */
+ f = (svm_fifo_t *) tx_fifo_space;
+ for (i = 0; i < a->preallocated_fifo_pairs; i++)
+ {
+ f->next = fsh->free_fifos[FIFO_SEGMENT_TX_FREELIST];
+ fsh->free_fifos[FIFO_SEGMENT_TX_FREELIST] = f;
+ tx_fifo_space += sizeof (*f) + a->tx_fifo_size;
+ f = (svm_fifo_t *) tx_fifo_space;
+ }
+}
+