Cache address translation result and use it in next translation. Due
to limited regions are supported, buffers are most likely in same
region when doing data transmission.

Signed-off-by: Marvin Liu <yong....@intel.com>

diff --git a/lib/librte_vhost/rte_vhost.h b/lib/librte_vhost/rte_vhost.h
index 7fb172912..d90235cd6 100644
--- a/lib/librte_vhost/rte_vhost.h
+++ b/lib/librte_vhost/rte_vhost.h
@@ -91,10 +91,18 @@ struct rte_vhost_mem_region {
        int fd;
 };
 
+struct rte_vhost_mem_region_cache {
+       uint64_t guest_phys_addr;
+       uint64_t guest_phys_addr_end;
+       int64_t host_user_addr_offset;
+       uint64_t size;
+};
+
 /**
  * Memory structure includes region and mapping information.
  */
 struct rte_vhost_memory {
+       struct rte_vhost_mem_region_cache cache_region;
        uint32_t nregions;
        struct rte_vhost_mem_region regions[];
 };
@@ -232,11 +240,30 @@ rte_vhost_va_from_guest_pa(struct rte_vhost_memory *mem,
        struct rte_vhost_mem_region *r;
        uint32_t i;
 
+       struct rte_vhost_mem_region_cache *r_cache;
+       /* check with cached region */
+       r_cache = &mem->cache_region;
+       if (likely(gpa >= r_cache->guest_phys_addr && gpa <
+                  r_cache->guest_phys_addr_end)) {
+               if (unlikely(*len > r_cache->guest_phys_addr_end - gpa))
+                       *len = r_cache->guest_phys_addr_end - gpa;
+
+               return gpa - r_cache->host_user_addr_offset;
+       }
+
+
        for (i = 0; i < mem->nregions; i++) {
                r = &mem->regions[i];
                if (gpa >= r->guest_phys_addr &&
                    gpa <  r->guest_phys_addr + r->size) {
 
+                       r_cache->guest_phys_addr = r->guest_phys_addr;
+                       r_cache->guest_phys_addr_end = r->guest_phys_addr +
+                                                      r->size;
+                       r_cache->size = r->size;
+                       r_cache->host_user_addr_offset = r->guest_phys_addr -
+                                                        r->host_user_addr;
+
                        if (unlikely(*len > r->guest_phys_addr + r->size - gpa))
                                *len = r->guest_phys_addr + r->size - gpa;
 
-- 
2.17.1

Reply via email to