Skip to content

Commit

Permalink
netdev: Add function for configuring tx and rx queues.
Browse files Browse the repository at this point in the history
This commit adds a new API to the 'struct netdev_class' which
allows user to configure the number of tx queues and rx queues
of 'netdev'.  Upcoming patches will use this function to set
multiple tx/rx queues when adding the netdev to dpif-netdev.

Currently, only netdev-dpdk module implements this function.

Signed-off-by: Alex Wang <[email protected]>
Acked-by: Pravin B Shelar <[email protected]>
  • Loading branch information
yew011 committed Sep 15, 2014
1 parent 2f9dd77 commit 5496878
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 9 deletions.
1 change: 1 addition & 0 deletions lib/netdev-bsd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1563,6 +1563,7 @@ netdev_bsd_update_flags(struct netdev *netdev_, enum netdev_flags off,
NULL, /* set_config */ \
NULL, /* get_tunnel_config */ \
NULL, /* get_numa_id */ \
NULL, /* set_multiq */ \
\
netdev_bsd_send, \
netdev_bsd_send_wait, \
Expand Down
50 changes: 41 additions & 9 deletions lib/netdev-dpdk.c
Original file line number Diff line number Diff line change
Expand Up @@ -398,13 +398,14 @@ dpdk_eth_dev_init(struct netdev_dpdk *dev) OVS_REQUIRES(dpdk_mutex)
return ENODEV;
}

diag = rte_eth_dev_configure(dev->port_id, NR_QUEUE, NR_QUEUE, &port_conf);
diag = rte_eth_dev_configure(dev->port_id, dev->up.n_rxq, dev->up.n_txq,
&port_conf);
if (diag) {
VLOG_ERR("eth dev config error %d",diag);
return -diag;
}

