diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-05-24 12:46:45 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-05-24 12:46:45 -0400 |
commit | ecaba7185894778c24895356d117a7f92e3c92de (patch) | |
tree | 03567db9d31a453f4262c923c9717e4d394e6881 /tools | |
parent | e989cc564691901d42e957059592fe3e7b6893fc (diff) | |
parent | bb991288728e6a47a6f0fac6a4e9dfaeecc27956 (diff) |
Merge tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost
Pull virtio updates from Michael Tsirkin:
"Looks like a quiet cycle for virtio. There's a new inorder option for
the ringtest tool, and a bugfix for balloon for ppc platforms when
using virtio 1 mode"
* tag 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mst/vhost:
ringtest: pass buf != NULL
virtio_balloon: fix PFN format for virtio-1
virtio: add inorder option
Diffstat (limited to 'tools')
-rw-r--r-- | tools/virtio/ringtest/Makefile | 5 | ||||
-rw-r--r-- | tools/virtio/ringtest/main.c | 2 | ||||
-rw-r--r-- | tools/virtio/ringtest/virtio_ring_0_9.c | 49 | ||||
-rw-r--r-- | tools/virtio/ringtest/virtio_ring_inorder.c | 2 |
4 files changed, 55 insertions, 3 deletions
diff --git a/tools/virtio/ringtest/Makefile b/tools/virtio/ringtest/Makefile index feaa64ac4630..6ba745529833 100644 --- a/tools/virtio/ringtest/Makefile +++ b/tools/virtio/ringtest/Makefile | |||
@@ -1,6 +1,6 @@ | |||
1 | all: | 1 | all: |
2 | 2 | ||
3 | all: ring virtio_ring_0_9 virtio_ring_poll | 3 | all: ring virtio_ring_0_9 virtio_ring_poll virtio_ring_inorder |
4 | 4 | ||
5 | CFLAGS += -Wall | 5 | CFLAGS += -Wall |
6 | CFLAGS += -pthread -O2 -ggdb | 6 | CFLAGS += -pthread -O2 -ggdb |
@@ -10,13 +10,16 @@ main.o: main.c main.h | |||
10 | ring.o: ring.c main.h | 10 | ring.o: ring.c main.h |
11 | virtio_ring_0_9.o: virtio_ring_0_9.c main.h | 11 | virtio_ring_0_9.o: virtio_ring_0_9.c main.h |
12 | virtio_ring_poll.o: virtio_ring_poll.c virtio_ring_0_9.c main.h | 12 | virtio_ring_poll.o: virtio_ring_poll.c virtio_ring_0_9.c main.h |
13 | virtio_ring_inorder.o: virtio_ring_inorder.c virtio_ring_0_9.c main.h | ||
13 | ring: ring.o main.o | 14 | ring: ring.o main.o |
14 | virtio_ring_0_9: virtio_ring_0_9.o main.o | 15 | virtio_ring_0_9: virtio_ring_0_9.o main.o |
15 | virtio_ring_poll: virtio_ring_poll.o main.o | 16 | virtio_ring_poll: virtio_ring_poll.o main.o |
17 | virtio_ring_inorder: virtio_ring_inorder.o main.o | ||
16 | clean: | 18 | clean: |
17 | -rm main.o | 19 | -rm main.o |
18 | -rm ring.o ring | 20 | -rm ring.o ring |
19 | -rm virtio_ring_0_9.o virtio_ring_0_9 | 21 | -rm virtio_ring_0_9.o virtio_ring_0_9 |
20 | -rm virtio_ring_poll.o virtio_ring_poll | 22 | -rm virtio_ring_poll.o virtio_ring_poll |
23 | -rm virtio_ring_inorder.o virtio_ring_inorder | ||
21 | 24 | ||
22 | .PHONY: all clean | 25 | .PHONY: all clean |
diff --git a/tools/virtio/ringtest/main.c b/tools/virtio/ringtest/main.c index 3a5ff438bd62..147abb452a6c 100644 --- a/tools/virtio/ringtest/main.c +++ b/tools/virtio/ringtest/main.c | |||
@@ -115,7 +115,7 @@ static void run_guest(void) | |||
115 | do { | 115 | do { |
116 | if (started < bufs && | 116 | if (started < bufs && |
117 | started - completed < max_outstanding) { | 117 | started - completed < max_outstanding) { |
118 | r = add_inbuf(0, NULL, "Hello, world!"); | 118 | r = add_inbuf(0, "Buffer\n", "Hello, world!"); |
119 | if (__builtin_expect(r == 0, true)) { | 119 | if (__builtin_expect(r == 0, true)) { |
120 | ++started; | 120 | ++started; |
121 | if (!--tokick) { | 121 | if (!--tokick) { |
diff --git a/tools/virtio/ringtest/virtio_ring_0_9.c b/tools/virtio/ringtest/virtio_ring_0_9.c index 47c9a1a18d36..761866212aac 100644 --- a/tools/virtio/ringtest/virtio_ring_0_9.c +++ b/tools/virtio/ringtest/virtio_ring_0_9.c | |||
@@ -26,6 +26,14 @@ struct vring ring; | |||
26 | * high bits of ring id ^ 0x8000). | 26 | * high bits of ring id ^ 0x8000). |
27 | */ | 27 | */ |
28 | /* #ifdef RING_POLL */ | 28 | /* #ifdef RING_POLL */ |
29 | /* enabling the below activates experimental in-order code | ||
30 | * (which skips ring updates and reads and writes len in descriptor). | ||
31 | */ | ||
32 | /* #ifdef INORDER */ | ||
33 | |||
34 | #if defined(RING_POLL) && defined(INORDER) | ||
35 | #error "RING_POLL and INORDER are mutually exclusive" | ||
36 | #endif | ||
29 | 37 | ||
30 | /* how much padding is needed to avoid false cache sharing */ | 38 | /* how much padding is needed to avoid false cache sharing */ |
31 | #define HOST_GUEST_PADDING 0x80 | 39 | #define HOST_GUEST_PADDING 0x80 |
@@ -35,7 +43,11 @@ struct guest { | |||
35 | unsigned short last_used_idx; | 43 | unsigned short last_used_idx; |
36 | unsigned short num_free; | 44 | unsigned short num_free; |
37 | unsigned short kicked_avail_idx; | 45 | unsigned short kicked_avail_idx; |
46 | #ifndef INORDER | ||
38 | unsigned short free_head; | 47 | unsigned short free_head; |
48 | #else | ||
49 | unsigned short reserved_free_head; | ||
50 | #endif | ||
39 | unsigned char reserved[HOST_GUEST_PADDING - 10]; | 51 | unsigned char reserved[HOST_GUEST_PADDING - 10]; |
40 | } guest; | 52 | } guest; |
41 | 53 | ||
@@ -66,8 +78,10 @@ void alloc_ring(void) | |||
66 | guest.avail_idx = 0; | 78 | guest.avail_idx = 0; |
67 | guest.kicked_avail_idx = -1; | 79 | guest.kicked_avail_idx = -1; |
68 | guest.last_used_idx = 0; | 80 | guest.last_used_idx = 0; |
81 | #ifndef INORDER | ||
69 | /* Put everything in free lists. */ | 82 | /* Put everything in free lists. */ |
70 | guest.free_head = 0; | 83 | guest.free_head = 0; |
84 | #endif | ||
71 | for (i = 0; i < ring_size - 1; i++) | 85 | for (i = 0; i < ring_size - 1; i++) |
72 | ring.desc[i].next = i + 1; | 86 | ring.desc[i].next = i + 1; |
73 | host.used_idx = 0; | 87 | host.used_idx = 0; |
@@ -84,13 +98,20 @@ void alloc_ring(void) | |||
84 | /* guest side */ | 98 | /* guest side */ |
85 | int add_inbuf(unsigned len, void *buf, void *datap) | 99 | int add_inbuf(unsigned len, void *buf, void *datap) |
86 | { | 100 | { |
87 | unsigned head, avail; | 101 | unsigned head; |
102 | #ifndef INORDER | ||
103 | unsigned avail; | ||
104 | #endif | ||
88 | struct vring_desc *desc; | 105 | struct vring_desc *desc; |
89 | 106 | ||
90 | if (!guest.num_free) | 107 | if (!guest.num_free) |
91 | return -1; | 108 | return -1; |
92 | 109 | ||
110 | #ifdef INORDER | ||
111 | head = (ring_size - 1) & (guest.avail_idx++); | ||
112 | #else | ||
93 | head = guest.free_head; | 113 | head = guest.free_head; |
114 | #endif | ||
94 | guest.num_free--; | 115 | guest.num_free--; |
95 | 116 | ||
96 | desc = ring.desc; | 117 | desc = ring.desc; |
@@ -102,7 +123,9 @@ int add_inbuf(unsigned len, void *buf, void *datap) | |||
102 | * descriptors. | 123 | * descriptors. |
103 | */ | 124 | */ |
104 | desc[head].flags &= ~VRING_DESC_F_NEXT; | 125 | desc[head].flags &= ~VRING_DESC_F_NEXT; |
126 | #ifndef INORDER | ||
105 | guest.free_head = desc[head].next; | 127 | guest.free_head = desc[head].next; |
128 | #endif | ||
106 | 129 | ||
107 | data[head].data = datap; | 130 | data[head].data = datap; |
108 | 131 | ||
@@ -113,8 +136,12 @@ int add_inbuf(unsigned len, void *buf, void *datap) | |||
113 | ring.avail->ring[avail & (ring_size - 1)] = | 136 | ring.avail->ring[avail & (ring_size - 1)] = |
114 | (head | (avail & ~(ring_size - 1))) ^ 0x8000; | 137 | (head | (avail & ~(ring_size - 1))) ^ 0x8000; |
115 | #else | 138 | #else |
139 | #ifndef INORDER | ||
140 | /* Barrier A (for pairing) */ | ||
141 | smp_release(); | ||
116 | avail = (ring_size - 1) & (guest.avail_idx++); | 142 | avail = (ring_size - 1) & (guest.avail_idx++); |
117 | ring.avail->ring[avail] = head; | 143 | ring.avail->ring[avail] = head; |
144 | #endif | ||
118 | /* Barrier A (for pairing) */ | 145 | /* Barrier A (for pairing) */ |
119 | smp_release(); | 146 | smp_release(); |
120 | #endif | 147 | #endif |
@@ -141,15 +168,27 @@ void *get_buf(unsigned *lenp, void **bufp) | |||
141 | return NULL; | 168 | return NULL; |
142 | /* Barrier B (for pairing) */ | 169 | /* Barrier B (for pairing) */ |
143 | smp_acquire(); | 170 | smp_acquire(); |
171 | #ifdef INORDER | ||
172 | head = (ring_size - 1) & guest.last_used_idx; | ||
173 | index = head; | ||
174 | #else | ||
144 | head = (ring_size - 1) & guest.last_used_idx; | 175 | head = (ring_size - 1) & guest.last_used_idx; |
145 | index = ring.used->ring[head].id; | 176 | index = ring.used->ring[head].id; |
146 | #endif | 177 | #endif |
178 | |||
179 | #endif | ||
180 | #ifdef INORDER | ||
181 | *lenp = ring.desc[index].len; | ||
182 | #else | ||
147 | *lenp = ring.used->ring[head].len; | 183 | *lenp = ring.used->ring[head].len; |
184 | #endif | ||
148 | datap = data[index].data; | 185 | datap = data[index].data; |
149 | *bufp = (void*)(unsigned long)ring.desc[index].addr; | 186 | *bufp = (void*)(unsigned long)ring.desc[index].addr; |
150 | data[index].data = NULL; | 187 | data[index].data = NULL; |
188 | #ifndef INORDER | ||
151 | ring.desc[index].next = guest.free_head; | 189 | ring.desc[index].next = guest.free_head; |
152 | guest.free_head = index; | 190 | guest.free_head = index; |
191 | #endif | ||
153 | guest.num_free++; | 192 | guest.num_free++; |
154 | guest.last_used_idx++; | 193 | guest.last_used_idx++; |
155 | return datap; | 194 | return datap; |
@@ -283,16 +322,24 @@ bool use_buf(unsigned *lenp, void **bufp) | |||
283 | smp_acquire(); | 322 | smp_acquire(); |
284 | 323 | ||
285 | used_idx &= ring_size - 1; | 324 | used_idx &= ring_size - 1; |
325 | #ifdef INORDER | ||
326 | head = used_idx; | ||
327 | #else | ||
286 | head = ring.avail->ring[used_idx]; | 328 | head = ring.avail->ring[used_idx]; |
329 | #endif | ||
287 | desc = &ring.desc[head]; | 330 | desc = &ring.desc[head]; |
288 | #endif | 331 | #endif |
289 | 332 | ||
290 | *lenp = desc->len; | 333 | *lenp = desc->len; |
291 | *bufp = (void *)(unsigned long)desc->addr; | 334 | *bufp = (void *)(unsigned long)desc->addr; |
292 | 335 | ||
336 | #ifdef INORDER | ||
337 | desc->len = desc->len - 1; | ||
338 | #else | ||
293 | /* now update used ring */ | 339 | /* now update used ring */ |
294 | ring.used->ring[used_idx].id = head; | 340 | ring.used->ring[used_idx].id = head; |
295 | ring.used->ring[used_idx].len = desc->len - 1; | 341 | ring.used->ring[used_idx].len = desc->len - 1; |
342 | #endif | ||
296 | /* Barrier B (for pairing) */ | 343 | /* Barrier B (for pairing) */ |
297 | smp_release(); | 344 | smp_release(); |
298 | host.used_idx++; | 345 | host.used_idx++; |
diff --git a/tools/virtio/ringtest/virtio_ring_inorder.c b/tools/virtio/ringtest/virtio_ring_inorder.c new file mode 100644 index 000000000000..2438ca58a2ad --- /dev/null +++ b/tools/virtio/ringtest/virtio_ring_inorder.c | |||
@@ -0,0 +1,2 @@ | |||
1 | #define INORDER 1 | ||
2 | #include "virtio_ring_0_9.c" | ||