FD.io VPP  v18.01.2-1-g9b554f3
Vector Packet Processing
virtio.c
Go to the documentation of this file.
1 /*
2  *------------------------------------------------------------------
3  * Copyright (c) 2017 Cisco and/or its affiliates.
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *------------------------------------------------------------------
16  */
17 
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 #include <fcntl.h>
21 #include <net/if.h>
22 #include <linux/if_tun.h>
23 #include <sys/ioctl.h>
24 #include <linux/virtio_net.h>
25 #include <linux/vhost.h>
26 #include <sys/eventfd.h>
27 
28 #include <vlib/vlib.h>
29 #include <vlib/unix/unix.h>
30 #include <vnet/ethernet/ethernet.h>
31 #include <vnet/ip/ip4_packet.h>
32 #include <vnet/ip/ip6_packet.h>
34 
36 
37 #define _IOCTL(fd,a,...) \
38  if (ioctl (fd, a, __VA_ARGS__) < 0) \
39  { \
40  err = clib_error_return_unix (0, "ioctl(" #a ")"); \
41  goto error; \
42  }
43 
44 static clib_error_t *
46 {
48  vnet_main_t *vnm = vnet_get_main ();
49  u16 qid = uf->private_data & 0xFFFF;
50  virtio_if_t *vif =
51  vec_elt_at_index (nm->interfaces, uf->private_data >> 16);
52  u64 b;
53 
54  CLIB_UNUSED (ssize_t size) = read (uf->file_descriptor, &b, sizeof (b));
55  if ((qid & 1) == 0)
57 
58  return 0;
59 }
60 
61 
64 {
65  clib_error_t *err = 0;
66  virtio_vring_t *vring;
67  struct vhost_vring_state state = { 0 };
68  struct vhost_vring_addr addr = { 0 };
69  struct vhost_vring_file file = { 0 };
70  clib_file_t t = { 0 };
71  int i;
72 
73  if (!is_pow2 (sz))
74  return clib_error_return (0, "ring size must be power of 2");
75 
76  if (sz > 32768)
77  return clib_error_return (0, "ring size must be 32768 or lower");
78 
79  if (sz == 0)
80  sz = 256;
81 
83  vring = vec_elt_at_index (vif->vrings, idx);
84 
85  i = sizeof (struct vring_desc) * sz;
88  memset (vring->desc, 0, i);
89 
90  i = sizeof (struct vring_avail) + sz * sizeof (vring->avail->ring[0]);
93  memset (vring->avail, 0, i);
94  // tell kernel that we don't need interrupt
95  vring->avail->flags = VIRTIO_RING_FLAG_MASK_INT;
96 
97  i = sizeof (struct vring_used) + sz * sizeof (struct vring_used_elem);
100  memset (vring->used, 0, i);
101 
102  ASSERT (vring->buffers == 0);
104 
105  vring->size = sz;
106  vring->call_fd = eventfd (0, EFD_NONBLOCK | EFD_CLOEXEC);
107  vring->kick_fd = eventfd (0, EFD_CLOEXEC);
108 
110  t.file_descriptor = vring->call_fd;
111  t.private_data = vif->dev_instance << 16 | idx;
112  vring->call_file_index = clib_file_add (&file_main, &t);
113 
114  state.index = idx;
115  state.num = sz;
116  _IOCTL (vif->fd, VHOST_SET_VRING_NUM, &state);
117 
118  addr.index = idx;
119  addr.flags = 0;
120  addr.desc_user_addr = pointer_to_uword (vring->desc);
121  addr.avail_user_addr = pointer_to_uword (vring->avail);
122  addr.used_user_addr = pointer_to_uword (vring->used);
123  _IOCTL (vif->fd, VHOST_SET_VRING_ADDR, &addr);
124 
125  file.index = idx;
126  file.fd = vring->kick_fd;
127  _IOCTL (vif->fd, VHOST_SET_VRING_KICK, &file);
128  file.fd = vring->call_fd;
129  _IOCTL (vif->fd, VHOST_SET_VRING_CALL, &file);
130  file.fd = vif->tap_fd;
131  _IOCTL (vif->fd, VHOST_NET_SET_BACKEND, &file);
132 
133 error:
134  return err;
135 }
136 
139 {
140  u16 used = vring->desc_in_use;
141  u16 last = vring->last_used_idx;
142  u16 mask = vring->size - 1;
143 
144  while (used)
145  {
146  vlib_buffer_free (vm, &vring->buffers[last & mask], 1);
147  last++;
148  used--;
149  }
150 }
151 
152 clib_error_t *
154 {
155  virtio_vring_t *vring = vec_elt_at_index (vif->vrings, idx);
156 
158  close (vring->kick_fd);
159  close (vring->call_fd);
160  if (vring->used)
161  {
162  if ((idx & 1) == 1)
163  virtio_free_used_desc (vm, vring);
164  else
165  virtio_free_rx_buffers (vm, vring);
166  clib_mem_free (vring->used);
167  }
168  if (vring->desc)
169  clib_mem_free (vring->desc);
170  if (vring->avail)
171  clib_mem_free (vring->avail);
172  vec_free (vring->buffers);
173  return 0;
174 }
175 
176 /*
177  * fd.io coding-style-patch-verification: ON
178  *
179  * Local Variables:
180  * eval: (c-set-style "gnu")
181  * End:
182  */
struct vring_used * used
Definition: virtio.h:77
virtio_if_t * interfaces
Definition: virtio.h:124
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:337
#define CLIB_UNUSED(x)
Definition: clib.h:79
static void vlib_buffer_free(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Free buffers Frees the entire buffer chain for each buffer.
Definition: buffer_funcs.h:356
vnet_main_t * vnet_get_main(void)
Definition: misc.c:47
u32 dev_instance
Definition: virtio.h:97
int kick_fd
Definition: virtio.h:81
u32 file_descriptor
Definition: file.h:53
static heap_elt_t * last(heap_header_t *h)
Definition: heap.c:53
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
Definition: vec.h:443
static_always_inline void virtio_free_rx_buffers(vlib_main_t *vm, virtio_vring_t *vring)
Definition: virtio.c:138
int call_fd
Definition: virtio.h:82
virtio_vring_t * vrings
Definition: virtio.h:103
clib_file_function_t * read_function
Definition: file.h:63
struct vring_avail * avail
Definition: virtio.h:78
#define static_always_inline
Definition: clib.h:93
u32 hw_if_index
Definition: virtio.h:98
static_always_inline void vnet_device_input_set_interrupt_pending(vnet_main_t *vnm, u32 hw_if_index, u16 queue_id)
Definition: devices.h:136
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
#define clib_error_return(e, args...)
Definition: error.h:99
clib_file_main_t file_main
Definition: main.c:63
unsigned long u64
Definition: types.h:89
static uword pointer_to_uword(const void *p)
Definition: types.h:131
int tap_fd
Definition: virtio.h:102
u16 last_used_idx
Definition: virtio.h:88
vlib_main_t * vm
Definition: buffer.c:283
#define VIRTIO_RING_FLAG_MASK_INT
Definition: virtio.h:84
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:336
u32 call_file_index
Definition: virtio.h:86
static uword round_pow2(uword x, uword pow2)
Definition: clib.h:286
void virtio_free_used_desc(vlib_main_t *vm, virtio_vring_t *vring)
Definition: device.c:92
#define ASSERT(truth)
unsigned int u32
Definition: types.h:88
static uword clib_file_add(clib_file_main_t *um, clib_file_t *template)
Definition: file.h:84
static void clib_file_del_by_index(clib_file_main_t *um, uword index)
Definition: file.h:103
clib_error_t * virtio_vring_init(vlib_main_t *vm, virtio_if_t *vif, u16 idx, u16 sz)
Definition: virtio.c:63
u64 size
Definition: vhost-user.h:76
static void clib_mem_free(void *p)
Definition: mem.h:179
clib_error_t * virtio_vring_free(vlib_main_t *vm, virtio_if_t *vif, u32 idx)
Definition: virtio.c:153
virtio_main_t virtio_main
Definition: virtio.c:35
static uword is_pow2(uword x)
Definition: clib.h:280
unsigned short u16
Definition: types.h:57
int fd
Definition: virtio.h:101
u32 * buffers
Definition: virtio.h:87
static void * clib_mem_alloc_aligned(uword size, uword align)
Definition: mem.h:120
uword private_data
Definition: file.h:60
struct vring_desc * desc
Definition: virtio.h:76
Definition: file.h:50
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:67
u16 desc_in_use
Definition: virtio.h:79
static clib_error_t * call_read_ready(clib_file_t *uf)
Definition: virtio.c:45