for (i = 0; i < NR_QUEUE; i++) {
for (i = 0; i < dev->up.n_txq; i++) {
diag = rte_eth_tx_queue_setup(dev->port_id, i, NIC_PORT_TX_Q_SIZE,
dev->socket_id, &tx_conf);
if (diag) {
Expand All @@ -413,7 +414,7 @@ dpdk_eth_dev_init(struct netdev_dpdk *dev) OVS_REQUIRES(dpdk_mutex)
}
}

for (i = 0; i < NR_QUEUE; i++) {
for (i = 0; i < dev->up.n_rxq; i++) {
diag = rte_eth_rx_queue_setup(dev->port_id, i, NIC_PORT_RX_Q_SIZE,
dev->socket_id,
&rx_conf, dev->dpdk_mp->mp);
Expand Down Expand Up @@ -490,12 +491,12 @@ netdev_dpdk_init(struct netdev *netdev_, unsigned int port_no) OVS_REQUIRES(dpdk
goto unlock;
}

netdev_->n_txq = NR_QUEUE;
netdev_->n_rxq = NR_QUEUE;
err = dpdk_eth_dev_init(netdev);
if (err) {
goto unlock;
}
netdev_->n_txq = NR_QUEUE;
netdev_->n_rxq = NR_QUEUE;

list_push_back(&dpdk_list, &netdev->list_node);

Expand Down Expand Up @@ -589,6 +590,30 @@ netdev_dpdk_get_numa_id(const struct netdev *netdev_)
return netdev->socket_id;
}

/* Sets the number of tx queues and rx queues for the dpdk interface.
* If the configuration fails, do not try restoring its old configuration
* and just returns the error. */
static int
netdev_dpdk_set_multiq(struct netdev *netdev_, unsigned int n_txq,
unsigned int n_rxq)
{
struct netdev_dpdk *netdev = netdev_dpdk_cast(netdev_);
int err = 0;

if (netdev->up.n_txq == n_txq && netdev->up.n_rxq == n_rxq) {
return err;
}

ovs_mutex_lock(&netdev->mutex);
rte_eth_dev_stop(netdev->port_id);
netdev->up.n_txq = n_txq;
netdev->up.n_rxq = n_rxq;
err = dpdk_eth_dev_init(netdev);
ovs_mutex_unlock(&netdev->mutex);

return err;
}

static struct netdev_rxq *
netdev_dpdk_rxq_alloc(void)
{
Expand Down Expand Up @@ -686,7 +711,11 @@ netdev_dpdk_rxq_recv(struct netdev_rxq *rxq_, struct dpif_packet **packets,
struct netdev_dpdk *dev = netdev_dpdk_cast(netdev);
int nb_rx;

dpdk_queue_flush(dev, rxq_->queue_id);
/* There is only one tx queue for this core. Do not flush other
* queueus. */
if (rxq_->queue_id == rte_lcore_id()) {
dpdk_queue_flush(dev, rxq_->queue_id);
}

nb_rx = rte_eth_rx_burst(rx->port_id, rxq_->queue_id,
(struct rte_mbuf **) packets,
Expand Down Expand Up @@ -1326,7 +1355,7 @@ netdev_dpdk_ring_construct(struct netdev *netdev)
return err;
}

#define NETDEV_DPDK_CLASS(NAME, INIT, CONSTRUCT) \
#define NETDEV_DPDK_CLASS(NAME, INIT, CONSTRUCT, MULTIQ) \
{ \
NAME, \
INIT, /* init */ \
Expand All @@ -1341,6 +1370,7 @@ netdev_dpdk_ring_construct(struct netdev *netdev)
NULL, /* netdev_dpdk_set_config */ \
NULL, /* get_tunnel_config */ \
netdev_dpdk_get_numa_id, /* get_numa_id */ \
MULTIQ, /* set_multiq */ \
\
netdev_dpdk_send, /* send */ \
NULL, /* send_wait */ \
Expand Down Expand Up @@ -1427,13 +1457,15 @@ const struct netdev_class dpdk_class =
NETDEV_DPDK_CLASS(
"dpdk",
dpdk_class_init,
netdev_dpdk_construct);
netdev_dpdk_construct,
netdev_dpdk_set_multiq);

const struct netdev_class dpdk_ring_class =
NETDEV_DPDK_CLASS(
"dpdkr",
NULL,
netdev_dpdk_ring_construct);
netdev_dpdk_ring_construct,
NULL);

void
netdev_dpdk_register(void)
Expand Down
1 change: 1 addition & 0 deletions lib/netdev-dummy.c
Original file line number Diff line number Diff line change
Expand Up @@ -1033,6 +1033,7 @@ static const struct netdev_class dummy_class = {
netdev_dummy_set_config,
NULL, /* get_tunnel_config */
NULL, /* get_numa_id */
NULL, /* set_multiq */

netdev_dummy_send, /* send */
NULL, /* send_wait */
Expand Down
1 change: 1 addition & 0 deletions lib/netdev-linux.c
Original file line number Diff line number Diff line change
Expand Up @@ -2716,6 +2716,7 @@ netdev_linux_update_flags(struct netdev *netdev_, enum netdev_flags off,
NULL, /* set_config */ \
NULL, /* get_tunnel_config */ \
NULL, /* get_numa_id */ \
NULL, /* set_multiq */ \
\
netdev_linux_send, \
netdev_linux_send_wait, \
Expand Down
10 changes: 10 additions & 0 deletions lib/netdev-provider.h
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,16 @@ struct netdev_class {
* such info, returns NETDEV_NUMA_UNSPEC. */
int (*get_numa_id)(const struct netdev *netdev);

/* Configures the number of tx queues and rx queues of 'netdev'.
* Return 0 if successful, otherwise a positive errno value.
*
* On error, the tx queue and rx queue configuration is indeterminant.
* Caller should make decision on whether to restore the previous or
* the default configuration. Also, caller must make sure there is no
* other thread accessing the queues at the same time. */
int (*set_multiq)(struct netdev *netdev, unsigned int n_txq,
unsigned int n_rxq);

/* Sends buffers on 'netdev'.
* Returns 0 if successful (for every buffer), otherwise a positive errno
* value. Returns EAGAIN without blocking if one or more packets cannot be
Expand Down
1 change: 1 addition & 0 deletions lib/netdev-vport.c
Original file line number Diff line number Diff line change
Expand Up @@ -776,6 +776,7 @@ get_stats(const struct netdev *netdev, struct netdev_stats *stats)
SET_CONFIG, \
GET_TUNNEL_CONFIG, \
NULL, /* get_numa_id */ \
NULL, /* set_multiq */ \
\
NULL, /* send */ \
NULL, /* send_wait */ \
Expand Down
27 changes: 27 additions & 0 deletions lib/netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,33 @@ netdev_rxq_drain(struct netdev_rxq *rx)
: 0);
}

/* Configures the number of tx queues and rx queues of 'netdev'.
* Return 0 if successful, otherwise a positive errno value.
*
* On error, the tx queue and rx queue configuration is indeterminant.
* Caller should make decision on whether to restore the previous or
* the default configuration. Also, caller must make sure there is no
* other thread accessing the queues at the same time. */
int
netdev_set_multiq(struct netdev *netdev, unsigned int n_txq,
unsigned int n_rxq)
{
int error;

error = (netdev->netdev_class->set_multiq
? netdev->netdev_class->set_multiq(netdev,
MAX(n_txq, 1),
MAX(n_rxq, 1))
: EOPNOTSUPP);

if (error != EOPNOTSUPP) {
VLOG_DBG_RL(&rl, "failed to set tx/rx queue for network device %s:"
"%s", netdev_get_name(netdev), ovs_strerror(error));
}

return error;
}

/* Sends 'buffers' on 'netdev'. Returns 0 if successful (for every packet),
* otherwise a positive errno value. Returns EAGAIN without blocking if
* at least one the packets cannot be queued immediately. Returns EMSGSIZE
Expand Down
1 change: 1 addition & 0 deletions lib/netdev.h
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ const char *netdev_get_type_from_name(const char *);
int netdev_get_mtu(const struct netdev *, int *mtup);
int netdev_set_mtu(const struct netdev *, int mtu);
int netdev_get_ifindex(const struct netdev *);
int netdev_set_multiq(struct netdev *, unsigned int n_txq, unsigned int n_rxq);

/* Packet reception. */
int netdev_rxq_open(struct netdev *, struct netdev_rxq **, int id);
Expand Down

0 comments on commit 5496878

Please sign in to comment.