diff options
Diffstat (limited to 'include/linux/hyperv.h')
-rw-r--r-- | include/linux/hyperv.h | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h index 42fe43fb0c80..183efde54269 100644 --- a/include/linux/hyperv.h +++ b/include/linux/hyperv.h | |||
@@ -128,6 +128,7 @@ struct hv_ring_buffer_info { | |||
128 | u32 ring_data_startoffset; | 128 | u32 ring_data_startoffset; |
129 | u32 priv_write_index; | 129 | u32 priv_write_index; |
130 | u32 priv_read_index; | 130 | u32 priv_read_index; |
131 | u32 cached_read_index; | ||
131 | }; | 132 | }; |
132 | 133 | ||
133 | /* | 134 | /* |
@@ -180,6 +181,19 @@ static inline u32 hv_get_bytes_to_write(struct hv_ring_buffer_info *rbi) | |||
180 | return write; | 181 | return write; |
181 | } | 182 | } |
182 | 183 | ||
184 | static inline u32 hv_get_cached_bytes_to_write( | ||
185 | const struct hv_ring_buffer_info *rbi) | ||
186 | { | ||
187 | u32 read_loc, write_loc, dsize, write; | ||
188 | |||
189 | dsize = rbi->ring_datasize; | ||
190 | read_loc = rbi->cached_read_index; | ||
191 | write_loc = rbi->ring_buffer->write_index; | ||
192 | |||
193 | write = write_loc >= read_loc ? dsize - (write_loc - read_loc) : | ||
194 | read_loc - write_loc; | ||
195 | return write; | ||
196 | } | ||
183 | /* | 197 | /* |
184 | * VMBUS version is 32 bit entity broken up into | 198 | * VMBUS version is 32 bit entity broken up into |
185 | * two 16 bit quantities: major_number. minor_number. | 199 | * two 16 bit quantities: major_number. minor_number. |
@@ -1488,7 +1502,7 @@ hv_get_ring_buffer(struct hv_ring_buffer_info *ring_info) | |||
1488 | 1502 | ||
1489 | static inline void hv_signal_on_read(struct vmbus_channel *channel) | 1503 | static inline void hv_signal_on_read(struct vmbus_channel *channel) |
1490 | { | 1504 | { |
1491 | u32 cur_write_sz; | 1505 | u32 cur_write_sz, cached_write_sz; |
1492 | u32 pending_sz; | 1506 | u32 pending_sz; |
1493 | struct hv_ring_buffer_info *rbi = &channel->inbound; | 1507 | struct hv_ring_buffer_info *rbi = &channel->inbound; |
1494 | 1508 | ||
@@ -1512,12 +1526,24 @@ static inline void hv_signal_on_read(struct vmbus_channel *channel) | |||
1512 | 1526 | ||
1513 | cur_write_sz = hv_get_bytes_to_write(rbi); | 1527 | cur_write_sz = hv_get_bytes_to_write(rbi); |
1514 | 1528 | ||
1515 | if (cur_write_sz >= pending_sz) | 1529 | if (cur_write_sz < pending_sz) |
1530 | return; | ||
1531 | |||
1532 | cached_write_sz = hv_get_cached_bytes_to_write(rbi); | ||
1533 | if (cached_write_sz < pending_sz) | ||
1516 | vmbus_setevent(channel); | 1534 | vmbus_setevent(channel); |
1517 | 1535 | ||
1518 | return; | 1536 | return; |
1519 | } | 1537 | } |
1520 | 1538 | ||
1539 | static inline void | ||
1540 | init_cached_read_index(struct vmbus_channel *channel) | ||
1541 | { | ||
1542 | struct hv_ring_buffer_info *rbi = &channel->inbound; | ||
1543 | |||
1544 | rbi->cached_read_index = rbi->ring_buffer->read_index; | ||
1545 | } | ||
1546 | |||
1521 | /* | 1547 | /* |
1522 | * An API to support in-place processing of incoming VMBUS packets. | 1548 | * An API to support in-place processing of incoming VMBUS packets. |
1523 | */ | 1549 | */ |
@@ -1569,6 +1595,8 @@ static inline void put_pkt_raw(struct vmbus_channel *channel, | |||
1569 | * This call commits the read index and potentially signals the host. | 1595 | * This call commits the read index and potentially signals the host. |
1570 | * Here is the pattern for using the "in-place" consumption APIs: | 1596 | * Here is the pattern for using the "in-place" consumption APIs: |
1571 | * | 1597 | * |
1598 | * init_cached_read_index(); | ||
1599 | * | ||
1572 | * while (get_next_pkt_raw() { | 1600 | * while (get_next_pkt_raw() { |
1573 | * process the packet "in-place"; | 1601 | * process the packet "in-place"; |
1574 | * put_pkt_raw(); | 1602 | * put_pkt_raw(); |