#define IOTLB_CACHE_SIZE 2048
+static void
+vhost_user_iotlb_cache_random_evict(struct vhost_virtqueue *vq);
+
static void
vhost_user_iotlb_pending_remove_all(struct vhost_virtqueue *vq)
{
ret = rte_mempool_get(vq->iotlb_pool, (void **)&node);
if (ret) {
- RTE_LOG(INFO, VHOST_CONFIG,
- "IOTLB pool empty, clear pending misses\n");
- vhost_user_iotlb_pending_remove_all(vq);
+ RTE_LOG(DEBUG, VHOST_CONFIG, "IOTLB pool empty, clear entries\n");
+ if (!TAILQ_EMPTY(&vq->iotlb_pending_list))
+ vhost_user_iotlb_pending_remove_all(vq);
+ else
+ vhost_user_iotlb_cache_random_evict(vq);
ret = rte_mempool_get(vq->iotlb_pool, (void **)&node);
if (ret) {
RTE_LOG(ERR, VHOST_CONFIG, "IOTLB pool still empty, failure\n");
rte_rwlock_write_unlock(&vq->iotlb_pending_lock);
}
-static void
+void
vhost_user_iotlb_pending_remove(struct vhost_virtqueue *vq,
uint64_t iova, uint64_t size, uint8_t perm)
{
ret = rte_mempool_get(vq->iotlb_pool, (void **)&new_node);
if (ret) {
- RTE_LOG(DEBUG, VHOST_CONFIG, "IOTLB pool empty, evict one entry\n");
- vhost_user_iotlb_cache_random_evict(vq);
+ RTE_LOG(DEBUG, VHOST_CONFIG, "IOTLB pool empty, clear entries\n");
+ if (!TAILQ_EMPTY(&vq->iotlb_list))
+ vhost_user_iotlb_cache_random_evict(vq);
+ else
+ vhost_user_iotlb_pending_remove_all(vq);
ret = rte_mempool_get(vq->iotlb_pool, (void **)&new_node);
if (ret) {
RTE_LOG(ERR, VHOST_CONFIG, "IOTLB pool still empty, failure\n");
return vva;
}
+void
+vhost_user_iotlb_flush_all(struct vhost_virtqueue *vq)
+{
+ vhost_user_iotlb_cache_remove_all(vq);
+ vhost_user_iotlb_pending_remove_all(vq);
+}
+
int
vhost_user_iotlb_init(struct virtio_net *dev, int vq_index)
{
* The cache has already been initialized,
* just drop all cached and pending entries.
*/
- vhost_user_iotlb_cache_remove_all(vq);
- vhost_user_iotlb_pending_remove_all(vq);
- return 0;
+ vhost_user_iotlb_flush_all(vq);
}
#ifdef RTE_LIBRTE_VHOST_NUMA