/* * 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; uint16_t nrxqs, ntxqs; RTE_LOG(INFO, VROUTER, "Adding vif %u (gen. %u) virtual device %s\n", vif->vif_idx, vif->vif_gen, vif->vif_name); nrxqs = vr_dpdk_virtio_nrxqs(vif); /* virtio TX is thread safe, so we assign TX queue to each lcore */ ntxqs = (uint16_t)-1; 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_rx_queue_init - initializes a virtio RX queue. * * Returns a pointer to the RX queue on success, NULL otherwise. */ struct vr_dpdk_queue * vr_dpdk_virtio_rx_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 *rx_queue = &lcore->lcore_rx_queues[vif_idx]; struct vr_dpdk_queue_params *rx_queue_params = &lcore->lcore_rx_queue_params[vif_idx]; /* Check input parameters */ if (queue_id >= vr_dpdk_virtio_nrxqs(vif)) { RTE_LOG(ERR, VROUTER, " error creating virtio device %s RX queue %" PRIu16 "\n", vif->vif_name, queue_id); return NULL; } /* init queue */ rx_queue->rxq_ops = vr_dpdk_virtio_reader_ops; rx_queue->q_vif = vrouter_get_interface(vif->vif_rid, vif_idx); /* init virtio queue */ vr_dpdk_virtio_rxqs[vif_idx][queue_id].vdv_ready_state = VQ_NOT_READY; vr_dpdk_virtio_rxqs[vif_idx][queue_id].vdv_last_used_idx = 0; vr_dpdk_virtio_rxqs[vif_idx][queue_id].vdv_last_used_idx_res = 0; vr_dpdk_virtio_rxqs[vif_idx][queue_id].vdv_vif_idx = vif->vif_idx; /* create the queue */ struct dpdk_virtio_reader_params reader_params = { .rx_virtioq = &vr_dpdk_virtio_rxqs[vif_idx][queue_id], }; rx_queue->q_queue_h = rx_queue->rxq_ops.f_create(&reader_params, socket_id); if (rx_queue->q_queue_h == NULL) { RTE_LOG(ERR, VROUTER, " error creating virtio device %s RX queue %" PRIu16 "\n", vif->vif_name, queue_id); return NULL; } /* store queue params */ rx_queue_params->qp_release_op = &dpdk_virtio_rx_queue_release; return rx_queue; }