X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=lib%2Flibrte_vhost%2Fvhost.h;h=686ce42a209d03a6f34449944af1a5d77bfc84a2;hb=f1ae60d696cb92d6529f37630e1f08defa4a80e3;hp=5131a97a39c527163cd3fc46fc03209c8cf69849;hpb=039253166a57ee660dd2fbe92ca77fa65154751c;p=dpdk.git diff --git a/lib/librte_vhost/vhost.h b/lib/librte_vhost/vhost.h index 5131a97a39..686ce42a20 100644 --- a/lib/librte_vhost/vhost.h +++ b/lib/librte_vhost/vhost.h @@ -39,6 +39,38 @@ #define VHOST_LOG_CACHE_NR 32 +#define PACKED_DESC_ENQUEUE_USED_FLAG(w) \ + ((w) ? (VRING_DESC_F_AVAIL | VRING_DESC_F_USED | VRING_DESC_F_WRITE) : \ + VRING_DESC_F_WRITE) +#define PACKED_DESC_DEQUEUE_USED_FLAG(w) \ + ((w) ? (VRING_DESC_F_AVAIL | VRING_DESC_F_USED) : 0x0) +#define PACKED_DESC_SINGLE_DEQUEUE_FLAG (VRING_DESC_F_NEXT | \ + VRING_DESC_F_INDIRECT) + +#define PACKED_BATCH_SIZE (RTE_CACHE_LINE_SIZE / \ + sizeof(struct vring_packed_desc)) +#define PACKED_BATCH_MASK (PACKED_BATCH_SIZE - 1) + +#ifdef VHOST_GCC_UNROLL_PRAGMA +#define vhost_for_each_try_unroll(iter, val, size) _Pragma("GCC unroll 4") \ + for (iter = val; iter < size; iter++) +#endif + +#ifdef VHOST_CLANG_UNROLL_PRAGMA +#define vhost_for_each_try_unroll(iter, val, size) _Pragma("unroll 4") \ + for (iter = val; iter < size; iter++) +#endif + +#ifdef VHOST_ICC_UNROLL_PRAGMA +#define vhost_for_each_try_unroll(iter, val, size) _Pragma("unroll (4)") \ + for (iter = val; iter < size; iter++) +#endif + +#ifndef vhost_for_each_try_unroll +#define vhost_for_each_try_unroll(iter, val, num) \ + for (iter = val; iter < num; iter++) +#endif + /** * Structure contains buffer address, length and descriptor index * from vring to do scatter RX. @@ -84,6 +116,7 @@ struct log_cache_entry { struct vring_used_elem_packed { uint16_t id; + uint16_t flags; uint32_t len; uint32_t count; }; @@ -128,6 +161,14 @@ struct vhost_virtqueue { /* Physical address of used ring, for logging */ uint64_t log_guest_addr; + /* inflight share memory info */ + union { + struct rte_vhost_inflight_info_split *inflight_split; + struct rte_vhost_inflight_info_packed *inflight_packed; + }; + struct rte_vhost_resubmit_info *resubmit_inflight; + uint64_t global_counter; + uint16_t nr_zmbuf; uint16_t zmbuf_size; uint16_t last_zmbuf_idx; @@ -139,6 +180,10 @@ struct vhost_virtqueue { struct vring_used_elem_packed *shadow_used_packed; }; uint16_t shadow_used_idx; + /* Record packed ring enqueue latest desc cache aligned index */ + uint16_t shadow_aligned_idx; + /* Record packed ring first dequeue desc index */ + uint16_t shadow_last_used_idx; struct vhost_vring_addr ring_addrs; struct batch_copy_elem *batch_copy_elems; @@ -286,6 +331,12 @@ struct guest_page { uint64_t size; }; +struct inflight_mem_info { + int fd; + void *addr; + uint64_t size; +}; + /** * Device structure contains all configuration information relating * to the device. @@ -302,7 +353,10 @@ struct virtio_net { rte_atomic16_t broadcast_rarp; uint32_t nr_vring; int dequeue_zero_copy; + int extbuf; + int linearbuf; struct vhost_virtqueue *virtqueue[VHOST_MAX_QUEUE_PAIRS * 2]; + struct inflight_mem_info *inflight_info; #define IF_NAME_SZ (PATH_MAX > IFNAMSIZ ? PATH_MAX : IFNAMSIZ) char ifname[IF_NAME_SZ]; uint64_t log_size; @@ -344,18 +398,43 @@ vq_is_packed(struct virtio_net *dev) static inline bool desc_is_avail(struct vring_packed_desc *desc, bool wrap_counter) { - uint16_t flags = *((volatile uint16_t *) &desc->flags); + uint16_t flags = __atomic_load_n(&desc->flags, __ATOMIC_ACQUIRE); return wrap_counter == !!(flags & VRING_DESC_F_AVAIL) && wrap_counter != !!(flags & VRING_DESC_F_USED); } +static inline void +vq_inc_last_used_packed(struct vhost_virtqueue *vq, uint16_t num) +{ + vq->last_used_idx += num; + if (vq->last_used_idx >= vq->size) { + vq->used_wrap_counter ^= 1; + vq->last_used_idx -= vq->size; + } +} + +static inline void +vq_inc_last_avail_packed(struct vhost_virtqueue *vq, uint16_t num) +{ + vq->last_avail_idx += num; + if (vq->last_avail_idx >= vq->size) { + vq->avail_wrap_counter ^= 1; + vq->last_avail_idx -= vq->size; + } +} + void __vhost_log_cache_write(struct virtio_net *dev, struct vhost_virtqueue *vq, uint64_t addr, uint64_t len); +void __vhost_log_cache_write_iova(struct virtio_net *dev, + struct vhost_virtqueue *vq, + uint64_t iova, uint64_t len); void __vhost_log_cache_sync(struct virtio_net *dev, struct vhost_virtqueue *vq); void __vhost_log_write(struct virtio_net *dev, uint64_t addr, uint64_t len); +void __vhost_log_write_iova(struct virtio_net *dev, struct vhost_virtqueue *vq, + uint64_t iova, uint64_t len); static __rte_always_inline void vhost_log_write(struct virtio_net *dev, uint64_t addr, uint64_t len) @@ -393,14 +472,47 @@ vhost_log_used_vring(struct virtio_net *dev, struct vhost_virtqueue *vq, vhost_log_write(dev, vq->log_guest_addr + offset, len); } -/* Macros for printing using RTE_LOG */ -#define RTE_LOGTYPE_VHOST_CONFIG RTE_LOGTYPE_USER1 -#define RTE_LOGTYPE_VHOST_DATA RTE_LOGTYPE_USER1 +static __rte_always_inline void +vhost_log_cache_write_iova(struct virtio_net *dev, struct vhost_virtqueue *vq, + uint64_t iova, uint64_t len) +{ + if (likely(!(dev->features & (1ULL << VHOST_F_LOG_ALL)))) + return; + + if (dev->features & (1ULL << VIRTIO_F_IOMMU_PLATFORM)) + __vhost_log_cache_write_iova(dev, vq, iova, len); + else + __vhost_log_cache_write(dev, vq, iova, len); +} + +static __rte_always_inline void +vhost_log_write_iova(struct virtio_net *dev, struct vhost_virtqueue *vq, + uint64_t iova, uint64_t len) +{ + if (likely(!(dev->features & (1ULL << VHOST_F_LOG_ALL)))) + return; + + if (dev->features & (1ULL << VIRTIO_F_IOMMU_PLATFORM)) + __vhost_log_write_iova(dev, vq, iova, len); + else + __vhost_log_write(dev, iova, len); +} + +extern int vhost_config_log_level; +extern int vhost_data_log_level; + +#define VHOST_LOG_CONFIG(level, fmt, args...) \ + rte_log(RTE_LOG_ ## level, vhost_config_log_level, \ + "VHOST_CONFIG: " fmt, ##args) + +#define VHOST_LOG_DATA(level, fmt, args...) \ + (void)((RTE_LOG_ ## level <= RTE_LOG_DP_LEVEL) ? \ + rte_log(RTE_LOG_ ## level, vhost_data_log_level, \ + "VHOST_DATA : " fmt, ##args) : \ + 0) #ifdef RTE_LIBRTE_VHOST_DEBUG #define VHOST_MAX_PRINT_BUFF 6072 -#define VHOST_LOG_DEBUG(log_type, fmt, args...) \ - RTE_LOG(DEBUG, log_type, fmt, ##args) #define PRINT_PACKET(device, addr, size, header) do { \ char *pkt_addr = (char *)(addr); \ unsigned int index; \ @@ -416,10 +528,9 @@ vhost_log_used_vring(struct virtio_net *dev, struct vhost_virtqueue *vq, } \ snprintf(packet + strnlen(packet, VHOST_MAX_PRINT_BUFF), VHOST_MAX_PRINT_BUFF - strnlen(packet, VHOST_MAX_PRINT_BUFF), "\n"); \ \ - VHOST_LOG_DEBUG(VHOST_DATA, "%s", packet); \ + VHOST_LOG_DATA(DEBUG, "%s", packet); \ } while (0) #else -#define VHOST_LOG_DEBUG(log_type, fmt, args...) do {} while (0) #define PRINT_PACKET(device, addr, size, header) do {} while (0) #endif @@ -447,13 +558,33 @@ gpa_to_hpa(struct virtio_net *dev, uint64_t gpa, uint64_t size) return 0; } +static __rte_always_inline uint64_t +hva_to_gpa(struct virtio_net *dev, uint64_t vva, uint64_t len) +{ + struct rte_vhost_mem_region *r; + uint32_t i; + + if (unlikely(!dev || !dev->mem)) + return 0; + + for (i = 0; i < dev->mem->nregions; i++) { + r = &dev->mem->regions[i]; + + if (vva >= r->host_user_addr && + vva + len < r->host_user_addr + r->size) { + return r->guest_phys_addr + vva - r->host_user_addr; + } + } + return 0; +} + static __rte_always_inline struct virtio_net * get_device(int vid) { struct virtio_net *dev = vhost_devices[vid]; if (unlikely(!dev)) { - RTE_LOG(ERR, VHOST_CONFIG, + VHOST_LOG_CONFIG(ERR, "(%d) device not found.\n", vid); } @@ -467,6 +598,7 @@ void vhost_destroy_device(int); void vhost_destroy_device_notify(struct virtio_net *dev); void cleanup_vq(struct vhost_virtqueue *vq, int destroy); +void cleanup_vq_inflight(struct virtio_net *dev, struct vhost_virtqueue *vq); void free_vq(struct virtio_net *dev, struct vhost_virtqueue *vq); int alloc_vring_queue(struct virtio_net *dev, uint32_t vring_idx); @@ -476,6 +608,8 @@ void vhost_attach_vdpa_device(int vid, int did); void vhost_set_ifname(int, const char *if_name, unsigned int if_len); void vhost_enable_dequeue_zero_copy(int vid); void vhost_set_builtin_virtio_net(int vid, bool enable); +void vhost_enable_extbuf(int vid); +void vhost_enable_linearbuf(int vid); struct vhost_device_ops const *vhost_driver_callback_get(const char *path); @@ -536,7 +670,7 @@ vhost_vring_call_split(struct virtio_net *dev, struct vhost_virtqueue *vq) vq->signalled_used = new; vq->signalled_used_valid = true; - VHOST_LOG_DEBUG(VHOST_DATA, "%s: used_event_idx=%d, old=%d, new=%d\n", + VHOST_LOG_DATA(DEBUG, "%s: used_event_idx=%d, old=%d, new=%d\n", __func__, vhost_used_event(vq), old, new);