aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/hyperv.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/hyperv.h')
-rw-r--r--include/linux/hyperv.h53
1 files changed, 25 insertions, 28 deletions
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index cd184bdca58f..42fe43fb0c80 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -696,7 +696,7 @@ enum vmbus_device_type {
696 HV_FCOPY, 696 HV_FCOPY,
697 HV_BACKUP, 697 HV_BACKUP,
698 HV_DM, 698 HV_DM,
699 HV_UNKOWN, 699 HV_UNKNOWN,
700}; 700};
701 701
702struct vmbus_device { 702struct vmbus_device {
@@ -1119,6 +1119,12 @@ struct hv_driver {
1119 1119
1120 struct device_driver driver; 1120 struct device_driver driver;
1121 1121
1122 /* dynamic device GUID's */
1123 struct {
1124 spinlock_t lock;
1125 struct list_head list;
1126 } dynids;
1127
1122 int (*probe)(struct hv_device *, const struct hv_vmbus_device_id *); 1128 int (*probe)(struct hv_device *, const struct hv_vmbus_device_id *);
1123 int (*remove)(struct hv_device *); 1129 int (*remove)(struct hv_device *);
1124 void (*shutdown)(struct hv_device *); 1130 void (*shutdown)(struct hv_device *);
@@ -1447,6 +1453,7 @@ void hv_event_tasklet_enable(struct vmbus_channel *channel);
1447 1453
1448void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid); 1454void hv_process_channel_removal(struct vmbus_channel *channel, u32 relid);
1449 1455
1456void vmbus_setevent(struct vmbus_channel *channel);
1450/* 1457/*
1451 * Negotiated version with the Host. 1458 * Negotiated version with the Host.
1452 */ 1459 */
@@ -1479,10 +1486,11 @@ hv_get_ring_buffer(struct hv_ring_buffer_info *ring_info)
1479 * there is room for the producer to send the pending packet. 1486 * there is room for the producer to send the pending packet.
1480 */ 1487 */
1481 1488
1482static inline bool hv_need_to_signal_on_read(struct hv_ring_buffer_info *rbi) 1489static inline void hv_signal_on_read(struct vmbus_channel *channel)
1483{ 1490{
1484 u32 cur_write_sz; 1491 u32 cur_write_sz;
1485 u32 pending_sz; 1492 u32 pending_sz;
1493 struct hv_ring_buffer_info *rbi = &channel->inbound;
1486 1494
1487 /* 1495 /*
1488 * Issue a full memory barrier before making the signaling decision. 1496 * Issue a full memory barrier before making the signaling decision.
@@ -1500,14 +1508,14 @@ static inline bool hv_need_to_signal_on_read(struct hv_ring_buffer_info *rbi)
1500 pending_sz = READ_ONCE(rbi->ring_buffer->pending_send_sz); 1508 pending_sz = READ_ONCE(rbi->ring_buffer->pending_send_sz);
1501 /* If the other end is not blocked on write don't bother. */ 1509 /* If the other end is not blocked on write don't bother. */
1502 if (pending_sz == 0) 1510 if (pending_sz == 0)
1503 return false; 1511 return;
1504 1512
1505 cur_write_sz = hv_get_bytes_to_write(rbi); 1513 cur_write_sz = hv_get_bytes_to_write(rbi);
1506 1514
1507 if (cur_write_sz >= pending_sz) 1515 if (cur_write_sz >= pending_sz)
1508 return true; 1516 vmbus_setevent(channel);
1509 1517
1510 return false; 1518 return;
1511} 1519}
1512 1520
1513/* 1521/*
@@ -1519,31 +1527,23 @@ static inline struct vmpacket_descriptor *
1519get_next_pkt_raw(struct vmbus_channel *channel) 1527get_next_pkt_raw(struct vmbus_channel *channel)
1520{ 1528{
1521 struct hv_ring_buffer_info *ring_info = &channel->inbound; 1529 struct hv_ring_buffer_info *ring_info = &channel->inbound;
1522 u32 read_loc = ring_info->priv_read_index; 1530 u32 priv_read_loc = ring_info->priv_read_index;
1523 void *ring_buffer = hv_get_ring_buffer(ring_info); 1531 void *ring_buffer = hv_get_ring_buffer(ring_info);
1524 struct vmpacket_descriptor *cur_desc;
1525 u32 packetlen;
1526 u32 dsize = ring_info->ring_datasize; 1532 u32 dsize = ring_info->ring_datasize;
1527 u32 delta = read_loc - ring_info->ring_buffer->read_index; 1533 /*
1534 * delta is the difference between what is available to read and
1535 * what was already consumed in place. We commit read index after
1536 * the whole batch is processed.
1537 */
1538 u32 delta = priv_read_loc >= ring_info->ring_buffer->read_index ?
1539 priv_read_loc - ring_info->ring_buffer->read_index :
1540 (dsize - ring_info->ring_buffer->read_index) + priv_read_loc;
1528 u32 bytes_avail_toread = (hv_get_bytes_to_read(ring_info) - delta); 1541 u32 bytes_avail_toread = (hv_get_bytes_to_read(ring_info) - delta);
1529 1542
1530 if (bytes_avail_toread < sizeof(struct vmpacket_descriptor)) 1543 if (bytes_avail_toread < sizeof(struct vmpacket_descriptor))
1531 return NULL; 1544 return NULL;
1532 1545
1533 if ((read_loc + sizeof(*cur_desc)) > dsize) 1546 return ring_buffer + priv_read_loc;
1534 return NULL;
1535
1536 cur_desc = ring_buffer + read_loc;
1537 packetlen = cur_desc->len8 << 3;
1538
1539 /*
1540 * If the packet under consideration is wrapping around,
1541 * return failure.
1542 */
1543 if ((read_loc + packetlen + VMBUS_PKT_TRAILER) > (dsize - 1))
1544 return NULL;
1545
1546 return cur_desc;
1547} 1547}
1548 1548
1549/* 1549/*
@@ -1555,16 +1555,14 @@ static inline void put_pkt_raw(struct vmbus_channel *channel,
1555 struct vmpacket_descriptor *desc) 1555 struct vmpacket_descriptor *desc)
1556{ 1556{
1557 struct hv_ring_buffer_info *ring_info = &channel->inbound; 1557 struct hv_ring_buffer_info *ring_info = &channel->inbound;
1558 u32 read_loc = ring_info->priv_read_index;
1559 u32 packetlen = desc->len8 << 3; 1558 u32 packetlen = desc->len8 << 3;
1560 u32 dsize = ring_info->ring_datasize; 1559 u32 dsize = ring_info->ring_datasize;
1561 1560
1562 if ((read_loc + packetlen + VMBUS_PKT_TRAILER) > dsize)
1563 BUG();
1564 /* 1561 /*
1565 * Include the packet trailer. 1562 * Include the packet trailer.
1566 */ 1563 */
1567 ring_info->priv_read_index += packetlen + VMBUS_PKT_TRAILER; 1564 ring_info->priv_read_index += packetlen + VMBUS_PKT_TRAILER;
1565 ring_info->priv_read_index %= dsize;
1568} 1566}
1569 1567
1570/* 1568/*
@@ -1589,8 +1587,7 @@ static inline void commit_rd_index(struct vmbus_channel *channel)
1589 virt_rmb(); 1587 virt_rmb();
1590 ring_info->ring_buffer->read_index = ring_info->priv_read_index; 1588 ring_info->ring_buffer->read_index = ring_info->priv_read_index;
1591 1589
1592 if (hv_need_to_signal_on_read(ring_info)) 1590 hv_signal_on_read(channel);
1593 vmbus_set_event(channel);
1594} 1591}
1595 1592
1596 1593