Skip to content

Commit 9fb6bc5

Browse files
mstsirkindavem330
authored andcommitted
ptr_ring: ring test
Add ringtest based unit test for ptr ring. Signed-off-by: Michael S. Tsirkin <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 2e0ab8c commit 9fb6bc5

File tree

2 files changed

+196
-1
lines changed

2 files changed

+196
-1
lines changed

tools/virtio/ringtest/Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,28 @@
11
all:
22

3-
all: ring virtio_ring_0_9 virtio_ring_poll virtio_ring_inorder
3+
all: ring virtio_ring_0_9 virtio_ring_poll virtio_ring_inorder ptr_ring
44

55
CFLAGS += -Wall
66
CFLAGS += -pthread -O2 -ggdb
77
LDFLAGS += -pthread -O2 -ggdb
88

99
main.o: main.c main.h
1010
ring.o: ring.c main.h
11+
ptr_ring.o: ptr_ring.c main.h ../../../include/linux/ptr_ring.h
1112
virtio_ring_0_9.o: virtio_ring_0_9.c main.h
1213
virtio_ring_poll.o: virtio_ring_poll.c virtio_ring_0_9.c main.h
1314
virtio_ring_inorder.o: virtio_ring_inorder.c virtio_ring_0_9.c main.h
1415
ring: ring.o main.o
1516
virtio_ring_0_9: virtio_ring_0_9.o main.o
1617
virtio_ring_poll: virtio_ring_poll.o main.o
1718
virtio_ring_inorder: virtio_ring_inorder.o main.o
19+
ptr_ring: ptr_ring.o main.o
1820
clean:
1921
-rm main.o
2022
-rm ring.o ring
2123
-rm virtio_ring_0_9.o virtio_ring_0_9
2224
-rm virtio_ring_poll.o virtio_ring_poll
2325
-rm virtio_ring_inorder.o virtio_ring_inorder
26+
-rm ptr_ring.o ptr_ring
2427

2528
.PHONY: all clean

tools/virtio/ringtest/ptr_ring.c

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
#define _GNU_SOURCE
2+
#include "main.h"
3+
#include <stdlib.h>
4+
#include <stdio.h>
5+
#include <string.h>
6+
#include <pthread.h>
7+
#include <malloc.h>
8+
#include <assert.h>
9+
#include <errno.h>
10+
#include <limits.h>
11+
12+
#define SMP_CACHE_BYTES 64
13+
#define cache_line_size() SMP_CACHE_BYTES
14+
#define ____cacheline_aligned_in_smp __attribute__ ((aligned (SMP_CACHE_BYTES)))
15+
#define unlikely(x) (__builtin_expect(!!(x), 0))
16+
#define ALIGN(x, a) (((x) + (a) - 1) / (a) * (a))
17+
typedef pthread_spinlock_t spinlock_t;
18+
19+
typedef int gfp_t;
20+
static void *kzalloc(unsigned size, gfp_t gfp)
21+
{
22+
void *p = memalign(64, size);
23+
if (!p)
24+
return p;
25+
memset(p, 0, size);
26+
27+
return p;
28+
}
29+
30+
static void kfree(void *p)
31+
{
32+
if (p)
33+
free(p);
34+
}
35+
36+
static void spin_lock_init(spinlock_t *lock)
37+
{
38+
int r = pthread_spin_init(lock, 0);
39+
assert(!r);
40+
}
41+
42+
static void spin_lock(spinlock_t *lock)
43+
{
44+
int ret = pthread_spin_lock(lock);
45+
assert(!ret);
46+
}
47+
48+
static void spin_unlock(spinlock_t *lock)
49+
{
50+
int ret = pthread_spin_unlock(lock);
51+
assert(!ret);
52+
}
53+
54+
static void spin_lock_bh(spinlock_t *lock)
55+
{
56+
spin_lock(lock);
57+
}
58+
59+
static void spin_unlock_bh(spinlock_t *lock)
60+
{
61+
spin_unlock(lock);
62+
}
63+
64+
static void spin_lock_irq(spinlock_t *lock)
65+
{
66+
spin_lock(lock);
67+
}
68+
69+
static void spin_unlock_irq(spinlock_t *lock)
70+
{
71+
spin_unlock(lock);
72+
}
73+
74+
static void spin_lock_irqsave(spinlock_t *lock, unsigned long f)
75+
{
76+
spin_lock(lock);
77+
}
78+
79+
static void spin_unlock_irqrestore(spinlock_t *lock, unsigned long f)
80+
{
81+
spin_unlock(lock);
82+
}
83+
84+
#include "../../../include/linux/ptr_ring.h"
85+
86+
static unsigned long long headcnt, tailcnt;
87+
static struct ptr_ring array ____cacheline_aligned_in_smp;
88+
89+
/* implemented by ring */
90+
void alloc_ring(void)
91+
{
92+
int ret = ptr_ring_init(&array, ring_size, 0);
93+
assert(!ret);
94+
}
95+
96+
/* guest side */
97+
int add_inbuf(unsigned len, void *buf, void *datap)
98+
{
99+
int ret;
100+
101+
ret = __ptr_ring_produce(&array, buf);
102+
if (ret >= 0) {
103+
ret = 0;
104+
headcnt++;
105+
}
106+
107+
return ret;
108+
}
109+
110+
/*
111+
* ptr_ring API provides no way for producer to find out whether a given
112+
* buffer was consumed. Our tests merely require that a successful get_buf
113+
* implies that add_inbuf succeed in the past, and that add_inbuf will succeed,
114+
* fake it accordingly.
115+
*/
116+
void *get_buf(unsigned *lenp, void **bufp)
117+
{
118+
void *datap;
119+
120+
if (tailcnt == headcnt || __ptr_ring_full(&array))
121+
datap = NULL;
122+
else {
123+
datap = "Buffer\n";
124+
++tailcnt;
125+
}
126+
127+
return datap;
128+
}
129+
130+
void poll_used(void)
131+
{
132+
void *b;
133+
134+
do {
135+
if (tailcnt == headcnt || __ptr_ring_full(&array)) {
136+
b = NULL;
137+
barrier();
138+
} else {
139+
b = "Buffer\n";
140+
}
141+
} while (!b);
142+
}
143+
144+
void disable_call()
145+
{
146+
assert(0);
147+
}
148+
149+
bool enable_call()
150+
{
151+
assert(0);
152+
}
153+
154+
void kick_available(void)
155+
{
156+
assert(0);
157+
}
158+
159+
/* host side */
160+
void disable_kick()
161+
{
162+
assert(0);
163+
}
164+
165+
bool enable_kick()
166+
{
167+
assert(0);
168+
}
169+
170+
void poll_avail(void)
171+
{
172+
void *b;
173+
174+
do {
175+
barrier();
176+
b = __ptr_ring_peek(&array);
177+
} while (!b);
178+
}
179+
180+
bool use_buf(unsigned *lenp, void **bufp)
181+
{
182+
void *ptr;
183+
184+
ptr = __ptr_ring_consume(&array);
185+
186+
return ptr;
187+
}
188+
189+
void call_used(void)
190+
{
191+
assert(0);
192+
}

0 commit comments

Comments
 (0)