#include "odp-util.h"
#include "ofp-print.h"
#include "ofpbuf.h"
+#include "ovs-numa.h"
#include "ovs-rcu.h"
#include "packet-dpif.h"
#include "packets.h"
return EINVAL;
}
+ if (netdev_is_pmd(netdev)) {
+ int n_cores = ovs_numa_get_n_cores();
+
+ if (n_cores == OVS_CORE_UNSPEC) {
+ VLOG_ERR("%s, cannot get cpu core info", devname);
+ return ENOENT;
+ }
+ /* There can only be ovs_numa_get_n_cores() pmd threads,
+ * so creates a tx_q for each. */
+ error = netdev_set_multiq(netdev, n_cores, NR_QUEUE);
+ if (error) {
+ VLOG_ERR("%s, cannot set multiq", devname);
+ return errno;
+ }
+ }
port = xzalloc(sizeof *port);
port->port_no = port_no;
port->netdev = netdev;
struct list list_node OVS_GUARDED_BY(dpdk_mutex);
};
+/* There should be one 'struct dpdk_tx_queue' created for
+ * each cpu core. */
struct dpdk_tx_queue {
rte_spinlock_t tx_lock;
int count;
int port_id;
int max_packet_len;
- struct dpdk_tx_queue tx_q[NR_QUEUE];
+ struct dpdk_tx_queue *tx_q;
struct ovs_mutex mutex OVS_ACQ_AFTER(dpdk_mutex);
return &netdev->up;
}
+static void
+netdev_dpdk_set_txq(struct netdev_dpdk *netdev, unsigned int n_txqs)
+{
+ int i;
+
+ netdev->tx_q = dpdk_rte_mzalloc(n_txqs * sizeof *netdev->tx_q);
+ for (i = 0; i < n_txqs; i++) {
+ rte_spinlock_init(&netdev->tx_q[i].tx_lock);
+ }
+}
+
static int
-netdev_dpdk_init(struct netdev *netdev_, unsigned int port_no) OVS_REQUIRES(dpdk_mutex)
+netdev_dpdk_init(struct netdev *netdev_, unsigned int port_no)
+ OVS_REQUIRES(dpdk_mutex)
{
struct netdev_dpdk *netdev = netdev_dpdk_cast(netdev_);
int err = 0;
- int i;
ovs_mutex_init(&netdev->mutex);
ovs_mutex_lock(&netdev->mutex);
- for (i = 0; i < NR_QUEUE; i++) {
- rte_spinlock_init(&netdev->tx_q[i].tx_lock);
- }
-
+ netdev_dpdk_set_txq(netdev, NR_QUEUE);
netdev->port_id = port_no;
-
netdev->flags = 0;
netdev->mtu = ETHER_MTU;
netdev->max_packet_len = MTU_TO_MAX_LEN(netdev->mtu);
list_push_back(&dpdk_list, &netdev->list_node);
unlock:
+ if (err) {
+ rte_free(netdev->tx_q);
+ }
ovs_mutex_unlock(&netdev->mutex);
return err;
}
ovs_mutex_unlock(&dev->mutex);
ovs_mutex_lock(&dpdk_mutex);
+ rte_free(dev->tx_q);
list_remove(&dev->list_node);
dpdk_mp_put(dev->dpdk_mp);
ovs_mutex_unlock(&dpdk_mutex);
netdev->up.n_txq = n_txq;
netdev->up.n_rxq = n_rxq;
err = dpdk_eth_dev_init(netdev);
+ if (!err && netdev->up.n_txq != n_txq) {
+ rte_free(netdev->tx_q);
+ netdev_dpdk_set_txq(netdev, n_txq);
+ }
ovs_mutex_unlock(&netdev->mutex);
return err;
int next_tx_idx = 0;
int dropped = 0;
- qid = rte_lcore_id() % NR_QUEUE;
+ qid = rte_lcore_id();
for (i = 0; i < cnt; i++) {
int size = ofpbuf_size(&pkts[i]->ofpbuf);