diff options
Diffstat (limited to 'include/linux/hyperv.h')
| -rw-r--r-- | include/linux/hyperv.h | 96 | 
1 files changed, 30 insertions, 66 deletions
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index 970771a5f739..0c170a3f0d8b 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h @@ -1508,14 +1508,6 @@ static inline  void hv_signal_on_read(struct vmbus_channel *channel)  	return;  } -static inline void -init_cached_read_index(struct vmbus_channel *channel) -{ -	struct hv_ring_buffer_info *rbi = &channel->inbound; - -	rbi->cached_read_index = rbi->ring_buffer->read_index; -} -  /*   * Mask off host interrupt callback notifications   */ @@ -1549,76 +1541,48 @@ static inline u32 hv_end_read(struct hv_ring_buffer_info *rbi)  /*   * An API to support in-place processing of incoming VMBUS packets.   */ -#define VMBUS_PKT_TRAILER	8 -static inline struct vmpacket_descriptor * -get_next_pkt_raw(struct vmbus_channel *channel) +/* Get data payload associated with descriptor */ +static inline void *hv_pkt_data(const struct vmpacket_descriptor *desc)  { -	struct hv_ring_buffer_info *ring_info = &channel->inbound; -	u32 priv_read_loc = ring_info->priv_read_index; -	void *ring_buffer = hv_get_ring_buffer(ring_info); -	u32 dsize = ring_info->ring_datasize; -	/* -	 * delta is the difference between what is available to read and -	 * what was already consumed in place. We commit read index after -	 * the whole batch is processed. -	 */ -	u32 delta = priv_read_loc >= ring_info->ring_buffer->read_index ? -		priv_read_loc - ring_info->ring_buffer->read_index : -		(dsize - ring_info->ring_buffer->read_index) + priv_read_loc; -	u32 bytes_avail_toread = (hv_get_bytes_to_read(ring_info) - delta); - -	if (bytes_avail_toread < sizeof(struct vmpacket_descriptor)) -		return NULL; - -	return ring_buffer + priv_read_loc; +	return (void *)((unsigned long)desc + (desc->offset8 << 3));  } -/* - * A helper function to step through packets "in-place" - * This API is to be called after each successful call - * get_next_pkt_raw(). - */ -static inline void put_pkt_raw(struct vmbus_channel *channel, -				struct vmpacket_descriptor *desc) +/* Get data size associated with descriptor */ +static inline u32 hv_pkt_datalen(const struct vmpacket_descriptor *desc)  { -	struct hv_ring_buffer_info *ring_info = &channel->inbound; -	u32 packetlen = desc->len8 << 3; -	u32 dsize = ring_info->ring_datasize; - -	/* -	 * Include the packet trailer. -	 */ -	ring_info->priv_read_index += packetlen + VMBUS_PKT_TRAILER; -	ring_info->priv_read_index %= dsize; +	return (desc->len8 << 3) - (desc->offset8 << 3);  } + +struct vmpacket_descriptor * +hv_pkt_iter_first(struct vmbus_channel *channel); + +struct vmpacket_descriptor * +__hv_pkt_iter_next(struct vmbus_channel *channel, +		   const struct vmpacket_descriptor *pkt); + +void hv_pkt_iter_close(struct vmbus_channel *channel); +  /* - * This call commits the read index and potentially signals the host. - * Here is the pattern for using the "in-place" consumption APIs: - * - * init_cached_read_index(); - * - * while (get_next_pkt_raw() { - *	process the packet "in-place"; - *	put_pkt_raw(); - * } - * if (packets processed in place) - *	commit_rd_index(); + * Get next packet descriptor from iterator + * If at end of list, return NULL and update host.   */ -static inline void commit_rd_index(struct vmbus_channel *channel) +static inline struct vmpacket_descriptor * +hv_pkt_iter_next(struct vmbus_channel *channel, +		 const struct vmpacket_descriptor *pkt)  { -	struct hv_ring_buffer_info *ring_info = &channel->inbound; -	/* -	 * Make sure all reads are done before we update the read index since -	 * the writer may start writing to the read area once the read index -	 * is updated. -	 */ -	virt_rmb(); -	ring_info->ring_buffer->read_index = ring_info->priv_read_index; +	struct vmpacket_descriptor *nxt; + +	nxt = __hv_pkt_iter_next(channel, pkt); +	if (!nxt) +		hv_pkt_iter_close(channel); -	hv_signal_on_read(channel); +	return nxt;  } +#define foreach_vmbus_pkt(pkt, channel) \ +	for (pkt = hv_pkt_iter_first(channel); pkt; \ +	    pkt = hv_pkt_iter_next(channel, pkt))  #endif /* _HYPERV_H */  | 
