Branch data Line data Source code
1 : : #ifndef _LINUX_VIRTIO_RING_H
2 : : #define _LINUX_VIRTIO_RING_H
3 : :
4 : : #include <asm/barrier.h>
5 : : #include <linux/irqreturn.h>
6 : : #include <uapi/linux/virtio_ring.h>
7 : :
8 : : /*
9 : : * Barriers in virtio are tricky. Non-SMP virtio guests can't assume
10 : : * they're not on an SMP host system, so they need to assume real
11 : : * barriers. Non-SMP virtio hosts could skip the barriers, but does
12 : : * anyone care?
13 : : *
14 : : * For virtio_pci on SMP, we don't need to order with respect to MMIO
15 : : * accesses through relaxed memory I/O windows, so smp_mb() et al are
16 : : * sufficient.
17 : : *
18 : : * For using virtio to talk to real devices (eg. other heterogeneous
19 : : * CPUs) we do need real barriers. In theory, we could be using both
20 : : * kinds of virtio, so it's a runtime decision, and the branch is
21 : : * actually quite cheap.
22 : : */
23 : :
24 : : #ifdef CONFIG_SMP
25 : : static inline void virtio_mb(bool weak_barriers)
26 : : {
27 [ # # ][ # # ]: 0 : if (weak_barriers)
[ # # ][ # # ]
[ # # ]
28 : 0 : smp_mb();
29 : : else
30 : 0 : mb();
31 : : }
32 : :
33 : : static inline void virtio_rmb(bool weak_barriers)
34 : : {
35 [ # # ]: 0 : if (weak_barriers)
36 : 0 : smp_rmb();
37 : : else
38 : 0 : rmb();
39 : : }
40 : :
41 : : static inline void virtio_wmb(bool weak_barriers)
42 : : {
43 [ # # ][ # # ]: 0 : if (weak_barriers)
[ # # ]
44 : 0 : smp_wmb();
45 : : else
46 : 0 : wmb();
47 : : }
48 : : #else
49 : : static inline void virtio_mb(bool weak_barriers)
50 : : {
51 : : mb();
52 : : }
53 : :
54 : : static inline void virtio_rmb(bool weak_barriers)
55 : : {
56 : : rmb();
57 : : }
58 : :
59 : : static inline void virtio_wmb(bool weak_barriers)
60 : : {
61 : : wmb();
62 : : }
63 : : #endif
64 : :
65 : : struct virtio_device;
66 : : struct virtqueue;
67 : :
68 : : struct virtqueue *vring_new_virtqueue(unsigned int index,
69 : : unsigned int num,
70 : : unsigned int vring_align,
71 : : struct virtio_device *vdev,
72 : : bool weak_barriers,
73 : : void *pages,
74 : : bool (*notify)(struct virtqueue *vq),
75 : : void (*callback)(struct virtqueue *vq),
76 : : const char *name);
77 : : void vring_del_virtqueue(struct virtqueue *vq);
78 : : /* Filter out transport-specific feature bits. */
79 : : void vring_transport_features(struct virtio_device *vdev);
80 : :
81 : : irqreturn_t vring_interrupt(int irq, void *_vq);
82 : : #endif /* _LINUX_VIRTIO_RING_H */
|