/* * dpdk_virtual_if_add - add a virtual (virtio) interface to vrouter. * Returns 0 on success, < 0 otherwise. */ static int dpdk_virtual_if_add(struct vr_interface *vif) { int ret; unsigned int nrxqs, ntxqs; RTE_LOG(INFO, VROUTER, "Adding vif %u virtual device %s\n", vif->vif_idx, vif->vif_name); nrxqs = vr_dpdk_virtio_nrxqs(vif); ntxqs = vr_dpdk_virtio_ntxqs(vif); ret = vr_dpdk_lcore_if_schedule(vif, vr_dpdk_lcore_least_used_get(), nrxqs, &vr_dpdk_virtio_rx_queue_init, ntxqs, &vr_dpdk_virtio_tx_queue_init); if (ret) { return ret; } /* * When something goes wrong, vr_netlink_uvhost_vif_add() returns * non-zero value. Then we return this value here. It is handled by * dp-core and dpdk_virtual_if_del() is called, so there is no need * to do it manually here. * * Check dp-core/vf_interface.c:eth_drv_add() for reference. */ return vr_netlink_uvhost_vif_add(vif->vif_name, vif->vif_idx, nrxqs, ntxqs); }
/* * vr_dpdk_virtio_tx_queue_init - initializes a virtio TX queue. * * Returns a pointer to the TX queue on success, NULL otherwise. */ struct vr_dpdk_queue * vr_dpdk_virtio_tx_queue_init(unsigned int lcore_id, struct vr_interface *vif, unsigned int queue_or_lcore_id) { uint16_t queue_id = queue_or_lcore_id; struct vr_dpdk_lcore *lcore = vr_dpdk.lcores[lcore_id]; const unsigned int socket_id = rte_lcore_to_socket_id(lcore_id); unsigned int vif_idx = vif->vif_idx; struct vr_dpdk_queue *tx_queue = &lcore->lcore_tx_queues[vif_idx]; struct vr_dpdk_queue_params *tx_queue_params = &lcore->lcore_tx_queue_params[vif_idx]; /* Check input parameters */ /* virtio TX is thread safe, so just use one of the rings */ queue_id = queue_id % vr_dpdk_virtio_ntxqs(vif); /* init queue */ tx_queue->txq_ops = vr_dpdk_virtio_writer_ops; tx_queue->q_vif = vrouter_get_interface(vif->vif_rid, vif_idx); /* init virtio queue */ vr_dpdk_virtio_txqs[vif_idx][queue_id].vdv_ready_state = VQ_NOT_READY; vr_dpdk_virtio_txqs[vif_idx][queue_id].vdv_last_used_idx = 0; vr_dpdk_virtio_txqs[vif_idx][queue_id].vdv_last_used_idx_res = 0; vr_dpdk_virtio_txqs[vif_idx][queue_id].vdv_vif_idx = vif->vif_idx; /* create the queue */ struct dpdk_virtio_writer_params writer_params = { .tx_virtioq = &vr_dpdk_virtio_txqs[vif_idx][queue_id], }; tx_queue->q_queue_h = tx_queue->txq_ops.f_create(&writer_params, socket_id); if (tx_queue->q_queue_h == NULL) { RTE_LOG(ERR, VROUTER, " error creating virtio device %s TX queue %" PRIu16 "\n", vif->vif_name, queue_id); return NULL; } /* store queue params */ tx_queue_params->qp_release_op = &dpdk_virtio_tx_queue_release; return tx_queue; }