- ca->segment_size = ~0;
- ca->rx_fifo_size = sm->properties->rx_fifo_size;
- ca->tx_fifo_size = sm->properties->tx_fifo_size;
- ca->preallocated_fifo_pairs = sm->properties->preallocated_fifo_pairs;
- ca->private_segment_count = sm->properties->private_segment_count;
- ca->private_segment_size = sm->properties->private_segment_size;
+ ca->private_segment_count = props->private_segment_count;
+
+ /* Calculate space requirements */
+ rx_rounded_data_size = (1 << (max_log2 (ca->rx_fifo_size)));
+ tx_rounded_data_size = (1 << (max_log2 (ca->tx_fifo_size)));
+
+ rx_fifo_size = sizeof (svm_fifo_t) + rx_rounded_data_size;
+ tx_fifo_size = sizeof (svm_fifo_t) + tx_rounded_data_size;
+
+ approx_total_size = (u64) ca->preallocated_fifo_pairs
+ * (rx_fifo_size + tx_fifo_size);
+ approx_segment_count = (approx_total_size + protected_space
+ + (ca->segment_size -
+ 1)) / (u64) ca->segment_size;
+
+ /* The user asked us to figure it out... */
+ if (ca->private_segment_count == 0
+ || approx_segment_count < ca->private_segment_count)
+ {
+ ca->private_segment_count = approx_segment_count;
+ }
+ /* Follow directions, but issue a warning */
+ else if (approx_segment_count < ca->private_segment_count)
+ {
+ clib_warning ("Honoring segment count %u, calculated count was %u",
+ ca->private_segment_count, approx_segment_count);
+ }
+ else if (approx_segment_count > ca->private_segment_count)
+ {
+ clib_warning ("Segment count too low %u, calculated %u.",
+ ca->private_segment_count, approx_segment_count);
+ return VNET_API_ERROR_INVALID_VALUE;
+ }