return VNET_DEV_ERR_NOT_SUPPORTED;
}
+ if (args->flags.e & VNET_DEV_PORT_F_QUEUE_PER_THREAD)
+ {
+ if (args->num_rx_queues)
+ return VNET_DEV_ERR_INVALID_NUM_RX_QUEUES;
+ if (args->num_tx_queues)
+ return VNET_DEV_ERR_INVALID_NUM_TX_QUEUES;
+ args->num_rx_queues = args->num_tx_queues = n_threads;
+ }
+
if (args->num_rx_queues)
{
if (args->num_rx_queues > port->attr.max_rx_queues)
clib_memcpy (a.name, args->intf_name, sizeof (a.name));
a.default_is_intr_mode = default_is_intr_mode;
a.consistent_qp = (args->flags.n & VNET_DEV_PORT_F_CONSISTENT_QP) != 0;
+ a.queue_per_thread = (args->flags.n & VNET_DEV_PORT_F_QUEUE_PER_THREAD) != 0;
rv = vnet_dev_process_call_port_op_with_ptr (vm, port,
vnet_dev_port_if_create, &a);
u16 txq_sz;
u8 default_is_intr_mode : 1;
u8 consistent_qp : 1;
+ u8 queue_per_thread : 1;
/* return */
u32 sw_if_index;
vnet_dev_port_op_t vnet_dev_port_if_remove;
/* queue.c */
-vnet_dev_rv_t vnet_dev_rx_queue_alloc (vlib_main_t *, vnet_dev_port_t *, u16);
-vnet_dev_rv_t vnet_dev_tx_queue_alloc (vlib_main_t *, vnet_dev_port_t *, u16);
+vnet_dev_rv_t vnet_dev_rx_queue_alloc (vlib_main_t *, vnet_dev_port_t *, u16,
+ vnet_dev_queue_id_t,
+ clib_thread_index_t);
+vnet_dev_rv_t vnet_dev_tx_queue_alloc (vlib_main_t *, vnet_dev_port_t *, u16,
+ vnet_dev_queue_id_t);
vnet_dev_rx_queue_op_no_rv_t vnet_dev_rx_queue_free;
vnet_dev_tx_queue_op_no_rv_t vnet_dev_tx_queue_free;
void vnet_dev_rx_queue_add_counters (vlib_main_t *, vnet_dev_rx_queue_t *,
foreach_vnet_dev_flag;
#undef _
+#ifndef VL_API_DEV_PORT_FLAG_QUEUE_PER_THREAD
+#define VL_API_DEV_PORT_FLAG_QUEUE_PER_THREAD VNET_DEV_PORT_F_QUEUE_PER_THREAD
+#endif
+
#define _(b, n, d) \
STATIC_ASSERT ((int) VL_API_DEV_PORT_FLAG_##n == (int) VNET_DEV_PORT_F_##n, \
"");
a->num_rx_queues, a->rxq_sz, a->num_tx_queues, a->txq_sz);
for (int i = 0; i < ifs->num_rx_queues; i++)
- if ((rv = vnet_dev_rx_queue_alloc (vm, port, ifs->rxq_sz)) != VNET_DEV_OK)
- goto error;
+ {
+ clib_thread_index_t ti = 0;
+ if (n_threads > 1)
+ {
+ if (!a->queue_per_thread)
+ {
+ ti = dm->next_rx_queue_thread++;
+ if (dm->next_rx_queue_thread >= n_threads)
+ dm->next_rx_queue_thread = 0;
+ }
+ else
+ ti = i;
+ }
+ if ((rv = vnet_dev_rx_queue_alloc (vm, port, ifs->rxq_sz, i, ti)) !=
+ VNET_DEV_OK)
+ goto error;
+ }
for (u32 i = 0; i < ifs->num_tx_queues; i++)
- if ((rv = vnet_dev_tx_queue_alloc (vm, port, ifs->txq_sz)) != VNET_DEV_OK)
+ if ((rv = vnet_dev_tx_queue_alloc (vm, port, ifs->txq_sz, i)) !=
+ VNET_DEV_OK)
goto error;
for (ti = 0; ti < n_threads; ti++)
vnet_dev_rv_t
vnet_dev_rx_queue_alloc (vlib_main_t *vm, vnet_dev_port_t *port,
- u16 queue_size)
+ u16 queue_size, vnet_dev_queue_id_t qid,
+ clib_thread_index_t ti)
{
- vnet_dev_main_t *dm = &vnet_dev_main;
vnet_dev_rx_queue_t *rxq, **qp;
vnet_dev_t *dev = port->dev;
vnet_dev_rv_t rv = VNET_DEV_OK;
- u16 n_threads = vlib_get_n_threads ();
vnet_dev_port_validate (vm, port);
rxq->index = qp - port->rx_queues;
/* default queue id - can be changed by driver */
- rxq->queue_id = qp - port->rx_queues;
+ rxq->queue_id = qid;
ASSERT (rxq->queue_id < port->attr.max_rx_queues);
- if (n_threads > 1)
- {
- rxq->rx_thread_index = dm->next_rx_queue_thread++;
- if (dm->next_rx_queue_thread >= n_threads)
- dm->next_rx_queue_thread = 1;
- }
+ rxq->rx_thread_index = ti;
if (port->rx_queue_ops.alloc)
rv = port->rx_queue_ops.alloc (vm, rxq);
vnet_dev_rv_t
vnet_dev_tx_queue_alloc (vlib_main_t *vm, vnet_dev_port_t *port,
- u16 queue_size)
+ u16 queue_size, vnet_dev_queue_id_t qid)
{
vnet_dev_tx_queue_t *txq, **qp;
vnet_dev_t *dev = port->dev;
txq->size = queue_size;
txq->index = qp - port->tx_queues;
- /* default queue id - can be changed by driver */
- txq->queue_id = qp - port->tx_queues;
+ txq->queue_id = qid;
ASSERT (txq->queue_id < port->attr.max_tx_queues);
if (port->tx_queue_ops.alloc)
/* do not change bit assignments - API dependency */
#define foreach_vnet_dev_port_flag \
_ (0, INTERRUPT_MODE, "enable interrupt mode") \
- _ (1, CONSISTENT_QP, "consistent queue pairs")
+ _ (1, CONSISTENT_QP, "consistent queue pairs") \
+ _ (2, QUEUE_PER_THREAD, "one rx and one tx queue per thread (inc main)")
typedef union
{