Skip to content

Commit 629a5d8

Browse files
committed
xen: sync include/xen/interface/io/ring.h with Xen's newest version
Sync include/xen/interface/io/ring.h with Xen's newest version in order to get the RING_COPY_RESPONSE() and RING_RESPONSE_PROD_OVERFLOW() macros. Note that this will correct the wrong license info by adding the missing original copyright notice. Signed-off-by: Juergen Gross <[email protected]>
1 parent 2060061 commit 629a5d8

File tree

1 file changed

+156
-122
lines changed
  • include/xen/interface/io

1 file changed

+156
-122
lines changed

include/xen/interface/io/ring.h

Lines changed: 156 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,53 @@
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

1547
typedef 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

Comments
 (0)