aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2016-10-06 05:39:11 -0400
committerMichael S. Tsirkin <mst@redhat.com>2016-10-30 18:21:43 -0400
commitd3c3589b8b3cd4fabf4cd137facb42a7fb36bd7f (patch)
treed71957ed6843a84c8328587604b9bdfe84363094 /tools
parent44d65ea1615099ae252407f2554338d450cfdb1c (diff)
ringtest: commonize implementation of poll_avail/poll_used
Provide new primitives used_empty/avail_empty and build poll_avail/poll_used on top of it. Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'tools')
-rw-r--r--tools/virtio/ringtest/main.c12
-rw-r--r--tools/virtio/ringtest/main.h4
-rw-r--r--tools/virtio/ringtest/noring.c6
-rw-r--r--tools/virtio/ringtest/ptr_ring.c22
-rw-r--r--tools/virtio/ringtest/ring.c18
-rw-r--r--tools/virtio/ringtest/virtio_ring_0_9.c64
6 files changed, 43 insertions, 83 deletions
diff --git a/tools/virtio/ringtest/main.c b/tools/virtio/ringtest/main.c
index bda7f0dad981..b00ecd619969 100644
--- a/tools/virtio/ringtest/main.c
+++ b/tools/virtio/ringtest/main.c
@@ -96,6 +96,12 @@ void set_affinity(const char *arg)
96 assert(!ret); 96 assert(!ret);
97} 97}
98 98
99void poll_used(void)
100{
101 while (used_empty())
102 busy_wait();
103}
104
99static void __attribute__((__flatten__)) run_guest(void) 105static void __attribute__((__flatten__)) run_guest(void)
100{ 106{
101 int completed_before; 107 int completed_before;
@@ -149,6 +155,12 @@ static void __attribute__((__flatten__)) run_guest(void)
149 } 155 }
150} 156}
151 157
158void poll_avail(void)
159{
160 while (avail_empty())
161 busy_wait();
162}
163
152static void __attribute__((__flatten__)) run_host(void) 164static void __attribute__((__flatten__)) run_host(void)
153{ 165{
154 int completed_before; 166 int completed_before;
diff --git a/tools/virtio/ringtest/main.h b/tools/virtio/ringtest/main.h
index 16917acb0ade..34e63cc4c572 100644
--- a/tools/virtio/ringtest/main.h
+++ b/tools/virtio/ringtest/main.h
@@ -56,15 +56,15 @@ void alloc_ring(void);
56int add_inbuf(unsigned, void *, void *); 56int add_inbuf(unsigned, void *, void *);
57void *get_buf(unsigned *, void **); 57void *get_buf(unsigned *, void **);
58void disable_call(); 58void disable_call();
59bool used_empty();
59bool enable_call(); 60bool enable_call();
60void kick_available(); 61void kick_available();
61void poll_used();
62/* host side */ 62/* host side */
63void disable_kick(); 63void disable_kick();
64bool avail_empty();
64bool enable_kick(); 65bool enable_kick();
65bool use_buf(unsigned *, void **); 66bool use_buf(unsigned *, void **);
66void call_used(); 67void call_used();
67void poll_avail();
68 68
69/* implemented by main */ 69/* implemented by main */
70extern bool do_sleep; 70extern bool do_sleep;
diff --git a/tools/virtio/ringtest/noring.c b/tools/virtio/ringtest/noring.c
index eda2f4824130..b8d1c1daac7c 100644
--- a/tools/virtio/ringtest/noring.c
+++ b/tools/virtio/ringtest/noring.c
@@ -24,8 +24,9 @@ void *get_buf(unsigned *lenp, void **bufp)
24 return "Buffer"; 24 return "Buffer";
25} 25}
26 26
27void poll_used(void) 27bool used_empty()
28{ 28{
29 return false;
29} 30}
30 31
31void disable_call() 32void disable_call()
@@ -54,8 +55,9 @@ bool enable_kick()
54 assert(0); 55 assert(0);
55} 56}
56 57
57void poll_avail(void) 58bool avail_empty()
58{ 59{
60 return false;
59} 61}
60 62
61bool use_buf(unsigned *lenp, void **bufp) 63bool use_buf(unsigned *lenp, void **bufp)
diff --git a/tools/virtio/ringtest/ptr_ring.c b/tools/virtio/ringtest/ptr_ring.c
index bd2ad1d3b7a9..635b07b4fdd3 100644
--- a/tools/virtio/ringtest/ptr_ring.c
+++ b/tools/virtio/ringtest/ptr_ring.c
@@ -133,18 +133,9 @@ void *get_buf(unsigned *lenp, void **bufp)
133 return datap; 133 return datap;
134} 134}
135 135
136void poll_used(void) 136bool used_empty()
137{ 137{
138 void *b; 138 return (tailcnt == headcnt || __ptr_ring_full(&array));
139
140 do {
141 if (tailcnt == headcnt || __ptr_ring_full(&array)) {
142 b = NULL;
143 barrier();
144 } else {
145 b = "Buffer\n";
146 }
147 } while (!b);
148} 139}
149 140
150void disable_call() 141void disable_call()
@@ -173,14 +164,9 @@ bool enable_kick()
173 assert(0); 164 assert(0);
174} 165}
175 166
176void poll_avail(void) 167bool avail_empty()
177{ 168{
178 void *b; 169 return !__ptr_ring_peek(&array);
179
180 do {
181 barrier();
182 b = __ptr_ring_peek(&array);
183 } while (!b);
184} 170}
185 171
186bool use_buf(unsigned *lenp, void **bufp) 172bool use_buf(unsigned *lenp, void **bufp)
diff --git a/tools/virtio/ringtest/ring.c b/tools/virtio/ringtest/ring.c
index c25c8d248b6b..747c5dd47be8 100644
--- a/tools/virtio/ringtest/ring.c
+++ b/tools/virtio/ringtest/ring.c
@@ -163,12 +163,11 @@ void *get_buf(unsigned *lenp, void **bufp)
163 return datap; 163 return datap;
164} 164}
165 165
166void poll_used(void) 166bool used_empty()
167{ 167{
168 unsigned head = (ring_size - 1) & guest.last_used_idx; 168 unsigned head = (ring_size - 1) & guest.last_used_idx;
169 169
170 while (ring[head].flags & DESC_HW) 170 return (ring[head].flags & DESC_HW);
171 busy_wait();
172} 171}
173 172
174void disable_call() 173void disable_call()
@@ -180,13 +179,11 @@ void disable_call()
180 179
181bool enable_call() 180bool enable_call()
182{ 181{
183 unsigned head = (ring_size - 1) & guest.last_used_idx;
184
185 event->call_index = guest.last_used_idx; 182 event->call_index = guest.last_used_idx;
186 /* Flush call index write */ 183 /* Flush call index write */
187 /* Barrier D (for pairing) */ 184 /* Barrier D (for pairing) */
188 smp_mb(); 185 smp_mb();
189 return ring[head].flags & DESC_HW; 186 return used_empty();
190} 187}
191 188
192void kick_available(void) 189void kick_available(void)
@@ -213,20 +210,17 @@ void disable_kick()
213 210
214bool enable_kick() 211bool enable_kick()
215{ 212{
216 unsigned head = (ring_size - 1) & host.used_idx;
217
218 event->kick_index = host.used_idx; 213 event->kick_index = host.used_idx;
219 /* Barrier C (for pairing) */ 214 /* Barrier C (for pairing) */
220 smp_mb(); 215 smp_mb();
221 return !(ring[head].flags & DESC_HW); 216 return avail_empty();
222} 217}
223 218
224void poll_avail(void) 219bool avail_empty()
225{ 220{
226 unsigned head = (ring_size - 1) & host.used_idx; 221 unsigned head = (ring_size - 1) & host.used_idx;
227 222
228 while (!(ring[head].flags & DESC_HW)) 223 return !(ring[head].flags & DESC_HW);
229 busy_wait();
230} 224}
231 225
232bool use_buf(unsigned *lenp, void **bufp) 226bool use_buf(unsigned *lenp, void **bufp)
diff --git a/tools/virtio/ringtest/virtio_ring_0_9.c b/tools/virtio/ringtest/virtio_ring_0_9.c
index 761866212aac..bbc3043b2fb1 100644
--- a/tools/virtio/ringtest/virtio_ring_0_9.c
+++ b/tools/virtio/ringtest/virtio_ring_0_9.c
@@ -194,24 +194,16 @@ void *get_buf(unsigned *lenp, void **bufp)
194 return datap; 194 return datap;
195} 195}
196 196
197void poll_used(void) 197bool used_empty()
198{ 198{
199 unsigned short last_used_idx = guest.last_used_idx;
199#ifdef RING_POLL 200#ifdef RING_POLL
200 unsigned head = (ring_size - 1) & guest.last_used_idx; 201 unsigned short head = last_used_idx & (ring_size - 1);
202 unsigned index = ring.used->ring[head].id;
201 203
202 for (;;) { 204 return (index ^ last_used_idx ^ 0x8000) & ~(ring_size - 1);
203 unsigned index = ring.used->ring[head].id;
204
205 if ((index ^ guest.last_used_idx ^ 0x8000) & ~(ring_size - 1))
206 busy_wait();
207 else
208 break;
209 }
210#else 205#else
211 unsigned head = guest.last_used_idx; 206 return ring.used->idx == last_used_idx;
212
213 while (ring.used->idx == head)
214 busy_wait();
215#endif 207#endif
216} 208}
217 209
@@ -224,22 +216,11 @@ void disable_call()
224 216
225bool enable_call() 217bool enable_call()
226{ 218{
227 unsigned short last_used_idx; 219 vring_used_event(&ring) = guest.last_used_idx;
228
229 vring_used_event(&ring) = (last_used_idx = guest.last_used_idx);
230 /* Flush call index write */ 220 /* Flush call index write */
231 /* Barrier D (for pairing) */ 221 /* Barrier D (for pairing) */
232 smp_mb(); 222 smp_mb();
233#ifdef RING_POLL 223 return used_empty();
234 {
235 unsigned short head = last_used_idx & (ring_size - 1);
236 unsigned index = ring.used->ring[head].id;
237
238 return (index ^ last_used_idx ^ 0x8000) & ~(ring_size - 1);
239 }
240#else
241 return ring.used->idx == last_used_idx;
242#endif
243} 224}
244 225
245void kick_available(void) 226void kick_available(void)
@@ -266,36 +247,21 @@ void disable_kick()
266 247
267bool enable_kick() 248bool enable_kick()
268{ 249{
269 unsigned head = host.used_idx; 250 vring_avail_event(&ring) = host.used_idx;
270
271 vring_avail_event(&ring) = head;
272 /* Barrier C (for pairing) */ 251 /* Barrier C (for pairing) */
273 smp_mb(); 252 smp_mb();
274#ifdef RING_POLL 253 return avail_empty();
275 {
276 unsigned index = ring.avail->ring[head & (ring_size - 1)];
277
278 return (index ^ head ^ 0x8000) & ~(ring_size - 1);
279 }
280#else
281 return head == ring.avail->idx;
282#endif
283} 254}
284 255
285void poll_avail(void) 256bool avail_empty()
286{ 257{
287 unsigned head = host.used_idx; 258 unsigned head = host.used_idx;
288#ifdef RING_POLL 259#ifdef RING_POLL
289 for (;;) { 260 unsigned index = ring.avail->ring[head & (ring_size - 1)];
290 unsigned index = ring.avail->ring[head & (ring_size - 1)]; 261
291 if ((index ^ head ^ 0x8000) & ~(ring_size - 1)) 262 return ((index ^ head ^ 0x8000) & ~(ring_size - 1));
292 busy_wait();
293 else
294 break;
295 }
296#else 263#else
297 while (ring.avail->idx == head) 264 return head == ring.avail->idx;
298 busy_wait();
299#endif 265#endif
300} 266}
301 267