| @@ -128,6 +128,7 @@ struct hv_ring_buffer_info { · 127 unmodified lines |
| 128 | 128 | u32 ring_data_startoffset; |
| 129 | 129 | u32 priv_write_index; |
| 130 | 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) · 46 unmodified lines |
| 180 | 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 | 198 | * VMBUS version is 32 bit entity broken up into |
| 185 | 199 | * two 16 bit quantities: major_number. minor_number. |
| @@ -1488,7 +1502,7 @@ hv_get_ring_buffer(struct hv_ring_buffer_info *ring_info) · 1302 unmodified lines |
| 1488 | 1502 | |
| 1489 | 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 | 1506 | u32 pending_sz; |
| 1493 | 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) · 17 unmodified lines |
| 1512 | 1526 | |
| 1513 | 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 | 1534 | vmbus_setevent(channel); |
| 1517 | 1535 | |
| 1518 | 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 | 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, · 45 unmodified lines |
| 1569 | 1595 | * This call commits the read index and potentially signals the host. |
| 1570 | 1596 | * Here is the pattern for using the "in-place" consumption APIs: |
| 1571 | 1597 | * |
| 1598 | + * init_cached_read_index(); |
| 1599 | + * |
| 1572 | 1600 | * while (get_next_pkt_raw() { |
| 1573 | 1601 | * process the packet "in-place"; |
| 1574 | 1602 | * put_pkt_raw(); |