1*8ac98aedSDavid Woodhouse /* SPDX-License-Identifier: MIT */ 2a3434a2dSAnthony PERARD /****************************************************************************** 3a3434a2dSAnthony PERARD * ring.h 4a3434a2dSAnthony PERARD * 5a3434a2dSAnthony PERARD * Shared producer-consumer ring macros. 6a3434a2dSAnthony PERARD * 7a3434a2dSAnthony PERARD * Tim Deegan and Andrew Warfield November 2004. 8a3434a2dSAnthony PERARD */ 9a3434a2dSAnthony PERARD 10a3434a2dSAnthony PERARD #ifndef __XEN_PUBLIC_IO_RING_H__ 11a3434a2dSAnthony PERARD #define __XEN_PUBLIC_IO_RING_H__ 12a3434a2dSAnthony PERARD 13a3434a2dSAnthony PERARD /* 14a3434a2dSAnthony PERARD * When #include'ing this header, you need to provide the following 15a3434a2dSAnthony PERARD * declaration upfront: 16a3434a2dSAnthony PERARD * - standard integers types (uint8_t, uint16_t, etc) 17a3434a2dSAnthony PERARD * They are provided by stdint.h of the standard headers. 18a3434a2dSAnthony PERARD * 19a3434a2dSAnthony PERARD * In addition, if you intend to use the FLEX macros, you also need to 20a3434a2dSAnthony PERARD * provide the following, before invoking the FLEX macros: 21a3434a2dSAnthony PERARD * - size_t 22a3434a2dSAnthony PERARD * - memcpy 23a3434a2dSAnthony PERARD * - grant_ref_t 24a3434a2dSAnthony PERARD * These declarations are provided by string.h of the standard headers, 25a3434a2dSAnthony PERARD * and grant_table.h from the Xen public headers. 26a3434a2dSAnthony PERARD */ 27a3434a2dSAnthony PERARD 2850c88402SJoao Martins #include "../xen-compat.h" 2950c88402SJoao Martins 3050c88402SJoao Martins #if __XEN_INTERFACE_VERSION__ < 0x00030208 3150c88402SJoao Martins #define xen_mb() mb() 3250c88402SJoao Martins #define xen_rmb() rmb() 3350c88402SJoao Martins #define xen_wmb() wmb() 3450c88402SJoao Martins #endif 3550c88402SJoao Martins 36a3434a2dSAnthony PERARD typedef unsigned int RING_IDX; 37a3434a2dSAnthony PERARD 38a3434a2dSAnthony PERARD /* Round a 32-bit unsigned constant down to the nearest power of two. */ 39a3434a2dSAnthony PERARD #define __RD2(_x) (((_x) & 0x00000002) ? 0x2 : ((_x) & 0x1)) 40a3434a2dSAnthony PERARD #define __RD4(_x) (((_x) & 0x0000000c) ? __RD2((_x)>>2)<<2 : __RD2(_x)) 41a3434a2dSAnthony PERARD #define __RD8(_x) (((_x) & 0x000000f0) ? __RD4((_x)>>4)<<4 : __RD4(_x)) 42a3434a2dSAnthony PERARD #define __RD16(_x) (((_x) & 0x0000ff00) ? __RD8((_x)>>8)<<8 : __RD8(_x)) 43a3434a2dSAnthony PERARD #define __RD32(_x) (((_x) & 0xffff0000) ? __RD16((_x)>>16)<<16 : __RD16(_x)) 44a3434a2dSAnthony PERARD 45a3434a2dSAnthony PERARD /* 46a3434a2dSAnthony PERARD * Calculate size of a shared ring, given the total available space for the 47a3434a2dSAnthony PERARD * ring and indexes (_sz), and the name tag of the request/response structure. 48a3434a2dSAnthony PERARD * A ring contains as many entries as will fit, rounded down to the nearest 49a3434a2dSAnthony PERARD * power of two (so we can mask with (size-1) to loop around). 50a3434a2dSAnthony PERARD */ 51a3434a2dSAnthony PERARD #define __CONST_RING_SIZE(_s, _sz) \ 52a3434a2dSAnthony PERARD (__RD32(((_sz) - offsetof(struct _s##_sring, ring)) / \ 5350c88402SJoao Martins sizeof(((struct _s##_sring *)0)->ring[0]))) 54a3434a2dSAnthony PERARD /* 55a3434a2dSAnthony PERARD * The same for passing in an actual pointer instead of a name tag. 56a3434a2dSAnthony PERARD */ 57a3434a2dSAnthony PERARD #define __RING_SIZE(_s, _sz) \ 58a3434a2dSAnthony PERARD (__RD32(((_sz) - (long)(_s)->ring + (long)(_s)) / sizeof((_s)->ring[0]))) 59a3434a2dSAnthony PERARD 60a3434a2dSAnthony PERARD /* 61a3434a2dSAnthony PERARD * Macros to make the correct C datatypes for a new kind of ring. 62a3434a2dSAnthony PERARD * 63a3434a2dSAnthony PERARD * To make a new ring datatype, you need to have two message structures, 64a3434a2dSAnthony PERARD * let's say request_t, and response_t already defined. 65a3434a2dSAnthony PERARD * 66a3434a2dSAnthony PERARD * In a header where you want the ring datatype declared, you then do: 67a3434a2dSAnthony PERARD * 68a3434a2dSAnthony PERARD * DEFINE_RING_TYPES(mytag, request_t, response_t); 69a3434a2dSAnthony PERARD * 70a3434a2dSAnthony PERARD * These expand out to give you a set of types, as you can see below. 71a3434a2dSAnthony PERARD * The most important of these are: 72a3434a2dSAnthony PERARD * 73a3434a2dSAnthony PERARD * mytag_sring_t - The shared ring. 74a3434a2dSAnthony PERARD * mytag_front_ring_t - The 'front' half of the ring. 75a3434a2dSAnthony PERARD * mytag_back_ring_t - The 'back' half of the ring. 76a3434a2dSAnthony PERARD * 77a3434a2dSAnthony PERARD * To initialize a ring in your code you need to know the location and size 78a3434a2dSAnthony PERARD * of the shared memory area (PAGE_SIZE, for instance). To initialise 79a3434a2dSAnthony PERARD * the front half: 80a3434a2dSAnthony PERARD * 81*8ac98aedSDavid Woodhouse * mytag_front_ring_t ring; 82*8ac98aedSDavid Woodhouse * XEN_FRONT_RING_INIT(&ring, (mytag_sring_t *)shared_page, PAGE_SIZE); 83a3434a2dSAnthony PERARD * 84a3434a2dSAnthony PERARD * Initializing the back follows similarly (note that only the front 85a3434a2dSAnthony PERARD * initializes the shared ring): 86a3434a2dSAnthony PERARD * 87a3434a2dSAnthony PERARD * mytag_back_ring_t back_ring; 88a3434a2dSAnthony PERARD * BACK_RING_INIT(&back_ring, (mytag_sring_t *)shared_page, PAGE_SIZE); 89a3434a2dSAnthony PERARD */ 90a3434a2dSAnthony PERARD 91a3434a2dSAnthony PERARD #define DEFINE_RING_TYPES(__name, __req_t, __rsp_t) \ 92a3434a2dSAnthony PERARD \ 93a3434a2dSAnthony PERARD /* Shared ring entry */ \ 94a3434a2dSAnthony PERARD union __name##_sring_entry { \ 95a3434a2dSAnthony PERARD __req_t req; \ 96a3434a2dSAnthony PERARD __rsp_t rsp; \ 97a3434a2dSAnthony PERARD }; \ 98a3434a2dSAnthony PERARD \ 99a3434a2dSAnthony PERARD /* Shared ring page */ \ 100a3434a2dSAnthony PERARD struct __name##_sring { \ 101a3434a2dSAnthony PERARD RING_IDX req_prod, req_event; \ 102a3434a2dSAnthony PERARD RING_IDX rsp_prod, rsp_event; \ 103a3434a2dSAnthony PERARD union { \ 104a3434a2dSAnthony PERARD struct { \ 105a3434a2dSAnthony PERARD uint8_t smartpoll_active; \ 106a3434a2dSAnthony PERARD } netif; \ 107a3434a2dSAnthony PERARD struct { \ 108a3434a2dSAnthony PERARD uint8_t msg; \ 109a3434a2dSAnthony PERARD } tapif_user; \ 110a3434a2dSAnthony PERARD uint8_t pvt_pad[4]; \ 111a3434a2dSAnthony PERARD } pvt; \ 112a3434a2dSAnthony PERARD uint8_t __pad[44]; \ 113a3434a2dSAnthony PERARD union __name##_sring_entry ring[1]; /* variable-length */ \ 114a3434a2dSAnthony PERARD }; \ 115a3434a2dSAnthony PERARD \ 116a3434a2dSAnthony PERARD /* "Front" end's private variables */ \ 117a3434a2dSAnthony PERARD struct __name##_front_ring { \ 118a3434a2dSAnthony PERARD RING_IDX req_prod_pvt; \ 119a3434a2dSAnthony PERARD RING_IDX rsp_cons; \ 120a3434a2dSAnthony PERARD unsigned int nr_ents; \ 121a3434a2dSAnthony PERARD struct __name##_sring *sring; \ 122a3434a2dSAnthony PERARD }; \ 123a3434a2dSAnthony PERARD \ 124a3434a2dSAnthony PERARD /* "Back" end's private variables */ \ 125a3434a2dSAnthony PERARD struct __name##_back_ring { \ 126a3434a2dSAnthony PERARD RING_IDX rsp_prod_pvt; \ 127a3434a2dSAnthony PERARD RING_IDX req_cons; \ 128a3434a2dSAnthony PERARD unsigned int nr_ents; \ 129a3434a2dSAnthony PERARD struct __name##_sring *sring; \ 130a3434a2dSAnthony PERARD }; \ 131a3434a2dSAnthony PERARD \ 132a3434a2dSAnthony PERARD /* Syntactic sugar */ \ 133a3434a2dSAnthony PERARD typedef struct __name##_sring __name##_sring_t; \ 134a3434a2dSAnthony PERARD typedef struct __name##_front_ring __name##_front_ring_t; \ 135a3434a2dSAnthony PERARD typedef struct __name##_back_ring __name##_back_ring_t 136a3434a2dSAnthony PERARD 137a3434a2dSAnthony PERARD /* 138a3434a2dSAnthony PERARD * Macros for manipulating rings. 139a3434a2dSAnthony PERARD * 140a3434a2dSAnthony PERARD * FRONT_RING_whatever works on the "front end" of a ring: here 141a3434a2dSAnthony PERARD * requests are pushed on to the ring and responses taken off it. 142a3434a2dSAnthony PERARD * 143a3434a2dSAnthony PERARD * BACK_RING_whatever works on the "back end" of a ring: here 144a3434a2dSAnthony PERARD * requests are taken off the ring and responses put on. 145a3434a2dSAnthony PERARD * 146a3434a2dSAnthony PERARD * N.B. these macros do NO INTERLOCKS OR FLOW CONTROL. 147a3434a2dSAnthony PERARD * This is OK in 1-for-1 request-response situations where the 148a3434a2dSAnthony PERARD * requestor (front end) never has more than RING_SIZE()-1 149a3434a2dSAnthony PERARD * outstanding requests. 150a3434a2dSAnthony PERARD */ 151a3434a2dSAnthony PERARD 152a3434a2dSAnthony PERARD /* Initialising empty rings */ 153a3434a2dSAnthony PERARD #define SHARED_RING_INIT(_s) do { \ 154a3434a2dSAnthony PERARD (_s)->req_prod = (_s)->rsp_prod = 0; \ 155a3434a2dSAnthony PERARD (_s)->req_event = (_s)->rsp_event = 1; \ 156a3434a2dSAnthony PERARD (void)memset((_s)->pvt.pvt_pad, 0, sizeof((_s)->pvt.pvt_pad)); \ 157a3434a2dSAnthony PERARD (void)memset((_s)->__pad, 0, sizeof((_s)->__pad)); \ 158a3434a2dSAnthony PERARD } while(0) 159a3434a2dSAnthony PERARD 16050c88402SJoao Martins #define FRONT_RING_ATTACH(_r, _s, _i, __size) do { \ 16150c88402SJoao Martins (_r)->req_prod_pvt = (_i); \ 16250c88402SJoao Martins (_r)->rsp_cons = (_i); \ 163a3434a2dSAnthony PERARD (_r)->nr_ents = __RING_SIZE(_s, __size); \ 164a3434a2dSAnthony PERARD (_r)->sring = (_s); \ 165a3434a2dSAnthony PERARD } while (0) 166a3434a2dSAnthony PERARD 16750c88402SJoao Martins #define FRONT_RING_INIT(_r, _s, __size) FRONT_RING_ATTACH(_r, _s, 0, __size) 16850c88402SJoao Martins 169*8ac98aedSDavid Woodhouse #define XEN_FRONT_RING_INIT(r, s, size) do { \ 170*8ac98aedSDavid Woodhouse SHARED_RING_INIT(s); \ 171*8ac98aedSDavid Woodhouse FRONT_RING_INIT(r, s, size); \ 172*8ac98aedSDavid Woodhouse } while (0) 173*8ac98aedSDavid Woodhouse 17450c88402SJoao Martins #define BACK_RING_ATTACH(_r, _s, _i, __size) do { \ 17550c88402SJoao Martins (_r)->rsp_prod_pvt = (_i); \ 17650c88402SJoao Martins (_r)->req_cons = (_i); \ 177a3434a2dSAnthony PERARD (_r)->nr_ents = __RING_SIZE(_s, __size); \ 178a3434a2dSAnthony PERARD (_r)->sring = (_s); \ 179a3434a2dSAnthony PERARD } while (0) 180a3434a2dSAnthony PERARD 18150c88402SJoao Martins #define BACK_RING_INIT(_r, _s, __size) BACK_RING_ATTACH(_r, _s, 0, __size) 18250c88402SJoao Martins 183a3434a2dSAnthony PERARD /* How big is this ring? */ 184a3434a2dSAnthony PERARD #define RING_SIZE(_r) \ 185a3434a2dSAnthony PERARD ((_r)->nr_ents) 186a3434a2dSAnthony PERARD 187a3434a2dSAnthony PERARD /* Number of free requests (for use on front side only). */ 188a3434a2dSAnthony PERARD #define RING_FREE_REQUESTS(_r) \ 189a3434a2dSAnthony PERARD (RING_SIZE(_r) - ((_r)->req_prod_pvt - (_r)->rsp_cons)) 190a3434a2dSAnthony PERARD 191a3434a2dSAnthony PERARD /* Test if there is an empty slot available on the front ring. 192a3434a2dSAnthony PERARD * (This is only meaningful from the front. ) 193a3434a2dSAnthony PERARD */ 194a3434a2dSAnthony PERARD #define RING_FULL(_r) \ 195a3434a2dSAnthony PERARD (RING_FREE_REQUESTS(_r) == 0) 196a3434a2dSAnthony PERARD 197a3434a2dSAnthony PERARD /* Test if there are outstanding messages to be processed on a ring. */ 198*8ac98aedSDavid Woodhouse #define XEN_RING_NR_UNCONSUMED_RESPONSES(_r) \ 199a3434a2dSAnthony PERARD ((_r)->sring->rsp_prod - (_r)->rsp_cons) 200a3434a2dSAnthony PERARD 20150c88402SJoao Martins #ifdef __GNUC__ 202*8ac98aedSDavid Woodhouse #define XEN_RING_NR_UNCONSUMED_REQUESTS(_r) ({ \ 203a3434a2dSAnthony PERARD unsigned int req = (_r)->sring->req_prod - (_r)->req_cons; \ 204a3434a2dSAnthony PERARD unsigned int rsp = RING_SIZE(_r) - \ 205a3434a2dSAnthony PERARD ((_r)->req_cons - (_r)->rsp_prod_pvt); \ 206a3434a2dSAnthony PERARD req < rsp ? req : rsp; \ 207a3434a2dSAnthony PERARD }) 20850c88402SJoao Martins #else 20950c88402SJoao Martins /* Same as above, but without the nice GCC ({ ... }) syntax. */ 210*8ac98aedSDavid Woodhouse #define XEN_RING_NR_UNCONSUMED_REQUESTS(_r) \ 21150c88402SJoao Martins ((((_r)->sring->req_prod - (_r)->req_cons) < \ 21250c88402SJoao Martins (RING_SIZE(_r) - ((_r)->req_cons - (_r)->rsp_prod_pvt))) ? \ 21350c88402SJoao Martins ((_r)->sring->req_prod - (_r)->req_cons) : \ 21450c88402SJoao Martins (RING_SIZE(_r) - ((_r)->req_cons - (_r)->rsp_prod_pvt))) 21550c88402SJoao Martins #endif 216a3434a2dSAnthony PERARD 217*8ac98aedSDavid Woodhouse #ifdef XEN_RING_HAS_UNCONSUMED_IS_BOOL 218*8ac98aedSDavid Woodhouse /* 219*8ac98aedSDavid Woodhouse * These variants should only be used in case no caller is abusing them for 220*8ac98aedSDavid Woodhouse * obtaining the number of unconsumed responses/requests. 221*8ac98aedSDavid Woodhouse */ 222*8ac98aedSDavid Woodhouse #define RING_HAS_UNCONSUMED_RESPONSES(_r) \ 223*8ac98aedSDavid Woodhouse (!!XEN_RING_NR_UNCONSUMED_RESPONSES(_r)) 224*8ac98aedSDavid Woodhouse #define RING_HAS_UNCONSUMED_REQUESTS(_r) \ 225*8ac98aedSDavid Woodhouse (!!XEN_RING_NR_UNCONSUMED_REQUESTS(_r)) 226*8ac98aedSDavid Woodhouse #else 227*8ac98aedSDavid Woodhouse #define RING_HAS_UNCONSUMED_RESPONSES(_r) XEN_RING_NR_UNCONSUMED_RESPONSES(_r) 228*8ac98aedSDavid Woodhouse #define RING_HAS_UNCONSUMED_REQUESTS(_r) XEN_RING_NR_UNCONSUMED_REQUESTS(_r) 229*8ac98aedSDavid Woodhouse #endif 230*8ac98aedSDavid Woodhouse 231a3434a2dSAnthony PERARD /* Direct access to individual ring elements, by index. */ 232a3434a2dSAnthony PERARD #define RING_GET_REQUEST(_r, _idx) \ 233a3434a2dSAnthony PERARD (&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].req)) 234a3434a2dSAnthony PERARD 23550c88402SJoao Martins #define RING_GET_RESPONSE(_r, _idx) \ 23650c88402SJoao Martins (&((_r)->sring->ring[((_idx) & (RING_SIZE(_r) - 1))].rsp)) 23750c88402SJoao Martins 238a3434a2dSAnthony PERARD /* 23950c88402SJoao Martins * Get a local copy of a request/response. 240a3434a2dSAnthony PERARD * 24150c88402SJoao Martins * Use this in preference to RING_GET_{REQUEST,RESPONSE}() so all processing is 242a3434a2dSAnthony PERARD * done on a local copy that cannot be modified by the other end. 243a3434a2dSAnthony PERARD * 244a3434a2dSAnthony PERARD * Note that https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58145 may cause this 24550c88402SJoao Martins * to be ineffective where dest is a struct which consists of only bitfields. 246a3434a2dSAnthony PERARD */ 24750c88402SJoao Martins #define RING_COPY_(type, r, idx, dest) do { \ 24850c88402SJoao Martins /* Use volatile to force the copy into dest. */ \ 24950c88402SJoao Martins *(dest) = *(volatile __typeof__(dest))RING_GET_##type(r, idx); \ 250a3434a2dSAnthony PERARD } while (0) 251a3434a2dSAnthony PERARD 25250c88402SJoao Martins #define RING_COPY_REQUEST(r, idx, req) RING_COPY_(REQUEST, r, idx, req) 25350c88402SJoao Martins #define RING_COPY_RESPONSE(r, idx, rsp) RING_COPY_(RESPONSE, r, idx, rsp) 254a3434a2dSAnthony PERARD 255a3434a2dSAnthony PERARD /* Loop termination condition: Would the specified index overflow the ring? */ 256a3434a2dSAnthony PERARD #define RING_REQUEST_CONS_OVERFLOW(_r, _cons) \ 257a3434a2dSAnthony PERARD (((_cons) - (_r)->rsp_prod_pvt) >= RING_SIZE(_r)) 258a3434a2dSAnthony PERARD 259a3434a2dSAnthony PERARD /* Ill-behaved frontend determination: Can there be this many requests? */ 260a3434a2dSAnthony PERARD #define RING_REQUEST_PROD_OVERFLOW(_r, _prod) \ 261a3434a2dSAnthony PERARD (((_prod) - (_r)->rsp_prod_pvt) > RING_SIZE(_r)) 262a3434a2dSAnthony PERARD 26350c88402SJoao Martins /* Ill-behaved backend determination: Can there be this many responses? */ 26450c88402SJoao Martins #define RING_RESPONSE_PROD_OVERFLOW(_r, _prod) \ 26550c88402SJoao Martins (((_prod) - (_r)->rsp_cons) > RING_SIZE(_r)) 26650c88402SJoao Martins 267a3434a2dSAnthony PERARD #define RING_PUSH_REQUESTS(_r) do { \ 268a3434a2dSAnthony PERARD xen_wmb(); /* back sees requests /before/ updated producer index */ \ 269a3434a2dSAnthony PERARD (_r)->sring->req_prod = (_r)->req_prod_pvt; \ 270a3434a2dSAnthony PERARD } while (0) 271a3434a2dSAnthony PERARD 272a3434a2dSAnthony PERARD #define RING_PUSH_RESPONSES(_r) do { \ 273a3434a2dSAnthony PERARD xen_wmb(); /* front sees resps /before/ updated producer index */ \ 274a3434a2dSAnthony PERARD (_r)->sring->rsp_prod = (_r)->rsp_prod_pvt; \ 275a3434a2dSAnthony PERARD } while (0) 276a3434a2dSAnthony PERARD 277a3434a2dSAnthony PERARD /* 278a3434a2dSAnthony PERARD * Notification hold-off (req_event and rsp_event): 279a3434a2dSAnthony PERARD * 280a3434a2dSAnthony PERARD * When queueing requests or responses on a shared ring, it may not always be 281a3434a2dSAnthony PERARD * necessary to notify the remote end. For example, if requests are in flight 282a3434a2dSAnthony PERARD * in a backend, the front may be able to queue further requests without 283a3434a2dSAnthony PERARD * notifying the back (if the back checks for new requests when it queues 284a3434a2dSAnthony PERARD * responses). 285a3434a2dSAnthony PERARD * 286a3434a2dSAnthony PERARD * When enqueuing requests or responses: 287a3434a2dSAnthony PERARD * 288a3434a2dSAnthony PERARD * Use RING_PUSH_{REQUESTS,RESPONSES}_AND_CHECK_NOTIFY(). The second argument 289a3434a2dSAnthony PERARD * is a boolean return value. True indicates that the receiver requires an 290a3434a2dSAnthony PERARD * asynchronous notification. 291a3434a2dSAnthony PERARD * 292a3434a2dSAnthony PERARD * After dequeuing requests or responses (before sleeping the connection): 293a3434a2dSAnthony PERARD * 294a3434a2dSAnthony PERARD * Use RING_FINAL_CHECK_FOR_REQUESTS() or RING_FINAL_CHECK_FOR_RESPONSES(). 295a3434a2dSAnthony PERARD * The second argument is a boolean return value. True indicates that there 296a3434a2dSAnthony PERARD * are pending messages on the ring (i.e., the connection should not be put 297a3434a2dSAnthony PERARD * to sleep). 298a3434a2dSAnthony PERARD * 299a3434a2dSAnthony PERARD * These macros will set the req_event/rsp_event field to trigger a 300a3434a2dSAnthony PERARD * notification on the very next message that is enqueued. If you want to 301a3434a2dSAnthony PERARD * create batches of work (i.e., only receive a notification after several 302a3434a2dSAnthony PERARD * messages have been enqueued) then you will need to create a customised 303a3434a2dSAnthony PERARD * version of the FINAL_CHECK macro in your own code, which sets the event 304a3434a2dSAnthony PERARD * field appropriately. 305a3434a2dSAnthony PERARD */ 306a3434a2dSAnthony PERARD 307a3434a2dSAnthony PERARD #define RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(_r, _notify) do { \ 308a3434a2dSAnthony PERARD RING_IDX __old = (_r)->sring->req_prod; \ 309a3434a2dSAnthony PERARD RING_IDX __new = (_r)->req_prod_pvt; \ 310a3434a2dSAnthony PERARD xen_wmb(); /* back sees requests /before/ updated producer index */ \ 311a3434a2dSAnthony PERARD (_r)->sring->req_prod = __new; \ 312a3434a2dSAnthony PERARD xen_mb(); /* back sees new requests /before/ we check req_event */ \ 313a3434a2dSAnthony PERARD (_notify) = ((RING_IDX)(__new - (_r)->sring->req_event) < \ 314a3434a2dSAnthony PERARD (RING_IDX)(__new - __old)); \ 315a3434a2dSAnthony PERARD } while (0) 316a3434a2dSAnthony PERARD 317a3434a2dSAnthony PERARD #define RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(_r, _notify) do { \ 318a3434a2dSAnthony PERARD RING_IDX __old = (_r)->sring->rsp_prod; \ 319a3434a2dSAnthony PERARD RING_IDX __new = (_r)->rsp_prod_pvt; \ 320a3434a2dSAnthony PERARD xen_wmb(); /* front sees resps /before/ updated producer index */ \ 321a3434a2dSAnthony PERARD (_r)->sring->rsp_prod = __new; \ 322a3434a2dSAnthony PERARD xen_mb(); /* front sees new resps /before/ we check rsp_event */ \ 323a3434a2dSAnthony PERARD (_notify) = ((RING_IDX)(__new - (_r)->sring->rsp_event) < \ 324a3434a2dSAnthony PERARD (RING_IDX)(__new - __old)); \ 325a3434a2dSAnthony PERARD } while (0) 326a3434a2dSAnthony PERARD 327a3434a2dSAnthony PERARD #define RING_FINAL_CHECK_FOR_REQUESTS(_r, _work_to_do) do { \ 328a3434a2dSAnthony PERARD (_work_to_do) = RING_HAS_UNCONSUMED_REQUESTS(_r); \ 329a3434a2dSAnthony PERARD if (_work_to_do) break; \ 330a3434a2dSAnthony PERARD (_r)->sring->req_event = (_r)->req_cons + 1; \ 331a3434a2dSAnthony PERARD xen_mb(); \ 332a3434a2dSAnthony PERARD (_work_to_do) = RING_HAS_UNCONSUMED_REQUESTS(_r); \ 333a3434a2dSAnthony PERARD } while (0) 334a3434a2dSAnthony PERARD 335a3434a2dSAnthony PERARD #define RING_FINAL_CHECK_FOR_RESPONSES(_r, _work_to_do) do { \ 336a3434a2dSAnthony PERARD (_work_to_do) = RING_HAS_UNCONSUMED_RESPONSES(_r); \ 337a3434a2dSAnthony PERARD if (_work_to_do) break; \ 338a3434a2dSAnthony PERARD (_r)->sring->rsp_event = (_r)->rsp_cons + 1; \ 339a3434a2dSAnthony PERARD xen_mb(); \ 340a3434a2dSAnthony PERARD (_work_to_do) = RING_HAS_UNCONSUMED_RESPONSES(_r); \ 341a3434a2dSAnthony PERARD } while (0) 342a3434a2dSAnthony PERARD 343a3434a2dSAnthony PERARD 344a3434a2dSAnthony PERARD /* 345a3434a2dSAnthony PERARD * DEFINE_XEN_FLEX_RING_AND_INTF defines two monodirectional rings and 346a3434a2dSAnthony PERARD * functions to check if there is data on the ring, and to read and 347a3434a2dSAnthony PERARD * write to them. 348a3434a2dSAnthony PERARD * 349a3434a2dSAnthony PERARD * DEFINE_XEN_FLEX_RING is similar to DEFINE_XEN_FLEX_RING_AND_INTF, but 350a3434a2dSAnthony PERARD * does not define the indexes page. As different protocols can have 351a3434a2dSAnthony PERARD * extensions to the basic format, this macro allow them to define their 352a3434a2dSAnthony PERARD * own struct. 353a3434a2dSAnthony PERARD * 354a3434a2dSAnthony PERARD * XEN_FLEX_RING_SIZE 355a3434a2dSAnthony PERARD * Convenience macro to calculate the size of one of the two rings 356a3434a2dSAnthony PERARD * from the overall order. 357a3434a2dSAnthony PERARD * 358a3434a2dSAnthony PERARD * $NAME_mask 359a3434a2dSAnthony PERARD * Function to apply the size mask to an index, to reduce the index 360a3434a2dSAnthony PERARD * within the range [0-size]. 361a3434a2dSAnthony PERARD * 362a3434a2dSAnthony PERARD * $NAME_read_packet 363a3434a2dSAnthony PERARD * Function to read data from the ring. The amount of data to read is 364a3434a2dSAnthony PERARD * specified by the "size" argument. 365a3434a2dSAnthony PERARD * 366a3434a2dSAnthony PERARD * $NAME_write_packet 367a3434a2dSAnthony PERARD * Function to write data to the ring. The amount of data to write is 368a3434a2dSAnthony PERARD * specified by the "size" argument. 369a3434a2dSAnthony PERARD * 370a3434a2dSAnthony PERARD * $NAME_get_ring_ptr 371a3434a2dSAnthony PERARD * Convenience function that returns a pointer to read/write to the 372a3434a2dSAnthony PERARD * ring at the right location. 373a3434a2dSAnthony PERARD * 374a3434a2dSAnthony PERARD * $NAME_data_intf 375a3434a2dSAnthony PERARD * Indexes page, shared between frontend and backend. It also 376a3434a2dSAnthony PERARD * contains the array of grant refs. 377a3434a2dSAnthony PERARD * 378a3434a2dSAnthony PERARD * $NAME_queued 379a3434a2dSAnthony PERARD * Function to calculate how many bytes are currently on the ring, 380a3434a2dSAnthony PERARD * ready to be read. It can also be used to calculate how much free 381a3434a2dSAnthony PERARD * space is currently on the ring (XEN_FLEX_RING_SIZE() - 382a3434a2dSAnthony PERARD * $NAME_queued()). 383a3434a2dSAnthony PERARD */ 384a3434a2dSAnthony PERARD 385a3434a2dSAnthony PERARD #ifndef XEN_PAGE_SHIFT 386a3434a2dSAnthony PERARD /* The PAGE_SIZE for ring protocols and hypercall interfaces is always 387a3434a2dSAnthony PERARD * 4K, regardless of the architecture, and page granularity chosen by 388a3434a2dSAnthony PERARD * operating systems. 389a3434a2dSAnthony PERARD */ 390a3434a2dSAnthony PERARD #define XEN_PAGE_SHIFT 12 391a3434a2dSAnthony PERARD #endif 392a3434a2dSAnthony PERARD #define XEN_FLEX_RING_SIZE(order) \ 393a3434a2dSAnthony PERARD (1UL << ((order) + XEN_PAGE_SHIFT - 1)) 394a3434a2dSAnthony PERARD 395a3434a2dSAnthony PERARD #define DEFINE_XEN_FLEX_RING(name) \ 396a3434a2dSAnthony PERARD static inline RING_IDX name##_mask(RING_IDX idx, RING_IDX ring_size) \ 397a3434a2dSAnthony PERARD { \ 398a3434a2dSAnthony PERARD return idx & (ring_size - 1); \ 399a3434a2dSAnthony PERARD } \ 400a3434a2dSAnthony PERARD \ 401a3434a2dSAnthony PERARD static inline unsigned char *name##_get_ring_ptr(unsigned char *buf, \ 402a3434a2dSAnthony PERARD RING_IDX idx, \ 403a3434a2dSAnthony PERARD RING_IDX ring_size) \ 404a3434a2dSAnthony PERARD { \ 405a3434a2dSAnthony PERARD return buf + name##_mask(idx, ring_size); \ 406a3434a2dSAnthony PERARD } \ 407a3434a2dSAnthony PERARD \ 408a3434a2dSAnthony PERARD static inline void name##_read_packet(void *opaque, \ 409a3434a2dSAnthony PERARD const unsigned char *buf, \ 410a3434a2dSAnthony PERARD size_t size, \ 411a3434a2dSAnthony PERARD RING_IDX masked_prod, \ 412a3434a2dSAnthony PERARD RING_IDX *masked_cons, \ 413a3434a2dSAnthony PERARD RING_IDX ring_size) \ 414a3434a2dSAnthony PERARD { \ 415a3434a2dSAnthony PERARD if (*masked_cons < masked_prod || \ 416a3434a2dSAnthony PERARD size <= ring_size - *masked_cons) { \ 417a3434a2dSAnthony PERARD memcpy(opaque, buf + *masked_cons, size); \ 418a3434a2dSAnthony PERARD } else { \ 419a3434a2dSAnthony PERARD memcpy(opaque, buf + *masked_cons, ring_size - *masked_cons); \ 420a3434a2dSAnthony PERARD memcpy((unsigned char *)opaque + ring_size - *masked_cons, buf, \ 421a3434a2dSAnthony PERARD size - (ring_size - *masked_cons)); \ 422a3434a2dSAnthony PERARD } \ 423a3434a2dSAnthony PERARD *masked_cons = name##_mask(*masked_cons + size, ring_size); \ 424a3434a2dSAnthony PERARD } \ 425a3434a2dSAnthony PERARD \ 426a3434a2dSAnthony PERARD static inline void name##_write_packet(unsigned char *buf, \ 427a3434a2dSAnthony PERARD const void *opaque, \ 428a3434a2dSAnthony PERARD size_t size, \ 429a3434a2dSAnthony PERARD RING_IDX *masked_prod, \ 430a3434a2dSAnthony PERARD RING_IDX masked_cons, \ 431a3434a2dSAnthony PERARD RING_IDX ring_size) \ 432a3434a2dSAnthony PERARD { \ 433a3434a2dSAnthony PERARD if (*masked_prod < masked_cons || \ 434a3434a2dSAnthony PERARD size <= ring_size - *masked_prod) { \ 435a3434a2dSAnthony PERARD memcpy(buf + *masked_prod, opaque, size); \ 436a3434a2dSAnthony PERARD } else { \ 437a3434a2dSAnthony PERARD memcpy(buf + *masked_prod, opaque, ring_size - *masked_prod); \ 438a3434a2dSAnthony PERARD memcpy(buf, (unsigned char *)opaque + (ring_size - *masked_prod), \ 439a3434a2dSAnthony PERARD size - (ring_size - *masked_prod)); \ 440a3434a2dSAnthony PERARD } \ 441a3434a2dSAnthony PERARD *masked_prod = name##_mask(*masked_prod + size, ring_size); \ 442a3434a2dSAnthony PERARD } \ 443a3434a2dSAnthony PERARD \ 444a3434a2dSAnthony PERARD static inline RING_IDX name##_queued(RING_IDX prod, \ 445a3434a2dSAnthony PERARD RING_IDX cons, \ 446a3434a2dSAnthony PERARD RING_IDX ring_size) \ 447a3434a2dSAnthony PERARD { \ 448a3434a2dSAnthony PERARD RING_IDX size; \ 449a3434a2dSAnthony PERARD \ 450a3434a2dSAnthony PERARD if (prod == cons) \ 451a3434a2dSAnthony PERARD return 0; \ 452a3434a2dSAnthony PERARD \ 453a3434a2dSAnthony PERARD prod = name##_mask(prod, ring_size); \ 454a3434a2dSAnthony PERARD cons = name##_mask(cons, ring_size); \ 455a3434a2dSAnthony PERARD \ 456a3434a2dSAnthony PERARD if (prod == cons) \ 457a3434a2dSAnthony PERARD return ring_size; \ 458a3434a2dSAnthony PERARD \ 459a3434a2dSAnthony PERARD if (prod > cons) \ 460a3434a2dSAnthony PERARD size = prod - cons; \ 461a3434a2dSAnthony PERARD else \ 462a3434a2dSAnthony PERARD size = ring_size - (cons - prod); \ 463a3434a2dSAnthony PERARD return size; \ 464a3434a2dSAnthony PERARD } \ 465a3434a2dSAnthony PERARD \ 466a3434a2dSAnthony PERARD struct name##_data { \ 467a3434a2dSAnthony PERARD unsigned char *in; /* half of the allocation */ \ 468a3434a2dSAnthony PERARD unsigned char *out; /* half of the allocation */ \ 469a3434a2dSAnthony PERARD } 470a3434a2dSAnthony PERARD 471a3434a2dSAnthony PERARD #define DEFINE_XEN_FLEX_RING_AND_INTF(name) \ 472a3434a2dSAnthony PERARD struct name##_data_intf { \ 473a3434a2dSAnthony PERARD RING_IDX in_cons, in_prod; \ 474a3434a2dSAnthony PERARD \ 475a3434a2dSAnthony PERARD uint8_t pad1[56]; \ 476a3434a2dSAnthony PERARD \ 477a3434a2dSAnthony PERARD RING_IDX out_cons, out_prod; \ 478a3434a2dSAnthony PERARD \ 479a3434a2dSAnthony PERARD uint8_t pad2[56]; \ 480a3434a2dSAnthony PERARD \ 481a3434a2dSAnthony PERARD RING_IDX ring_order; \ 482a3434a2dSAnthony PERARD grant_ref_t ref[]; \ 483a3434a2dSAnthony PERARD }; \ 484a3434a2dSAnthony PERARD DEFINE_XEN_FLEX_RING(name) 485a3434a2dSAnthony PERARD 486a3434a2dSAnthony PERARD #endif /* __XEN_PUBLIC_IO_RING_H__ */ 487a3434a2dSAnthony PERARD 488a3434a2dSAnthony PERARD /* 489a3434a2dSAnthony PERARD * Local variables: 490a3434a2dSAnthony PERARD * mode: C 491a3434a2dSAnthony PERARD * c-file-style: "BSD" 492a3434a2dSAnthony PERARD * c-basic-offset: 4 493a3434a2dSAnthony PERARD * tab-width: 4 494a3434a2dSAnthony PERARD * indent-tabs-mode: nil 495a3434a2dSAnthony PERARD * End: 496a3434a2dSAnthony PERARD */ 497