1- /* SPDX-License-Identifier: GPL-2.0 */
21/******************************************************************************
32 * ring.h
43 *
54 * Shared producer-consumer ring macros.
65 *
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+ *
724 * Tim Deegan and Andrew Warfield November 2004.
825 */
926
1027#ifndef __XEN_PUBLIC_IO_RING_H__
1128#define __XEN_PUBLIC_IO_RING_H__
1229
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+
1345#include <xen/interface/grant_table.h>
1446
1547typedef unsigned int RING_IDX ;
1648
1749/* 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))
1951#define __RD4 (_x ) (((_x) & 0x0000000c) ? __RD2((_x)>>2)<<2 : __RD2(_x))
2052#define __RD8 (_x ) (((_x) & 0x000000f0) ? __RD4((_x)>>4)<<4 : __RD4(_x))
2153#define __RD16 (_x ) (((_x) & 0x0000ff00) ? __RD8((_x)>>8)<<8 : __RD8(_x))
@@ -27,82 +59,79 @@ typedef unsigned int RING_IDX;
2759 * A ring contains as many entries as will fit, rounded down to the nearest
2860 * power of two (so we can mask with (size-1) to loop around).
2961 */
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])))
3465/*
3566 * The same for passing in an actual pointer instead of a name tag.
3667 */
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])))
3970
4071/*
4172 * Macros to make the correct C datatypes for a new kind of ring.
4273 *
4374 * 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.
4576 *
4677 * In a header where you want the ring datatype declared, you then do:
4778 *
48- * DEFINE_RING_TYPES(mytag, struct request, struct response );
79+ * DEFINE_RING_TYPES(mytag, request_t, response_t );
4980 *
5081 * These expand out to give you a set of types, as you can see below.
5182 * The most important of these are:
5283 *
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.
5687 *
5788 * To initialize a ring in your code you need to know the location and size
5889 * of the shared memory area (PAGE_SIZE, for instance). To initialise
5990 * the front half:
6091 *
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);
6595 *
6696 * Initializing the back follows similarly (note that only the front
6797 * initializes the shared ring):
6898 *
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);
72101 */
73102
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+ \
106135/*
107136 * Macros for manipulating rings.
108137 *
@@ -119,94 +148,99 @@ struct __name##_back_ring { \
119148 */
120149
121150/* 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 )); \
126155} while(0)
127156
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); \
133162} while (0)
134163
135164#define FRONT_RING_INIT (_r , _s , __size ) FRONT_RING_ATTACH(_r, _s, 0, __size)
136165
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); \
142171} while (0)
143172
144173#define BACK_RING_INIT (_r , _s , __size ) BACK_RING_ATTACH(_r, _s, 0, __size)
145174
146175/* How big is this ring? */
147- #define RING_SIZE (_r ) \
176+ #define RING_SIZE (_r ) \
148177 ((_r)->nr_ents)
149178
150179/* Number of free requests (for use on front side only). */
151- #define RING_FREE_REQUESTS (_r ) \
180+ #define RING_FREE_REQUESTS (_r ) \
152181 (RING_SIZE(_r) - ((_r)->req_prod_pvt - (_r)->rsp_cons))
153182
154183/* Test if there is an empty slot available on the front ring.
155184 * (This is only meaningful from the front. )
156185 */
157- #define RING_FULL (_r ) \
186+ #define RING_FULL (_r ) \
158187 (RING_FREE_REQUESTS(_r) == 0)
159188
160189/* 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 ) \
162191 ((_r)->sring->rsp_prod - (_r)->rsp_cons)
163192
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+ })
171199
172200/* Direct access to individual ring elements, by index. */
173- #define RING_GET_REQUEST (_r , _idx ) \
201+ #define RING_GET_REQUEST (_r , _idx ) \
174202 (&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].req))
175203
204+ #define RING_GET_RESPONSE (_r , _idx ) \
205+ (&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].rsp))
206+
176207/*
177- * Get a local copy of a request.
208+ * Get a local copy of a request/response .
178209 *
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
180211 * done on a local copy that cannot be modified by the other end.
181212 *
182213 * 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.
184215 */
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 ); \
188219} while (0)
189220
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)
192223
193224/* 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 ) \
195226 (((_cons) - (_r)->rsp_prod_pvt) >= RING_SIZE(_r))
196227
197228/* 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 ) \
199230 (((_prod) - (_r)->rsp_prod_pvt) > RING_SIZE(_r))
200231
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))
201235
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 ; \
205239} while (0 )
206240
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 ; \
210244} while (0 )
211245
212246/*
@@ -239,40 +273,40 @@ struct __name##_back_ring { \
239273 * field appropriately.
240274 */
241275
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 )); \
250284} while (0 )
251285
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 )); \
260294} while (0 )
261295
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); \
268302} while (0)
269303
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); \
276310} while (0)
277311
278312
0 commit comments