b86f42e70e8a1055eeac0e9232e0f3ebc43d4f57
[vpp.git] / src / vnet / devices / virtio / vhost_user.h
1 /*
2  * Copyright (c) 2015 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #ifndef __VIRTIO_VHOST_USER_H__
16 #define __VIRTIO_VHOST_USER_H__
17 /* vhost-user data structures */
18
19 #define VHOST_MEMORY_MAX_NREGIONS       8
20 #define VHOST_USER_MSG_HDR_SZ           12
21 #define VHOST_VRING_MAX_SIZE            32768
22 #define VHOST_VRING_MAX_N               16      //8TX + 8RX
23 #define VHOST_VRING_IDX_RX(qid)         (2*qid)
24 #define VHOST_VRING_IDX_TX(qid)         (2*qid + 1)
25
26 #define VHOST_USER_VRING_NOFD_MASK      0x100
27 #define VIRTQ_DESC_F_NEXT               1
28 #define VIRTQ_DESC_F_WRITE              2
29 #define VIRTQ_DESC_F_INDIRECT           4
30
31 #define VIRTQ_DESC_F_AVAIL              (1 << 7)
32 #define VIRTQ_DESC_F_USED               (1 << 15)
33
34 #define VRING_EVENT_F_ENABLE            0x0
35 #define VRING_EVENT_F_DISABLE           0x1
36 #define VRING_EVENT_F_DESC              0x2
37
38 #define VHOST_USER_PROTOCOL_F_MQ   0
39 #define VHOST_USER_PROTOCOL_F_LOG_SHMFD 1
40 #define VHOST_VRING_F_LOG 0
41
42 #define VHOST_USER_F_PROTOCOL_FEATURES  30
43 #define VHOST_USER_PROTOCOL_FEATURES   ((1ULL << VHOST_USER_PROTOCOL_F_MQ) |    \
44                                         (1ULL << VHOST_USER_PROTOCOL_F_LOG_SHMFD))
45
46 /* If multiqueue is provided by host, then we support it. */
47 #define VIRTIO_NET_CTRL_MQ   4
48 #define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET        0
49 #define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MIN        1
50 #define VIRTIO_NET_CTRL_MQ_VQ_PAIRS_MAX        0x8000
51
52 #define VRING_USED_F_NO_NOTIFY  1
53 #define VRING_AVAIL_F_NO_INTERRUPT 1
54
55 #define vu_log_debug(dev, f, ...) \
56 {                                                                             \
57   vlib_log(VLIB_LOG_LEVEL_DEBUG, vhost_user_main.log_default, "%U: " f,       \
58            format_vnet_hw_if_index_name, vnet_get_main(),                     \
59            dev->hw_if_index, ##__VA_ARGS__);                                  \
60 };
61
62 #define vu_log_warn(dev, f, ...) \
63 {                                                                             \
64   vlib_log(VLIB_LOG_LEVEL_WARNING, vhost_user_main.log_default, "%U: " f,     \
65            format_vnet_hw_if_index_name, vnet_get_main(),                     \
66            dev->hw_if_index, ##__VA_ARGS__);                                  \
67 };
68 #define vu_log_err(dev, f, ...) \
69 {                                                                             \
70   vlib_log(VLIB_LOG_LEVEL_ERR, vhost_user_main.log_default, "%U: " f,         \
71            format_vnet_hw_if_index_name, vnet_get_main(),                     \
72            dev->hw_if_index, ##__VA_ARGS__);                                  \
73 };
74
75 #define UNIX_GET_FD(unixfd_idx) ({ \
76     typeof(unixfd_idx) __unixfd_idx = (unixfd_idx); \
77     (__unixfd_idx != ~0) ? \
78         pool_elt_at_index (file_main.file_pool, \
79                            __unixfd_idx)->file_descriptor : -1; })
80
81 #define foreach_virtio_trace_flags \
82   _ (SIMPLE_CHAINED, 0, "Simple descriptor chaining") \
83   _ (SINGLE_DESC,  1, "Single descriptor packet") \
84   _ (INDIRECT, 2, "Indirect descriptor") \
85   _ (MAP_ERROR, 4, "Memory mapping error")
86
87 typedef enum
88 {
89 #define _(n,i,s) VIRTIO_TRACE_F_##n,
90   foreach_virtio_trace_flags
91 #undef _
92 } virtio_trace_flag_t;
93
94 #define foreach_virtio_net_feature      \
95  _ (VIRTIO_NET_F_CSUM, 0)               \
96  _ (VIRTIO_NET_F_GUEST_CSUM, 1)         \
97  _ (VIRTIO_NET_F_GUEST_TSO4, 7)         \
98  _ (VIRTIO_NET_F_GUEST_TSO6, 8)         \
99  _ (VIRTIO_NET_F_GUEST_UFO, 10)         \
100  _ (VIRTIO_NET_F_HOST_TSO4, 11)         \
101  _ (VIRTIO_NET_F_HOST_TSO6, 12)         \
102  _ (VIRTIO_NET_F_HOST_UFO, 14)          \
103  _ (VIRTIO_NET_F_MRG_RXBUF, 15)         \
104  _ (VIRTIO_NET_F_CTRL_VQ, 17)           \
105  _ (VIRTIO_NET_F_GUEST_ANNOUNCE, 21)    \
106  _ (VIRTIO_NET_F_MQ, 22)                \
107  _ (VHOST_F_LOG_ALL, 26)                \
108  _ (VIRTIO_F_ANY_LAYOUT, 27)            \
109  _ (VIRTIO_F_INDIRECT_DESC, 28)         \
110  _ (VIRTIO_F_EVENT_IDX, 29)             \
111  _ (VHOST_USER_F_PROTOCOL_FEATURES, 30) \
112  _ (VIRTIO_F_VERSION_1, 32)             \
113  _ (VIRTIO_F_RING_PACKED, 34)           \
114  _ (VIRTIO_F_IN_ORDER, 35)
115
116 typedef enum
117 {
118 #define _(f,n) FEAT_##f = (n),
119   foreach_virtio_net_feature
120 #undef _
121 } virtio_net_feature_t;
122
123 #define FEATURE_VIRTIO_NET_F_HOST_TSO_FEATURE_BITS \
124   ((1ULL << FEAT_VIRTIO_NET_F_CSUM) |              \
125    (1ULL << FEAT_VIRTIO_NET_F_HOST_UFO) |          \
126    (1ULL << FEAT_VIRTIO_NET_F_HOST_TSO4) |         \
127    (1ULL << FEAT_VIRTIO_NET_F_HOST_TSO6))
128
129 #define FEATURE_VIRTIO_NET_F_GUEST_TSO_FEATURE_BITS \
130   ((1ULL << FEAT_VIRTIO_NET_F_GUEST_CSUM) |         \
131    (1ULL << FEAT_VIRTIO_NET_F_GUEST_UFO) |          \
132    (1ULL << FEAT_VIRTIO_NET_F_GUEST_TSO4) |         \
133    (1ULL << FEAT_VIRTIO_NET_F_GUEST_TSO6))
134
135 #define FEATURE_VIRTIO_NET_F_HOST_GUEST_TSO_FEATURE_BITS \
136   (FEATURE_VIRTIO_NET_F_HOST_TSO_FEATURE_BITS |          \
137    FEATURE_VIRTIO_NET_F_GUEST_TSO_FEATURE_BITS)
138
139 int vhost_user_create_if (vnet_main_t * vnm, vlib_main_t * vm,
140                           const char *sock_filename, u8 is_server,
141                           u32 * sw_if_index, u64 feature_mask,
142                           u8 renumber, u32 custom_dev_instance, u8 * hwaddr,
143                           u8 enable_gso, u8 enable_packed);
144 int vhost_user_modify_if (vnet_main_t * vnm, vlib_main_t * vm,
145                           const char *sock_filename, u8 is_server,
146                           u32 sw_if_index, u64 feature_mask,
147                           u8 renumber, u32 custom_dev_instance,
148                           u8 enable_gso, u8 enable_packed);
149 int vhost_user_delete_if (vnet_main_t * vnm, vlib_main_t * vm,
150                           u32 sw_if_index);
151
152 /* *INDENT-OFF* */
153 typedef struct vhost_user_memory_region
154 {
155   u64 guest_phys_addr;
156   u64 memory_size;
157   u64 userspace_addr;
158   u64 mmap_offset;
159 } __attribute ((packed)) vhost_user_memory_region_t;
160
161 typedef struct vhost_user_memory
162 {
163   u32 nregions;
164   u32 padding;
165   vhost_user_memory_region_t regions[VHOST_MEMORY_MAX_NREGIONS];
166 } __attribute ((packed)) vhost_user_memory_t;
167
168 typedef struct
169 {
170   u32 index, num;
171 } __attribute ((packed)) vhost_vring_state_t;
172
173 typedef struct
174 {
175   u32 index, flags;
176   u64 desc_user_addr, used_user_addr, avail_user_addr, log_guest_addr;
177 } __attribute ((packed)) vhost_vring_addr_t;
178
179 typedef struct vhost_user_log
180 {
181   u64 size;
182   u64 offset;
183 } __attribute ((packed)) vhost_user_log_t;
184
185 typedef enum vhost_user_req
186 {
187   VHOST_USER_NONE = 0,
188   VHOST_USER_GET_FEATURES = 1,
189   VHOST_USER_SET_FEATURES = 2,
190   VHOST_USER_SET_OWNER = 3,
191   VHOST_USER_RESET_OWNER = 4,
192   VHOST_USER_SET_MEM_TABLE = 5,
193   VHOST_USER_SET_LOG_BASE = 6,
194   VHOST_USER_SET_LOG_FD = 7,
195   VHOST_USER_SET_VRING_NUM = 8,
196   VHOST_USER_SET_VRING_ADDR = 9,
197   VHOST_USER_SET_VRING_BASE = 10,
198   VHOST_USER_GET_VRING_BASE = 11,
199   VHOST_USER_SET_VRING_KICK = 12,
200   VHOST_USER_SET_VRING_CALL = 13,
201   VHOST_USER_SET_VRING_ERR = 14,
202   VHOST_USER_GET_PROTOCOL_FEATURES = 15,
203   VHOST_USER_SET_PROTOCOL_FEATURES = 16,
204   VHOST_USER_GET_QUEUE_NUM = 17,
205   VHOST_USER_SET_VRING_ENABLE = 18,
206   VHOST_USER_MAX
207 } vhost_user_req_t;
208
209 // vring_desc I/O buffer descriptor
210 typedef struct
211 {
212   uint64_t addr;  // packet data buffer address
213   uint32_t len;   // packet data buffer size
214   uint16_t flags; // (see below)
215   uint16_t next;  // optional index next descriptor in chain
216 } __attribute ((packed)) vring_desc_t;
217
218 typedef struct
219 {
220   uint16_t flags;
221   volatile uint16_t idx;
222   uint16_t ring[VHOST_VRING_MAX_SIZE];
223 } __attribute ((packed)) vring_avail_t;
224
225 typedef struct
226 {
227   uint16_t flags;
228   uint16_t idx;
229   struct /* vring_used_elem */
230     {
231       uint32_t id;
232       uint32_t len;
233     } ring[VHOST_VRING_MAX_SIZE];
234 } __attribute ((packed)) vring_used_t;
235
236 typedef CLIB_PACKED (struct
237 {
238   u64 addr;                     // packet data buffer address
239   u32 len;                      // packet data buffer size
240   u16 id;                       // buffer id
241   u16 flags;                    // flags
242 }) vring_packed_desc_t;
243
244 STATIC_ASSERT_SIZEOF (vring_packed_desc_t, 16);
245
246 typedef CLIB_PACKED (struct
247 {
248   u16 off_wrap;
249   u16 flags;
250 }) vring_desc_event_t;
251
252 typedef struct
253 {
254   u8 flags;
255   u8 gso_type;
256   u16 hdr_len;
257   u16 gso_size;
258   u16 csum_start;
259   u16 csum_offset;
260 } __attribute ((packed)) virtio_net_hdr_t;
261
262 typedef struct  {
263   virtio_net_hdr_t hdr;
264   u16 num_buffers;
265 } __attribute ((packed)) virtio_net_hdr_mrg_rxbuf_t;
266
267 typedef struct vhost_user_msg {
268   vhost_user_req_t request;
269   u32 flags;
270   u32 size;
271   union
272     {
273       u64 u64;
274       vhost_vring_state_t state;
275       vhost_vring_addr_t addr;
276       vhost_user_memory_t memory;
277       vhost_user_log_t log;
278     };
279 } __attribute ((packed)) vhost_user_msg_t;
280 /* *INDENT-ON* */
281
282 typedef struct
283 {
284   CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
285   u16 qsz_mask;
286   u16 last_avail_idx;
287   u16 last_used_idx;
288   u16 n_since_last_int;
289   union
290   {
291     vring_desc_t *desc;
292     vring_packed_desc_t *packed_desc;
293   };
294   union
295   {
296     vring_avail_t *avail;
297     vring_desc_event_t *avail_event;
298   };
299   union
300   {
301     vring_used_t *used;
302     vring_desc_event_t *used_event;
303   };
304   uword desc_user_addr;
305   uword used_user_addr;
306   uword avail_user_addr;
307   f64 int_deadline;
308   u8 started;
309   u8 enabled;
310   u8 log_used;
311   //Put non-runtime in a different cache line
312     CLIB_CACHE_LINE_ALIGN_MARK (cacheline1);
313   int errfd;
314   u32 callfd_idx;
315   u32 kickfd_idx;
316   u64 log_guest_addr;
317
318   /* The rx queue policy (interrupt/adaptive/polling) for this queue */
319   u32 mode;
320
321   /*
322    * It contains the device queue number. -1 if it does not. The idea is
323    * to not invoke vnet_hw_interface_assign_rx_thread and
324    * vnet_hw_interface_unassign_rx_thread more than once for the duration of
325    * the interface even if it is disconnected and reconnected.
326    */
327   i16 qid;
328
329   u16 used_wrap_counter;
330   u16 avail_wrap_counter;
331 } vhost_user_vring_t;
332
333 #define VHOST_USER_EVENT_START_TIMER 1
334 #define VHOST_USER_EVENT_STOP_TIMER  2
335
336 typedef struct
337 {
338   CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
339   u32 is_ready;
340   u32 admin_up;
341   u32 unix_server_index;
342   u32 clib_file_index;
343   char sock_filename[256];
344   int sock_errno;
345   uword if_index;
346   u32 hw_if_index, sw_if_index;
347
348   //Feature negotiation
349   u64 features;
350   u64 feature_mask;
351   u64 protocol_features;
352
353   //Memory region information
354   u32 nregions;
355   vhost_user_memory_region_t regions[VHOST_MEMORY_MAX_NREGIONS];
356   void *region_mmap_addr[VHOST_MEMORY_MAX_NREGIONS];
357   u64 region_guest_addr_lo[VHOST_MEMORY_MAX_NREGIONS];
358   u64 region_guest_addr_hi[VHOST_MEMORY_MAX_NREGIONS];
359   u32 region_mmap_fd[VHOST_MEMORY_MAX_NREGIONS];
360
361   //Virtual rings
362   vhost_user_vring_t vrings[VHOST_VRING_MAX_N];
363   volatile u32 *vring_locks[VHOST_VRING_MAX_N];
364
365   int virtio_net_hdr_sz;
366   int is_any_layout;
367
368   void *log_base_addr;
369   u64 log_size;
370
371   /* Whether to use spinlock or per_cpu_tx_qid assignment */
372   u8 use_tx_spinlock;
373   u16 *per_cpu_tx_qid;
374
375   u8 enable_gso;
376
377   /* Packed ring configured */
378   u8 enable_packed;
379
380 } vhost_user_intf_t;
381
382 typedef struct
383 {
384   uword dst;
385   uword src;
386   u32 len;
387 } vhost_copy_t;
388
389 typedef struct
390 {
391   u16 qid; /** The interface queue index (Not the virtio vring idx) */
392   u16 device_index; /** The device index */
393   u32 virtio_ring_flags; /** Runtime queue flags  **/
394   u16 first_desc_len; /** Length of the first data descriptor **/
395   virtio_net_hdr_mrg_rxbuf_t hdr; /** Virtio header **/
396 } vhost_trace_t;
397
398 #define VHOST_USER_RX_BUFFERS_N (2 * VLIB_FRAME_SIZE + 2)
399 #define VHOST_USER_COPY_ARRAY_N (4 * VLIB_FRAME_SIZE)
400
401 typedef struct
402 {
403   u32 rx_buffers_len;
404   u32 rx_buffers[VHOST_USER_RX_BUFFERS_N];
405
406   virtio_net_hdr_mrg_rxbuf_t tx_headers[VLIB_FRAME_SIZE];
407   vhost_copy_t copy[VHOST_USER_COPY_ARRAY_N];
408
409   /* This is here so it doesn't end-up
410    * using stack or registers. */
411   vhost_trace_t *current_trace;
412
413   u32 *to_next_list;
414   vlib_buffer_t **rx_buffers_pdesc;
415 } vhost_cpu_t;
416
417 typedef struct
418 {
419   mhash_t if_index_by_sock_name;
420   u32 mtu_bytes;
421   vhost_user_intf_t *vhost_user_interfaces;
422   u32 *show_dev_instance_by_real_dev_instance;
423   u32 coalesce_frames;
424   f64 coalesce_time;
425   int dont_dump_vhost_user_memory;
426
427   /** Per-CPU data for vhost-user */
428   vhost_cpu_t *cpus;
429
430   /** Pseudo random iterator */
431   u32 random;
432
433   /* The number of rx interface/queue pairs in interrupt mode */
434   u32 ifq_count;
435
436   /* logging */
437   vlib_log_class_t log_default;
438
439   /* gso interface count */
440   u32 gso_count;
441 } vhost_user_main_t;
442
443 typedef struct
444 {
445   u8 if_name[64];
446   u32 sw_if_index;
447   u32 virtio_net_hdr_sz;
448   u64 features;
449   u8 is_server;
450   u8 sock_filename[256];
451   u32 num_regions;
452   int sock_errno;
453 } vhost_user_intf_details_t;
454
455 int vhost_user_dump_ifs (vnet_main_t * vnm, vlib_main_t * vm,
456                          vhost_user_intf_details_t ** out_vuids);
457
458 extern vlib_node_registration_t vhost_user_send_interrupt_node;
459 extern vnet_device_class_t vhost_user_device_class;
460 extern vlib_node_registration_t vhost_user_input_node;
461 extern vhost_user_main_t vhost_user_main;
462
463 #endif
464
465 /*
466  * fd.io coding-style-patch-verification: ON
467  *
468  * Local Variables:
469  * eval: (c-set-style "gnu")
470  * End:
471  */