1
- /* SPDX-License-Identifier: GPL-2.0 */
2
1
/******************************************************************************
3
2
* ring.h
4
3
*
5
4
* Shared producer-consumer ring macros.
6
5
*
6
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ * of this software and associated documentation files (the "Software"), to
8
+ * deal in the Software without restriction, including without limitation the
9
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10
+ * sell copies of the Software, and to permit persons to whom the Software is
11
+ * furnished to do so, subject to the following conditions:
12
+ *
13
+ * The above copyright notice and this permission notice shall be included in
14
+ * all copies or substantial portions of the Software.
15
+ *
16
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22
+ * DEALINGS IN THE SOFTWARE.
23
+ *
7
24
* Tim Deegan and Andrew Warfield November 2004.
8
25
*/
9
26
10
27
#ifndef __XEN_PUBLIC_IO_RING_H__
11
28
#define __XEN_PUBLIC_IO_RING_H__
12
29
30
+ /*
31
+ * When #include'ing this header, you need to provide the following
32
+ * declaration upfront:
33
+ * - standard integers types (uint8_t, uint16_t, etc)
34
+ * They are provided by stdint.h of the standard headers.
35
+ *
36
+ * In addition, if you intend to use the FLEX macros, you also need to
37
+ * provide the following, before invoking the FLEX macros:
38
+ * - size_t
39
+ * - memcpy
40
+ * - grant_ref_t
41
+ * These declarations are provided by string.h of the standard headers,
42
+ * and grant_table.h from the Xen public headers.
43
+ */
44
+
13
45
#include <xen/interface/grant_table.h>
14
46
15
47
typedef unsigned int RING_IDX ;
16
48
17
49
/* Round a 32-bit unsigned constant down to the nearest power of two. */
18
- #define __RD2 (_x ) (((_x) & 0x00000002) ? 0x2 : ((_x) & 0x1))
50
+ #define __RD2 (_x ) (((_x) & 0x00000002) ? 0x2 : ((_x) & 0x1))
19
51
#define __RD4 (_x ) (((_x) & 0x0000000c) ? __RD2((_x)>>2)<<2 : __RD2(_x))
20
52
#define __RD8 (_x ) (((_x) & 0x000000f0) ? __RD4((_x)>>4)<<4 : __RD4(_x))
21
53
#define __RD16 (_x ) (((_x) & 0x0000ff00) ? __RD8((_x)>>8)<<8 : __RD8(_x))
@@ -27,82 +59,79 @@ typedef unsigned int RING_IDX;
27
59
* A ring contains as many entries as will fit, rounded down to the nearest
28
60
* power of two (so we can mask with (size-1) to loop around).
29
61
*/
30
- #define __CONST_RING_SIZE (_s , _sz ) \
31
- (__RD32(((_sz) - offsetof(struct _s##_sring, ring)) / \
32
- sizeof(((struct _s##_sring *)0)->ring[0])))
33
-
62
+ #define __CONST_RING_SIZE (_s , _sz ) \
63
+ (__RD32(((_sz) - offsetof(struct _s##_sring, ring)) / \
64
+ sizeof(((struct _s##_sring *)0)->ring[0])))
34
65
/*
35
66
* The same for passing in an actual pointer instead of a name tag.
36
67
*/
37
- #define __RING_SIZE (_s , _sz ) \
38
- (__RD32(((_sz) - (long)& (_s)->ring + (long)(_s)) / sizeof((_s)->ring[0])))
68
+ #define __RING_SIZE (_s , _sz ) \
69
+ (__RD32(((_sz) - (long)(_s)->ring + (long)(_s)) / sizeof((_s)->ring[0])))
39
70
40
71
/*
41
72
* Macros to make the correct C datatypes for a new kind of ring.
42
73
*
43
74
* To make a new ring datatype, you need to have two message structures,
44
- * let's say struct request , and struct response already defined.
75
+ * let's say request_t , and response_t already defined.
45
76
*
46
77
* In a header where you want the ring datatype declared, you then do:
47
78
*
48
- * DEFINE_RING_TYPES(mytag, struct request, struct response );
79
+ * DEFINE_RING_TYPES(mytag, request_t, response_t );
49
80
*
50
81
* These expand out to give you a set of types, as you can see below.
51
82
* The most important of these are:
52
83
*
53
- * struct mytag_sring - The shared ring.
54
- * struct mytag_front_ring - The 'front' half of the ring.
55
- * struct mytag_back_ring - The 'back' half of the ring.
84
+ * mytag_sring_t - The shared ring.
85
+ * mytag_front_ring_t - The 'front' half of the ring.
86
+ * mytag_back_ring_t - The 'back' half of the ring.
56
87
*
57
88
* To initialize a ring in your code you need to know the location and size
58
89
* of the shared memory area (PAGE_SIZE, for instance). To initialise
59
90
* the front half:
60
91
*
61
- * struct mytag_front_ring front_ring;
62
- * SHARED_RING_INIT((struct mytag_sring *)shared_page);
63
- * FRONT_RING_INIT(&front_ring, (struct mytag_sring *)shared_page,
64
- * PAGE_SIZE);
92
+ * mytag_front_ring_t front_ring;
93
+ * SHARED_RING_INIT((mytag_sring_t *)shared_page);
94
+ * FRONT_RING_INIT(&front_ring, (mytag_sring_t *)shared_page, PAGE_SIZE);
65
95
*
66
96
* Initializing the back follows similarly (note that only the front
67
97
* initializes the shared ring):
68
98
*
69
- * struct mytag_back_ring back_ring;
70
- * BACK_RING_INIT(&back_ring, (struct mytag_sring *)shared_page,
71
- * PAGE_SIZE);
99
+ * mytag_back_ring_t back_ring;
100
+ * BACK_RING_INIT(&back_ring, (mytag_sring_t *)shared_page, PAGE_SIZE);
72
101
*/
73
102
74
- #define DEFINE_RING_TYPES (__name , __req_t , __rsp_t ) \
75
- \
76
- /* Shared ring entry */ \
77
- union __name##_sring_entry { \
78
- __req_t req; \
79
- __rsp_t rsp; \
80
- }; \
81
- \
82
- /* Shared ring page */ \
83
- struct __name ##_sring { \
84
- RING_IDX req_prod , req_event ; \
85
- RING_IDX rsp_prod , rsp_event ; \
86
- uint8_t pad [48 ]; \
87
- union __name ##_sring_entry ring [1 ]; /* variable-length */ \
88
- }; \
89
- \
90
- /* "Front" end's private variables */ \
91
- struct __name ##_front_ring { \
92
- RING_IDX req_prod_pvt ; \
93
- RING_IDX rsp_cons ; \
94
- unsigned int nr_ents ; \
95
- struct __name ##_sring * sring ; \
96
- }; \
97
- \
98
- /* "Back" end's private variables */ \
99
- struct __name ##_back_ring { \
100
- RING_IDX rsp_prod_pvt ; \
101
- RING_IDX req_cons ; \
102
- unsigned int nr_ents ; \
103
- struct __name ##_sring * sring ; \
104
- };
105
-
103
+ #define DEFINE_RING_TYPES (__name , __req_t , __rsp_t ) \
104
+ \
105
+ /* Shared ring entry */ \
106
+ union __name##_sring_entry { \
107
+ __req_t req; \
108
+ __rsp_t rsp; \
109
+ }; \
110
+ \
111
+ /* Shared ring page */ \
112
+ struct __name ##_sring { \
113
+ RING_IDX req_prod , req_event ; \
114
+ RING_IDX rsp_prod , rsp_event ; \
115
+ uint8_t __pad [48 ]; \
116
+ union __name ##_sring_entry ring [1 ]; /* variable-length */ \
117
+ }; \
118
+ \
119
+ /* "Front" end's private variables */ \
120
+ struct __name ##_front_ring { \
121
+ RING_IDX req_prod_pvt ; \
122
+ RING_IDX rsp_cons ; \
123
+ unsigned int nr_ents ; \
124
+ struct __name ##_sring * sring ; \
125
+ }; \
126
+ \
127
+ /* "Back" end's private variables */ \
128
+ struct __name ##_back_ring { \
129
+ RING_IDX rsp_prod_pvt ; \
130
+ RING_IDX req_cons ; \
131
+ unsigned int nr_ents ; \
132
+ struct __name ##_sring * sring ; \
133
+ }; \
134
+ \
106
135
/*
107
136
* Macros for manipulating rings.
108
137
*
@@ -119,94 +148,99 @@ struct __name##_back_ring { \
119
148
*/
120
149
121
150
/* Initialising empty rings */
122
- #define SHARED_RING_INIT (_s ) do { \
123
- (_s)->req_prod = (_s)->rsp_prod = 0; \
124
- (_s)->req_event = (_s)->rsp_event = 1; \
125
- memset((_s)->pad , 0, sizeof((_s)->pad )); \
151
+ #define SHARED_RING_INIT (_s ) do { \
152
+ (_s)->req_prod = (_s)->rsp_prod = 0; \
153
+ (_s)->req_event = (_s)->rsp_event = 1; \
154
+ (void) memset((_s)->__pad , 0, sizeof((_s)->__pad )); \
126
155
} while(0)
127
156
128
- #define FRONT_RING_ATTACH (_r , _s , _i , __size ) do { \
129
- (_r)->req_prod_pvt = (_i); \
130
- (_r)->rsp_cons = (_i); \
131
- (_r)->nr_ents = __RING_SIZE(_s, __size); \
132
- (_r)->sring = (_s); \
157
+ #define FRONT_RING_ATTACH (_r , _s , _i , __size ) do { \
158
+ (_r)->req_prod_pvt = (_i); \
159
+ (_r)->rsp_cons = (_i); \
160
+ (_r)->nr_ents = __RING_SIZE(_s, __size); \
161
+ (_r)->sring = (_s); \
133
162
} while (0)
134
163
135
164
#define FRONT_RING_INIT (_r , _s , __size ) FRONT_RING_ATTACH(_r, _s, 0, __size)
136
165
137
- #define BACK_RING_ATTACH (_r , _s , _i , __size ) do { \
138
- (_r)->rsp_prod_pvt = (_i); \
139
- (_r)->req_cons = (_i); \
140
- (_r)->nr_ents = __RING_SIZE(_s, __size); \
141
- (_r)->sring = (_s); \
166
+ #define BACK_RING_ATTACH (_r , _s , _i , __size ) do { \
167
+ (_r)->rsp_prod_pvt = (_i); \
168
+ (_r)->req_cons = (_i); \
169
+ (_r)->nr_ents = __RING_SIZE(_s, __size); \
170
+ (_r)->sring = (_s); \
142
171
} while (0)
143
172
144
173
#define BACK_RING_INIT (_r , _s , __size ) BACK_RING_ATTACH(_r, _s, 0, __size)
145
174
146
175
/* How big is this ring? */
147
- #define RING_SIZE (_r ) \
176
+ #define RING_SIZE (_r ) \
148
177
((_r)->nr_ents)
149
178
150
179
/* Number of free requests (for use on front side only). */
151
- #define RING_FREE_REQUESTS (_r ) \
180
+ #define RING_FREE_REQUESTS (_r ) \
152
181
(RING_SIZE(_r) - ((_r)->req_prod_pvt - (_r)->rsp_cons))
153
182
154
183
/* Test if there is an empty slot available on the front ring.
155
184
* (This is only meaningful from the front. )
156
185
*/
157
- #define RING_FULL (_r ) \
186
+ #define RING_FULL (_r ) \
158
187
(RING_FREE_REQUESTS(_r) == 0)
159
188
160
189
/* Test if there are outstanding messages to be processed on a ring. */
161
- #define RING_HAS_UNCONSUMED_RESPONSES (_r ) \
190
+ #define RING_HAS_UNCONSUMED_RESPONSES (_r ) \
162
191
((_r)->sring->rsp_prod - (_r)->rsp_cons)
163
192
164
- #define RING_HAS_UNCONSUMED_REQUESTS (_r ) \
165
- ({ \
166
- unsigned int req = (_r)->sring->req_prod - (_r)->req_cons; \
167
- unsigned int rsp = RING_SIZE(_r) - \
168
- ((_r)->req_cons - (_r)->rsp_prod_pvt); \
169
- req < rsp ? req : rsp; \
170
- })
193
+ #define RING_HAS_UNCONSUMED_REQUESTS (_r ) ({ \
194
+ unsigned int req = (_r)->sring->req_prod - (_r)->req_cons; \
195
+ unsigned int rsp = RING_SIZE(_r) - \
196
+ ((_r)->req_cons - (_r)->rsp_prod_pvt); \
197
+ req < rsp ? req : rsp; \
198
+ })
171
199
172
200
/* Direct access to individual ring elements, by index. */
173
- #define RING_GET_REQUEST (_r , _idx ) \
201
+ #define RING_GET_REQUEST (_r , _idx ) \
174
202
(&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].req))
175
203
204
+ #define RING_GET_RESPONSE (_r , _idx ) \
205
+ (&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].rsp))
206
+
176
207
/*
177
- * Get a local copy of a request.
208
+ * Get a local copy of a request/response .
178
209
*
179
- * Use this in preference to RING_GET_REQUEST () so all processing is
210
+ * Use this in preference to RING_GET_{REQUEST,RESPONSE} () so all processing is
180
211
* done on a local copy that cannot be modified by the other end.
181
212
*
182
213
* Note that https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58145 may cause this
183
- * to be ineffective where _req is a struct which consists of only bitfields.
214
+ * to be ineffective where dest is a struct which consists of only bitfields.
184
215
*/
185
- #define RING_COPY_REQUEST ( _r , _idx , _req ) do { \
186
- /* Use volatile to force the copy into _req . */ \
187
- * (_req ) = * (volatile typeof (_req )) RING_GET_REQUEST ( _r , _idx ); \
216
+ #define RING_COPY_ ( type , r , idx , dest ) do { \
217
+ /* Use volatile to force the copy into dest . */ \
218
+ * (dest ) = * (volatile typeof (dest )) RING_GET_ # #type (r, idx ); \
188
219
} while (0)
189
220
190
- #define RING_GET_RESPONSE ( _r , _idx ) \
191
- (&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))]. rsp) )
221
+ #define RING_COPY_REQUEST ( r , idx , req ) RING_COPY_(REQUEST, r, idx, req)
222
+ #define RING_COPY_RESPONSE ( r , idx , rsp ) RING_COPY_(RESPONSE, r, idx, rsp)
192
223
193
224
/* Loop termination condition: Would the specified index overflow the ring? */
194
- #define RING_REQUEST_CONS_OVERFLOW (_r , _cons ) \
225
+ #define RING_REQUEST_CONS_OVERFLOW (_r , _cons ) \
195
226
(((_cons) - (_r)->rsp_prod_pvt) >= RING_SIZE(_r))
196
227
197
228
/* Ill-behaved frontend determination: Can there be this many requests? */
198
- #define RING_REQUEST_PROD_OVERFLOW (_r , _prod ) \
229
+ #define RING_REQUEST_PROD_OVERFLOW (_r , _prod ) \
199
230
(((_prod) - (_r)->rsp_prod_pvt) > RING_SIZE(_r))
200
231
232
+ /* Ill-behaved backend determination: Can there be this many responses? */
233
+ #define RING_RESPONSE_PROD_OVERFLOW (_r , _prod ) \
234
+ (((_prod) - (_r)->rsp_cons) > RING_SIZE(_r))
201
235
202
- #define RING_PUSH_REQUESTS (_r ) do { \
203
- virt_wmb(); /* back sees requests /before/ updated producer index */ \
204
- (_r )-> sring -> req_prod = (_r )-> req_prod_pvt ; \
236
+ #define RING_PUSH_REQUESTS (_r ) do { \
237
+ virt_wmb(); /* back sees requests /before/ updated producer index */ \
238
+ (_r )-> sring -> req_prod = (_r )-> req_prod_pvt ; \
205
239
} while (0 )
206
240
207
- #define RING_PUSH_RESPONSES (_r ) do { \
208
- virt_wmb(); /* front sees responses /before/ updated producer index */ \
209
- (_r )-> sring -> rsp_prod = (_r )-> rsp_prod_pvt ; \
241
+ #define RING_PUSH_RESPONSES (_r ) do { \
242
+ virt_wmb(); /* front sees resps /before/ updated producer index */ \
243
+ (_r )-> sring -> rsp_prod = (_r )-> rsp_prod_pvt ; \
210
244
} while (0 )
211
245
212
246
/*
@@ -239,40 +273,40 @@ struct __name##_back_ring { \
239
273
* field appropriately.
240
274
*/
241
275
242
- #define RING_PUSH_REQUESTS_AND_CHECK_NOTIFY (_r , _notify ) do { \
243
- RING_IDX __old = (_r)->sring->req_prod; \
244
- RING_IDX __new = (_r)->req_prod_pvt; \
245
- virt_wmb(); /* back sees requests /before/ updated producer index */ \
246
- (_r )-> sring -> req_prod = __new ; \
247
- virt_mb (); /* back sees new requests /before/ we check req_event */ \
248
- (_notify ) = ((RING_IDX )(__new - (_r )-> sring -> req_event ) < \
249
- (RING_IDX )(__new - __old )); \
276
+ #define RING_PUSH_REQUESTS_AND_CHECK_NOTIFY (_r , _notify ) do { \
277
+ RING_IDX __old = (_r)->sring->req_prod; \
278
+ RING_IDX __new = (_r)->req_prod_pvt; \
279
+ virt_wmb(); /* back sees requests /before/ updated producer index */ \
280
+ (_r )-> sring -> req_prod = __new ; \
281
+ virt_mb (); /* back sees new requests /before/ we check req_event */ \
282
+ (_notify ) = ((RING_IDX )(__new - (_r )-> sring -> req_event ) < \
283
+ (RING_IDX )(__new - __old )); \
250
284
} while (0 )
251
285
252
- #define RING_PUSH_RESPONSES_AND_CHECK_NOTIFY (_r , _notify ) do { \
253
- RING_IDX __old = (_r)->sring->rsp_prod; \
254
- RING_IDX __new = (_r)->rsp_prod_pvt; \
255
- virt_wmb(); /* front sees responses /before/ updated producer index */ \
256
- (_r )-> sring -> rsp_prod = __new ; \
257
- virt_mb (); /* front sees new responses /before/ we check rsp_event */ \
258
- (_notify ) = ((RING_IDX )(__new - (_r )-> sring -> rsp_event ) < \
259
- (RING_IDX )(__new - __old )); \
286
+ #define RING_PUSH_RESPONSES_AND_CHECK_NOTIFY (_r , _notify ) do { \
287
+ RING_IDX __old = (_r)->sring->rsp_prod; \
288
+ RING_IDX __new = (_r)->rsp_prod_pvt; \
289
+ virt_wmb(); /* front sees resps /before/ updated producer index */ \
290
+ (_r )-> sring -> rsp_prod = __new ; \
291
+ virt_mb (); /* front sees new resps /before/ we check rsp_event */ \
292
+ (_notify ) = ((RING_IDX )(__new - (_r )-> sring -> rsp_event ) < \
293
+ (RING_IDX )(__new - __old )); \
260
294
} while (0 )
261
295
262
- #define RING_FINAL_CHECK_FOR_REQUESTS (_r , _work_to_do ) do { \
263
- (_work_to_do) = RING_HAS_UNCONSUMED_REQUESTS(_r); \
264
- if (_work_to_do) break; \
265
- (_r)->sring->req_event = (_r)->req_cons + 1; \
266
- virt_mb(); \
267
- (_work_to_do) = RING_HAS_UNCONSUMED_REQUESTS(_r); \
296
+ #define RING_FINAL_CHECK_FOR_REQUESTS (_r , _work_to_do ) do { \
297
+ (_work_to_do) = RING_HAS_UNCONSUMED_REQUESTS(_r); \
298
+ if (_work_to_do) break; \
299
+ (_r)->sring->req_event = (_r)->req_cons + 1; \
300
+ virt_mb(); \
301
+ (_work_to_do) = RING_HAS_UNCONSUMED_REQUESTS(_r); \
268
302
} while (0)
269
303
270
- #define RING_FINAL_CHECK_FOR_RESPONSES (_r , _work_to_do ) do { \
271
- (_work_to_do) = RING_HAS_UNCONSUMED_RESPONSES(_r); \
272
- if (_work_to_do) break; \
273
- (_r)->sring->rsp_event = (_r)->rsp_cons + 1; \
274
- virt_mb(); \
275
- (_work_to_do) = RING_HAS_UNCONSUMED_RESPONSES(_r); \
304
+ #define RING_FINAL_CHECK_FOR_RESPONSES (_r , _work_to_do ) do { \
305
+ (_work_to_do) = RING_HAS_UNCONSUMED_RESPONSES(_r); \
306
+ if (_work_to_do) break; \
307
+ (_r)->sring->rsp_event = (_r)->rsp_cons + 1; \
308
+ virt_mb(); \
309
+ (_work_to_do) = RING_HAS_UNCONSUMED_RESPONSES(_r); \
276
310
} while (0)
277
311
278
312
0 commit comments