Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754661AbdCFULn (ORCPT ); Mon, 6 Mar 2017 15:11:43 -0500 Received: from mail.kernel.org ([198.145.29.136]:51920 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754105AbdCFULS (ORCPT ); Mon, 6 Mar 2017 15:11:18 -0500 From: Stefano Stabellini To: xen-devel@lists.xenproject.org Cc: linux-kernel@vger.kernel.org, sstabellini@kernel.org, Stefano Stabellini , konrad.wilk@oracle.com, boris.ostrovsky@oracle.com, jgross@suse.com Subject: [PATCH 1/7] xen: import new ring macros in ring.h Date: Mon, 6 Mar 2017 12:01:22 -0800 Message-Id: <1488830488-18506-1-git-send-email-sstabellini@kernel.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 9238 Lines: 158 Sync the ring.h file with upstream Xen, to introduce the new ring macros. They will be used by the Xen transport for 9pfs. Signed-off-by: Stefano Stabellini CC: konrad.wilk@oracle.com CC: boris.ostrovsky@oracle.com CC: jgross@suse.com --- NB: The new macros have not been committed to Xen yet. Do not apply this patch until they do. --- --- include/xen/interface/io/ring.h | 131 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) diff --git a/include/xen/interface/io/ring.h b/include/xen/interface/io/ring.h index 21f4fbd..e16aa92 100644 --- a/include/xen/interface/io/ring.h +++ b/include/xen/interface/io/ring.h @@ -283,4 +283,135 @@ struct __name##_back_ring { \ (_work_to_do) = RING_HAS_UNCONSUMED_RESPONSES(_r); \ } while (0) + +/* + * DEFINE_XEN_FLEX_RING_AND_INTF defines two monodirectional rings and + * functions to check if there is data on the ring, and to read and + * write to them. + * + * DEFINE_XEN_FLEX_RING is similar to DEFINE_XEN_FLEX_RING_AND_INTF, but + * does not define the indexes page. As different protocols can have + * extensions to the basic format, this macro allow them to define their + * own struct. + * + * XEN_FLEX_RING_SIZE + * Convenience macro to calculate the size of one of the two rings + * from the overall order. + * + * $NAME_mask + * Function to apply the size mask to an index, to reduce the index + * within the range [0-size]. + * + * $NAME_read_packet + * Function to read data from the ring. The amount of data to read is + * specified by the "size" argument. + * + * $NAME_write_packet + * Function to write data to the ring. The amount of data to write is + * specified by the "size" argument. + * + * $NAME_get_ring_ptr + * Convenience function that returns a pointer to read/write to the + * ring at the right location. + * + * $NAME_data_intf + * Indexes page, shared between frontend and backend. It also + * contains the array of grant refs. + * + * $NAME_queued + * Function to calculate how many bytes are currently on the ring, + * ready to be read. It can also be used to calculate how much free + * space is currently on the ring (ring_size - $NAME_queued()). + */ +#define XEN_FLEX_RING_SIZE(order) \ + (1UL << (order + PAGE_SHIFT - 1)) + +#define DEFINE_XEN_FLEX_RING_AND_INTF(name) \ +struct name##_data_intf { \ + RING_IDX in_cons, in_prod; \ + \ + uint8_t pad1[56]; \ + \ + RING_IDX out_cons, out_prod; \ + \ + uint8_t pad2[56]; \ + \ + RING_IDX ring_order; \ + grant_ref_t ref[]; \ +}; \ +DEFINE_XEN_FLEX_RING(name); + +#define DEFINE_XEN_FLEX_RING(name) \ +static inline RING_IDX name##_mask(RING_IDX idx, RING_IDX ring_size) \ +{ \ + return (idx & (ring_size - 1)); \ +} \ + \ +static inline RING_IDX name##_mask_order(RING_IDX idx, RING_IDX ring_order) \ +{ \ + return (idx & (XEN_FLEX_RING_SIZE(ring_order) - 1)); \ +} \ + \ +static inline unsigned char* name##_get_ring_ptr(unsigned char *buf, \ + RING_IDX idx, \ + RING_IDX ring_order) \ +{ \ + return buf + name##_mask_order(idx, ring_order); \ +} \ + \ +static inline void name##_read_packet(const unsigned char *buf, \ + RING_IDX masked_prod, RING_IDX *masked_cons, \ + RING_IDX ring_size, void *opaque, size_t size) { \ + if (*masked_cons < masked_prod || \ + size <= ring_size - *masked_cons) { \ + memcpy(opaque, buf + *masked_cons, size); \ + } else { \ + memcpy(opaque, buf + *masked_cons, ring_size - *masked_cons); \ + memcpy((unsigned char *)opaque + ring_size - *masked_cons, buf, \ + size - (ring_size - *masked_cons)); \ + } \ + *masked_cons = name##_mask(*masked_cons + size, ring_size); \ +} \ + \ +static inline void name##_write_packet(unsigned char *buf, \ + RING_IDX *masked_prod, RING_IDX masked_cons, \ + RING_IDX ring_size, const void *opaque, size_t size) { \ + if (*masked_prod < masked_cons || \ + size <= ring_size - *masked_prod) { \ + memcpy(buf + *masked_prod, opaque, size); \ + } else { \ + memcpy(buf + *masked_prod, opaque, ring_size - *masked_prod); \ + memcpy(buf, (unsigned char *)opaque + (ring_size - *masked_prod), \ + size - (ring_size - *masked_prod)); \ + } \ + *masked_prod = name##_mask(*masked_prod + size, ring_size); \ +} \ + \ +struct name##_data { \ + unsigned char *in; /* half of the allocation */ \ + unsigned char *out; /* half of the allocation */ \ +}; \ + \ + \ +static inline RING_IDX name##_queued(RING_IDX prod, \ + RING_IDX cons, RING_IDX ring_size) \ +{ \ + RING_IDX size; \ + \ + if (prod == cons) \ + return 0; \ + \ + prod = name##_mask(prod, ring_size); \ + cons = name##_mask(cons, ring_size); \ + \ + if (prod == cons) \ + return ring_size; \ + \ + if (prod > cons) \ + size = prod - cons; \ + else \ + size = ring_size - (cons - prod); \ + return size; \ +}; + #endif /* __XEN_PUBLIC_IO_RING_H__ */ -- 1.9.1