On Fri, Sep 08, 2017 at 10:50:49AM +0200, Maxime Coquelin wrote:
> >>>>+{
> >>>>+ struct vhost_iotlb_entry *node, *temp_node;
> >>>>+
> >>>>+ rte_rwlock_write_lock(&vq->iotlb_lock);
> >>>>+
> >>>>+ TAILQ_FOREACH_SAFE(node, &vq->iotlb_list, next, temp_node) {
> >>>>+         TAILQ_REMOVE(&vq->iotlb_list, node, next);
> >>>>+         rte_mempool_put(vq->iotlb_pool, node);
> >>>>+ }
> >>>>+
> >>>>+ rte_rwlock_write_unlock(&vq->iotlb_lock);
> >>>>+}
> >>>>+
> >>>>+void vhost_user_iotlb_cache_insert(struct vhost_virtqueue *vq, uint64_t 
> >>>>iova,
> >>>>+                         uint64_t uaddr, uint64_t size, uint8_t perm)
> >>>>+{
> >>>>+ struct vhost_iotlb_entry *node, *new_node;
> >>>>+ int ret;
> >>>>+
> >>>>+ ret = rte_mempool_get(vq->iotlb_pool, (void **)&new_node);
> >>>>+ if (ret) {
> >>>>+         RTE_LOG(ERR, VHOST_CONFIG, "IOTLB pool empty, invalidate 
> >>>>cache\n");
> >>>
> >>>It's a cache, why not considering remove one to get space for new one?
> >>
> >>It would mean having to track every lookups not to remove hot entries,
> >>which would have an impact on performance.
> >
> >You were removing all caches, how can we do worse than that? Even a
> >random evict would be better. Or, more simply, just to remove the
> >head or the tail?
> 
> I think removing head or tail could cause deadlocks.
> For example it needs to translate from 0x0 to 0x2000, with page size
> being 0x1000.
> 
> If cache is full, when inserting 0x1000-0x1fff, it will remove
> 0x0-0xfff, so a miss will be sent for 0x0-0xffff and 0x1000-0x1fff will
> be remove at insert time, etc...

Okay, that means we can't simply remove the head or tail.

> Note that we really need to size the cache large enough for performance
> purpose, so having the cache full could be cause by either buggy or
> malicious guest.

I agree. But for the malicious guest, it could lead to a DDOS attack:
assume it keeps vhost running out of cache and then vhost keeps printing
above message.

What I suggested was to evict one (by some polices) to get a space for
the new one we want to insert. Note that it won't be a performance issue,
IMO, due to we only do that when we run out of caches, which, according
to your sayings, should not happen in normal cases.

        --yliu

> >>Moreover, the idea is to have the cache large enough, else you could
> >>face packet drops due to random cache misses.
> >>
> >>We might consider to improve it, but I consider it an optimization that
> >>could be implemented later if needed.
> >>
> >>>>+         vhost_user_iotlb_cache_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;
> >>>>+         }
> >>>>+ }

Reply via email to