ed55cd7524d5333bb2b03447891fcc3418cf24fa
[dpdk.git] / drivers / net / virtio / virtio_user / virtio_user_dev.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2016 Intel Corporation
3  */
4
5 #include <stdint.h>
6 #include <stdio.h>
7 #include <fcntl.h>
8 #include <string.h>
9 #include <errno.h>
10 #include <sys/mman.h>
11 #include <unistd.h>
12 #include <sys/eventfd.h>
13 #include <sys/types.h>
14 #include <sys/stat.h>
15
16 #include <rte_alarm.h>
17 #include <rte_string_fns.h>
18 #include <rte_eal_memconfig.h>
19
20 #include "vhost.h"
21 #include "virtio_user_dev.h"
22 #include "../virtio_ethdev.h"
23
24 #define VIRTIO_USER_MEM_EVENT_CLB_NAME "virtio_user_mem_event_clb"
25
26 const char * const virtio_user_backend_strings[] = {
27         [VIRTIO_USER_BACKEND_UNKNOWN] = "VIRTIO_USER_BACKEND_UNKNOWN",
28         [VIRTIO_USER_BACKEND_VHOST_USER] = "VHOST_USER",
29         [VIRTIO_USER_BACKEND_VHOST_KERNEL] = "VHOST_NET",
30         [VIRTIO_USER_BACKEND_VHOST_VDPA] = "VHOST_VDPA",
31 };
32
33 static int
34 virtio_user_create_queue(struct virtio_user_dev *dev, uint32_t queue_sel)
35 {
36         /* Of all per virtqueue MSGs, make sure VHOST_SET_VRING_CALL come
37          * firstly because vhost depends on this msg to allocate virtqueue
38          * pair.
39          */
40         struct vhost_vring_file file;
41         int ret;
42
43         file.index = queue_sel;
44         file.fd = dev->callfds[queue_sel];
45         ret = dev->ops->set_vring_call(dev, &file);
46         if (ret < 0) {
47                 PMD_INIT_LOG(ERR, "(%s) Failed to create queue %u\n", dev->path, queue_sel);
48                 return -1;
49         }
50
51         return 0;
52 }
53
54 static int
55 virtio_user_kick_queue(struct virtio_user_dev *dev, uint32_t queue_sel)
56 {
57         int ret;
58         struct vhost_vring_file file;
59         struct vhost_vring_state state;
60         struct vring *vring = &dev->vrings[queue_sel];
61         struct vring_packed *pq_vring = &dev->packed_vrings[queue_sel];
62         struct vhost_vring_addr addr = {
63                 .index = queue_sel,
64                 .log_guest_addr = 0,
65                 .flags = 0, /* disable log */
66         };
67
68         if (dev->features & (1ULL << VIRTIO_F_RING_PACKED)) {
69                 addr.desc_user_addr =
70                         (uint64_t)(uintptr_t)pq_vring->desc;
71                 addr.avail_user_addr =
72                         (uint64_t)(uintptr_t)pq_vring->driver;
73                 addr.used_user_addr =
74                         (uint64_t)(uintptr_t)pq_vring->device;
75         } else {
76                 addr.desc_user_addr = (uint64_t)(uintptr_t)vring->desc;
77                 addr.avail_user_addr = (uint64_t)(uintptr_t)vring->avail;
78                 addr.used_user_addr = (uint64_t)(uintptr_t)vring->used;
79         }
80
81         state.index = queue_sel;
82         state.num = vring->num;
83         ret = dev->ops->set_vring_num(dev, &state);
84         if (ret < 0)
85                 goto err;
86
87         state.index = queue_sel;
88         state.num = 0; /* no reservation */
89         if (dev->features & (1ULL << VIRTIO_F_RING_PACKED))
90                 state.num |= (1 << 15);
91         ret = dev->ops->set_vring_base(dev, &state);
92         if (ret < 0)
93                 goto err;
94
95         ret = dev->ops->set_vring_addr(dev, &addr);
96         if (ret < 0)
97                 goto err;
98
99         /* Of all per virtqueue MSGs, make sure VHOST_USER_SET_VRING_KICK comes
100          * lastly because vhost depends on this msg to judge if
101          * virtio is ready.
102          */
103         file.index = queue_sel;
104         file.fd = dev->kickfds[queue_sel];
105         ret = dev->ops->set_vring_kick(dev, &file);
106         if (ret < 0)
107                 goto err;
108
109         return 0;
110 err:
111         PMD_INIT_LOG(ERR, "(%s) Failed to kick queue %u\n", dev->path, queue_sel);
112
113         return -1;
114 }
115
116 static int
117 virtio_user_queue_setup(struct virtio_user_dev *dev,
118                         int (*fn)(struct virtio_user_dev *, uint32_t))
119 {
120         uint32_t i, queue_sel;
121
122         for (i = 0; i < dev->max_queue_pairs; ++i) {
123                 queue_sel = 2 * i + VTNET_SQ_RQ_QUEUE_IDX;
124                 if (fn(dev, queue_sel) < 0) {
125                         PMD_DRV_LOG(ERR, "(%s) setup rx vq %u failed", dev->path, i);
126                         return -1;
127                 }
128         }
129         for (i = 0; i < dev->max_queue_pairs; ++i) {
130                 queue_sel = 2 * i + VTNET_SQ_TQ_QUEUE_IDX;
131                 if (fn(dev, queue_sel) < 0) {
132                         PMD_DRV_LOG(INFO, "(%s) setup tx vq %u failed", dev->path, i);
133                         return -1;
134                 }
135         }
136
137         return 0;
138 }
139
140 int
141 virtio_user_dev_set_features(struct virtio_user_dev *dev)
142 {
143         uint64_t features;
144         int ret = -1;
145
146         pthread_mutex_lock(&dev->mutex);
147
148         /* Step 0: tell vhost to create queues */
149         if (virtio_user_queue_setup(dev, virtio_user_create_queue) < 0)
150                 goto error;
151
152         features = dev->features;
153
154         /* Strip VIRTIO_NET_F_MAC, as MAC address is handled in vdev init */
155         features &= ~(1ull << VIRTIO_NET_F_MAC);
156         /* Strip VIRTIO_NET_F_CTRL_VQ, as devices do not really need to know */
157         features &= ~(1ull << VIRTIO_NET_F_CTRL_VQ);
158         features &= ~(1ull << VIRTIO_NET_F_STATUS);
159         ret = dev->ops->set_features(dev, features);
160         if (ret < 0)
161                 goto error;
162         PMD_DRV_LOG(INFO, "(%s) set features: 0x%" PRIx64, dev->path, features);
163 error:
164         pthread_mutex_unlock(&dev->mutex);
165
166         return ret;
167 }
168
169 int
170 virtio_user_start_device(struct virtio_user_dev *dev)
171 {
172         int ret;
173
174         /*
175          * XXX workaround!
176          *
177          * We need to make sure that the locks will be
178          * taken in the correct order to avoid deadlocks.
179          *
180          * Before releasing this lock, this thread should
181          * not trigger any memory hotplug events.
182          *
183          * This is a temporary workaround, and should be
184          * replaced when we get proper supports from the
185          * memory subsystem in the future.
186          */
187         rte_mcfg_mem_read_lock();
188         pthread_mutex_lock(&dev->mutex);
189
190         /* Step 2: share memory regions */
191         ret = dev->ops->set_memory_table(dev);
192         if (ret < 0)
193                 goto error;
194
195         /* Step 3: kick queues */
196         ret = virtio_user_queue_setup(dev, virtio_user_kick_queue);
197         if (ret < 0)
198                 goto error;
199
200         /* Step 4: enable queues
201          * we enable the 1st queue pair by default.
202          */
203         ret = dev->ops->enable_qp(dev, 0, 1);
204         if (ret < 0)
205                 goto error;
206
207         dev->started = true;
208
209         pthread_mutex_unlock(&dev->mutex);
210         rte_mcfg_mem_read_unlock();
211
212         return 0;
213 error:
214         pthread_mutex_unlock(&dev->mutex);
215         rte_mcfg_mem_read_unlock();
216
217         PMD_INIT_LOG(ERR, "(%s) Failed to start device\n", dev->path);
218
219         /* TODO: free resource here or caller to check */
220         return -1;
221 }
222
223 int virtio_user_stop_device(struct virtio_user_dev *dev)
224 {
225         struct vhost_vring_state state;
226         uint32_t i;
227         int ret;
228
229         pthread_mutex_lock(&dev->mutex);
230         if (!dev->started)
231                 goto out;
232
233         for (i = 0; i < dev->max_queue_pairs; ++i) {
234                 ret = dev->ops->enable_qp(dev, i, 0);
235                 if (ret < 0)
236                         goto err;
237         }
238
239         /* Stop the backend. */
240         for (i = 0; i < dev->max_queue_pairs * 2; ++i) {
241                 state.index = i;
242                 ret = dev->ops->get_vring_base(dev, &state);
243                 if (ret < 0) {
244                         PMD_DRV_LOG(ERR, "(%s) get_vring_base failed, index=%u", dev->path, i);
245                         goto err;
246                 }
247         }
248
249         dev->started = false;
250
251 out:
252         pthread_mutex_unlock(&dev->mutex);
253
254         return 0;
255 err:
256         pthread_mutex_unlock(&dev->mutex);
257
258         PMD_INIT_LOG(ERR, "(%s) Failed to stop device\n", dev->path);
259
260         return -1;
261 }
262
263 static inline void
264 parse_mac(struct virtio_user_dev *dev, const char *mac)
265 {
266         struct rte_ether_addr tmp;
267
268         if (!mac)
269                 return;
270
271         if (rte_ether_unformat_addr(mac, &tmp) == 0) {
272                 memcpy(dev->mac_addr, &tmp, RTE_ETHER_ADDR_LEN);
273                 dev->mac_specified = 1;
274         } else {
275                 /* ignore the wrong mac, use random mac */
276                 PMD_DRV_LOG(ERR, "wrong format of mac: %s", mac);
277         }
278 }
279
280 static int
281 virtio_user_dev_init_notify(struct virtio_user_dev *dev)
282 {
283         uint32_t i, j;
284         int callfd;
285         int kickfd;
286
287         for (i = 0; i < dev->max_queue_pairs * 2; i++) {
288                 /* May use invalid flag, but some backend uses kickfd and
289                  * callfd as criteria to judge if dev is alive. so finally we
290                  * use real event_fd.
291                  */
292                 callfd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
293                 if (callfd < 0) {
294                         PMD_DRV_LOG(ERR, "(%s) callfd error, %s", dev->path, strerror(errno));
295                         goto err;
296                 }
297                 kickfd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK);
298                 if (kickfd < 0) {
299                         close(callfd);
300                         PMD_DRV_LOG(ERR, "(%s) kickfd error, %s", dev->path, strerror(errno));
301                         goto err;
302                 }
303                 dev->callfds[i] = callfd;
304                 dev->kickfds[i] = kickfd;
305         }
306
307         return 0;
308 err:
309         for (j = 0; j < i; j++) {
310                 if (dev->kickfds[j] >= 0) {
311                         close(dev->kickfds[j]);
312                         dev->kickfds[j] = -1;
313                 }
314                 if (dev->callfds[j] >= 0) {
315                         close(dev->callfds[j]);
316                         dev->callfds[j] = -1;
317                 }
318         }
319
320         return -1;
321 }
322
323 static void
324 virtio_user_dev_uninit_notify(struct virtio_user_dev *dev)
325 {
326         uint32_t i;
327
328         for (i = 0; i < dev->max_queue_pairs * 2; ++i) {
329                 if (dev->kickfds[i] >= 0) {
330                         close(dev->kickfds[i]);
331                         dev->kickfds[i] = -1;
332                 }
333                 if (dev->callfds[i] >= 0) {
334                         close(dev->callfds[i]);
335                         dev->callfds[i] = -1;
336                 }
337         }
338 }
339
340 static int
341 virtio_user_fill_intr_handle(struct virtio_user_dev *dev)
342 {
343         uint32_t i;
344         struct rte_eth_dev *eth_dev = &rte_eth_devices[dev->hw.port_id];
345
346         if (!eth_dev->intr_handle) {
347                 eth_dev->intr_handle = malloc(sizeof(*eth_dev->intr_handle));
348                 if (!eth_dev->intr_handle) {
349                         PMD_DRV_LOG(ERR, "(%s) failed to allocate intr_handle", dev->path);
350                         return -1;
351                 }
352                 memset(eth_dev->intr_handle, 0, sizeof(*eth_dev->intr_handle));
353         }
354
355         for (i = 0; i < dev->max_queue_pairs; ++i)
356                 eth_dev->intr_handle->efds[i] = dev->callfds[i];
357         eth_dev->intr_handle->nb_efd = dev->max_queue_pairs;
358         eth_dev->intr_handle->max_intr = dev->max_queue_pairs + 1;
359         eth_dev->intr_handle->type = RTE_INTR_HANDLE_VDEV;
360         /* For virtio vdev, no need to read counter for clean */
361         eth_dev->intr_handle->efd_counter_size = 0;
362         eth_dev->intr_handle->fd = dev->ops->get_intr_fd(dev);
363
364         return 0;
365 }
366
367 static void
368 virtio_user_mem_event_cb(enum rte_mem_event type __rte_unused,
369                          const void *addr,
370                          size_t len __rte_unused,
371                          void *arg)
372 {
373         struct virtio_user_dev *dev = arg;
374         struct rte_memseg_list *msl;
375         uint16_t i;
376         int ret = 0;
377
378         /* ignore externally allocated memory */
379         msl = rte_mem_virt2memseg_list(addr);
380         if (msl->external)
381                 return;
382
383         pthread_mutex_lock(&dev->mutex);
384
385         if (dev->started == false)
386                 goto exit;
387
388         /* Step 1: pause the active queues */
389         for (i = 0; i < dev->queue_pairs; i++) {
390                 ret = dev->ops->enable_qp(dev, i, 0);
391                 if (ret < 0)
392                         goto exit;
393         }
394
395         /* Step 2: update memory regions */
396         ret = dev->ops->set_memory_table(dev);
397         if (ret < 0)
398                 goto exit;
399
400         /* Step 3: resume the active queues */
401         for (i = 0; i < dev->queue_pairs; i++) {
402                 ret = dev->ops->enable_qp(dev, i, 1);
403                 if (ret < 0)
404                         goto exit;
405         }
406
407 exit:
408         pthread_mutex_unlock(&dev->mutex);
409
410         if (ret < 0)
411                 PMD_DRV_LOG(ERR, "(%s) Failed to update memory table\n", dev->path);
412 }
413
414 static int
415 virtio_user_dev_setup(struct virtio_user_dev *dev)
416 {
417         if (dev->is_server) {
418                 if (dev->backend_type != VIRTIO_USER_BACKEND_VHOST_USER) {
419                         PMD_DRV_LOG(ERR, "Server mode only supports vhost-user!");
420                         return -1;
421                 }
422         }
423
424         switch (dev->backend_type) {
425         case VIRTIO_USER_BACKEND_VHOST_USER:
426                 dev->ops = &virtio_ops_user;
427                 break;
428         case VIRTIO_USER_BACKEND_VHOST_KERNEL:
429                 dev->ops = &virtio_ops_kernel;
430                 break;
431         case VIRTIO_USER_BACKEND_VHOST_VDPA:
432                 dev->ops = &virtio_ops_vdpa;
433                 break;
434         default:
435                 PMD_DRV_LOG(ERR, "(%s) Unknown backend type", dev->path);
436                 return -1;
437         }
438
439         if (dev->ops->setup(dev) < 0) {
440                 PMD_INIT_LOG(ERR, "(%s) Failed to setup backend\n", dev->path);
441                 return -1;
442         }
443
444         if (virtio_user_dev_init_notify(dev) < 0) {
445                 PMD_INIT_LOG(ERR, "(%s) Failed to init notifiers\n", dev->path);
446                 goto destroy;
447         }
448
449         if (virtio_user_fill_intr_handle(dev) < 0) {
450                 PMD_INIT_LOG(ERR, "(%s) Failed to init interrupt handler\n", dev->path);
451                 goto uninit;
452         }
453
454         return 0;
455
456 uninit:
457         virtio_user_dev_uninit_notify(dev);
458 destroy:
459         dev->ops->destroy(dev);
460
461         return -1;
462 }
463
464 /* Use below macro to filter features from vhost backend */
465 #define VIRTIO_USER_SUPPORTED_FEATURES                  \
466         (1ULL << VIRTIO_NET_F_MAC               |       \
467          1ULL << VIRTIO_NET_F_STATUS            |       \
468          1ULL << VIRTIO_NET_F_MQ                |       \
469          1ULL << VIRTIO_NET_F_CTRL_MAC_ADDR     |       \
470          1ULL << VIRTIO_NET_F_CTRL_VQ           |       \
471          1ULL << VIRTIO_NET_F_CTRL_RX           |       \
472          1ULL << VIRTIO_NET_F_CTRL_VLAN         |       \
473          1ULL << VIRTIO_NET_F_CSUM              |       \
474          1ULL << VIRTIO_NET_F_HOST_TSO4         |       \
475          1ULL << VIRTIO_NET_F_HOST_TSO6         |       \
476          1ULL << VIRTIO_NET_F_MRG_RXBUF         |       \
477          1ULL << VIRTIO_RING_F_INDIRECT_DESC    |       \
478          1ULL << VIRTIO_NET_F_GUEST_CSUM        |       \
479          1ULL << VIRTIO_NET_F_GUEST_TSO4        |       \
480          1ULL << VIRTIO_NET_F_GUEST_TSO6        |       \
481          1ULL << VIRTIO_F_IN_ORDER              |       \
482          1ULL << VIRTIO_F_VERSION_1             |       \
483          1ULL << VIRTIO_F_RING_PACKED)
484
485 int
486 virtio_user_dev_init(struct virtio_user_dev *dev, char *path, int queues,
487                      int cq, int queue_size, const char *mac, char **ifname,
488                      int server, int mrg_rxbuf, int in_order, int packed_vq,
489                      enum virtio_user_backend_type backend_type)
490 {
491         uint64_t backend_features;
492         int i;
493
494         pthread_mutex_init(&dev->mutex, NULL);
495         strlcpy(dev->path, path, PATH_MAX);
496
497         for (i = 0; i < VIRTIO_MAX_VIRTQUEUES; i++) {
498                 dev->kickfds[i] = -1;
499                 dev->callfds[i] = -1;
500         }
501
502         dev->started = 0;
503         dev->max_queue_pairs = queues;
504         dev->queue_pairs = 1; /* mq disabled by default */
505         dev->queue_size = queue_size;
506         dev->is_server = server;
507         dev->mac_specified = 0;
508         dev->frontend_features = 0;
509         dev->unsupported_features = 0;
510         dev->backend_type = backend_type;
511
512         parse_mac(dev, mac);
513
514         if (*ifname) {
515                 dev->ifname = *ifname;
516                 *ifname = NULL;
517         }
518
519         if (virtio_user_dev_setup(dev) < 0) {
520                 PMD_INIT_LOG(ERR, "(%s) backend set up fails", dev->path);
521                 return -1;
522         }
523
524         if (dev->ops->set_owner(dev) < 0) {
525                 PMD_INIT_LOG(ERR, "(%s) Failed to set backend owner", dev->path);
526                 return -1;
527         }
528
529         if (dev->ops->get_backend_features(&backend_features) < 0) {
530                 PMD_INIT_LOG(ERR, "(%s) Failed to get backend features", dev->path);
531                 return -1;
532         }
533
534         dev->unsupported_features = ~(VIRTIO_USER_SUPPORTED_FEATURES | backend_features);
535
536         if (dev->ops->get_features(dev, &dev->device_features) < 0) {
537                 PMD_INIT_LOG(ERR, "(%s) Failed to get device features", dev->path);
538                 return -1;
539         }
540
541         if (!mrg_rxbuf)
542                 dev->unsupported_features |= (1ull << VIRTIO_NET_F_MRG_RXBUF);
543
544         if (!in_order)
545                 dev->unsupported_features |= (1ull << VIRTIO_F_IN_ORDER);
546
547         if (!packed_vq)
548                 dev->unsupported_features |= (1ull << VIRTIO_F_RING_PACKED);
549
550         if (dev->mac_specified)
551                 dev->frontend_features |= (1ull << VIRTIO_NET_F_MAC);
552         else
553                 dev->unsupported_features |= (1ull << VIRTIO_NET_F_MAC);
554
555         if (cq) {
556                 /* device does not really need to know anything about CQ,
557                  * so if necessary, we just claim to support CQ
558                  */
559                 dev->frontend_features |= (1ull << VIRTIO_NET_F_CTRL_VQ);
560         } else {
561                 dev->unsupported_features |= (1ull << VIRTIO_NET_F_CTRL_VQ);
562                 /* Also disable features that depend on VIRTIO_NET_F_CTRL_VQ */
563                 dev->unsupported_features |= (1ull << VIRTIO_NET_F_CTRL_RX);
564                 dev->unsupported_features |= (1ull << VIRTIO_NET_F_CTRL_VLAN);
565                 dev->unsupported_features |=
566                         (1ull << VIRTIO_NET_F_GUEST_ANNOUNCE);
567                 dev->unsupported_features |= (1ull << VIRTIO_NET_F_MQ);
568                 dev->unsupported_features |=
569                         (1ull << VIRTIO_NET_F_CTRL_MAC_ADDR);
570         }
571
572         /* The backend will not report this feature, we add it explicitly */
573         if (dev->backend_type == VIRTIO_USER_BACKEND_VHOST_USER)
574                 dev->frontend_features |= (1ull << VIRTIO_NET_F_STATUS);
575
576         dev->frontend_features &= ~dev->unsupported_features;
577         dev->device_features &= ~dev->unsupported_features;
578
579         if (rte_mem_event_callback_register(VIRTIO_USER_MEM_EVENT_CLB_NAME,
580                                 virtio_user_mem_event_cb, dev)) {
581                 if (rte_errno != ENOTSUP) {
582                         PMD_INIT_LOG(ERR, "(%s) Failed to register mem event callback\n",
583                                         dev->path);
584                         return -1;
585                 }
586         }
587
588         return 0;
589 }
590
591 void
592 virtio_user_dev_uninit(struct virtio_user_dev *dev)
593 {
594         virtio_user_stop_device(dev);
595
596         rte_mem_event_callback_unregister(VIRTIO_USER_MEM_EVENT_CLB_NAME, dev);
597
598         virtio_user_dev_uninit_notify(dev);
599
600         free(dev->ifname);
601
602         if (dev->is_server)
603                 unlink(dev->path);
604
605         dev->ops->destroy(dev);
606 }
607
608 uint8_t
609 virtio_user_handle_mq(struct virtio_user_dev *dev, uint16_t q_pairs)
610 {
611         uint16_t i;
612         uint8_t ret = 0;
613
614         if (q_pairs > dev->max_queue_pairs) {
615                 PMD_INIT_LOG(ERR, "(%s) multi-q config %u, but only %u supported",
616                              dev->path, q_pairs, dev->max_queue_pairs);
617                 return -1;
618         }
619
620         for (i = 0; i < q_pairs; ++i)
621                 ret |= dev->ops->enable_qp(dev, i, 1);
622         for (i = q_pairs; i < dev->max_queue_pairs; ++i)
623                 ret |= dev->ops->enable_qp(dev, i, 0);
624
625         dev->queue_pairs = q_pairs;
626
627         return ret;
628 }
629
630 static uint32_t
631 virtio_user_handle_ctrl_msg(struct virtio_user_dev *dev, struct vring *vring,
632                             uint16_t idx_hdr)
633 {
634         struct virtio_net_ctrl_hdr *hdr;
635         virtio_net_ctrl_ack status = ~0;
636         uint16_t i, idx_data, idx_status;
637         uint32_t n_descs = 0;
638
639         /* locate desc for header, data, and status */
640         idx_data = vring->desc[idx_hdr].next;
641         n_descs++;
642
643         i = idx_data;
644         while (vring->desc[i].flags == VRING_DESC_F_NEXT) {
645                 i = vring->desc[i].next;
646                 n_descs++;
647         }
648
649         /* locate desc for status */
650         idx_status = i;
651         n_descs++;
652
653         hdr = (void *)(uintptr_t)vring->desc[idx_hdr].addr;
654         if (hdr->class == VIRTIO_NET_CTRL_MQ &&
655             hdr->cmd == VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET) {
656                 uint16_t queues;
657
658                 queues = *(uint16_t *)(uintptr_t)vring->desc[idx_data].addr;
659                 status = virtio_user_handle_mq(dev, queues);
660         } else if (hdr->class == VIRTIO_NET_CTRL_RX  ||
661                    hdr->class == VIRTIO_NET_CTRL_MAC ||
662                    hdr->class == VIRTIO_NET_CTRL_VLAN) {
663                 status = 0;
664         }
665
666         /* Update status */
667         *(virtio_net_ctrl_ack *)(uintptr_t)vring->desc[idx_status].addr = status;
668
669         return n_descs;
670 }
671
672 static inline int
673 desc_is_avail(struct vring_packed_desc *desc, bool wrap_counter)
674 {
675         uint16_t flags = __atomic_load_n(&desc->flags, __ATOMIC_ACQUIRE);
676
677         return wrap_counter == !!(flags & VRING_PACKED_DESC_F_AVAIL) &&
678                 wrap_counter != !!(flags & VRING_PACKED_DESC_F_USED);
679 }
680
681 static uint32_t
682 virtio_user_handle_ctrl_msg_packed(struct virtio_user_dev *dev,
683                                    struct vring_packed *vring,
684                                    uint16_t idx_hdr)
685 {
686         struct virtio_net_ctrl_hdr *hdr;
687         virtio_net_ctrl_ack status = ~0;
688         uint16_t idx_data, idx_status;
689         /* initialize to one, header is first */
690         uint32_t n_descs = 1;
691
692         /* locate desc for header, data, and status */
693         idx_data = idx_hdr + 1;
694         if (idx_data >= dev->queue_size)
695                 idx_data -= dev->queue_size;
696
697         n_descs++;
698
699         idx_status = idx_data;
700         while (vring->desc[idx_status].flags & VRING_DESC_F_NEXT) {
701                 idx_status++;
702                 if (idx_status >= dev->queue_size)
703                         idx_status -= dev->queue_size;
704                 n_descs++;
705         }
706
707         hdr = (void *)(uintptr_t)vring->desc[idx_hdr].addr;
708         if (hdr->class == VIRTIO_NET_CTRL_MQ &&
709             hdr->cmd == VIRTIO_NET_CTRL_MQ_VQ_PAIRS_SET) {
710                 uint16_t queues;
711
712                 queues = *(uint16_t *)(uintptr_t)
713                                 vring->desc[idx_data].addr;
714                 status = virtio_user_handle_mq(dev, queues);
715         } else if (hdr->class == VIRTIO_NET_CTRL_RX  ||
716                    hdr->class == VIRTIO_NET_CTRL_MAC ||
717                    hdr->class == VIRTIO_NET_CTRL_VLAN) {
718                 status = 0;
719         }
720
721         /* Update status */
722         *(virtio_net_ctrl_ack *)(uintptr_t)
723                 vring->desc[idx_status].addr = status;
724
725         /* Update used descriptor */
726         vring->desc[idx_hdr].id = vring->desc[idx_status].id;
727         vring->desc[idx_hdr].len = sizeof(status);
728
729         return n_descs;
730 }
731
732 void
733 virtio_user_handle_cq_packed(struct virtio_user_dev *dev, uint16_t queue_idx)
734 {
735         struct virtio_user_queue *vq = &dev->packed_queues[queue_idx];
736         struct vring_packed *vring = &dev->packed_vrings[queue_idx];
737         uint16_t n_descs, flags;
738
739         /* Perform a load-acquire barrier in desc_is_avail to
740          * enforce the ordering between desc flags and desc
741          * content.
742          */
743         while (desc_is_avail(&vring->desc[vq->used_idx],
744                              vq->used_wrap_counter)) {
745
746                 n_descs = virtio_user_handle_ctrl_msg_packed(dev, vring,
747                                 vq->used_idx);
748
749                 flags = VRING_DESC_F_WRITE;
750                 if (vq->used_wrap_counter)
751                         flags |= VRING_PACKED_DESC_F_AVAIL_USED;
752
753                 __atomic_store_n(&vring->desc[vq->used_idx].flags, flags,
754                                  __ATOMIC_RELEASE);
755
756                 vq->used_idx += n_descs;
757                 if (vq->used_idx >= dev->queue_size) {
758                         vq->used_idx -= dev->queue_size;
759                         vq->used_wrap_counter ^= 1;
760                 }
761         }
762 }
763
764 void
765 virtio_user_handle_cq(struct virtio_user_dev *dev, uint16_t queue_idx)
766 {
767         uint16_t avail_idx, desc_idx;
768         struct vring_used_elem *uep;
769         uint32_t n_descs;
770         struct vring *vring = &dev->vrings[queue_idx];
771
772         /* Consume avail ring, using used ring idx as first one */
773         while (__atomic_load_n(&vring->used->idx, __ATOMIC_RELAXED)
774                != vring->avail->idx) {
775                 avail_idx = __atomic_load_n(&vring->used->idx, __ATOMIC_RELAXED)
776                             & (vring->num - 1);
777                 desc_idx = vring->avail->ring[avail_idx];
778
779                 n_descs = virtio_user_handle_ctrl_msg(dev, vring, desc_idx);
780
781                 /* Update used ring */
782                 uep = &vring->used->ring[avail_idx];
783                 uep->id = desc_idx;
784                 uep->len = n_descs;
785
786                 __atomic_add_fetch(&vring->used->idx, 1, __ATOMIC_RELAXED);
787         }
788 }
789
790 int
791 virtio_user_dev_set_status(struct virtio_user_dev *dev, uint8_t status)
792 {
793         int ret;
794
795         pthread_mutex_lock(&dev->mutex);
796         dev->status = status;
797         ret = dev->ops->set_status(dev, status);
798         if (ret && ret != -ENOTSUP)
799                 PMD_INIT_LOG(ERR, "(%s) Failed to set backend status\n", dev->path);
800
801         pthread_mutex_unlock(&dev->mutex);
802         return ret;
803 }
804
805 int
806 virtio_user_dev_update_status(struct virtio_user_dev *dev)
807 {
808         int ret;
809         uint8_t status;
810
811         pthread_mutex_lock(&dev->mutex);
812
813         ret = dev->ops->get_status(dev, &status);
814         if (!ret) {
815                 dev->status = status;
816                 PMD_INIT_LOG(DEBUG, "Updated Device Status(0x%08x):\n"
817                         "\t-RESET: %u\n"
818                         "\t-ACKNOWLEDGE: %u\n"
819                         "\t-DRIVER: %u\n"
820                         "\t-DRIVER_OK: %u\n"
821                         "\t-FEATURES_OK: %u\n"
822                         "\t-DEVICE_NEED_RESET: %u\n"
823                         "\t-FAILED: %u\n",
824                         dev->status,
825                         (dev->status == VIRTIO_CONFIG_STATUS_RESET),
826                         !!(dev->status & VIRTIO_CONFIG_STATUS_ACK),
827                         !!(dev->status & VIRTIO_CONFIG_STATUS_DRIVER),
828                         !!(dev->status & VIRTIO_CONFIG_STATUS_DRIVER_OK),
829                         !!(dev->status & VIRTIO_CONFIG_STATUS_FEATURES_OK),
830                         !!(dev->status & VIRTIO_CONFIG_STATUS_DEV_NEED_RESET),
831                         !!(dev->status & VIRTIO_CONFIG_STATUS_FAILED));
832         } else if (ret != -ENOTSUP) {
833                 PMD_INIT_LOG(ERR, "(%s) Failed to get backend status\n", dev->path);
834         }
835
836         pthread_mutex_unlock(&dev->mutex);
837         return ret;
838 }
839
840 int
841 virtio_user_dev_update_link_state(struct virtio_user_dev *dev)
842 {
843         if (dev->ops->update_link_state)
844                 return dev->ops->update_link_state(dev);
845
846         return 0;
847 }
848
849 static void
850 virtio_user_dev_reset_queues_packed(struct rte_eth_dev *eth_dev)
851 {
852         struct virtio_user_dev *dev = eth_dev->data->dev_private;
853         struct virtio_hw *hw = &dev->hw;
854         struct virtnet_rx *rxvq;
855         struct virtnet_tx *txvq;
856         uint16_t i;
857
858         /* Add lock to avoid queue contention. */
859         rte_spinlock_lock(&hw->state_lock);
860         hw->started = 0;
861
862         /*
863          * Waiting for datapath to complete before resetting queues.
864          * 1 ms should be enough for the ongoing Tx/Rx function to finish.
865          */
866         rte_delay_ms(1);
867
868         /* Vring reset for each Tx queue and Rx queue. */
869         for (i = 0; i < eth_dev->data->nb_rx_queues; i++) {
870                 rxvq = eth_dev->data->rx_queues[i];
871                 virtqueue_rxvq_reset_packed(virtnet_rxq_to_vq(rxvq));
872                 virtio_dev_rx_queue_setup_finish(eth_dev, i);
873         }
874
875         for (i = 0; i < eth_dev->data->nb_tx_queues; i++) {
876                 txvq = eth_dev->data->tx_queues[i];
877                 virtqueue_txvq_reset_packed(virtnet_txq_to_vq(txvq));
878         }
879
880         hw->started = 1;
881         rte_spinlock_unlock(&hw->state_lock);
882 }
883
884 void
885 virtio_user_dev_delayed_disconnect_handler(void *param)
886 {
887         struct virtio_user_dev *dev = param;
888         struct rte_eth_dev *eth_dev = &rte_eth_devices[dev->hw.port_id];
889
890         if (rte_intr_disable(eth_dev->intr_handle) < 0) {
891                 PMD_DRV_LOG(ERR, "interrupt disable failed");
892                 return;
893         }
894         PMD_DRV_LOG(DEBUG, "Unregistering intr fd: %d",
895                     eth_dev->intr_handle->fd);
896         if (rte_intr_callback_unregister(eth_dev->intr_handle,
897                                          virtio_interrupt_handler,
898                                          eth_dev) != 1)
899                 PMD_DRV_LOG(ERR, "interrupt unregister failed");
900
901         if (dev->is_server) {
902                 if (dev->ops->server_disconnect)
903                         dev->ops->server_disconnect(dev);
904
905                 eth_dev->intr_handle->fd = dev->ops->get_intr_fd(dev);
906
907                 PMD_DRV_LOG(DEBUG, "Registering intr fd: %d",
908                             eth_dev->intr_handle->fd);
909
910                 if (rte_intr_callback_register(eth_dev->intr_handle,
911                                                virtio_interrupt_handler,
912                                                eth_dev))
913                         PMD_DRV_LOG(ERR, "interrupt register failed");
914
915                 if (rte_intr_enable(eth_dev->intr_handle) < 0) {
916                         PMD_DRV_LOG(ERR, "interrupt enable failed");
917                         return;
918                 }
919         }
920 }
921
922 static void
923 virtio_user_dev_delayed_intr_reconfig_handler(void *param)
924 {
925         struct virtio_user_dev *dev = param;
926         struct rte_eth_dev *eth_dev = &rte_eth_devices[dev->hw.port_id];
927
928         PMD_DRV_LOG(DEBUG, "Unregistering intr fd: %d",
929                     eth_dev->intr_handle->fd);
930
931         if (rte_intr_callback_unregister(eth_dev->intr_handle,
932                                          virtio_interrupt_handler,
933                                          eth_dev) != 1)
934                 PMD_DRV_LOG(ERR, "interrupt unregister failed");
935
936         eth_dev->intr_handle->fd = dev->ops->get_intr_fd(dev);
937
938         PMD_DRV_LOG(DEBUG, "Registering intr fd: %d", eth_dev->intr_handle->fd);
939
940         if (rte_intr_callback_register(eth_dev->intr_handle,
941                                        virtio_interrupt_handler, eth_dev))
942                 PMD_DRV_LOG(ERR, "interrupt register failed");
943
944         if (rte_intr_enable(eth_dev->intr_handle) < 0)
945                 PMD_DRV_LOG(ERR, "interrupt enable failed");
946 }
947
948 int
949 virtio_user_dev_server_reconnect(struct virtio_user_dev *dev)
950 {
951         int ret, old_status;
952         struct rte_eth_dev *eth_dev = &rte_eth_devices[dev->hw.port_id];
953         struct virtio_hw *hw = &dev->hw;
954
955         if (!dev->ops->server_reconnect) {
956                 PMD_DRV_LOG(ERR, "(%s) Missing server reconnect callback", dev->path);
957                 return -1;
958         }
959
960         if (dev->ops->server_reconnect(dev)) {
961                 PMD_DRV_LOG(ERR, "(%s) Reconnect callback call failed", dev->path);
962                 return -1;
963         }
964
965         old_status = dev->status;
966
967         virtio_reset(hw);
968
969         virtio_set_status(hw, VIRTIO_CONFIG_STATUS_ACK);
970
971         virtio_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER);
972
973         if (dev->ops->get_features(dev, &dev->device_features) < 0) {
974                 PMD_INIT_LOG(ERR, "get_features failed: %s",
975                              strerror(errno));
976                 return -1;
977         }
978
979         /* unmask vhost-user unsupported features */
980         dev->device_features &= ~(dev->unsupported_features);
981
982         dev->features &= (dev->device_features | dev->frontend_features);
983
984         /* For packed ring, resetting queues is required in reconnection. */
985         if (virtio_with_packed_queue(hw) &&
986            (old_status & VIRTIO_CONFIG_STATUS_DRIVER_OK)) {
987                 PMD_INIT_LOG(NOTICE, "Packets on the fly will be dropped"
988                                 " when packed ring reconnecting.");
989                 virtio_user_dev_reset_queues_packed(eth_dev);
990         }
991
992         virtio_set_status(hw, VIRTIO_CONFIG_STATUS_FEATURES_OK);
993
994         /* Start the device */
995         virtio_set_status(hw, VIRTIO_CONFIG_STATUS_DRIVER_OK);
996         if (!dev->started)
997                 return -1;
998
999         if (dev->queue_pairs > 1) {
1000                 ret = virtio_user_handle_mq(dev, dev->queue_pairs);
1001                 if (ret != 0) {
1002                         PMD_INIT_LOG(ERR, "Fails to enable multi-queue pairs!");
1003                         return -1;
1004                 }
1005         }
1006         if (eth_dev->data->dev_flags & RTE_ETH_DEV_INTR_LSC) {
1007                 if (rte_intr_disable(eth_dev->intr_handle) < 0) {
1008                         PMD_DRV_LOG(ERR, "interrupt disable failed");
1009                         return -1;
1010                 }
1011                 /*
1012                  * This function can be called from the interrupt handler, so
1013                  * we can't unregister interrupt handler here.  Setting
1014                  * alarm to do that later.
1015                  */
1016                 rte_eal_alarm_set(1,
1017                         virtio_user_dev_delayed_intr_reconfig_handler,
1018                         (void *)dev);
1019         }
1020         PMD_INIT_LOG(NOTICE, "server mode virtio-user reconnection succeeds!");
1021         return 0;
1022 }