aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefano Stabellini <sstabellini@kernel.org>2017-04-05 15:03:55 -0400
committerJuergen Gross <jgross@suse.com>2017-05-02 05:10:59 -0400
commit564f7dfde24a405d877168f150ae5d29d3ad99c7 (patch)
tree05439bc6e0383aad3fcf30717e46a7bd93bc4ca8
parentab1570a427551be2d3eeb30b09834ba01c6109eb (diff)
xen: import new ring macros in ring.h
Sync the ring.h file with upstream Xen, to introduce the new ring macros. They will be used by the Xen transport for 9pfs. CC: konrad.wilk@oracle.com CC: boris.ostrovsky@oracle.com CC: jgross@suse.com CC: groug@kaod.org Signed-off-by: Stefano Stabellini <stefano@aporeto.com> Acked-by: Juergen Gross <jgross@suse.com> Signed-off-by: Juergen Gross <jgross@suse.com>
-rw-r--r--include/xen/interface/io/ring.h143
1 files changed, 143 insertions, 0 deletions
diff --git a/include/xen/interface/io/ring.h b/include/xen/interface/io/ring.h
index 21f4fbd55e48..c79456855539 100644
--- a/include/xen/interface/io/ring.h
+++ b/include/xen/interface/io/ring.h
@@ -283,4 +283,147 @@ struct __name##_back_ring { \
283 (_work_to_do) = RING_HAS_UNCONSUMED_RESPONSES(_r); \ 283 (_work_to_do) = RING_HAS_UNCONSUMED_RESPONSES(_r); \
284} while (0) 284} while (0)
285 285
286
287/*
288 * DEFINE_XEN_FLEX_RING_AND_INTF defines two monodirectional rings and
289 * functions to check if there is data on the ring, and to read and
290 * write to them.
291 *
292 * DEFINE_XEN_FLEX_RING is similar to DEFINE_XEN_FLEX_RING_AND_INTF, but
293 * does not define the indexes page. As different protocols can have
294 * extensions to the basic format, this macro allow them to define their
295 * own struct.
296 *
297 * XEN_FLEX_RING_SIZE
298 * Convenience macro to calculate the size of one of the two rings
299 * from the overall order.
300 *
301 * $NAME_mask
302 * Function to apply the size mask to an index, to reduce the index
303 * within the range [0-size].
304 *
305 * $NAME_read_packet
306 * Function to read data from the ring. The amount of data to read is
307 * specified by the "size" argument.
308 *
309 * $NAME_write_packet
310 * Function to write data to the ring. The amount of data to write is
311 * specified by the "size" argument.
312 *
313 * $NAME_get_ring_ptr
314 * Convenience function that returns a pointer to read/write to the
315 * ring at the right location.
316 *
317 * $NAME_data_intf
318 * Indexes page, shared between frontend and backend. It also
319 * contains the array of grant refs.
320 *
321 * $NAME_queued
322 * Function to calculate how many bytes are currently on the ring,
323 * ready to be read. It can also be used to calculate how much free
324 * space is currently on the ring (XEN_FLEX_RING_SIZE() -
325 * $NAME_queued()).
326 */
327
328#ifndef XEN_PAGE_SHIFT
329/* The PAGE_SIZE for ring protocols and hypercall interfaces is always
330 * 4K, regardless of the architecture, and page granularity chosen by
331 * operating systems.
332 */
333#define XEN_PAGE_SHIFT 12
334#endif
335#define XEN_FLEX_RING_SIZE(order) \
336 (1UL << ((order) + XEN_PAGE_SHIFT - 1))
337
338#define DEFINE_XEN_FLEX_RING(name) \
339static inline RING_IDX name##_mask(RING_IDX idx, RING_IDX ring_size) \
340{ \
341 return idx & (ring_size - 1); \
342} \
343 \
344static inline unsigned char *name##_get_ring_ptr(unsigned char *buf, \
345 RING_IDX idx, \
346 RING_IDX ring_size) \
347{ \
348 return buf + name##_mask(idx, ring_size); \
349} \
350 \
351static inline void name##_read_packet(void *opaque, \
352 const unsigned char *buf, \
353 size_t size, \
354 RING_IDX masked_prod, \
355 RING_IDX *masked_cons, \
356 RING_IDX ring_size) \
357{ \
358 if (*masked_cons < masked_prod || \
359 size <= ring_size - *masked_cons) { \
360 memcpy(opaque, buf + *masked_cons, size); \
361 } else { \
362 memcpy(opaque, buf + *masked_cons, ring_size - *masked_cons); \
363 memcpy((unsigned char *)opaque + ring_size - *masked_cons, buf, \
364 size - (ring_size - *masked_cons)); \
365 } \
366 *masked_cons = name##_mask(*masked_cons + size, ring_size); \
367} \
368 \
369static inline void name##_write_packet(unsigned char *buf, \
370 const void *opaque, \
371 size_t size, \
372 RING_IDX *masked_prod, \
373 RING_IDX masked_cons, \
374 RING_IDX ring_size) \
375{ \
376 if (*masked_prod < masked_cons || \
377 size <= ring_size - *masked_prod) { \
378 memcpy(buf + *masked_prod, opaque, size); \
379 } else { \
380 memcpy(buf + *masked_prod, opaque, ring_size - *masked_prod); \
381 memcpy(buf, (unsigned char *)opaque + (ring_size - *masked_prod), \
382 size - (ring_size - *masked_prod)); \
383 } \
384 *masked_prod = name##_mask(*masked_prod + size, ring_size); \
385} \
386 \
387static inline RING_IDX name##_queued(RING_IDX prod, \
388 RING_IDX cons, \
389 RING_IDX ring_size) \
390{ \
391 RING_IDX size; \
392 \
393 if (prod == cons) \
394 return 0; \
395 \
396 prod = name##_mask(prod, ring_size); \
397 cons = name##_mask(cons, ring_size); \
398 \
399 if (prod == cons) \
400 return ring_size; \
401 \
402 if (prod > cons) \
403 size = prod - cons; \
404 else \
405 size = ring_size - (cons - prod); \
406 return size; \
407} \
408 \
409struct name##_data { \
410 unsigned char *in; /* half of the allocation */ \
411 unsigned char *out; /* half of the allocation */ \
412}
413
414#define DEFINE_XEN_FLEX_RING_AND_INTF(name) \
415struct name##_data_intf { \
416 RING_IDX in_cons, in_prod; \
417 \
418 uint8_t pad1[56]; \
419 \
420 RING_IDX out_cons, out_prod; \
421 \
422 uint8_t pad2[56]; \
423 \
424 RING_IDX ring_order; \
425 grant_ref_t ref[]; \
426}; \
427DEFINE_XEN_FLEX_RING(name)
428
286#endif /* __XEN_PUBLIC_IO_RING_H__ */ 429#endif /* __XEN_PUBLIC_IO_RING_H__ */